[gimp/soc-2010-cage] app: make the alpha channel work on canvas overlay widgets



commit d2f6767bd4d7f4fb475287ec32409e330b27b2c3
Author: Michael Natterer <mitch gimp org>
Date:   Sat Jun 12 23:38:13 2010 +0200

    app: make the alpha channel work on canvas overlay widgets
    
    * app/widgets/gimpoverlaychild.c: when creating offscreen windows, try
      to set an RGBA colormap on the offscreen window's widget and use the
      RGBA colormap to create the window. This has to be done here,
      because it's not possible to get to the right screen *inside* the
      offscreen widget before it's parented, and we need that screen
      before the widget is realized, and the widget can't be parented
      before it's realized or it will get the wrong parent window.
      Everything clear now?
    
    * app/widgets/gimpoverlayframe.c: draw the round corners only if the
      screen has an RGBA colormap.

 app/widgets/gimpoverlaychild.c |   17 ++++-
 app/widgets/gimpoverlayframe.c |  120 ++++++++++++++++++++--------------------
 2 files changed, 74 insertions(+), 63 deletions(-)
---
diff --git a/app/widgets/gimpoverlaychild.c b/app/widgets/gimpoverlaychild.c
index 7643d2e..a344cdd 100644
--- a/app/widgets/gimpoverlaychild.c
+++ b/app/widgets/gimpoverlaychild.c
@@ -129,6 +129,8 @@ gimp_overlay_child_realize (GimpOverlayBox   *box,
 {
   GtkWidget     *widget;
   GdkDisplay    *display;
+  GdkScreen     *screen;
+  GdkColormap   *colormap;
   GtkAllocation  child_allocation;
   GdkWindowAttr  attributes;
   gint           attributes_mask;
@@ -139,6 +141,11 @@ gimp_overlay_child_realize (GimpOverlayBox   *box,
   widget = GTK_WIDGET (box);
 
   display = gtk_widget_get_display (widget);
+  screen  = gtk_widget_get_screen (widget);
+
+  colormap = gdk_screen_get_rgba_colormap (screen);
+  if (colormap)
+    gtk_widget_set_colormap (child->widget, colormap);
 
   gtk_widget_get_allocation (child->widget, &child_allocation);
 
@@ -157,9 +164,9 @@ gimp_overlay_child_realize (GimpOverlayBox   *box,
   attributes.y           = child_allocation.y;
   attributes.window_type = GDK_WINDOW_OFFSCREEN;
   attributes.wclass      = GDK_INPUT_OUTPUT;
-  attributes.visual      = gtk_widget_get_visual (widget);
-  attributes.colormap    = gtk_widget_get_colormap (widget);
-  attributes.event_mask  = gtk_widget_get_events (widget);
+  attributes.visual      = gtk_widget_get_visual (child->widget);
+  attributes.colormap    = gtk_widget_get_colormap (child->widget);
+  attributes.event_mask  = gtk_widget_get_events (child->widget) | GDK_EXPOSURE_MASK;
   attributes.cursor      = gdk_cursor_new_for_display (display, GDK_LEFT_PTR);
 
   attributes_mask = (GDK_WA_X        |
@@ -345,11 +352,13 @@ gimp_overlay_child_expose (GimpOverlayBox   *box,
     }
   else if (event->window == child->window)
     {
-      gtk_paint_flat_box (gtk_widget_get_style (widget),
+#if 0
+      gtk_paint_flat_box (gtk_widget_get_style (child->widget),
                           event->window,
                           GTK_STATE_NORMAL, GTK_SHADOW_NONE,
                           &event->area, widget, NULL,
                           0, 0, -1, -1);
+#endif
 
       gtk_container_propagate_expose (GTK_CONTAINER (widget),
                                       child->widget,
diff --git a/app/widgets/gimpoverlayframe.c b/app/widgets/gimpoverlayframe.c
index 63c23e5..8897f82 100644
--- a/app/widgets/gimpoverlayframe.c
+++ b/app/widgets/gimpoverlayframe.c
@@ -53,19 +53,7 @@ gimp_overlay_frame_class_init (GimpOverlayFrameClass *klass)
 static void
 gimp_overlay_frame_init (GimpOverlayFrame *frame)
 {
-  GtkWidget   *widget = GTK_WIDGET (frame);
-
-#if 0 /* crashes badly beause gtk+ doesn't support offscreen windows
-       * with colormap != parent_colormap yet
-       */
-  GdkScreen   *screen = gtk_widget_get_screen (widget);
-  GdkColormap *rgba   = gdk_screen_get_rgba_colormap (screen);
-
-  if (rgba)
-    gtk_widget_set_colormap (widget, rgba);
-#endif
-
-  gtk_widget_set_app_paintable (widget, TRUE);
+  gtk_widget_set_app_paintable (GTK_WIDGET (frame), TRUE);
 }
 
 static void
@@ -122,62 +110,76 @@ static gboolean
 gimp_overlay_frame_expose (GtkWidget      *widget,
                            GdkEventExpose *eevent)
 {
-  cairo_t       *cr    = gdk_cairo_create (gtk_widget_get_window (widget));
-  GtkStyle      *style = gtk_widget_get_style (widget);
-  GtkAllocation  allocation;
-  gint           border_width;
-
-  gtk_widget_get_allocation (widget, &allocation);
+  cairo_t  *cr    = gdk_cairo_create (gtk_widget_get_window (widget));
+  GtkStyle *style = gtk_widget_get_style (widget);
+  gboolean  rgba;
 
-  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+  rgba = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)) != NULL;
 
-  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
-  gdk_cairo_region (cr, eevent->region);
-  cairo_clip_preserve (cr);
-  cairo_fill (cr);
+  if (rgba)
+    {
+      cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+      gdk_cairo_region (cr, eevent->region);
+      cairo_clip_preserve (cr);
+      cairo_fill (cr);
+    }
 
   cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
   gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
 
+  if (rgba)
+    {
+      GtkAllocation  allocation;
+      gint           border_width;
+
+      gtk_widget_get_allocation (widget, &allocation);
+
+      border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
 #define DEG_TO_RAD(deg) ((deg) * (G_PI / 180.0))
 
-  cairo_arc (cr,
-             border_width,
-             border_width,
-             border_width,
-             DEG_TO_RAD (180),
-             DEG_TO_RAD (270));
-  cairo_line_to (cr,
+      cairo_arc (cr,
+                 border_width,
+                 border_width,
+                 border_width,
+                 DEG_TO_RAD (180),
+                 DEG_TO_RAD (270));
+      cairo_line_to (cr,
+                     allocation.width - border_width,
+                     0);
+
+      cairo_arc (cr,
                  allocation.width - border_width,
-                 0);
-
-  cairo_arc (cr,
-             allocation.width - border_width,
-             border_width,
-             border_width,
-             DEG_TO_RAD (270),
-             DEG_TO_RAD (0));
-  cairo_line_to (cr,
-                 allocation.width,
-                 allocation.height - border_width);
-
-  cairo_arc (cr,
-             allocation.width  - border_width,
-             allocation.height - border_width,
-             border_width,
-             DEG_TO_RAD (0),
-             DEG_TO_RAD (90));
-  cairo_line_to (cr,
                  border_width,
-                 allocation.height);
-
-  cairo_arc (cr,
-             border_width,
-             allocation.height - border_width,
-             border_width,
-             DEG_TO_RAD (90),
-             DEG_TO_RAD (180));
-  cairo_close_path (cr);
+                 border_width,
+                 DEG_TO_RAD (270),
+                 DEG_TO_RAD (0));
+      cairo_line_to (cr,
+                     allocation.width,
+                     allocation.height - border_width);
+
+      cairo_arc (cr,
+                 allocation.width  - border_width,
+                 allocation.height - border_width,
+                 border_width,
+                 DEG_TO_RAD (0),
+                 DEG_TO_RAD (90));
+      cairo_line_to (cr,
+                     border_width,
+                     allocation.height);
+
+      cairo_arc (cr,
+                 border_width,
+                 allocation.height - border_width,
+                 border_width,
+                 DEG_TO_RAD (90),
+                 DEG_TO_RAD (180));
+      cairo_close_path (cr);
+    }
+  else
+    {
+      gdk_cairo_region (cr, eevent->region);
+    }
 
   cairo_fill (cr);
 



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