[gnome-games] mahjongg: Work with GTK3



commit aab65121a74d703a639a3fd756797bbe07a1a6fe
Author: Robert Ancell <robert ancell canonical com>
Date:   Mon Dec 6 11:40:11 2010 +1100

    mahjongg: Work with GTK3

 configure.in       |    4 +-
 mahjongg/drawing.c |  208 +++++++++++++++++++++-------------------------------
 2 files changed, 85 insertions(+), 127 deletions(-)
---
diff --git a/configure.in b/configure.in
index dc3081e..c1fdaf2 100644
--- a/configure.in
+++ b/configure.in
@@ -23,9 +23,9 @@ AM_MAINTAINER_MODE([enable])
 # we support and which features to check for
 
 # This is the canonical list of all game subdirectories.
-allgames="aisleriot glines gnect gnibbles gnobots2 gnomine gnotravex gnotski gtali iagno quadrapassel"
+allgames="aisleriot glines gnect gnibbles gnobots2 gnomine gnotravex gnotski gtali iagno mahjongg quadrapassel"
 AC_SUBST([allgames])
-staginggames="swell-foop mahjongg glchess gnome-sudoku lightsoff"
+staginggames="swell-foop glchess gnome-sudoku lightsoff"
 AC_SUBST([staginggames])
 
 gamelist=""
diff --git a/mahjongg/drawing.c b/mahjongg/drawing.c
index 748ba52..0922039 100644
--- a/mahjongg/drawing.c
+++ b/mahjongg/drawing.c
@@ -34,7 +34,7 @@ typedef struct _view_geom_record {
   guchar overlaps[MAX_TILES - 1];
 } view_geom_record;
 
-view_geom_record view_geometry[MAX_TILES];
+static view_geom_record view_geometry[MAX_TILES];
 
 /* The number of different tile patterns plus a blank tile at the end. */
 #define NUM_PATTERNS 43
@@ -43,32 +43,27 @@ view_geom_record view_geometry[MAX_TILES];
  * 1.375 = 64/88 */
 #define ASPECT 1.375
 
-GtkWidget *board = NULL;
-GdkPixmap *buffer = NULL;
-GdkPixmap *tileimages = NULL;
-GdkPixmap *tilebuffer = NULL;
-GdkBitmap *tilemask = NULL;
+static GtkWidget *board = NULL;
+static GamesPreimage *tilepreimage = NULL;
+static GdkPixbuf *tileimages = NULL;
+static cairo_surface_t *buffer = NULL;
 
-GdkGC *gc = NULL;
-
-gboolean update_tileimages = TRUE;
-gboolean nowindow = TRUE;
+static gboolean update_tileimages = TRUE;
+static gboolean nowindow = TRUE;
 
 GdkColor bgcolour;
 
-GamesPreimage *tilepreimage = NULL;
-
 static gint windowwidth;
 static gint windowheight;
-gint prior_tilebasewidth = 0;
-gint tilebasewidth = 0;
-gint tilebaseheight = 0;
-gint tileoffsetx;
-gint tileoffsety;
-gint tilewidth;
-gint tileheight;
-gint xoffset;
-gint yoffset;
+static gint prior_tilebasewidth = 0;
+static gint tilebasewidth = 0;
+static gint tilebaseheight = 0;
+static gint tileoffsetx;
+static gint tileoffsety;
+static gint tilewidth;
+static gint tileheight;
+static gint xoffset;
+static gint yoffset;
 
 /* This is the minimum size of the widget containing the tiles. These
  * numbers are completely arbitrary and any resemblance to the resolution
@@ -150,11 +145,11 @@ calculate_view_geometry (void)
       /* We include the tile as an overlap with itself. This simplifies the
        * drawing routines later. */
       if ((((v2->x >= v->x) && (v2->x < v->x + tilewidth)) ||
-	   ((v2->x < v->x) && (v2->x + tilewidth > v->x))) &&
-	  (((v2->y >= v->y) && (v2->y < v->y + tileheight)) ||
-	   ((v2->y < v->y) && (v2->y + tileheight > v->y)))) {
-	v->overlaps[v->noverlaps] = j;
-	v->noverlaps++;
+           ((v2->x < v->x) && (v2->x + tilewidth > v->x))) &&
+          (((v2->y >= v->y) && (v2->y < v->y + tileheight)) ||
+           ((v2->y < v->y) && (v2->y + tileheight > v->y)))) {
+        v->overlaps[v->noverlaps] = j;
+        v->noverlaps++;
       }
       v2++;
     }
@@ -180,8 +175,8 @@ find_tile (guint x, guint y)
       tx = view_geometry[i].x;
       ty = view_geometry[i].y;
       if ((x >= tx) && (x < (tx + tilewidth)) &&
-	  (y >= ty) && (y < (ty + tileheight))) {
-	return i;
+          (y >= ty) && (y < (ty + tileheight))) {
+        return i;
       }
     }
   }
@@ -195,74 +190,71 @@ set_background (gchar * colour)
   if (!colour || !gdk_color_parse (colour, &bgcolour)) {
     bgcolour.red = bgcolour.green = bgcolour.blue = 0;
   }
-
-  if (gc) {
-    gdk_colormap_alloc_color (gdk_colormap_get_system (), &bgcolour, FALSE,
-			      TRUE);
-    gdk_gc_set_foreground (gc, &bgcolour);
-  }
 }
 
 void
 draw_tile (gint tileno)
 {
-  guint ox, oy;
-  guint dx, dy;
-  guint sx, sy;
+  gint ox, oy;
+  gint dx, dy;
+  gint sx, sy;
   gint i, j;
-   
+  cairo_t *cr;
+
   if (nowindow)
     return;
 
+  cr = cairo_create (buffer);
+
   ox = view_geometry[tileno].x;
   oy = view_geometry[tileno].y;
-  gdk_gc_set_clip_mask (gc, tilemask);
-  gdk_gc_set_clip_origin (gc, 0, 0);
 
-  gdk_draw_rectangle (tilebuffer, gc, TRUE, 0, 0, tilewidth, tileheight);
+  cairo_rectangle (cr, ox, oy, tilewidth, tileheight);
+  cairo_clip (cr); 
+  cairo_rectangle (cr, ox, oy, tilewidth, tileheight);
+  gdk_cairo_set_source_color (cr, &bgcolour);
+  cairo_fill (cr);
 
   for (i = view_geometry[tileno].noverlaps - 1; i >= 0; i--) {
     j = view_geometry[tileno].overlaps[i];
     if (tiles[j].visible) {
-      dx = view_geometry[j].x - ox;
-      dy = view_geometry[j].y - oy;
+      dx = view_geometry[j].x;
+      dy = view_geometry[j].y;
       sy = tiles[j].selected ? tileheight : 0;
       sx = tiles[j].image * tilewidth;
-      gdk_gc_set_clip_origin (gc, dx, dy);
-      gdk_draw_drawable (tilebuffer, gc, tileimages,
-			 sx, sy, dx, dy, tilewidth, tileheight);
+
+      gdk_cairo_set_source_pixbuf (cr, tileimages, dx - sx, dy - sy);
+      cairo_rectangle (cr, dx, dy, tilewidth, tileheight);
+      cairo_fill (cr);
     }
   }
 
-  gdk_gc_set_clip_origin (gc, ox, oy);
-  gdk_draw_drawable (buffer, gc, tilebuffer, 0, 0, ox, oy,
-		     tilewidth, tileheight);
+  cairo_destroy (cr);
 
-  /* We could queue this draw, but given that this function is at worst case
-   * called twice in a short time span it doesn't seem worth the code. */
-  gdk_draw_drawable (gtk_widget_get_window (board),
-                     gtk_widget_get_style (board)->black_gc, buffer, ox, oy,
-		     ox, oy, tilewidth, tileheight);
+  gtk_widget_queue_draw (board);
 }
 
 void
 draw_all_tiles (void)
 {
   gint i;
-  guint sx, sy;
-  guint dx, dy;
+  gint sx, sy;
+  gint dx, dy;
+  cairo_t *cr;
    
   if (nowindow)
     return;
 
-  gdk_gc_set_clip_mask (gc, NULL);
-  gdk_draw_rectangle (buffer, gc, TRUE, 0, 0, windowwidth, windowheight);
+  cr = cairo_create (buffer);
+
+  gdk_cairo_set_source_color (cr, &bgcolour);
+  cairo_rectangle (cr, 0, 0, windowwidth, windowheight);
+  cairo_fill (cr);
 
   /* This works because of the way the tiles are sorted. We could
    * reverse them to make this look a little nicer, but when searching
    * for a tile we want it the other way around. */
 
-  gdk_gc_set_clip_mask (gc, tilemask);
   for (i = MAX_TILES - 1; i >= 0; i--) {
     if (!tiles[i].visible)
       continue;
@@ -278,34 +270,35 @@ draw_all_tiles (void)
       sy = tiles[i].selected ? tileheight : 0;
     }
 
-    gdk_gc_set_clip_origin (gc, dx, dy);
-
-    gdk_draw_drawable (buffer, gc, tileimages,
-		       sx, sy, dx, dy, tilewidth, tileheight);
+    gdk_cairo_set_source_pixbuf (cr, tileimages, dx - sx, dy - sy);
+    cairo_rectangle (cr, dx, dy, tilewidth, tileheight);
+    cairo_fill (cr);
   }
 
+  cairo_destroy (cr);
+
   gtk_widget_queue_draw (board);
 }
 
 static void
 recreate_tile_images (void)
 {
-  GdkPixbuf *fg = NULL;
-
   /* Now composite the tiles across it. */
 
   if (tilepreimage) {
-    fg = games_preimage_render (tilepreimage, tilewidth * NUM_PATTERNS,
-				tileheight * 2);
+    if (tileimages)
+       gdk_pixbuf_unref (tileimages);
+    tileimages = games_preimage_render (tilepreimage, tilewidth * NUM_PATTERNS,
+                                        tileheight * 2);
 
     /* Handle corrupt images that were not caught during preimage creation. */
-    if (fg == NULL) {
+    if (tileimages == NULL) {
       g_object_unref (tilepreimage);
       tilepreimage = NULL;
 
       g_free (warning_message);
       warning_message = g_strdup (_("The selected theme failed to render.\n\n"
-				    "Please check that Mahjongg is installed correctly."));
+                                    "Please check that Mahjongg is installed correctly."));
     }
 
   }
@@ -316,22 +309,6 @@ recreate_tile_images (void)
     g_free (warning_message);
     warning_message = NULL;
   }
-
-  /* If there's no theme pixbuf, provide a blank one. */
-  if (fg == NULL) {
-    fg = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
-			 tilewidth * NUM_PATTERNS, tileheight * 2);
-    gdk_pixbuf_fill (fg, 0x00000000);
-  }
-
-  gdk_pixbuf_render_threshold_alpha (fg, tilemask, 0, 0, 0, 0,
-				     tilewidth, tileheight, 128);
-  gdk_draw_pixbuf (tileimages, NULL, fg, 0, 0, 0, 0,
-		   tilewidth * NUM_PATTERNS, tileheight * 2,
-		   GDK_RGB_DITHER_MAX, 0, 0);
-
-  g_object_unref (fg);
-
 }
 
 /* This is for when the geometry changes. It is called both from the
@@ -348,27 +325,8 @@ configure_pixmaps (void)
   recalculate_sizes (windowwidth, windowheight);
   calculate_tile_positions ();
 
-  if (buffer != NULL)
-    g_object_unref (buffer);
-  buffer = gdk_pixmap_new (gtk_widget_get_window (board), windowwidth, 
-                           windowheight, -1);
-
   /* Recreate the tile images only if the theme or tile size changed. */
   if ((prior_tilebasewidth != tilebasewidth) || (update_tileimages)) {
-
-    if (tileimages != NULL)
-      g_object_unref (tileimages);
-    if (tilemask != NULL)
-      g_object_unref (tilemask);
-    if (tilebuffer != NULL)
-      g_object_unref (tilebuffer);
-
-    tileimages = gdk_pixmap_new (gtk_widget_get_window (board),
-                                 NUM_PATTERNS * tilewidth, 2 * tileheight, -1);
-    tilemask = gdk_pixmap_new (NULL, tilewidth, tileheight, 1);
-    tilebuffer = gdk_pixmap_new (gtk_widget_get_window (board), tilewidth,
-                                 tileheight, -1);
-
     recreate_tile_images ();
     update_tileimages = FALSE;
   }
@@ -380,17 +338,17 @@ configure_board (GtkWidget * w, GdkEventConfigure * e, gpointer data)
 {
   nowindow = FALSE;
 
-  if (gc == NULL) {
-    gc = gdk_gc_new (gtk_widget_get_window (w));
-    gdk_gc_copy (gc, gtk_widget_get_style (w)->black_gc);
-    gdk_colormap_alloc_color (gdk_colormap_get_system (), &bgcolour, FALSE,
-			      TRUE);
-    gdk_gc_set_foreground (gc, &bgcolour);
-  }
-
   windowwidth = e->width;
   windowheight = e->height;
 
+  if (!buffer ||
+      cairo_image_surface_get_width (buffer) != windowwidth ||
+      cairo_image_surface_get_height (buffer) != windowheight) {
+    if (buffer)
+      cairo_surface_destroy (buffer);
+    buffer = cairo_image_surface_create (CAIRO_FORMAT_RGB24, windowwidth, windowheight);
+  }
+
   configure_pixmaps ();
 
   draw_all_tiles ();
@@ -400,12 +358,12 @@ configure_board (GtkWidget * w, GdkEventConfigure * e, gpointer data)
 
 /* Handle exposes by dumping out the backing pixmap. */
 static gboolean
-expose_board (GtkWidget * w, GdkEventExpose * e, gpointer data)
+draw_board (GtkWidget * w, cairo_t * cr, gpointer data)
 {
-  gdk_draw_drawable (gtk_widget_get_window (w),
-                     gtk_widget_get_style (w)->black_gc, buffer, e->area.x,
-		     e->area.y, e->area.x, e->area.y, e->area.width,
-                     e->area.height);
+  cairo_set_source_surface (cr, buffer, 0, 0);
+  cairo_rectangle (cr, 0, 0, gtk_widget_get_allocated_width (w), gtk_widget_get_allocated_height (w));
+  cairo_fill (cr);
+
   return TRUE;
 }
 
@@ -438,12 +396,12 @@ create_mahjongg_board (void)
 
   gtk_widget_add_events (board, GDK_BUTTON_PRESS_MASK);
 
-  g_signal_connect (G_OBJECT (board), "expose_event",
-		    G_CALLBACK (expose_board), NULL);
-  g_signal_connect (G_OBJECT (board), "configure_event",
-		    G_CALLBACK (configure_board), NULL);
-  g_signal_connect (G_OBJECT (board), "button_press_event",
-		    G_CALLBACK (board_click), NULL);
+  g_signal_connect (G_OBJECT (board), "draw",
+                    G_CALLBACK (draw_board), NULL);
+  g_signal_connect (G_OBJECT (board), "configure-event",
+                    G_CALLBACK (configure_board), NULL);
+  g_signal_connect (G_OBJECT (board), "button-press-event",
+                    G_CALLBACK (board_click), NULL);
   /* We do our own double-buffering. */
   gtk_widget_set_double_buffered (board, FALSE);
 
@@ -482,8 +440,8 @@ load_images (gchar * file)
       /* This usually happens with bad images or a missing image loader. */
       g_free (warning_message);
       warning_message = g_strdup_printf (_("Unable to render file:\n'%s'\n\n"
-					   "Please check that Mahjongg is installed correctly."),
-					 error->message);
+                                           "Please check that Mahjongg is installed correctly."),
+                                         error->message);
       g_error_free (error);
     }
   }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]