diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c index 65ca990aca..d25829f08f 100644 --- a/gdk/broadway/gdkwindow-broadway.c +++ b/gdk/broadway/gdkwindow-broadway.c @@ -368,16 +368,6 @@ _gdk_broadway_window_destroy (GdkWindow *window, impl->id); } -static gboolean -gdk_window_broadway_resize_cairo_surface (GdkWindow *window, - cairo_surface_t *surface, - gint width, - gint height) -{ - /* Image surfaces cannot be resized */ - return FALSE; -} - static void gdk_broadway_window_destroy_foreign (GdkWindow *window) { @@ -1552,7 +1542,6 @@ gdk_window_impl_broadway_class_init (GdkWindowImplBroadwayClass *klass) impl_class->queue_antiexpose = _gdk_broadway_window_queue_antiexpose; impl_class->destroy = _gdk_broadway_window_destroy; impl_class->destroy_foreign = gdk_broadway_window_destroy_foreign; - impl_class->resize_cairo_surface = gdk_window_broadway_resize_cairo_surface; impl_class->get_shape = gdk_broadway_window_get_shape; impl_class->get_input_shape = gdk_broadway_window_get_input_shape; impl_class->beep = gdk_broadway_window_beep; diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h index 3cc26cc6dd..56c7725048 100644 --- a/gdk/gdkinternals.h +++ b/gdk/gdkinternals.h @@ -266,8 +266,6 @@ struct _GdkWindow cairo_region_t *shape; cairo_region_t *input_shape; - cairo_surface_t *cairo_surface; - GList *devices_inside; GHashTable *device_events; diff --git a/gdk/gdkoffscreenwindow.c b/gdk/gdkoffscreenwindow.c index 74b82bc4c2..5ee179f86d 100644 --- a/gdk/gdkoffscreenwindow.c +++ b/gdk/gdkoffscreenwindow.c @@ -549,18 +549,6 @@ gdk_offscreen_window_queue_antiexpose (GdkWindow *window, return FALSE; } -static gboolean -gdk_offscreen_window_resize_cairo_surface (GdkWindow *window, - cairo_surface_t *surface, - gint width, - gint height) -{ - /* No-op. The surface gets resized in - * gdk_offscreen_window_move_resize_internal(). - */ - return TRUE; -} - /** * gdk_offscreen_window_set_embedder: * @window: a #GdkWindow @@ -727,7 +715,6 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass) impl_class->queue_antiexpose = gdk_offscreen_window_queue_antiexpose; impl_class->destroy = gdk_offscreen_window_destroy; impl_class->destroy_foreign = NULL; - impl_class->resize_cairo_surface = gdk_offscreen_window_resize_cairo_surface; impl_class->get_shape = NULL; impl_class->get_input_shape = NULL; impl_class->beep = NULL; diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index dc658c3eb6..e864606ac0 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -151,12 +151,11 @@ struct _GdkWindowPaint { cairo_region_t *region; cairo_surface_t *surface; + gboolean surface_needs_composite; }; /* Global info */ -static void gdk_window_drop_cairo_surface (GdkWindow *private); - static void gdk_window_free_paint_stack (GdkWindow *window); static void gdk_window_finalize (GObject *object); @@ -477,8 +476,6 @@ gdk_window_finalize (GObject *object) _gdk_window_destroy (window, TRUE); } - gdk_window_drop_cairo_surface (window); - if (window->impl) { g_object_unref (window->impl); @@ -1002,18 +999,6 @@ recompute_visible_regions_internal (GdkWindow *private, FALSE); } } - - if (private->cairo_surface) - { - if (!gdk_window_has_impl (private) || - !GDK_WINDOW_IMPL_GET_CLASS (private->impl)->resize_cairo_surface (private, - private->cairo_surface, - private->width, - private->height)) - { - gdk_window_drop_cairo_surface (private); - } - } } /* Call this when private has changed in one or more of these ways: @@ -1531,10 +1516,6 @@ gdk_window_reparent (GdkWindow *window, if (is_parent_of (window, new_parent)) return; - /* This might be wrong in the new parent, e.g. for non-native surfaces. - To make sure we're ok, just wipe it. */ - gdk_window_drop_cairo_surface (window); - impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl); old_parent = window->parent; @@ -1716,8 +1697,6 @@ gdk_window_ensure_native (GdkWindow *window) /* Need to create a native window */ - gdk_window_drop_cairo_surface (window); - screen = gdk_window_get_screen (window); display = gdk_screen_get_display (screen); parent = window->parent; @@ -1889,7 +1868,6 @@ _gdk_window_destroy_hierarchy (GdkWindow *window, if (temp_window == window) g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL); - switch (window->window_type) { case GDK_WINDOW_ROOT: @@ -1987,8 +1965,6 @@ _gdk_window_destroy_hierarchy (GdkWindow *window, _gdk_window_clear_update_area (window); - gdk_window_drop_cairo_surface (window); - impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl); if (gdk_window_has_impl (window)) @@ -2780,6 +2756,12 @@ gdk_window_begin_paint_region (GdkWindow *window, cairo_surface_get_device_scale (paint->surface, &sx, &sy); #endif cairo_surface_set_device_offset (paint->surface, -clip_box.x*sx, -clip_box.y*sy); + + paint->surface_needs_composite = TRUE; + } + else + { + paint->surface = gdk_window_ref_impl_surface (window); } for (list = window->paint_stack; list != NULL; list = list->next) @@ -2796,6 +2778,23 @@ gdk_window_begin_paint_region (GdkWindow *window, paint->region); } +/* This returns either the current working surface on the paint stack + * or the actual impl surface of the window. This should not be used + * from very many places: be careful! */ +static cairo_surface_t * +get_window_surface (GdkWindow *window) +{ + if (window->impl_window->paint_stack) + { + GdkWindowPaint *paint = window->impl_window->paint_stack->data; + return cairo_surface_reference (paint->surface); + } + else + { + return gdk_window_ref_impl_surface (window); + } +} + /** * gdk_window_end_paint: * @window: a #GdkWindow @@ -2841,14 +2840,18 @@ gdk_window_end_paint (GdkWindow *window) window->paint_stack = g_slist_delete_link (window->paint_stack, window->paint_stack); - - if (paint->surface != NULL) + if (paint->surface_needs_composite) { + cairo_surface_t *surface; + cairo_region_get_extents (paint->region, &clip_box); full_clip = cairo_region_copy (window->clip_region); cairo_region_intersect (full_clip, paint->region); - cr = gdk_cairo_create (window); + surface = get_window_surface (window); + cr = cairo_create (surface); + cairo_surface_destroy (surface); + cairo_set_source_surface (cr, paint->surface, 0, 0); gdk_cairo_region (cr, full_clip); cairo_clip (cr); @@ -2866,10 +2869,10 @@ gdk_window_end_paint (GdkWindow *window) cairo_destroy (cr); cairo_region_destroy (full_clip); - - cairo_surface_destroy (paint->surface); } + cairo_surface_destroy (paint->surface); + cairo_region_destroy (paint->region); g_free (paint); @@ -2908,8 +2911,7 @@ gdk_window_free_paint_stack (GdkWindow *window) { GdkWindowPaint *paint = tmp_list->data; - if (tmp_list == window->paint_stack && - paint->surface != NULL) + if (tmp_list == window->paint_stack) cairo_surface_destroy (paint->surface); cairo_region_destroy (paint->region); @@ -3012,7 +3014,7 @@ gdk_window_clear_backing_region (GdkWindow *window, int x_offset = 0, y_offset = 0; cairo_t *cr; - if (GDK_WINDOW_DESTROYED (window) || paint->surface == NULL) + if (GDK_WINDOW_DESTROYED (window)) return; cr = cairo_create (paint->surface); @@ -3047,88 +3049,23 @@ gdk_window_clear_backing_region (GdkWindow *window, cairo_region_destroy (clip); } -static void -gdk_window_drop_cairo_surface (GdkWindow *window) -{ - if (window->cairo_surface) - { - cairo_surface_finish (window->cairo_surface); - cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key, - NULL, NULL); - window->cairo_surface = NULL; - } -} - -static void -gdk_window_cairo_surface_destroy (void *data) -{ - GdkWindow *window = data; - - window->cairo_surface = NULL; -} - -static cairo_surface_t * -gdk_window_create_cairo_surface (GdkWindow *window, - int width, - int height) -{ - cairo_surface_t *surface, *subsurface; - - surface = gdk_window_ref_impl_surface (window); - if (gdk_window_has_impl (window)) - return surface; - - subsurface = cairo_surface_create_for_rectangle (surface, - window->abs_x, - window->abs_y, - width, - height); - cairo_surface_destroy (surface); - return subsurface; -} - - +/* This is used in places like gdk_cairo_set_source_window and + * other places to take "screenshots" of windows. Thus, we allow + * it to be used outside of a begin_paint / end_paint. */ cairo_surface_t * _gdk_window_ref_cairo_surface (GdkWindow *window) { cairo_surface_t *surface; - GdkWindowPaint *paint; g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); - paint = NULL; - if (window->impl_window->paint_stack) - paint = window->impl_window->paint_stack->data; + surface = get_window_surface (window); - if (paint && paint->surface != NULL) - { - surface = cairo_surface_create_for_rectangle (paint->surface, - window->abs_x, - window->abs_y, - window->width, - window->height); - } - else - { - if (!window->cairo_surface) - { - window->cairo_surface = gdk_window_create_cairo_surface (window, - window->width, - window->height); - - if (window->cairo_surface) - { - cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key, - window, gdk_window_cairo_surface_destroy); - } - } - else - cairo_surface_reference (window->cairo_surface); - - surface = window->cairo_surface; - } - - return surface; + return cairo_surface_create_for_rectangle (surface, + window->abs_x, + window->abs_y, + window->width, + window->height); } /** @@ -3149,31 +3086,35 @@ cairo_t * gdk_cairo_create (GdkWindow *window) { GdkWindowPaint *paint; - cairo_surface_t *surface; cairo_region_t *region; cairo_t *cr; g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); - surface = _gdk_window_ref_cairo_surface (window); - cr = cairo_create (surface); - - if (window->impl_window->paint_stack) + if (window->impl_window->paint_stack == NULL) { - paint = window->impl_window->paint_stack->data; + cairo_surface_t *dummy_surface; + cairo_t *cr; - region = cairo_region_copy (paint->region); - cairo_region_translate (region, -window->abs_x, -window->abs_y); - gdk_cairo_region (cr, region); - cairo_region_destroy (region); - } - else - gdk_cairo_region (cr, window->clip_region); + g_warning ("gdk_cairo_create called from outside a paint. Make sure to call " + "gdk_window_begin_paint_region before calling gdk_cairo_create!"); + /* Return a dummy surface to keep apps from crashing. */ + dummy_surface = cairo_image_surface_create (gdk_window_get_content (window), 0, 0); + cr = cairo_create (dummy_surface); + cairo_surface_destroy (dummy_surface); + return cr; + } + + paint = window->impl_window->paint_stack->data; + + cr = cairo_create (paint->surface); + region = cairo_region_copy (paint->region); + cairo_region_translate (region, -window->abs_x, -window->abs_y); + gdk_cairo_region (cr, region); + cairo_region_destroy (region); cairo_clip (cr); - cairo_surface_destroy (surface); - return cr; } diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h index b1e9290bc1..694a244761 100644 --- a/gdk/gdkwindowimpl.h +++ b/gdk/gdkwindowimpl.h @@ -158,15 +158,6 @@ struct _GdkWindowImplClass */ void (*destroy_foreign) (GdkWindow *window); - /* Resizes @surface to a new size. If successful, return %TRUE. - * If the backend cannot resize surfaces, return %FALSE and a new - * surface will be created instead. - */ - gboolean (* resize_cairo_surface) (GdkWindow *window, - cairo_surface_t *surface, - gint width, - gint height); - /* optional */ gboolean (* beep) (GdkWindow *window); diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index 84e7ab871d..37efa7ccca 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -1104,16 +1104,6 @@ gdk_quartz_window_destroy (GdkWindow *window, } } -static gboolean -gdk_window_quartz_resize_cairo_surface (GdkWindow *window, - cairo_surface_t *surface, - gint width, - gint height) -{ - /* Quartz surfaces cannot be resized */ - return FALSE; -} - static void gdk_quartz_window_destroy_foreign (GdkWindow *window) { @@ -2949,7 +2939,6 @@ gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass) impl_class->queue_antiexpose = gdk_quartz_window_queue_antiexpose; impl_class->destroy = gdk_quartz_window_destroy; impl_class->destroy_foreign = gdk_quartz_window_destroy_foreign; - impl_class->resize_cairo_surface = gdk_window_quartz_resize_cairo_surface; impl_class->get_shape = gdk_quartz_window_get_shape; impl_class->get_input_shape = gdk_quartz_window_get_input_shape; impl_class->begin_paint_region = gdk_window_impl_quartz_begin_paint_region; diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 461d1ce9d7..a3058de847 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -1350,16 +1350,6 @@ gdk_window_wayland_destroy_foreign (GdkWindow *window) { } -static gboolean -gdk_window_wayland_resize_cairo_surface (GdkWindow *window, - cairo_surface_t *surface, - gint width, - gint height) -{ - /* cairo image surfaces cannot be resized */ - return FALSE; -} - static cairo_region_t * gdk_wayland_window_get_shape (GdkWindow *window) { @@ -1994,7 +1984,6 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass) impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose; impl_class->destroy = gdk_wayland_window_destroy; impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign; - impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface; impl_class->get_shape = gdk_wayland_window_get_shape; impl_class->get_input_shape = gdk_wayland_window_get_input_shape; impl_class->begin_paint_region = gdk_window_impl_wayland_begin_paint_region; diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index aa8f5916ea..23e1848c02 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -796,16 +796,6 @@ gdk_win32_window_destroy (GdkWindow *window, } } -static gboolean -gdk_win32_window_resize_cairo_surface (GdkWindow *window, - cairo_surface_t *surface, - gint width, - gint height) -{ - /* XXX: Make Cairo surface use DC clip */ - return FALSE; -} - static void gdk_win32_window_destroy_foreign (GdkWindow *window) { @@ -3433,7 +3423,6 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass) impl_class->queue_antiexpose = _gdk_win32_window_queue_antiexpose; impl_class->destroy = gdk_win32_window_destroy; impl_class->destroy_foreign = gdk_win32_window_destroy_foreign; - impl_class->resize_cairo_surface = gdk_win32_window_resize_cairo_surface; impl_class->get_shape = gdk_win32_window_get_shape; //FIXME?: impl_class->get_input_shape = gdk_win32_window_get_input_shape; diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 1fa3afc2aa..3c7c6cc59d 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -1337,17 +1337,6 @@ gdk_x11_window_destroy (GdkWindow *window, XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); } -static gboolean -gdk_window_x11_resize_cairo_surface (GdkWindow *window, - cairo_surface_t *surface, - gint width, - gint height) -{ - cairo_xlib_surface_set_size (surface, width, height); - - return TRUE; -} - static void gdk_x11_window_destroy_foreign (GdkWindow *window) { @@ -5780,7 +5769,6 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass) impl_class->queue_antiexpose = _gdk_x11_window_queue_antiexpose; impl_class->destroy = gdk_x11_window_destroy; impl_class->destroy_foreign = gdk_x11_window_destroy_foreign; - impl_class->resize_cairo_surface = gdk_window_x11_resize_cairo_surface; impl_class->get_shape = gdk_x11_window_get_shape; impl_class->get_input_shape = gdk_x11_window_get_input_shape; impl_class->beep = gdk_x11_window_beep;