Back to index

gcompris  8.2.2
Defines | Typedefs | Functions | Variables
gameutil.c File Reference
#include <math.h>
#include <string.h>
#include <time.h>
#include <glib/gstdio.h>
#include <libxml/parserInternals.h>
#include "gcompris.h"

Go to the source code of this file.

Defines

#define G_STDIO_NO_WRAP_ON_UNIX

Typedefs

typedef void(* sighandler_t )(int)

Functions

GdkPixbuf * gc_pixmap_load (const gchar *format,...)
 load a pixmap from the filesystem
static void do_colorshift (GdkPixbuf *dest, GdkPixbuf *src, int shift)
static GdkPixbuf * make_hc_pixbuf (GdkPixbuf *pb, gint val)
void gc_item_focus_free (GnomeCanvasItem *item, void *none)
 Free the highlight image from our image_focus system.
void gc_item_focus_set (GnomeCanvasItem *item, gboolean focus)
 Set the focus of the given image (highlight or not)
gint gc_item_focus_event (GnomeCanvasItem *item, GdkEvent *event, GnomeCanvasItem *dest_item)
 Callback over a canvas item, this function will highlight the focussed item or the given one.
gchar * reactivate_newline (char *str)
void gc_item_absolute_move (GnomeCanvasItem *item, int x, int y)
void gc_item_rotate (GnomeCanvasItem *item, double angle)
 As gnome does not implement its own API : gc_item_rotate we have to do it ourselves ....
void gc_item_rotate_relative (GnomeCanvasItem *item, double angle)
void gc_item_rotate_with_center (GnomeCanvasItem *item, double angle, int x, int y)
 rotates an item around the center (x,y), relative to the widget's coordinates
void gc_item_rotate_relative_with_center (GnomeCanvasItem *item, double angle, int x, int y)
 rotates an item around the center (x,y), relative to the widget's coordinates The rotation is relative to the previous rotation
GnomeCanvasGroup * gc_difficulty_display (GnomeCanvasGroup *parent, double x, double y, double ratio, gint difficulty)
 Display the number of stars representing the difficulty level at the x,y location The stars are created in a group 'parent' The new group in which the stars are created is returned.
gchar * g_utf8_strndup (gchar *utf8text, gint n)
gchar * gc_file_find_absolute (const gchar *format,...)
 search a given relative file in all gcompris dir it could be found
int gc_util_create_rootdir (gchar *rootdir)
 Create a directory if needed.

Variables

GnomeCanvas * canvas

Define Documentation

Definition at line 27 of file gameutil.c.


Typedef Documentation

typedef void(* sighandler_t)(int)

Definition at line 37 of file gameutil.c.


Function Documentation

static void do_colorshift ( GdkPixbuf *  dest,
GdkPixbuf *  src,
int  shift 
) [static]

Definition at line 100 of file gameutil.c.

{
  gint i, j;
  gint width, height, has_alpha, srcrowstride, destrowstride;
  guchar *target_pixels;
  guchar *original_pixels;
  guchar *pixsrc;
  guchar *pixdest;
  int val;
  guchar r,g,b;

  has_alpha = gdk_pixbuf_get_has_alpha (src);
  width = gdk_pixbuf_get_width (src);
  height = gdk_pixbuf_get_height (src);
  srcrowstride = gdk_pixbuf_get_rowstride (src);
  destrowstride = gdk_pixbuf_get_rowstride (dest);
  target_pixels = gdk_pixbuf_get_pixels (dest);
  original_pixels = gdk_pixbuf_get_pixels (src);

  for (i = 0; i < height; i++) {
    pixdest = target_pixels + i*destrowstride;
    pixsrc = original_pixels + i*srcrowstride;
    for (j = 0; j < width; j++) {
      r = *(pixsrc++);
      g = *(pixsrc++);
      b = *(pixsrc++);
      val = r + shift;
      *(pixdest++) = CLAMP(val, 0, 255);
      val = g + shift;
      *(pixdest++) = CLAMP(val, 0, 255);
      val = b + shift;
      *(pixdest++) = CLAMP(val, 0, 255);
      if (has_alpha)
       *(pixdest++) = *(pixsrc++);
    }
  }
}

Here is the caller graph for this function:

gchar* g_utf8_strndup ( gchar *  utf8text,
gint  n 
)

Definition at line 478 of file gameutil.c.

{
 gchar* result;

 gint len = g_utf8_strlen(utf8text, -1);

 if( n < len && n > 0 )
   len = n;

 result = g_strndup(utf8text, g_utf8_offset_to_pointer(utf8text, len) - utf8text);

 return result;
}

Here is the caller graph for this function:

GnomeCanvasGroup* gc_difficulty_display ( GnomeCanvasGroup *  parent,
double  x,
double  y,
double  ratio,
gint  difficulty 
)

Display the number of stars representing the difficulty level at the x,y location The stars are created in a group 'parent' The new group in which the stars are created is returned.

This is only usefull for the menu plugin and the configuration dialog box.

Definition at line 431 of file gameutil.c.

{
  GdkPixbuf *pixmap = NULL;
  GnomeCanvasGroup *stars_group = NULL;
  GnomeCanvasPixbuf *item = NULL;
  gchar *filename = NULL;

  if(difficulty==0 || difficulty>6)
    return NULL;

  filename = g_strdup_printf("difficulty_star%d.png", difficulty);
  pixmap   = gc_skin_pixmap_load(filename);
  g_free(filename);

  if(!pixmap)
    return NULL;

  stars_group = GNOME_CANVAS_GROUP(
                              gnome_canvas_item_new (parent,
                                                  gnome_canvas_group_get_type (),
                                                  "x", (double) 0,
                                                  "y", (double) 0,
                                                  NULL));

  item = GNOME_CANVAS_PIXBUF(gnome_canvas_item_new (stars_group,
                                              gnome_canvas_pixbuf_get_type (),
                                              "pixbuf", pixmap,
                                              "x", x,
                                              "y", y,
                                              "width", (double) gdk_pixbuf_get_width(pixmap) * ratio,
                                              "height", (double) gdk_pixbuf_get_height(pixmap) * ratio,
                                              "width_set", TRUE,
                                              "height_set", TRUE,
                                              NULL));

  gtk_signal_connect(GTK_OBJECT(item), "event",
                   (GtkSignalFunc) gc_item_focus_event,
                   NULL);

  gdk_pixbuf_unref(pixmap);

  return(stars_group);
}

Here is the call graph for this function:

Here is the caller graph for this function:

gchar* gc_file_find_absolute ( const gchar *  format,
  ... 
)

search a given relative file in all gcompris dir it could be found

Parameters:
format,:If format contains $LOCALE, it will be first replaced by the current long locale and if not found the short locale name. It support printf formating.
...,:additional params for the format (printf like)
Returns:
NULL or a new gchar* with the absolute_filename of the given filename or a full url to it.

Definition at line 502 of file gameutil.c.

{
  va_list             args;
  int                 i = 0;
  gchar                     *filename;
  gchar                     *absolute_filename;
  gchar                     *dir_to_search[4];
  GcomprisProperties *properties = gc_prop_get();

  if (!format)
    return NULL;

  va_start (args, format);
  filename = g_strdup_vprintf (format, args);
  va_end (args);

  /* Check it's already an absolute file */
  if( ((g_path_is_absolute (filename) &&
       g_file_test (filename, G_FILE_TEST_EXISTS))
       || gc_net_is_url(filename)) )
    {
      return filename;
    }

  /*
   * Search it on the file system
   */

  dir_to_search[i++] = properties->package_data_dir;
  dir_to_search[i++] = properties->user_data_dir;
  dir_to_search[i++] = NULL;

  absolute_filename = g_strdup(filename);
  i = 0;

  while (dir_to_search[i])
    {
      gchar **tmp;
      g_free(absolute_filename);

      /* Check there is a $LOCALE to replace */
      if((tmp = g_strsplit(filename, "$LOCALE", -1)))
       {
         gchar locale[6];
         gchar *filename2;

         /* First try with the long locale */
         g_strlcpy(locale, gc_locale_get(), sizeof(locale));
         filename2 = g_strjoinv(locale, tmp);
         absolute_filename = g_strdup_printf("%s/%s", dir_to_search[i], filename2);
         if(g_file_test (absolute_filename, G_FILE_TEST_EXISTS))
           {
             g_strfreev(tmp);
             g_free(filename2);
             goto FOUND;
           }
      g_free(absolute_filename);
         /* Now check if this file is on the net */
         if((absolute_filename = gc_net_get_url_from_file(filename2, NULL)))
           {
             g_strfreev(tmp);
             g_free(filename2);
             goto FOUND;
           }

      g_free(filename2);
      g_free(absolute_filename);
         /* Try the short locale */
         if(g_strv_length(tmp)>1)
           {
             locale[2] = '\0';
             filename2 = g_strjoinv(locale, tmp);
             g_strfreev(tmp);
             absolute_filename = g_strdup_printf("%s/%s", dir_to_search[i], filename2);
             if(g_file_test (absolute_filename, G_FILE_TEST_EXISTS))
              {
                g_free(filename2);
                goto FOUND;
              }

             /* Now check if this file is on the net */
             if((absolute_filename = gc_net_get_url_from_file(filename2, NULL)))
              {
                g_free(filename2);
                goto FOUND;
              }
        g_free(filename2);

           }
      else
          g_strfreev(tmp);
       }
      else
       {
         absolute_filename = g_strdup_printf("%s/%s", dir_to_search[i], filename);

         if(g_file_test (absolute_filename, G_FILE_TEST_EXISTS))
           goto FOUND;
    g_free(absolute_filename);
         /* Now check if this file is on the net */
         if((absolute_filename = gc_net_get_url_from_file(filename, NULL)))
           goto FOUND;
      g_free(absolute_filename);
       }

      i++;
    }

  g_free(filename);
  g_free(absolute_filename);
  return NULL;

 FOUND:
  g_free(filename);
  return absolute_filename;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void gc_item_absolute_move ( GnomeCanvasItem *  item,
int  x,
int  y 
)

Definition at line 285 of file gameutil.c.

                                                                {
  double dx1, dy1, dx2, dy2;
  gnome_canvas_item_get_bounds(item, &dx1, &dy1, &dx2, &dy2);
  gnome_canvas_item_move(item, ((double)x)-dx1, ((double)y)-dy1);
}

Here is the caller graph for this function:

gint gc_item_focus_event ( GnomeCanvasItem *  item,
GdkEvent *  event,
GnomeCanvasItem *  dest_item 
)

Callback over a canvas item, this function will highlight the focussed item or the given one.

Definition at line 234 of file gameutil.c.

{

  if(dest_item!=NULL)
    item = dest_item;

  switch (event->type)
    {
    case GDK_ENTER_NOTIFY:
      gc_item_focus_set(item, TRUE);
      break;
    case GDK_LEAVE_NOTIFY:
      gc_item_focus_set(item, FALSE);
      break;
    default:
      break;
    }

  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void gc_item_focus_free ( GnomeCanvasItem *  item,
void *  none 
)

Free the highlight image from our image_focus system.

It must be called before assigning a new image to an item that already has a focus enabled with gc_item_focus_event().

Definition at line 165 of file gameutil.c.

{
  GdkPixbuf *pixbuf;

  pixbuf = (GdkPixbuf *)g_object_get_data (G_OBJECT (item), "pixbuf_ref");
  if(pixbuf)
    {
      g_object_set_data (G_OBJECT (item), "pixbuf_ref", NULL);
      gdk_pixbuf_unref(pixbuf);
    }
}

Here is the caller graph for this function:

void gc_item_focus_set ( GnomeCanvasItem *  item,
gboolean  focus 
)

Set the focus of the given image (highlight or not)

Definition at line 181 of file gameutil.c.

{
  GdkPixbuf *dest = NULL;
  GdkPixbuf *pixbuf;
  GdkPixbuf *pixbuf_ref;

  gtk_object_get (GTK_OBJECT (item), "pixbuf", &pixbuf, NULL);
  g_return_if_fail (pixbuf != NULL);
  gdk_pixbuf_unref(pixbuf);

  /* Store the first pixbuf */
  pixbuf_ref = (GdkPixbuf *)g_object_get_data (G_OBJECT (item), "pixbuf_ref");
  if(!pixbuf_ref)
    {
      g_object_set_data (G_OBJECT (item), "pixbuf_ref", pixbuf);
      pixbuf_ref = pixbuf;
      gdk_pixbuf_ref(pixbuf);
      g_signal_connect (item, "destroy",
                     G_CALLBACK (gc_item_focus_free),
                     NULL);

    }


  switch (focus)
    {
    case TRUE:
      dest = make_hc_pixbuf(pixbuf, 30);
      gnome_canvas_item_set (item,
                          "pixbuf", dest,
                          NULL);

      break;
    case FALSE:
      gnome_canvas_item_set (item,
                          "pixbuf", pixbuf_ref,
                          NULL);
      break;
    default:
      break;
    }

  if(dest!=NULL)
    gdk_pixbuf_unref (dest);

}

Here is the call graph for this function:

Here is the caller graph for this function:

void gc_item_rotate ( GnomeCanvasItem *  item,
double  angle 
)

As gnome does not implement its own API : gc_item_rotate we have to do it ourselves ....

IMPORTANT NOTE : This is designed for an item with "anchor" = GTK_ANCHOR_CENTER rotation is clockwise if angle > 0

Definition at line 298 of file gameutil.c.

                                                    {
  double r[6],t[6], x1, x2, y1, y2;

  gnome_canvas_item_get_bounds( item, &x1, &y1, &x2, &y2 );
  art_affine_translate( t , -(x2+x1)/2, -(y2+y1)/2 );
  art_affine_rotate( r, angle );
  art_affine_multiply( r, t, r);
  art_affine_translate( t , (x2+x1)/2, (y2+y1)/2 );
  art_affine_multiply( r, r, t);

  gnome_canvas_item_affine_absolute(item, r );
}

Here is the caller graph for this function:

void gc_item_rotate_relative ( GnomeCanvasItem *  item,
double  angle 
)

Definition at line 317 of file gameutil.c.

                                                             {
  double x1, x2, y1, y2;
  double tx1, tx2, ty1, ty2;
  double cx, cy;
  double t;
  double r[6];

  //  gnome_canvas_item_get_bounds( item, &x1, &y1, &x2, &y2 );
  /* WARNING: Do not use gnome_canvas_item_get_bounds which gives unpredictable results */
  if(GNOME_IS_CANVAS_LINE(item)) {
    GnomeCanvasPoints       *points;
    gtk_object_get (GTK_OBJECT (item), "points", &points, NULL);
    x1 = points->coords[0];
    y1 = points->coords[1];
    x2 = points->coords[2];
    y2 = points->coords[3];
  } else if(GNOME_IS_CANVAS_PIXBUF(item)){
    gtk_object_get (GTK_OBJECT (item), "x", &x1, NULL);
    gtk_object_get (GTK_OBJECT (item), "y", &y1, NULL);
    gtk_object_get (GTK_OBJECT (item), "width",  &x2, NULL);
    gtk_object_get (GTK_OBJECT (item), "height", &y2, NULL);
    x2 += x1;
    y2 += y1;
  } else if(GNOME_IS_CANVAS_GROUP(item)){
    gtk_object_get (GTK_OBJECT (item), "x", &x1, NULL);
    gtk_object_get (GTK_OBJECT (item), "y", &y1, NULL);
    x2 = x1;
    y2 = y1;
  } else {
    gtk_object_get (GTK_OBJECT (item), "x1", &x1, NULL);
    gtk_object_get (GTK_OBJECT (item), "y1", &y1, NULL);
    gtk_object_get (GTK_OBJECT (item), "x2", &x2, NULL);
    gtk_object_get (GTK_OBJECT (item), "y2", &y2, NULL);
  }

  tx1 = x1;
  ty1 = y1;
  tx2 = x2;
  ty2 = y2;

  x1 = MIN(tx1,tx2);
  y1 = MIN(ty1,ty2);
  x2 = MAX(tx1,tx2);
  y2 = MAX(ty1,ty2);


  cx = (x2+x1)/2;
  cy = (y2+y1)/2;

  /* Taken from anim by Yves Combe
   * This matrix rotate around ( cx, cy )
   * This is the result of the product:
   *            T_{-c}             Rot (t)                 T_c
   *
   *       1    0   cx       cos(t) -sin(t)    0        1    0  -cx
   *       0    1   cy  by   sin(t)  cos(t)    0   by   0    1  -cy
   *       0    0    1         0       0       1        0    0   1
   */

  t = M_PI*angle/180.0;

  r[0] = cos(t);
  r[1] = sin(t);
  r[2] = -sin(t);
  r[3] = cos(t);
  r[4] = (1-cos(t))*cx + sin(t)*cy;
  r[5] = -sin(t)*cx + (1 - cos(t))*cy;

  gnome_canvas_item_affine_relative(item, r );
}

Here is the caller graph for this function:

void gc_item_rotate_relative_with_center ( GnomeCanvasItem *  item,
double  angle,
int  x,
int  y 
)

rotates an item around the center (x,y), relative to the widget's coordinates The rotation is relative to the previous rotation

Definition at line 410 of file gameutil.c.

                                                                                       {
  double r[6],t[6], x1, x2, y1, y2, tx, ty;

  gnome_canvas_item_get_bounds( item, &x1, &y1, &x2, &y2 );
  tx = x1 + x;
  ty = y1 + y;
  art_affine_translate( t , -tx, -ty );
  art_affine_rotate( r, angle );
  art_affine_multiply( r, t, r);
  art_affine_translate( t , tx, ty );
  art_affine_multiply( r, r, t);

  gnome_canvas_item_affine_relative(item, r );
}

Here is the caller graph for this function:

void gc_item_rotate_with_center ( GnomeCanvasItem *  item,
double  angle,
int  x,
int  y 
)

rotates an item around the center (x,y), relative to the widget's coordinates

Definition at line 391 of file gameutil.c.

                                                                              {
  double r[6],t[6], x1, x2, y1, y2, tx, ty;

  gnome_canvas_item_get_bounds( item, &x1, &y1, &x2, &y2 );
  tx = x1 + x;
  ty = y1 + y;
  art_affine_translate( t , -tx, -ty );
  art_affine_rotate( r, angle );
  art_affine_multiply( r, t, r);
  art_affine_translate( t , tx, ty );
  art_affine_multiply( r, r, t);

  gnome_canvas_item_affine_absolute(item, r );
}

Here is the caller graph for this function:

GdkPixbuf* gc_pixmap_load ( const gchar *  format,
  ... 
)

load a pixmap from the filesystem

Parameters:
format,:If format contains $LOCALE, it will be first replaced by the current long locale and if not found the short locale name. It support printf formating.
...,:additional params for the format (printf like)
Returns:
a new allocated pixbuf or NULL

Definition at line 48 of file gameutil.c.

{
  va_list args;
  gchar *filename;
  gchar *pixmapfile;
  GdkPixbuf *pixmap=NULL;

  if (!format)
    return NULL;

  va_start (args, format);
  pixmapfile = g_strdup_vprintf (format, args);
  va_end (args);

  /* Search */
  filename = gc_file_find_absolute(pixmapfile);

  if(filename)
    pixmap = gc_net_load_pixmap(filename);

  if (!filename || !pixmap)
    {
      char *str;

      if(!pixmap)
       g_warning("Loading image '%s' returned a null pointer", filename);
      else
       g_warning ("Couldn't find file %s !", pixmapfile);

      str = g_strdup_printf("%s\n%s\n%s\n%s",
                         _("Couldn't find or load the file"),
                         pixmapfile,
                         _("This activity is incomplete."),
                         _("Exit it and report\nthe problem to the authors."));
      gc_dialog (str, NULL);
      g_free(pixmapfile);
      g_free(str);
      return NULL;
    }

  g_free(pixmapfile);
  g_free(filename);


  return(pixmap);
}

Here is the call graph for this function:

int gc_util_create_rootdir ( gchar *  rootdir)

Create a directory if needed.

If a file is given, it is removed and a directory is created instead.

Parameters:
rootdir,:the directory to create

return 0 if OK, -1 if ERROR

Definition at line 627 of file gameutil.c.

{

  /* Case where ~/.gcompris already exist as a file. We remove it */
  if(g_file_test(rootdir, G_FILE_TEST_IS_REGULAR)) {
    g_unlink(rootdir);
  }

  if(g_file_test(rootdir, G_FILE_TEST_IS_DIR)) {
    return 0;
  }

  return(g_mkdir(rootdir, 0755));

}

Here is the caller graph for this function:

static GdkPixbuf* make_hc_pixbuf ( GdkPixbuf *  pb,
gint  val 
) [static]

Definition at line 141 of file gameutil.c.

{
  GdkPixbuf *new;
  if(!pb)
    return NULL;

  new = gdk_pixbuf_new(gdk_pixbuf_get_colorspace(pb),
                     gdk_pixbuf_get_has_alpha(pb),
                     gdk_pixbuf_get_bits_per_sample(pb),
                     gdk_pixbuf_get_width(pb),
                     gdk_pixbuf_get_height(pb));
  do_colorshift(new, pb, val);
  /*do_saturate_darken (new, pb, (int)(1.00*255), (int)(1.15*255));*/

  return new;
}

Here is the call graph for this function:

Here is the caller graph for this function:

gchar* reactivate_newline ( char *  str)

Definition at line 263 of file gameutil.c.

{
  gchar *newstr;

  if(str==NULL)
    return NULL;

  xmlParserCtxtPtr ctxt = xmlNewParserCtxt();

  newstr =  (gchar *)xmlStringDecodeEntities(ctxt,
                                        BAD_CAST str,
                                        XML_SUBSTITUTE_REF,
                                        0,
                                        0,
                                        0);

  xmlFreeParserCtxt(ctxt);

  return newstr;
}

Here is the caller graph for this function:


Variable Documentation

GnomeCanvas* canvas