From 9f5d8d1a2ace209f3c57ef48adcc0204bd6ca104 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 24 Sep 2010 13:30:40 +0200 Subject: [PATCH] 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 1554af3d5..37a169503 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 558d56338..f8be2b557 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 69f45d4b1..3d6bd34c2 100644 --- a/src/gdk2-drawing-utils.h +++ b/src/gdk2-drawing-utils.h @@ -24,6 +24,26 @@ #include +#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 b45c538e7..14c22e708 100644 --- a/src/tools/mutter-mag.c +++ b/src/tools/mutter-mag.c @@ -28,7 +28,8 @@ #include #include #include -#include + +#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 bb536df8e..e006e8c07 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 d8d0c9632..ab55f1051 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -40,6 +40,8 @@ #include "gtk-compat.h" #include "gdk-compat.h" +#include + #ifdef HAVE_SHAPE #include #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 8bab2f14c..54dc14b93 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 b08c0d6f5..134cbe007 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 87b641afb..f49c97012 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 face14c5a..0c2e3c2ae 100644 --- a/src/ui/tabpopup.c +++ b/src/ui/tabpopup.c @@ -38,6 +38,7 @@ #include #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 1e2a71efe..bb2ad992d 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 a3eba721a..83123d121 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 #include +#include 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)