[mutter] Fix compilation against latest GTK3 changes



commit 9f5d8d1a2ace209f3c57ef48adcc0204bd6ca104
Author: Benjamin Otte <otte redhat com>
Date:   Fri Sep 24 13:30:40 2010 +0200

    Fix compilation against latest GTK3 changes
    
    With the newest changes to GTK3, some things were changed. This patch
    now uses the features introduced in gtk3-compat.h in previous patches.
    
    This patch also introduces a macro named USE_GTK3 that is used to
    differentiate between GTK3 and GTK2. Its main use is differenting
    between expose and draw handlers for GtkWidget subclasses.
    
    The draw vs expose handlers question is usually handled by using ifdefs
    at the beginning and end to set up/tear down a cairo_t and then use it.
    
    However, when the function is too different and too many ifdefs would be
    necessary, two versions of the function are written. This is currently
    the case for:
    - MetaAccelLabel
    - MetaFrames
    
    https://bugzilla.gnome.org/show_bug.cgi?id=630203

 src/gdk-compat.h         |   30 +++++++++++++-
 src/gdk2-drawing-utils.c |    3 +
 src/gdk2-drawing-utils.h |   22 ++++++++++
 src/tools/mutter-mag.c   |   10 ++--
 src/ui/fixedtip.c        |   24 ++++++++++
 src/ui/frames.c          |   81 +++++++++++++++++++++++++++++++++++-
 src/ui/menu.c            |    4 +-
 src/ui/metaaccellabel.c  |   99 +++++++++++++++++++++++++++++++++++++++++++
 src/ui/preview-widget.c  |   88 ++++++++++++++++++++++++--------------
 src/ui/tabpopup.c        |  105 +++++++++++++++++++++++++++++++--------------
 src/ui/tile-preview.c    |   37 ++++++++++++----
 src/ui/ui.c              |   70 ++++++++++++++++++++++++++++++
 12 files changed, 489 insertions(+), 84 deletions(-)
---
diff --git a/src/gdk-compat.h b/src/gdk-compat.h
index 1554af3..37a1695 100644
--- a/src/gdk-compat.h
+++ b/src/gdk-compat.h
@@ -14,7 +14,34 @@
 
 #define gdk_visual_get_depth(v)           GDK_VISUAL(v)->depth
 
-#endif /*GTK_CHECK_VERSION */
+#endif /* GTK_CHECK_VERSION (2, 21, 1) */
+
+#if !GTK_CHECK_VERSION (2, 90, 8)
+
+#define gdk_window_get_screen gdk_drawable_get_screen
+#define gdk_pixbuf_get_from_window(dest, window, src_x, src_y, dest_x, dest_y, width, height) \
+    gdk_pixbuf_get_from_drawable(dest, window, NULL, src_x, src_y, dest_x, dest_y, width, height)
+
+static inline int
+gdk_window_get_width (GdkWindow *window)
+{
+  int width;
+
+  gdk_drawable_get_size (window, &width, NULL);
+
+  return width;
+}
+
+static inline int
+gdk_window_get_height (GdkWindow *window)
+{
+  int height;
+
+  gdk_drawable_get_size (window, NULL, &height);
+
+  return height;
+}
+
 
 static inline gboolean
 gdk_cairo_get_clip_rectangle (cairo_t      *cr,
@@ -43,6 +70,7 @@ gdk_cairo_get_clip_rectangle (cairo_t      *cr,
   return clip_exists;
 }
 
+#endif /* GTK_CHECK_VERSION (2, 90, 8) */
 
 /* Compatibility with old GDK key symbols */
 #ifndef GDK_KEY_Escape
diff --git a/src/gdk2-drawing-utils.c b/src/gdk2-drawing-utils.c
index 558d563..f8be2b5 100644
--- a/src/gdk2-drawing-utils.c
+++ b/src/gdk2-drawing-utils.c
@@ -27,6 +27,8 @@
 
 #include "gdk-compat.h"
 
+#ifndef USE_GTK3
+
 static const cairo_user_data_key_t context_key;
 
 cairo_t *
@@ -172,3 +174,4 @@ meta_paint_flat_box (GtkStyle           *style,
                       x + dx, y + dy, width, height);
 }
 
+#endif /* USE_GTK3 */
diff --git a/src/gdk2-drawing-utils.h b/src/gdk2-drawing-utils.h
index 69f45d4..3d6bd34 100644
--- a/src/gdk2-drawing-utils.h
+++ b/src/gdk2-drawing-utils.h
@@ -24,6 +24,26 @@
 
 #include <gtk/gtk.h>
 
+#if GTK_CHECK_VERSION (2, 90, 8)
+
+#define USE_GTK3 1
+
+#define MetaPixmap cairo_surface_t
+
+#define meta_pixmap_new(window, w, h) gdk_window_create_similar_surface (window, CAIRO_CONTENT_COLOR, w, h)
+#define meta_pixmap_free(pixmap) cairo_surface_destroy (pixmap)
+#define meta_pixmap_cairo_create(pixmap) cairo_create (pixmap)
+#define meta_cairo_set_source_pixmap(cr, pixmap, x, y) cairo_set_source_surface (cr, pixmap, x, y)
+
+#define meta_paint_vline gtk_paint_vline
+#define meta_paint_box gtk_paint_box
+#define meta_paint_arrow gtk_paint_arrow
+#define meta_paint_flat_box gtk_paint_flat_box
+
+#else /* GTK_VERSION < 2.90.8 */
+
+#undef USE_GTK3
+
 #define MetaPixmap GdkPixmap
 
 #define meta_pixmap_new(window, w, h) gdk_pixmap_new (window, w, h, -1)
@@ -75,4 +95,6 @@ void          meta_paint_flat_box          (GtkStyle           *style,
                                             gint                width,
                                             gint                height);
 
+#endif /* GTK_VERSION < 2.90.8 */
+
 #endif /* __GTK3_COMPAT_H__ */
diff --git a/src/tools/mutter-mag.c b/src/tools/mutter-mag.c
index b45c538..14c22e7 100644
--- a/src/tools/mutter-mag.c
+++ b/src/tools/mutter-mag.c
@@ -28,7 +28,8 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <math.h>
-#include <gdk-compat.h>
+
+#include "gdk-compat.h"
 
 static GtkWidget *grab_widget = NULL;
 static GtkWidget *display_window = NULL;
@@ -53,10 +54,9 @@ get_pixbuf (void)
            last_grab_width, last_grab_height);
 #endif
   
-  screenshot = gdk_pixbuf_get_from_drawable (NULL, gdk_get_default_root_window (),
-                                             NULL,
-                                             last_grab_x, last_grab_y, 0, 0,
-                                             last_grab_width, last_grab_height);
+  screenshot = gdk_pixbuf_get_from_window (NULL, gdk_get_default_root_window (),
+                                           last_grab_x, last_grab_y, 0, 0,
+                                           last_grab_width, last_grab_height);
 
   if (screenshot == NULL)
     {
diff --git a/src/ui/fixedtip.c b/src/ui/fixedtip.c
index bb536df..e006e8c 100644
--- a/src/ui/fixedtip.c
+++ b/src/ui/fixedtip.c
@@ -25,6 +25,8 @@
 #include "fixedtip.h"
 #include "ui.h"
 
+#include "gdk2-drawing-utils.h"
+
 /**
  * The floating rectangle.  This is a GtkWindow, and it contains
  * the "label" widget, below.
@@ -50,6 +52,22 @@ static int screen_right_edge = 0;
  */
 static int screen_bottom_edge = 0;
 
+#ifdef USE_GTK3
+static gboolean
+draw_handler (GtkWidget *tooltips,
+              cairo_t   *cr)
+{
+  gtk_paint_flat_box (gtk_widget_get_style (tip),
+                      cr,
+                      GTK_STATE_NORMAL, GTK_SHADOW_OUT, 
+                      tip, "tooltip",
+                      0, 0,
+                      gtk_widget_get_allocated_width (tooltips),
+                      gtk_widget_get_allocated_height (tooltips));
+
+  return FALSE;
+}
+#else /* !USE_GTK3 */
 static gint
 expose_handler (GtkWidget *tooltips)
 {
@@ -61,6 +79,7 @@ expose_handler (GtkWidget *tooltips)
 
   return FALSE;
 }
+#endif /* !USE_GTK3 */
 
 void
 meta_fixed_tip_show (Display *xdisplay, int screen_number,
@@ -94,8 +113,13 @@ meta_fixed_tip_show (Display *xdisplay, int screen_number,
       gtk_widget_set_name (tip, "gtk-tooltips");
       gtk_container_set_border_width (GTK_CONTAINER (tip), 4);
 
+#ifdef USE_GTK3
+      g_signal_connect_swapped (tip, "draw",
+				 G_CALLBACK (draw_handler), NULL);
+#else
       g_signal_connect_swapped (tip, "expose_event",
 				 G_CALLBACK (expose_handler), NULL);
+#endif
 
       label = gtk_label_new (NULL);
       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
diff --git a/src/ui/frames.c b/src/ui/frames.c
index d8d0c96..ab55f10 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -40,6 +40,8 @@
 #include "gtk-compat.h"
 #include "gdk-compat.h"
 
+#include <cairo-xlib.h>
+
 #ifdef HAVE_SHAPE
 #include <X11/extensions/shape.h>
 #endif
@@ -64,8 +66,13 @@ static gboolean meta_frames_motion_notify_event   (GtkWidget           *widget,
                                                    GdkEventMotion      *event);
 static gboolean meta_frames_destroy_event         (GtkWidget           *widget,
                                                    GdkEventAny         *event);
+#ifdef USE_GTK3
+static gboolean meta_frames_draw                  (GtkWidget           *widget,
+                                                   cairo_t             *cr);
+#else
 static gboolean meta_frames_expose_event          (GtkWidget           *widget,
                                                    GdkEventExpose      *event);
+#endif
 static gboolean meta_frames_enter_notify_event    (GtkWidget           *widget,
                                                    GdkEventCrossing    *event);
 static gboolean meta_frames_leave_notify_event    (GtkWidget           *widget,
@@ -148,7 +155,11 @@ meta_frames_class_init (MetaFramesClass *class)
   widget_class->map = meta_frames_map;
   widget_class->unmap = meta_frames_unmap;
   
+#ifdef USE_GTK3
+  widget_class->draw = meta_frames_draw;
+#else
   widget_class->expose_event = meta_frames_expose_event;
+#endif
   widget_class->destroy_event = meta_frames_destroy_event;  
   widget_class->button_press_event = meta_frames_button_press_event;
   widget_class->button_release_event = meta_frames_button_release_event;
@@ -1016,7 +1027,8 @@ meta_frames_move_resize_frame (MetaFrames *frames,
   MetaUIFrame *frame = meta_frames_lookup_window (frames, xwindow);
   int old_width, old_height;
   
-  gdk_drawable_get_size (frame->window, &old_width, &old_height);
+  old_width = gdk_window_get_width (frame->window);
+  old_height = gdk_window_get_height (frame->window);
 
   gdk_window_move_resize (frame->window, x, y, width, height);
 
@@ -2278,6 +2290,72 @@ cached_pixels_draw (CachedPixels *pixels,
     }
 }
 
+#ifdef USE_GTK3
+static gboolean
+meta_frames_draw (GtkWidget *widget,
+                  cairo_t   *cr)
+{
+  MetaUIFrame *frame;
+  MetaFrames *frames;
+  CachedPixels *pixels;
+  MetaRegion *region;
+  GdkRectangle *areas, clip;
+  int i, n_areas;
+  cairo_surface_t *target;
+
+  frames = META_FRAMES (widget);
+  target = cairo_get_target (cr);
+  gdk_cairo_get_clip_rectangle (cr, &clip);
+
+  g_assert (cairo_surface_get_type (target) == CAIRO_SURFACE_TYPE_XLIB);
+  frame = meta_frames_lookup_window (frames, cairo_xlib_surface_get_drawable (target));
+  if (frame == NULL)
+    return FALSE;
+
+  if (frames->expose_delay_count > 0)
+    {
+      /* Redraw this entire frame later */
+      frame->expose_delayed = TRUE;
+      return TRUE;
+    }
+
+  populate_cache (frames, frame);
+
+  region = meta_region_new_from_rectangle (&clip);
+  
+  pixels = get_cache (frames, frame);
+
+  cached_pixels_draw (pixels, cr, region);
+  
+  clip_to_screen (region, frame);
+  subtract_client_area (region, frame);
+
+  meta_region_get_rectangles (region, &areas, &n_areas);
+
+  for (i = 0; i < n_areas; i++)
+    {
+      cairo_save (cr);
+
+      gdk_cairo_rectangle (cr, &areas[i]);
+      cairo_clip (cr);
+
+      cairo_push_group (cr);
+
+      meta_frames_paint (frames, frame, cr, 0, 0);
+
+      cairo_pop_group_to_source (cr);
+      cairo_paint (cr);
+
+      cairo_restore (cr);
+    }
+
+  g_free (areas);
+
+  meta_region_destroy (region);
+  
+  return TRUE;
+}
+#else /* !USE_GTK3 */
 static gboolean
 meta_frames_expose_event (GtkWidget           *widget,
                           GdkEventExpose      *event)
@@ -2341,6 +2419,7 @@ meta_frames_expose_event (GtkWidget           *widget,
   
   return TRUE;
 }
+#endif /* !USE_GTK3 */
 
 static void
 meta_frames_paint (MetaFrames   *frames,
diff --git a/src/ui/menu.c b/src/ui/menu.c
index 8bab2f1..54dc14b 100644
--- a/src/ui/menu.c
+++ b/src/ui/menu.c
@@ -33,6 +33,8 @@
 #include "metaaccellabel.h"
 #include "ui.h"
 
+#include "gdk-compat.h"
+
 typedef struct _MenuItem MenuItem;
 typedef struct _MenuData MenuData;
 
@@ -403,7 +405,7 @@ meta_window_menu_new   (MetaFrames         *frames,
                   window = gtk_widget_get_window (GTK_WIDGET (frames));
                   display = gdk_x11_drawable_get_xdisplay (window);
 
-                  screen = gdk_drawable_get_screen (window);
+                  screen = gdk_window_get_screen (window);
                   xroot = GDK_DRAWABLE_XID (gdk_screen_get_root_window (screen));
 
                   submenu = gtk_menu_new ();
diff --git a/src/ui/metaaccellabel.c b/src/ui/metaaccellabel.c
index b08c0d6..134cbe0 100644
--- a/src/ui/metaaccellabel.c
+++ b/src/ui/metaaccellabel.c
@@ -38,13 +38,19 @@
 #include "util.h"
 
 #include "gtk-compat.h"
+#include "gdk2-drawing-utils.h"
 
 static void     meta_accel_label_destroy      (GtkObject           *object);
 static void     meta_accel_label_finalize     (GObject             *object);
 static void     meta_accel_label_size_request (GtkWidget           *widget,
                                                GtkRequisition      *requisition);
+#ifdef USE_GTK3
+static gboolean meta_accel_label_draw         (GtkWidget           *widget,
+                                               cairo_t             *cr);
+#else
 static gboolean meta_accel_label_expose_event (GtkWidget           *widget,
                                                GdkEventExpose      *event);
+#endif
 
 static void  meta_accel_label_update          (MetaAccelLabel *accel_label);
 static int   meta_accel_label_get_accel_width (MetaAccelLabel *accel_label);
@@ -63,7 +69,11 @@ meta_accel_label_class_init (MetaAccelLabelClass *class)
   object_class->destroy = meta_accel_label_destroy;
 
   widget_class->size_request = meta_accel_label_size_request;
+#ifdef USE_GTK3
+  widget_class->draw = meta_accel_label_draw;
+#else
   widget_class->expose_event = meta_accel_label_expose_event;
+#endif
 
   class->signal_quote1 = g_strdup ("<:");
   class->signal_quote2 = g_strdup (":>");
@@ -225,6 +235,94 @@ meta_accel_label_size_request (GtkWidget	     *widget,
   g_object_unref (G_OBJECT (layout));
 }
 
+#ifdef USE_GTK3
+/* Mostly taken from GTK3. */
+static gboolean
+meta_accel_label_draw (GtkWidget *widget,
+                       cairo_t   *cr)
+{
+  MetaAccelLabel *accel_label = META_ACCEL_LABEL (widget);
+  GtkMisc *misc = GTK_MISC (accel_label);
+  GtkTextDirection direction;
+  int ac_width;
+  GtkAllocation allocation;
+  GtkRequisition requisition;
+
+  direction = gtk_widget_get_direction (widget);
+  ac_width = meta_accel_label_get_accel_width (accel_label);
+  gtk_widget_get_allocation (widget, &allocation);
+  gtk_widget_get_preferred_size (widget,
+                                 &requisition, NULL);
+
+  if (allocation.width >= requisition.width + ac_width)
+    {
+      PangoLayout *label_layout;
+      PangoLayout *accel_layout;
+      GtkLabel *label = GTK_LABEL (widget);
+      gint x, y, xpad, ypad;
+      gfloat xalign, yalign;
+
+      label_layout = gtk_label_get_layout (GTK_LABEL (accel_label));
+      gtk_misc_get_alignment (misc, &xalign, &yalign);
+
+      cairo_save (cr);
+
+      /* XXX: Mad hack: We modify the label's width so it renders
+       * properly in its draw function that we chain to. */
+      if (direction == GTK_TEXT_DIR_RTL)
+        cairo_translate (cr, ac_width, 0);
+      if (gtk_label_get_ellipsize (label))
+        pango_layout_set_width (label_layout,
+                                pango_layout_get_width (label_layout) 
+                                - ac_width * PANGO_SCALE);
+      
+      allocation.width -= ac_width;
+      gtk_widget_set_allocation (widget, &allocation);
+      if (GTK_WIDGET_CLASS (meta_accel_label_parent_class)->draw)
+        GTK_WIDGET_CLASS (meta_accel_label_parent_class)->draw (widget,
+                                                               cr);
+      allocation.width += ac_width;
+      gtk_widget_set_allocation (widget, &allocation);
+      if (gtk_label_get_ellipsize (label))
+        pango_layout_set_width (label_layout,
+                                pango_layout_get_width (label_layout) 
+                                + ac_width * PANGO_SCALE);
+
+      cairo_restore (cr);
+
+      gtk_misc_get_padding (misc, &xpad, &ypad);
+
+      if (direction == GTK_TEXT_DIR_RTL)
+        x = xpad;
+      else
+        x = gtk_widget_get_allocated_width (widget) - xpad - ac_width;
+
+      gtk_label_get_layout_offsets (GTK_LABEL (accel_label), NULL, &y);
+
+      accel_layout = gtk_widget_create_pango_layout (widget, accel_label->accel_string);
+
+      y = (allocation.height - (requisition.height - ypad * 2)) * yalign + 1.5;
+
+      gtk_paint_layout (gtk_widget_get_style (widget),
+                        cr,
+                        gtk_widget_get_state (widget),
+                        FALSE,
+                        widget,
+                        "accellabel",
+                        x, y,
+                        accel_layout);                            
+
+      g_object_unref (accel_layout);
+    }
+  else
+    {
+      if (GTK_WIDGET_CLASS (meta_accel_label_parent_class)->draw)
+        GTK_WIDGET_CLASS (meta_accel_label_parent_class)->draw (widget, cr);
+    }
+  
+  return FALSE;
+}
+#else /* !USE_GTK3 */
 static gboolean
 meta_accel_label_expose_event (GtkWidget      *widget,
 			      GdkEventExpose *event)
@@ -306,6 +404,7 @@ meta_accel_label_expose_event (GtkWidget      *widget,
 
   return FALSE;
 }
+#endif /* !USE_GTK3 */
 
 static void
 meta_accel_label_update (MetaAccelLabel *accel_label)
diff --git a/src/ui/preview-widget.c b/src/ui/preview-widget.c
index 87b641a..f49c970 100644
--- a/src/ui/preview-widget.c
+++ b/src/ui/preview-widget.c
@@ -34,8 +34,13 @@ static void     meta_preview_size_request  (GtkWidget        *widget,
                                             GtkRequisition   *req);
 static void     meta_preview_size_allocate (GtkWidget        *widget,
                                             GtkAllocation    *allocation);
+#ifdef USE_GTK3
+static gboolean meta_preview_draw          (GtkWidget        *widget,
+                                            cairo_t          *cr);
+#else
 static gboolean meta_preview_expose        (GtkWidget        *widget,
                                             GdkEventExpose   *event);
+#endif
 static void     meta_preview_finalize      (GObject          *object);
 
 G_DEFINE_TYPE (MetaPreview, meta_preview, GTK_TYPE_BIN);
@@ -50,7 +55,11 @@ meta_preview_class_init (MetaPreviewClass *class)
 
   gobject_class->finalize = meta_preview_finalize;
 
+#ifdef USE_GTK3
+  widget_class->draw = meta_preview_draw;
+#else
   widget_class->expose_event = meta_preview_expose;
+#endif
   widget_class->size_request = meta_preview_size_request;
   widget_class->size_allocate = meta_preview_size_allocate;
 }
@@ -185,54 +194,61 @@ ensure_info (MetaPreview *preview)
     }
 }
 
+#ifdef USE_GTK3
+static gboolean
+meta_preview_draw (GtkWidget *widget,
+                   cairo_t   *cr)
+{
+  MetaPreview *preview = META_PREVIEW (widget);
+  GtkAllocation allocation;
+
+  gtk_widget_get_allocation (widget, &allocation);
+#else
 static gboolean
 meta_preview_expose (GtkWidget      *widget,
                      GdkEventExpose *event)
 {
-  MetaPreview *preview;
+  cairo_t *cr = meta_cairo_create (gtk_widget_get_window (widget));
+  MetaPreview *preview = META_PREVIEW (widget);
   GtkAllocation allocation;
-  int border_width;
-  int client_width;
-  int client_height;
-  MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
-  {
-    META_BUTTON_STATE_NORMAL,
-    META_BUTTON_STATE_NORMAL,
-    META_BUTTON_STATE_NORMAL,
-    META_BUTTON_STATE_NORMAL
-  };
-  
-  g_return_val_if_fail (META_IS_PREVIEW (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  preview = META_PREVIEW (widget);
 
-  ensure_info (preview);
-
-  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+  gdk_cairo_region (cr, event->region);
+  cairo_clip (cr);
 
   gtk_widget_get_allocation (widget, &allocation);
-  client_width = allocation.width - preview->left_width - preview->right_width - border_width * 2;
-  client_height = allocation.height - preview->top_height - preview->bottom_height - border_width * 2;
+  cairo_translate (cr, allocation.x, allocation.y);
+#endif
 
-  if (client_width < 0)
-    client_width = 1;
-  if (client_height < 0)
-    client_height = 1;  
-  
   if (preview->theme)
     {
-      cairo_t *cr;
+      int border_width;
+      int client_width;
+      int client_height;
+      MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
+      {
+        META_BUTTON_STATE_NORMAL,
+        META_BUTTON_STATE_NORMAL,
+        META_BUTTON_STATE_NORMAL,
+        META_BUTTON_STATE_NORMAL
+      };
+  
+      ensure_info (preview);
 
-      cr = meta_cairo_create (gtk_widget_get_window (widget));
-      gdk_cairo_region (cr, event->region);
-      cairo_clip (cr);
+      border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
 
+      client_width = allocation.width - preview->left_width - preview->right_width - border_width * 2;
+      client_height = allocation.height - preview->top_height - preview->bottom_height - border_width * 2;
+
+      if (client_width < 0)
+        client_width = 1;
+      if (client_height < 0)
+        client_height = 1;  
+      
       meta_theme_draw_frame (preview->theme,
                              widget,
                              cr,
-                             allocation.x + border_width,
-                             allocation.y + border_width,
+                             border_width,
+                             border_width,
                              preview->type,
                              preview->flags,
                              client_width, client_height,
@@ -243,11 +259,17 @@ meta_preview_expose (GtkWidget      *widget,
                              meta_preview_get_mini_icon (),
                              meta_preview_get_icon ());
 
-      cairo_destroy (cr);
     }
 
+#ifdef USE_GTK3
+  /* draw child */
+  return GTK_WIDGET_CLASS (meta_preview_parent_class)->draw (widget, cr);
+#else
+  cairo_destroy (cr);
+
   /* draw child */
   return GTK_WIDGET_CLASS (meta_preview_parent_class)->expose_event (widget, event);
+#endif
 }
 
 static void
diff --git a/src/ui/tabpopup.c b/src/ui/tabpopup.c
index face14c..0c2e3c2 100644
--- a/src/ui/tabpopup.c
+++ b/src/ui/tabpopup.c
@@ -38,6 +38,7 @@
 #include <math.h>
 
 #include "gtk-compat.h"
+#include "gdk2-drawing-utils.h"
 
 #define OUTSIDE_SELECT_RECT 2
 #define INSIDE_SELECT_RECT 2
@@ -74,16 +75,24 @@ static GtkWidget* selectable_workspace_new (MetaWorkspace *workspace);
 static void       select_workspace         (GtkWidget *widget);
 static void       unselect_workspace       (GtkWidget *widget);
 
+#ifdef USE_GTK3
+static gboolean
+outline_window_draw (GtkWidget *widget,
+                     cairo_t   *cr,
+                     gpointer   data)
+{
+#else /* !USE_GTK3 */
 static gboolean
 outline_window_expose (GtkWidget      *widget,
                        GdkEventExpose *event,
                        gpointer        data)
 {
+  cairo_t *cr = gdk_cairo_create (event->window);
+#endif /* !USE_GTK3 */
+
   MetaTabPopup *popup;
   TabEntry *te;
   GtkStyle *style;
-  GdkWindow *window;
-  cairo_t *cr;
   
   popup = data;
 
@@ -91,9 +100,7 @@ outline_window_expose (GtkWidget      *widget,
     return FALSE;
 
   te = popup->current_selected_entry;
-  window = gtk_widget_get_window (widget);
   style = gtk_widget_get_style (widget);
-  cr = gdk_cairo_create (window);
 
   cairo_set_line_width (cr, 1.0);
   gdk_cairo_set_source_color (cr, &style->white);
@@ -110,7 +117,9 @@ outline_window_expose (GtkWidget      *widget,
                    te->inner_rect.height + 1);
   cairo_stroke (cr);
 
+#ifndef USE_GTK3
   cairo_destroy (cr);
+#endif
 
   return FALSE;
 }
@@ -252,8 +261,13 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
   gtk_widget_set_app_paintable (popup->outline_window, TRUE);
   gtk_widget_realize (popup->outline_window);
 
+#ifdef USE_GTK3
+  g_signal_connect (G_OBJECT (popup->outline_window), "draw",
+                    G_CALLBACK (outline_window_draw), popup);
+#else
   g_signal_connect (G_OBJECT (popup->outline_window), "expose_event",
                     G_CALLBACK (outline_window_expose), popup);
+#endif
   
   popup->window = gtk_window_new (GTK_WINDOW_POPUP);
 
@@ -659,8 +673,13 @@ unselect_image (GtkWidget *widget)
 }
 
 static void     meta_select_image_class_init   (MetaSelectImageClass *klass);
+#if USE_GTK3
+static gboolean meta_select_image_draw         (GtkWidget            *widget,
+                                                cairo_t              *cr);
+#else
 static gboolean meta_select_image_expose_event (GtkWidget            *widget,
                                                 GdkEventExpose       *event);
+#endif
 
 static GtkImageClass *parent_class;
 
@@ -699,16 +718,37 @@ meta_select_image_class_init (MetaSelectImageClass *klass)
 
   widget_class = GTK_WIDGET_CLASS (klass);
   
+#if USE_GTK3
+  widget_class->draw = meta_select_image_draw;
+#else
   widget_class->expose_event = meta_select_image_expose_event;
+#endif
 }
 
+#if USE_GTK3
+static gboolean
+meta_select_image_draw (GtkWidget *widget,
+                        cairo_t   *cr)
+{
+  GtkAllocation allocation;
+
+  gtk_widget_get_allocation (widget, &allocation);
+#else /* !USE_GTK3 */
 static gboolean
 meta_select_image_expose_event (GtkWidget      *widget,
                                 GdkEventExpose *event)
 {
+  GtkAllocation allocation;
+  cairo_t *cr = gdk_cairo_create (event->window);
+
+  gdk_cairo_region (cr, event->region);
+  cairo_clip (cr);
+  gtk_widget_get_allocation (widget, &allocation);
+  cairo_translate (cr, allocation.x, allocation.y);
+#endif
+
   if (META_SELECT_IMAGE (widget)->selected)
     {
-      GtkAllocation allocation;
       GtkMisc *misc;
       GtkRequisition requisition;
       GtkStyle *style;
@@ -717,21 +757,15 @@ meta_select_image_expose_event (GtkWidget      *widget,
       int x, y, w, h;
       gint xpad, ypad;
       gfloat xalign, yalign;
-      cairo_t *cr;
 
       misc = GTK_MISC (widget);
 
-      gtk_widget_get_allocation (widget, &allocation);
       gtk_widget_get_requisition (widget, &requisition);
       gtk_misc_get_alignment (misc, &xalign, &yalign);
       gtk_misc_get_padding (misc, &xpad, &ypad);
       
-      x = (allocation.x * (1.0 - xalign) +
-           (allocation.x + allocation.width
-            - (requisition.width - xpad * 2)) * xalign) + 0.5;
-      y = (allocation.y * (1.0 - yalign) +
-           (allocation.y + allocation.height
-            - (requisition.height - ypad * 2)) * yalign) + 0.5;
+      x = (allocation.width - (requisition.width - xpad * 2)) * xalign + 0.5;
+      y = (allocation.height - (requisition.height - ypad * 2)) * yalign + 0.5;
 
       x -= INSIDE_SELECT_RECT + 1;
       y -= INSIDE_SELECT_RECT + 1;      
@@ -742,7 +776,6 @@ meta_select_image_expose_event (GtkWidget      *widget,
       window = gtk_widget_get_window (widget);
       style = gtk_widget_get_style (widget);
       state = gtk_widget_get_state (widget);
-      cr = gdk_cairo_create (window);
 
       cairo_set_line_width (cr, 2.0);
       gdk_cairo_set_source_color (cr, &style->fg[state]);
@@ -751,22 +784,15 @@ meta_select_image_expose_event (GtkWidget      *widget,
       cairo_stroke (cr);
 
       cairo_set_line_width (cr, 1.0);
-#if 0
-      gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_SELECTED]);
-      cairo_rectangle (cr, x, y, w, h);
-      cairo_fill (cr);
-#endif
-
-#if 0      
-      gtk_paint_focus (widget->style, widget->window,
-                       &event->area, widget, "meta-tab-image",
-                       x, y, w, h);
-#endif
-
-      cairo_destroy (cr);
     }
 
+#ifdef USE_GTK3
+  return GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
+#else
+  cairo_destroy (cr);
+
   return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
+#endif /* !USE_GTK3 */
 }
 
 #define META_TYPE_SELECT_WORKSPACE   (meta_select_workspace_get_type ())
@@ -830,8 +856,13 @@ unselect_workspace (GtkWidget *widget)
 
 static void meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass);
 
+#if USE_GTK3
+static gboolean meta_select_workspace_draw         (GtkWidget      *widget,
+                                                    cairo_t        *cr);
+#else
 static gboolean meta_select_workspace_expose_event (GtkWidget      *widget,
                                                     GdkEventExpose *event);
+#endif
 
 GType
 meta_select_workspace_get_type (void)
@@ -869,7 +900,11 @@ meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass)
   
   widget_class = GTK_WIDGET_CLASS (klass);
   
+#if USE_GTK3
+  widget_class->draw = meta_select_workspace_draw;
+#else
   widget_class->expose_event = meta_select_workspace_expose_event;
+#endif
 }
 
 /**
@@ -906,16 +941,22 @@ meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen)
 }
 
 
+#ifdef USE_GTK3
+static gboolean
+meta_select_workspace_draw (GtkWidget *widget,
+                            cairo_t   *cr)
+{
+#else /* !USE_GTK3 */
 static gboolean
 meta_select_workspace_expose_event (GtkWidget      *widget,
                                     GdkEventExpose *event)
 {
+  cairo_t *cr = gdk_cairo_create (event->window);
+#endif /* !USE_GTK3 */
   MetaWorkspace *workspace;
   WnckWindowDisplayInfo *windows;
   GtkAllocation allocation;
   GtkStyle *style;
-  GdkWindow *window;
-  cairo_t *cr;
   int i, n_windows;
   GList *tmp, *list;
 
@@ -954,11 +995,8 @@ meta_select_workspace_expose_event (GtkWidget      *widget,
 
   g_list_free (list);
 
-  window = gtk_widget_get_window (widget);
   gtk_widget_get_allocation (widget, &allocation);
 
-  cr = gdk_cairo_create (window);
-
   wnck_draw_workspace (widget,
                        cr,
                        SELECT_OUTLINE_WIDTH,
@@ -989,8 +1027,9 @@ meta_select_workspace_expose_event (GtkWidget      *widget,
       cairo_stroke (cr);
     }
 
+#ifndef USE_GTK3
   cairo_destroy (cr);
+#endif
 
   return TRUE;
 }
-
diff --git a/src/ui/tile-preview.c b/src/ui/tile-preview.c
index 1e2a71e..bb2ad99 100644
--- a/src/ui/tile-preview.c
+++ b/src/ui/tile-preview.c
@@ -30,6 +30,8 @@
 #include "core.h"
 #include "region.h"
 
+#include "gdk2-drawing-utils.h"
+
 #define OUTLINE_WIDTH 5  /* frame width in non-composite case */
 
 
@@ -45,17 +47,21 @@ struct _MetaTilePreview {
   gboolean       has_alpha: 1;
 };
 
+#ifdef USE_GTK3
+static gboolean
+meta_tile_preview_draw (GtkWidget *widget,
+                        cairo_t   *cr,
+                        gpointer   user_data)
+{
+#else
 static gboolean
 meta_tile_preview_expose (GtkWidget      *widget,
                           GdkEventExpose *event,
                           gpointer        user_data)
 {
+  cairo_t *cr = gdk_cairo_create (event->window);
+#endif
   MetaTilePreview *preview = user_data;
-  GdkWindow *window;
-  cairo_t   *cr;
-
-  window = gtk_widget_get_window (widget);
-  cr = gdk_cairo_create (window);
 
   cairo_set_line_width (cr, 1.0);
 
@@ -93,7 +99,9 @@ meta_tile_preview_expose (GtkWidget      *widget,
                    preview->tile_rect.height - 1);
   cairo_stroke (cr);
 
+#ifndef USE_GTK3
   cairo_destroy (cr);
+#endif
 
   return FALSE;
 }
@@ -134,11 +142,9 @@ meta_tile_preview_new (int      screen_number,
                        gboolean composited)
 {
   MetaTilePreview *preview;
-  GdkColormap *rgba_colormap;
   GdkScreen *screen;
 
   screen = gdk_display_get_screen (gdk_display_get_default (), screen_number);
-  rgba_colormap = gdk_screen_get_rgba_colormap (screen);
 
   preview = g_new (MetaTilePreview, 1);
 
@@ -153,11 +159,18 @@ meta_tile_preview_new (int      screen_number,
   preview->tile_rect.x = preview->tile_rect.y = 0;
   preview->tile_rect.width = preview->tile_rect.height = 0;
 
-  preview->has_alpha = rgba_colormap && composited;
+  preview->has_alpha = composited &&
+                       (gdk_screen_get_rgba_visual (screen) != NULL);
 
   if (preview->has_alpha)
     {
-      gtk_widget_set_colormap (preview->preview_window, rgba_colormap);
+#ifdef USE_GTK3
+      gtk_window_set_visual (GTK_WINDOW (preview->preview_window),
+                             gdk_screen_get_rgba_visual (screen));
+#else
+      gtk_widget_set_colormap (preview->preview_window,
+                               gdk_screen_get_rgba_colormap (screen));
+#endif
 
       g_signal_connect (preview->preview_window, "style-set",
                         G_CALLBACK (on_preview_window_style_set), preview);
@@ -169,11 +182,15 @@ meta_tile_preview_new (int      screen_number,
    */
   preview->create_serial = XNextRequest (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
   gtk_widget_realize (preview->preview_window);
+#ifdef USE_GTK3
+  g_signal_connect (preview->preview_window, "draw",
+                    G_CALLBACK (meta_tile_preview_draw), preview);
+#else
   gdk_window_set_back_pixmap (gtk_widget_get_window (preview->preview_window),
                               NULL, FALSE);
-
   g_signal_connect (preview->preview_window, "expose-event",
                     G_CALLBACK (meta_tile_preview_expose), preview);
+#endif
 
   return preview;
 }
diff --git a/src/ui/ui.c b/src/ui/ui.c
index a3eba72..83123d1 100644
--- a/src/ui/ui.c
+++ b/src/ui/ui.c
@@ -33,9 +33,11 @@
 
 #include "inlinepixbufs.h"
 #include "gdk-compat.h"
+#include "gdk2-drawing-utils.h"
 
 #include <string.h>
 #include <stdlib.h>
+#include <cairo-xlib.h>
 
 static void meta_stock_icons_init (void);
 static void meta_ui_accelerator_parse (const char      *accel,
@@ -172,7 +174,9 @@ meta_ui_create_frame_window (MetaUI *ui,
   gint attributes_mask;
   GdkWindow *window;
   GdkVisual *visual;
+#ifndef USE_GTK3
   GdkColormap *cmap = gdk_screen_get_default_colormap (screen);
+#endif
   
   /* Default depth/visual handles clients with weird visuals; they can
    * always be children of the root depth/visual obviously, but
@@ -185,7 +189,9 @@ meta_ui_create_frame_window (MetaUI *ui,
     {
       visual = gdk_x11_screen_lookup_visual (screen,
                                              XVisualIDFromVisual (xvisual));
+#ifndef USE_GTK3
       cmap = gdk_colormap_new (visual, FALSE);
+#endif
     }
 
   attrs.title = NULL;
@@ -201,7 +207,9 @@ meta_ui_create_frame_window (MetaUI *ui,
   attrs.y = y;
   attrs.wclass = GDK_INPUT_OUTPUT;
   attrs.visual = visual;
+#ifndef USE_GTK3
   attrs.colormap = cmap;
+#endif
   attrs.window_type = GDK_WINDOW_CHILD;
   attrs.cursor = NULL;
   attrs.wmclass_name = NULL;
@@ -211,7 +219,11 @@ meta_ui_create_frame_window (MetaUI *ui,
   attrs.width  = width;
   attrs.height = height;
 
+#ifdef USE_GTK3
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
+#else
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+#endif
 
   /* We make an assumption that gdk_window_new() is going to call
    * XCreateWindow as it's first operation; this seems to be true currently
@@ -358,6 +370,63 @@ meta_ui_window_menu_free (MetaWindowMenu *menu)
   meta_window_menu_free (menu);
 }
 
+#ifdef USE_GTK3
+GdkPixbuf*
+meta_gdk_pixbuf_get_from_pixmap (GdkPixbuf   *dest,
+                                 Pixmap       xpixmap,
+                                 int          src_x,
+                                 int          src_y,
+                                 int          dest_x,
+                                 int          dest_y,
+                                 int          width,
+                                 int          height)
+{
+  cairo_surface_t *surface;
+  Display *display;
+  Window root_return;
+  int x_ret, y_ret;
+  unsigned int w_ret, h_ret, bw_ret, depth_ret;
+  XWindowAttributes attrs;
+  GdkPixbuf *retval;
+
+  display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+  if (!XGetGeometry (display, xpixmap, &root_return,
+                     &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
+    return NULL;
+
+  if (depth_ret == 1)
+    {
+      surface = cairo_xlib_surface_create_for_bitmap (display,
+                                                      xpixmap,
+                                                      GDK_SCREEN_XSCREEN (gdk_screen_get_default ()),
+                                                      w_ret,
+                                                      h_ret);
+    }
+  else
+    {
+      if (!XGetWindowAttributes (display, root_return, &attrs))
+        return NULL;
+
+      surface = cairo_xlib_surface_create (display,
+                                           xpixmap,
+                                           attrs.visual,
+                                           w_ret, h_ret);
+    }
+
+  retval = gdk_pixbuf_get_from_surface (dest,
+                                        surface,
+                                        src_x,
+                                        src_y,
+                                        dest_x,
+                                        dest_y,
+                                        width,
+                                        height);
+  cairo_surface_destroy (surface);
+
+  return retval;
+}
+#else /* !USE_GTK3 */
 static GdkColormap*
 get_cmap (GdkPixmap *pixmap)
 {
@@ -437,6 +506,7 @@ meta_gdk_pixbuf_get_from_pixmap (GdkPixbuf   *dest,
 
   return retval;
 }
+#endif /* !USE_GTK3 */
 
 void
 meta_ui_push_delay_exposes (MetaUI *ui)



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