]> Pileus Git - ~andy/gtk/commitdiff
Take shaped windows in consideration when generating clip region.
authorAlexander Larsson <alexl@redhat.com>
Fri, 12 Jan 2001 15:45:26 +0000 (15:45 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Fri, 12 Jan 2001 15:45:26 +0000 (15:45 +0000)
2001-01-12  Alexander Larsson  <alexl@redhat.com>

* gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_clip_region): Take shaped
windows in consideration when generating clip region.

* gdk/linux-fb/gdkfb.h:
Huge HACK. Added GDK_FB_USE_CHILD_SHAPE.

* gdk/linux-fb/gdkprivate-fb.h:
Add shape to GdkWindowFBDatat.
exported gdk_fb_window_get_abs_shape().
removed gdk_fb_draw_lines declaration.

* gdk/linux-fb/gdkwindow-fb.c (gdk_window_impl_fb_init):
Init shape to NULL. (gdk_fb_window_send_crossing_events): Don't
send focus changes when there is a grabbed window.
(gdk_window_get_pointer): Handle shaped windows.
(gdk_fb_region_create_from_bitmap): Convert bitmap to region.
(gdk_fb_window_peek_shape): Returns the shape for a window,
handles GDK_FB_USE_CHILD_SHAPE.
(gdk_fb_window_get_abs_shape): Returns the shape of the window,
offseted to absolute positions. Handles GDK_FB_USE_CHILD_SHAPE.
(gdk_window_shape_combine_mask): Implement.

* gtk/gtkwindow-decorate.c:
HACK! Set GDK_FB_USE_CHILD_SHAPE on window->frame to make sure
setting the shape of a window makes the window transparent.

12 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/linux-fb/gdkdrawable-fb2.c
gdk/linux-fb/gdkfb.h
gdk/linux-fb/gdkprivate-fb.h
gdk/linux-fb/gdkwindow-fb.c
gtk/gtkwindow-decorate.c

index 49a76e26233a9df217a7ee3ffb8ae2560948ee87..f4988d8f055bef7a84de66006506844a16f53e14 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2001-01-12  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_clip_region): Take shaped
+       windows in consideration when generating clip region.
+
+       * gdk/linux-fb/gdkfb.h:
+       Huge HACK. Added GDK_FB_USE_CHILD_SHAPE.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add shape to GdkWindowFBDatat.
+       exported gdk_fb_window_get_abs_shape().
+       removed gdk_fb_draw_lines declaration.
+
+       * gdk/linux-fb/gdkwindow-fb.c (gdk_window_impl_fb_init):
+       Init shape to NULL. (gdk_fb_window_send_crossing_events): Don't
+       send focus changes when there is a grabbed window.
+       (gdk_window_get_pointer): Handle shaped windows.
+       (gdk_fb_region_create_from_bitmap): Convert bitmap to region.
+       (gdk_fb_window_peek_shape): Returns the shape for a window,
+       handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_fb_window_get_abs_shape): Returns the shape of the window,
+       offseted to absolute positions. Handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_window_shape_combine_mask): Implement.
+
+       * gtk/gtkwindow-decorate.c:
+       HACK! Set GDK_FB_USE_CHILD_SHAPE on window->frame to make sure
+       setting the shape of a window makes the window transparent.
+
 2001-01-11  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreemodelsimple.h: Oops, broke some macros
index 49a76e26233a9df217a7ee3ffb8ae2560948ee87..f4988d8f055bef7a84de66006506844a16f53e14 100644 (file)
@@ -1,3 +1,31 @@
+2001-01-12  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_clip_region): Take shaped
+       windows in consideration when generating clip region.
+
+       * gdk/linux-fb/gdkfb.h:
+       Huge HACK. Added GDK_FB_USE_CHILD_SHAPE.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add shape to GdkWindowFBDatat.
+       exported gdk_fb_window_get_abs_shape().
+       removed gdk_fb_draw_lines declaration.
+
+       * gdk/linux-fb/gdkwindow-fb.c (gdk_window_impl_fb_init):
+       Init shape to NULL. (gdk_fb_window_send_crossing_events): Don't
+       send focus changes when there is a grabbed window.
+       (gdk_window_get_pointer): Handle shaped windows.
+       (gdk_fb_region_create_from_bitmap): Convert bitmap to region.
+       (gdk_fb_window_peek_shape): Returns the shape for a window,
+       handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_fb_window_get_abs_shape): Returns the shape of the window,
+       offseted to absolute positions. Handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_window_shape_combine_mask): Implement.
+
+       * gtk/gtkwindow-decorate.c:
+       HACK! Set GDK_FB_USE_CHILD_SHAPE on window->frame to make sure
+       setting the shape of a window makes the window transparent.
+
 2001-01-11  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreemodelsimple.h: Oops, broke some macros
index 49a76e26233a9df217a7ee3ffb8ae2560948ee87..f4988d8f055bef7a84de66006506844a16f53e14 100644 (file)
@@ -1,3 +1,31 @@
+2001-01-12  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_clip_region): Take shaped
+       windows in consideration when generating clip region.
+
+       * gdk/linux-fb/gdkfb.h:
+       Huge HACK. Added GDK_FB_USE_CHILD_SHAPE.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add shape to GdkWindowFBDatat.
+       exported gdk_fb_window_get_abs_shape().
+       removed gdk_fb_draw_lines declaration.
+
+       * gdk/linux-fb/gdkwindow-fb.c (gdk_window_impl_fb_init):
+       Init shape to NULL. (gdk_fb_window_send_crossing_events): Don't
+       send focus changes when there is a grabbed window.
+       (gdk_window_get_pointer): Handle shaped windows.
+       (gdk_fb_region_create_from_bitmap): Convert bitmap to region.
+       (gdk_fb_window_peek_shape): Returns the shape for a window,
+       handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_fb_window_get_abs_shape): Returns the shape of the window,
+       offseted to absolute positions. Handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_window_shape_combine_mask): Implement.
+
+       * gtk/gtkwindow-decorate.c:
+       HACK! Set GDK_FB_USE_CHILD_SHAPE on window->frame to make sure
+       setting the shape of a window makes the window transparent.
+
 2001-01-11  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreemodelsimple.h: Oops, broke some macros
index 49a76e26233a9df217a7ee3ffb8ae2560948ee87..f4988d8f055bef7a84de66006506844a16f53e14 100644 (file)
@@ -1,3 +1,31 @@
+2001-01-12  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_clip_region): Take shaped
+       windows in consideration when generating clip region.
+
+       * gdk/linux-fb/gdkfb.h:
+       Huge HACK. Added GDK_FB_USE_CHILD_SHAPE.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add shape to GdkWindowFBDatat.
+       exported gdk_fb_window_get_abs_shape().
+       removed gdk_fb_draw_lines declaration.
+
+       * gdk/linux-fb/gdkwindow-fb.c (gdk_window_impl_fb_init):
+       Init shape to NULL. (gdk_fb_window_send_crossing_events): Don't
+       send focus changes when there is a grabbed window.
+       (gdk_window_get_pointer): Handle shaped windows.
+       (gdk_fb_region_create_from_bitmap): Convert bitmap to region.
+       (gdk_fb_window_peek_shape): Returns the shape for a window,
+       handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_fb_window_get_abs_shape): Returns the shape of the window,
+       offseted to absolute positions. Handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_window_shape_combine_mask): Implement.
+
+       * gtk/gtkwindow-decorate.c:
+       HACK! Set GDK_FB_USE_CHILD_SHAPE on window->frame to make sure
+       setting the shape of a window makes the window transparent.
+
 2001-01-11  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreemodelsimple.h: Oops, broke some macros
index 49a76e26233a9df217a7ee3ffb8ae2560948ee87..f4988d8f055bef7a84de66006506844a16f53e14 100644 (file)
@@ -1,3 +1,31 @@
+2001-01-12  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_clip_region): Take shaped
+       windows in consideration when generating clip region.
+
+       * gdk/linux-fb/gdkfb.h:
+       Huge HACK. Added GDK_FB_USE_CHILD_SHAPE.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add shape to GdkWindowFBDatat.
+       exported gdk_fb_window_get_abs_shape().
+       removed gdk_fb_draw_lines declaration.
+
+       * gdk/linux-fb/gdkwindow-fb.c (gdk_window_impl_fb_init):
+       Init shape to NULL. (gdk_fb_window_send_crossing_events): Don't
+       send focus changes when there is a grabbed window.
+       (gdk_window_get_pointer): Handle shaped windows.
+       (gdk_fb_region_create_from_bitmap): Convert bitmap to region.
+       (gdk_fb_window_peek_shape): Returns the shape for a window,
+       handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_fb_window_get_abs_shape): Returns the shape of the window,
+       offseted to absolute positions. Handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_window_shape_combine_mask): Implement.
+
+       * gtk/gtkwindow-decorate.c:
+       HACK! Set GDK_FB_USE_CHILD_SHAPE on window->frame to make sure
+       setting the shape of a window makes the window transparent.
+
 2001-01-11  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreemodelsimple.h: Oops, broke some macros
index 49a76e26233a9df217a7ee3ffb8ae2560948ee87..f4988d8f055bef7a84de66006506844a16f53e14 100644 (file)
@@ -1,3 +1,31 @@
+2001-01-12  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_clip_region): Take shaped
+       windows in consideration when generating clip region.
+
+       * gdk/linux-fb/gdkfb.h:
+       Huge HACK. Added GDK_FB_USE_CHILD_SHAPE.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add shape to GdkWindowFBDatat.
+       exported gdk_fb_window_get_abs_shape().
+       removed gdk_fb_draw_lines declaration.
+
+       * gdk/linux-fb/gdkwindow-fb.c (gdk_window_impl_fb_init):
+       Init shape to NULL. (gdk_fb_window_send_crossing_events): Don't
+       send focus changes when there is a grabbed window.
+       (gdk_window_get_pointer): Handle shaped windows.
+       (gdk_fb_region_create_from_bitmap): Convert bitmap to region.
+       (gdk_fb_window_peek_shape): Returns the shape for a window,
+       handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_fb_window_get_abs_shape): Returns the shape of the window,
+       offseted to absolute positions. Handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_window_shape_combine_mask): Implement.
+
+       * gtk/gtkwindow-decorate.c:
+       HACK! Set GDK_FB_USE_CHILD_SHAPE on window->frame to make sure
+       setting the shape of a window makes the window transparent.
+
 2001-01-11  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreemodelsimple.h: Oops, broke some macros
index 49a76e26233a9df217a7ee3ffb8ae2560948ee87..f4988d8f055bef7a84de66006506844a16f53e14 100644 (file)
@@ -1,3 +1,31 @@
+2001-01-12  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_clip_region): Take shaped
+       windows in consideration when generating clip region.
+
+       * gdk/linux-fb/gdkfb.h:
+       Huge HACK. Added GDK_FB_USE_CHILD_SHAPE.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add shape to GdkWindowFBDatat.
+       exported gdk_fb_window_get_abs_shape().
+       removed gdk_fb_draw_lines declaration.
+
+       * gdk/linux-fb/gdkwindow-fb.c (gdk_window_impl_fb_init):
+       Init shape to NULL. (gdk_fb_window_send_crossing_events): Don't
+       send focus changes when there is a grabbed window.
+       (gdk_window_get_pointer): Handle shaped windows.
+       (gdk_fb_region_create_from_bitmap): Convert bitmap to region.
+       (gdk_fb_window_peek_shape): Returns the shape for a window,
+       handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_fb_window_get_abs_shape): Returns the shape of the window,
+       offseted to absolute positions. Handles GDK_FB_USE_CHILD_SHAPE.
+       (gdk_window_shape_combine_mask): Implement.
+
+       * gtk/gtkwindow-decorate.c:
+       HACK! Set GDK_FB_USE_CHILD_SHAPE on window->frame to make sure
+       setting the shape of a window makes the window transparent.
+
 2001-01-11  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreemodelsimple.h: Oops, broke some macros
index b5315802335b25fdefaefa74730bc22a1bfd5e83..00e4e0cb9756cc366e3b35dc8f49d2c4454b3ac8 100644 (file)
@@ -304,9 +304,10 @@ gdk_fb_clip_region (GdkDrawable *drawable,
                    gboolean do_children)
 {
   GdkRectangle draw_rect;
-  GdkRegion *real_clip_region, *tmpreg;
+  GdkRegion *real_clip_region, *tmpreg, *shape;
   gboolean skipit = FALSE;
   GdkDrawableFBData *private;
+  GdkWindowObject *parent;
 
   private = GDK_DRAWABLE_FBDATA (drawable);
   
@@ -330,6 +331,21 @@ gdk_fb_clip_region (GdkDrawable *drawable,
   if (skipit)
     return real_clip_region;
 
+  if (GDK_IS_WINDOW (private->wrapper))
+    {
+      parent = GDK_WINDOW_P (private->wrapper);
+      while (parent != (GdkWindowObject *)gdk_parent_root)
+       {
+         shape = gdk_fb_window_get_abs_shape (GDK_DRAWABLE (parent));
+         if (shape)
+           {
+             gdk_region_intersect (real_clip_region, shape);
+             gdk_region_destroy (shape);
+           }
+         parent = parent->parent;
+       }
+    }
+
   if (gc && GDK_GC_FBDATA(gc)->values.subwindow_mode == GDK_INCLUDE_INFERIORS)
     do_children = FALSE;
 
@@ -347,6 +363,7 @@ gdk_fb_clip_region (GdkDrawable *drawable,
       else
        parentwin = (GdkWindow *)GDK_WINDOW_P (lastwin)->parent;
 
+      /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
       for (; parentwin; lastwin = parentwin, parentwin = (GdkWindow *)GDK_WINDOW_P (parentwin)->parent)
        {
          GList *cur;
@@ -364,6 +381,13 @@ gdk_fb_clip_region (GdkDrawable *drawable,
 
              tmpreg = gdk_region_rectangle (&draw_rect);
 
+             shape = gdk_fb_window_get_abs_shape (impl_private->wrapper);
+             if (shape)
+               {
+                 gdk_region_intersect (tmpreg, shape);
+                 gdk_region_destroy (shape);
+               }
+             
              gdk_region_subtract (real_clip_region, tmpreg);
              gdk_region_destroy (tmpreg);
            }
index 71d97e448bd249b6ff887ad8300db9f253a49633..542d0196dfdee3b67ad1dfed1103e049870e5f00 100644 (file)
@@ -29,6 +29,8 @@ typedef enum {
   GDK_FB_270_DEGREES
 } GdkFBAngle;
 
+#define GDK_FB_USE_CHILD_SHAPE ((void *)1)
+
 /* FB specific functions: */
 
 typedef gboolean (*GdkWindowChildChanged) (GdkWindow *window,
@@ -39,10 +41,10 @@ typedef void     (*GdkWindowChildGetPos)  (GdkWindow *window,
                                           gint *x, gint *y,
                                           gpointer user_data);
 
-void      gdk_fb_window_set_child_handler (GdkWindow             *window,
-                                          GdkWindowChildChanged changed,
-                                          GdkWindowChildGetPos  get_pos,
-                                          gpointer              user_data);
+void      gdk_fb_window_set_child_handler (GdkWindow              *window,
+                                          GdkWindowChildChanged  changed,
+                                          GdkWindowChildGetPos   get_pos,
+                                          gpointer               user_data);
 
 void      gdk_fb_set_rotation             (GdkFBAngle angle);
 
index 2d69755a80fcfcc63f23bebed5a5ecfd8ba9c7ef..b3f408f1f161bf282dfcd48c4f2eae0a588dec7a 100644 (file)
@@ -111,6 +111,8 @@ struct _GdkWindowFBData
   GdkCursor *cursor;
   GHashTable *properties;
 
+  GdkRegion *shape; /* Can also be GDK_FB_USE_CHILD_SHAPE */
+  
   GdkEventMask event_mask;
   gboolean realized : 1;
 };
@@ -269,6 +271,7 @@ void       gdk_fb_window_move_resize          (GdkWindow       *window,
                                               gint             height,
                                               gboolean         send_expose_events);
 GdkWindow *gdk_fb_window_find_focus           (void);
+GdkRegion *gdk_fb_window_get_abs_shape        (GdkDrawable *window);
 GdkGC *   _gdk_fb_gc_new                      (GdkDrawable     *drawable,
                                               GdkGCValues     *values,
                                               GdkGCValuesMask  values_mask);
@@ -344,10 +347,6 @@ void       gdk_fb_draw_rectangle           (GdkDrawable         *drawable,
                                            gint                 y,
                                            gint                 width,
                                            gint                 height);
-void       gdk_fb_draw_lines               (GdkDrawable         *drawable,
-                                           GdkGC               *gc,
-                                           GdkPoint            *points,
-                                           gint                 npoints);
 void       gdk_fb_fill_spans               (GdkDrawable         *real_drawable,
                                            GdkGC               *gc,
                                            GdkSpan             *spans,
index 2030036d9425fe6f8118fbc502c1da7650cdaf30..8006f2a4568340f3f949e24e351769429e592e0a 100644 (file)
@@ -41,12 +41,13 @@ static gpointer parent_class = NULL;
 static void recompute_drawable (GdkDrawable *drawable);
 static void gdk_fb_window_raise (GdkWindow *window);
 static GdkRegion* gdk_window_fb_get_visible_region (GdkDrawable *drawable);
+static GdkRegion *gdk_fb_window_peek_shape (GdkDrawable *window);
 
 typedef struct
 {
-  GdkWindowChildChanged changed;
-  GdkWindowChildGetPos get_pos;
-  gpointer user_data;
+  GdkWindowChildChanged  changed;
+  GdkWindowChildGetPos   get_pos;
+  gpointer               user_data;
 }  GdkWindowChildHandlerData;
 
 static void
@@ -96,6 +97,7 @@ gdk_window_impl_fb_init (GdkWindowFBData *impl)
   impl->drawable_data.depth = gdk_display->modeinfo.bits_per_pixel;
   impl->drawable_data.colormap = gdk_colormap_get_system ();
   impl->event_mask = GDK_STRUCTURE_MASK;
+  impl->shape = NULL;
 }
 
 GType
@@ -703,7 +705,8 @@ gdk_fb_window_send_crossing_events (GdkWindow *dest,
     }
 
   if ((mode != GDK_CROSSING_GRAB) &&
-      (b != gdk_fb_window_containing_pointer))
+      (b != gdk_fb_window_containing_pointer) &&
+      !only_grabbed_window)
     {
       gdk_fb_send_focus_change (gdk_fb_window_containing_pointer, b);
       gdk_window_unref (gdk_fb_window_containing_pointer);
@@ -1534,6 +1537,7 @@ gdk_window_get_pointer (GdkWindow       *window,
   int winy = 0;
   int x_int, y_int;
   GdkModifierType my_mask;
+  GdkRegion *shape;
 
   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
   
@@ -1555,8 +1559,10 @@ gdk_window_get_pointer (GdkWindow       *window,
   
   return_val = NULL;
   
+  shape = gdk_fb_window_peek_shape (window);
   if ((winx >= 0) && (winx < GDK_DRAWABLE_IMPL_FBDATA (window)->width) &&
-      (winy >= 0) && (winy < GDK_DRAWABLE_IMPL_FBDATA (window)->height))
+      (winy >= 0) && (winy < GDK_DRAWABLE_IMPL_FBDATA (window)->height) &&
+      (!shape || gdk_region_point_in (shape, winx, winy)))
     {
       GdkWindowObject *private;
       GdkWindowObject *sub;
@@ -1573,10 +1579,12 @@ gdk_window_get_pointer (GdkWindow       *window,
              if (!sub->mapped)
                continue;
 
+             shape = gdk_fb_window_peek_shape (GDK_WINDOW (sub));
              if (subx >= sub->x &&
                  (subx < (GDK_DRAWABLE_IMPL_FBDATA (sub)->width + sub->x)) &&
                  (suby >= sub->y) &&
-                 (suby < (GDK_DRAWABLE_IMPL_FBDATA (sub)->height + sub->y)))
+                 (suby < (GDK_DRAWABLE_IMPL_FBDATA (sub)->height + sub->y)) &&
+                 (!shape || gdk_region_point_in (shape, subx - sub->x, suby - sub->y)))
                {
                  subx -= sub->x;
                  suby -= sub->y;
@@ -1652,18 +1660,146 @@ gdk_window_add_colormap_windows (GdkWindow *window)
   /* N/A */
 }
 
-/*
- * This needs the X11 shape extension.
- * If not available, shaped windows will look
- * ugly, but programs still work.    Stefan Wille
- */
+
+GdkRegion*
+gdk_fb_region_create_from_bitmap (GdkBitmap *bitmap)
+{
+  GdkDrawableFBData *private;
+  GdkRegion *region;
+  GdkRectangle rect;
+  gboolean in_rect;
+  gint x;
+  guchar bit_mask;
+  guchar *src;
+
+  g_return_val_if_fail(bitmap != NULL, NULL);
+  g_return_val_if_fail(GDK_IS_PIXMAP(bitmap), NULL);
+
+  private = GDK_DRAWABLE_IMPL_FBDATA (bitmap);
+
+  g_return_val_if_fail(private->depth == 1, NULL);
+
+  region = gdk_region_new();
+
+  rect.height = 1;
+
+  in_rect = FALSE; /* Haven't started a rectangle yet */
+
+  for (rect.y = 0; rect.y < private->height; (rect.y)++)
+    {
+      src = private->mem + rect.y * private->rowstride;
+      bit_mask = 1;
+      for (x = 0; x < private->width; x++)
+       {
+         if ((*src & bit_mask) && !in_rect)
+           {
+             /* Start of rect */
+             in_rect = TRUE;
+             rect.x = x;
+           }
+         else if (!(*src & bit_mask) && in_rect)
+           {
+             /* End of rect */
+             in_rect = FALSE;
+             rect.width = x - rect.x;
+             gdk_region_union_with_rect (region, &rect);
+           }
+         
+         if (bit_mask == 1<<7)
+           {
+             bit_mask = 1;
+             src++;
+           }
+         else
+           bit_mask <<= 1;
+       }
+      
+      if (in_rect)
+       {
+         /* Past end of line */
+         in_rect = FALSE;
+         rect.width = x - rect.x;
+         gdk_region_union_with_rect (region, &rect);
+       }
+    }
+
+  return region;
+}
+
+static GdkRegion *
+gdk_fb_window_peek_shape (GdkDrawable *window)
+{
+  if (!GDK_IS_WINDOW (window))
+    return NULL;
+
+  if (GDK_WINDOW_IMPL_FBDATA (window)->shape == NULL)
+    return NULL;
+  
+  if (GDK_WINDOW_IMPL_FBDATA (window)->shape == GDK_FB_USE_CHILD_SHAPE)
+    {
+      GList *children;
+      children = ((GdkWindowObject*)window)->children;
+      if (children)
+       return gdk_fb_window_peek_shape ((GdkDrawable *)children->data);
+      else
+       return NULL;
+    }
+
+  return GDK_WINDOW_IMPL_FBDATA (window)->shape;
+}
+GdkRegion *
+gdk_fb_window_get_abs_shape (GdkDrawable *window)
+{
+  GdkRegion *shape;
+  
+  if (!GDK_IS_WINDOW (window))
+    return NULL;
+
+  if (GDK_WINDOW_IMPL_FBDATA (window)->shape == NULL)
+    return NULL;
+  
+  if (GDK_WINDOW_IMPL_FBDATA (window)->shape == GDK_FB_USE_CHILD_SHAPE)
+    {
+      GList *children;
+      children = ((GdkWindowObject*)window)->children;
+      if (children)
+       return gdk_fb_window_get_abs_shape ((GdkDrawable *)children->data);
+      else
+       return NULL;
+    }
+
+  shape = gdk_region_copy (GDK_WINDOW_IMPL_FBDATA (window)->shape);
+  gdk_region_offset (shape,
+                    GDK_DRAWABLE_IMPL_FBDATA (window)->abs_x,
+                    GDK_DRAWABLE_IMPL_FBDATA (window)->abs_y);
+  return shape;
+}
+
 void
 gdk_window_shape_combine_mask (GdkWindow *window,
                               GdkBitmap *mask,
                               gint x, gint y)
 {
+  GdkWindowFBData *private;
+  
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
+
+  private = GDK_WINDOW_IMPL_FBDATA (window);
+
+  if (private->shape && private->shape != GDK_FB_USE_CHILD_SHAPE)
+    gdk_region_destroy (private->shape);
+
+  /* Warning. HUGE hack */
+  if (mask == GDK_FB_USE_CHILD_SHAPE)
+    private->shape = GDK_FB_USE_CHILD_SHAPE;
+  else if (mask)
+    {
+      private->shape = gdk_fb_region_create_from_bitmap (mask);
+      gdk_region_offset (private->shape, x, y);
+    }
+  else
+    private->shape = NULL;
 }
 
 void
@@ -1712,9 +1848,9 @@ gdk_window_set_group (GdkWindow *window,
 
 void
 gdk_fb_window_set_child_handler (GdkWindow             *window,
-                                GdkWindowChildChanged changed,
-                                GdkWindowChildGetPos  get_pos,
-                                gpointer              user_data)
+                                GdkWindowChildChanged  changed,
+                                GdkWindowChildGetPos   get_pos,
+                                gpointer               user_data)
 {
   GdkWindowChildHandlerData *data;
     
index d864e1509222a6d483af96520a6773f386b9dee2..c12f52bad88fbc776490217a7b78ab1e8cdf99f4 100644 (file)
@@ -266,8 +266,13 @@ gtk_decorated_window_realize (GtkWindow   *window)
                                   gtk_decorated_window_inner_change,
                                   gtk_decorated_window_inner_get_pos,
                                   window);
+
+  /* This is a huge hack to make frames have the same shape as
+     the window they wrap */
+  gdk_window_shape_combine_mask (window->frame, GDK_FB_USE_CHILD_SHAPE, 0, 0);
 }
 
+
 static void
 gtk_decorated_window_unrealize (GtkWindow   *window)
 {