Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2005:
[Freeciv-Dev] (PR#11979) fog problem on windows gtk2 client
Home

[Freeciv-Dev] (PR#11979) fog problem on windows gtk2 client

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#11979) fog problem on windows gtk2 client
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 19 Jan 2005 12:49:18 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=11979 >

Apparently on Windows the GdkImage doesn't work quite the same way, so 
ftile->visual is NULL and the program crashes.

 From the gdk manual:

"A GdkImage stores client-side image data (pixels). In contrast, 
GdkPixmap and GdkWindow are server-side objects. 
gdk_drawable_get_image() obtains the pixels from a server-side drawable 
as a client-side GdkImage. The format of a GdkImage depends on the 
GdkVisual of the current display, which makes manipulating GdkImage 
extremely difficult; therefore, in most cases you should use 
gdk_pixbuf_get_from_drawable() instead of this lower-level function. A 
GdkPixbuf contains image data in a canonicalized RGB format, rather than 
a display-dependent format. Of course, there's a convenience vs. speed 
tradeoff here, so you'll want to think about what makes sense for your 
application."

http://developer.gnome.org/doc/API/2.0/gdk/gdk-Drawing-Primitives.html#gdk-drawable-get-image

which basically says to use GdkPixbufs instead of GdkImages.  Andreas 
had a patch to use pixbufs instead of images here, but since everything 
worked I committed the original image patch instead.  Hmmm....


So here are two possible fixes.  One of them keeps the GdkImage usage, 
but avoids the crash.  The other switches to GdkPixbufs, basically 
copying Andreas's code from 11433.

Both patches are written for S2_0.  However I assume this problem 
affects the dev branch as well.  For the dev branch the pixbuf patch is 
surely better (since this is the "right way" according to the 
documentation).  For S2_0 I'm not sure which patch is better.  The 
current "image" method has a lot more testing, so it will "work" 
(actually just disable better-fog) on non-truecolor systems.  The pixbuf 
method hasn't been tested on non-truecolor systems: it might work better 
or worse than the image method does now.

-jason

? win32.diff
Index: client/gui-gtk-2.0/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapview.c,v
retrieving revision 1.142.2.10
diff -u -r1.142.2.10 mapview.c
--- client/gui-gtk-2.0/mapview.c        8 Jan 2005 05:33:34 -0000       
1.142.2.10
+++ client/gui-gtk-2.0/mapview.c        19 Jan 2005 20:44:05 -0000
@@ -900,9 +900,9 @@
 {
   int x, y;
   GdkImage* ftile;
+  GdkVisual *visual = gdk_drawable_get_visual(sprite->pixmap);
 
-  if (gdk_drawable_get_visual(sprite->pixmap)->type
-      != GDK_VISUAL_TRUE_COLOR) {
+  if (visual->type != GDK_VISUAL_TRUE_COLOR) {
     /* In this case the below code won't work. */
     return;
   }
@@ -910,20 +910,24 @@
   ftile = gdk_drawable_get_image(sprite->pixmap,
                                 0, 0, sprite->width, sprite->height);
 
+  if (ftile->visual) {
+    visual = ftile->visual;
+  }
+
   /* Iterate over all pixels, reducing brightness by 50%. */
   for (x = 0; x < sprite->width; x++) {
     for (y = 0; y < sprite->height; y++) {
       guint32 pixel =  gdk_image_get_pixel(ftile, x, y);
 
-      guint8 red = ((pixel & ftile->visual->red_mask)
-                   >> ftile->visual->red_shift) * 65 / 100;
-      guint8 green = ((pixel & ftile->visual->green_mask)
-                     >> ftile->visual->green_shift) * 65 / 100;
-      guint8 blue = ((pixel & ftile->visual->blue_mask)
-                    >> ftile->visual->blue_shift) * 65 / 100;
-      guint32 result = red << ftile->visual->red_shift
-       | green << ftile->visual->green_shift          
-       | blue << ftile->visual->blue_shift;
+      guint8 red = ((pixel & visual->red_mask)
+                   >> visual->red_shift) * 65 / 100;
+      guint8 green = ((pixel & visual->green_mask)
+                     >> visual->green_shift) * 65 / 100;
+      guint8 blue = ((pixel & visual->blue_mask)
+                    >> visual->blue_shift) * 65 / 100;
+      guint32 result = red << visual->red_shift
+       | green << visual->green_shift          
+       | blue << visual->blue_shift;
 
       gdk_image_put_pixel(ftile, x , y, result);
     }
? win32.diff
Index: client/gui-gtk-2.0/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapview.c,v
retrieving revision 1.142.2.10
diff -u -r1.142.2.10 mapview.c
--- client/gui-gtk-2.0/mapview.c        8 Jan 2005 05:33:34 -0000       
1.142.2.10
+++ client/gui-gtk-2.0/mapview.c        19 Jan 2005 20:40:05 -0000
@@ -899,46 +899,31 @@
 static void fog_sprite(struct Sprite *sprite)
 {
   int x, y;
-  GdkImage* ftile;
-
-  if (gdk_drawable_get_visual(sprite->pixmap)->type
-      != GDK_VISUAL_TRUE_COLOR) {
-    /* In this case the below code won't work. */
-    return;
-  }
-
-  ftile = gdk_drawable_get_image(sprite->pixmap,
-                                0, 0, sprite->width, sprite->height);
+  GdkPixbuf *fogged;
+  guchar *pixel;
+  const int bright = 65; /* Brightness percentage */
+
+  fogged = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
+                         sprite->width, sprite->height);
+  gdk_pixbuf_get_from_drawable(fogged, sprite->pixmap, NULL,
+                              0, 0, 0, 0, sprite->width, sprite->height);
 
   /* Iterate over all pixels, reducing brightness by 50%. */
   for (x = 0; x < sprite->width; x++) {
     for (y = 0; y < sprite->height; y++) {
-      guint32 pixel =  gdk_image_get_pixel(ftile, x, y);
-
-      guint8 red = ((pixel & ftile->visual->red_mask)
-                   >> ftile->visual->red_shift) * 65 / 100;
-      guint8 green = ((pixel & ftile->visual->green_mask)
-                     >> ftile->visual->green_shift) * 65 / 100;
-      guint8 blue = ((pixel & ftile->visual->blue_mask)
-                    >> ftile->visual->blue_shift) * 65 / 100;
-      guint32 result = red << ftile->visual->red_shift
-       | green << ftile->visual->green_shift          
-       | blue << ftile->visual->blue_shift;
-
-      gdk_image_put_pixel(ftile, x , y, result);
+      pixel = gdk_pixbuf_get_pixels(fogged)
+       + y * gdk_pixbuf_get_rowstride(fogged)
+       + x * gdk_pixbuf_get_n_channels(fogged);
+
+      pixel[0] = pixel[0] * bright / 100;
+      pixel[1] = pixel[1] * bright / 100;
+      pixel[2] = pixel[2] * bright / 100;
     }
   }
 
-  /* Convert the image back to a pixmap, since pixmaps are much faster
-   * to draw. */
-  sprite->fogged = gdk_pixmap_new(root_window,
-                                 sprite->width, sprite->height, -1);
-  gdk_gc_set_clip_origin(fill_tile_gc, 0, 0);
-  gdk_gc_set_clip_mask(fill_tile_gc, sprite->mask);
-  gdk_draw_image(sprite->fogged, fill_tile_gc, ftile,
-                0, 0, 0, 0, sprite->width, sprite->height);
-  gdk_gc_set_clip_mask(fill_tile_gc, NULL);
-  g_object_unref(ftile);
+  gdk_pixbuf_render_pixmap_and_mask(fogged, &sprite->fogged,
+                                   NULL, 0);
+  g_object_unref(fogged);
 }
 
 /**************************************************************************

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#11979) fog problem on windows gtk2 client, Jason Short <=