X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gdk%2Fgdkoffscreenwindow.c;h=a21ad163a0097b4e2f7b4c88bad8ed78711ddce4;hb=46206f8bb824d82d89b528bc9bd557b3bd30d5d2;hp=72bb5b62c65353fa865d5b78accfecf839e10965;hpb=864649157dd98ba8d86e0fd3561ea7345c00893d;p=~andy%2Fgtk diff --git a/gdk/gdkoffscreenwindow.c b/gdk/gdkoffscreenwindow.c index 72bb5b62c..a21ad163a 100644 --- a/gdk/gdkoffscreenwindow.c +++ b/gdk/gdkoffscreenwindow.c @@ -37,7 +37,7 @@ #include "gdkgc.h" #include "gdkcolor.h" #include "gdkcursor.h" -#include "gdkalias.h" + /* LIMITATIONS: * @@ -59,6 +59,7 @@ struct _GdkOffscreenWindow GdkScreen *screen; GdkPixmap *pixmap; + GdkWindow *embedder; }; struct _GdkOffscreenWindowClass @@ -75,17 +76,10 @@ struct _GdkOffscreenWindowClass static void gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface); static void gdk_offscreen_window_hide (GdkWindow *window); -static void gdk_offscreen_window_clear_area (GdkWindow *window, - gint x, - gint y, - gint width, - gint height, - gboolean send_expose); - G_DEFINE_TYPE_WITH_CODE (GdkOffscreenWindow, - gdk_offscreen_window, - GDK_TYPE_DRAWABLE, + gdk_offscreen_window, + GDK_TYPE_DRAWABLE, G_IMPLEMENT_INTERFACE (GDK_TYPE_WINDOW_IMPL, gdk_offscreen_window_impl_iface_init)); @@ -100,8 +94,8 @@ gdk_offscreen_window_finalize (GObject *object) offscreen->cursor = NULL; - gdk_pixmap_unref (offscreen->pixmap); - + g_object_unref (offscreen->pixmap); + G_OBJECT_CLASS (gdk_offscreen_window_parent_class)->finalize (object); } @@ -110,15 +104,18 @@ gdk_offscreen_window_init (GdkOffscreenWindow *window) { } -void -_gdk_offscreen_window_destroy (GdkWindow *window, - gboolean recursing) +static void +gdk_offscreen_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy) { GdkWindowObject *private = GDK_WINDOW_OBJECT (window); GdkOffscreenWindow *offscreen; offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + gdk_offscreen_window_set_embedder (window, NULL); + if (!recursing) gdk_offscreen_window_hide (window); @@ -128,7 +125,7 @@ _gdk_offscreen_window_destroy (GdkWindow *window, static gboolean is_parent_of (GdkWindow *parent, - GdkWindow *child) + GdkWindow *child) { GdkWindow *w; @@ -154,31 +151,11 @@ gdk_offscreen_window_create_gc (GdkDrawable *drawable, return gdk_gc_new_with_values (offscreen->pixmap, values, values_mask); } -static GdkImage* -gdk_offscreen_window_copy_to_image (GdkDrawable *drawable, - GdkImage *image, - gint src_x, - gint src_y, - gint dest_x, - gint dest_y, - gint width, - gint height) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - - return gdk_drawable_copy_to_image (offscreen->pixmap, - image, - src_x, - src_y, - dest_x, dest_y, - width, height); -} - static cairo_surface_t * gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - + return _gdk_drawable_ref_cairo_surface (offscreen->pixmap); } @@ -260,19 +237,40 @@ gdk_offscreen_window_get_visual (GdkDrawable *drawable) static void add_damage (GdkOffscreenWindow *offscreen, int x, int y, - int w, int h) + int w, int h, + gboolean is_line) { GdkRectangle rect; - GdkRegion *damage; - + cairo_region_t *damage; + rect.x = x; rect.y = y; rect.width = w; rect.height = h; - damage = gdk_region_rectangle (&rect); + if (is_line) + { + /* This should really take into account line width, line + * joins (and miter) and line caps. But these are hard + * to compute, rarely used and generally a pain. And in + * the end a snug damage rectangle is not that important + * as multiple damages are generally created anyway. + * + * So, we just add some padding around the rect. + * We use a padding of 3 pixels, plus an extra row + * below and on the right for the normal line size. I.E. + * line from (0,0) to (2,0) gets h=0 but is really + * at least one pixel tall. + */ + rect.x -= 3; + rect.y -= 3; + rect.width += 7; + rect.height += 7; + } + + damage = cairo_region_create_rectangle (&rect); _gdk_window_add_damage (offscreen->wrapper, damage); - gdk_region_destroy (damage); + cairo_region_destroy (damage); } static GdkDrawable * @@ -292,318 +290,27 @@ gdk_offscreen_window_draw_drawable (GdkDrawable *drawable, gint xdest, gint ydest, gint width, - gint height) + gint height, + GdkDrawable *original_src) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); GdkDrawable *real_drawable = get_real_drawable (offscreen); - + gdk_draw_drawable (real_drawable, gc, src, xsrc, ysrc, xdest, ydest, width, height); - add_damage (offscreen, xdest, ydest, width, height); + add_damage (offscreen, xdest, ydest, width, height, FALSE); } -static void -gdk_offscreen_window_draw_rectangle (GdkDrawable *drawable, - GdkGC *gc, - gboolean filled, - gint x, - gint y, - gint width, - gint height) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - - gdk_draw_rectangle (real_drawable, - gc, filled, x, y, width, height); - - add_damage (offscreen, x, y, width, height); - -} - -static void -gdk_offscreen_window_draw_arc (GdkDrawable *drawable, - GdkGC *gc, - gboolean filled, - gint x, - gint y, - gint width, - gint height, - gint angle1, - gint angle2) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - - gdk_draw_arc (real_drawable, - gc, - filled, - x, - y, - width, - height, - angle1, - angle2); - add_damage (offscreen, x, y, width, height); -} - -static void -gdk_offscreen_window_draw_polygon (GdkDrawable *drawable, - GdkGC *gc, - gboolean filled, - GdkPoint *points, - gint npoints) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - - gdk_draw_polygon (real_drawable, - gc, - filled, - points, - npoints); - - if (npoints > 0) - { - int min_x, min_y, max_x, max_y, i; - - min_x = max_x = points[0].x; - min_y = max_y = points[0].y; - - for (i = 1; i < npoints; i++) - { - min_x = MIN (min_x, points[i].x); - max_x = MAX (max_x, points[i].x); - min_y = MIN (min_y, points[i].y); - max_y = MAX (max_y, points[i].y); - } - - add_damage (offscreen, min_x, min_y, - max_x - min_x, - max_y - min_y); - } -} - -static void -gdk_offscreen_window_draw_text (GdkDrawable *drawable, - GdkFont *font, - GdkGC *gc, - gint x, - gint y, - const gchar *text, - gint text_length) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); - - gdk_draw_text (real_drawable, - font, - gc, - x, - y, - text, - text_length); - - /* Hard to compute the minimal size, not that often used anyway. */ - add_damage (offscreen, 0, 0, private->width, private->height); -} - -static void -gdk_offscreen_window_draw_text_wc (GdkDrawable *drawable, - GdkFont *font, - GdkGC *gc, - gint x, - gint y, - const GdkWChar *text, - gint text_length) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); - - gdk_draw_text_wc (real_drawable, - font, - gc, - x, - y, - text, - text_length); - - /* Hard to compute the minimal size, not that often used anyway. */ - add_damage (offscreen, 0, 0, private->width, private->height); -} - -static void -gdk_offscreen_window_draw_points (GdkDrawable *drawable, - GdkGC *gc, - GdkPoint *points, - gint npoints) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - - gdk_draw_points (real_drawable, - gc, - points, - npoints); - - - if (npoints > 0) - { - int min_x, min_y, max_x, max_y, i; - - min_x = max_x = points[0].x; - min_y = max_y = points[0].y; - - for (i = 1; i < npoints; i++) - { - min_x = MIN (min_x, points[i].x); - max_x = MAX (max_x, points[i].x); - min_y = MIN (min_y, points[i].y); - max_y = MAX (max_y, points[i].y); - } - - add_damage (offscreen, min_x, min_y, - max_x - min_x, - max_y - min_y); - } -} - -static void -gdk_offscreen_window_draw_segments (GdkDrawable *drawable, - GdkGC *gc, - GdkSegment *segs, - gint nsegs) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - - gdk_draw_segments (real_drawable, - gc, - segs, - nsegs); - - if (nsegs > 0) - { - int min_x, min_y, max_x, max_y, i; - - min_x = max_x = segs[0].x1; - min_y = max_y = segs[0].y1; - - for (i = 1; i < nsegs; i++) - { - min_x = MIN (min_x, segs[i].x1); - max_x = MAX (max_x, segs[i].x1); - min_x = MIN (min_x, segs[i].x2); - max_x = MAX (max_x, segs[i].x2); - min_y = MIN (min_y, segs[i].y1); - max_y = MAX (max_y, segs[i].y1); - min_y = MIN (min_y, segs[i].y2); - max_y = MAX (max_y, segs[i].y2); - } - - add_damage (offscreen, min_x, min_y, - max_x - min_x, - max_y - min_y); - } - -} - -static void -gdk_offscreen_window_draw_lines (GdkDrawable *drawable, - GdkGC *gc, - GdkPoint *points, - gint npoints) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); - - gdk_draw_lines (real_drawable, - gc, - points, - npoints); - - /* Hard to compute the minimal size, as we don't know the line - width, and since joins are hard to calculate. - Its not that often used anyway, damage it all */ - add_damage (offscreen, 0, 0, private->width, private->height); -} - -static void -gdk_offscreen_window_draw_image (GdkDrawable *drawable, - GdkGC *gc, - GdkImage *image, - gint xsrc, - gint ysrc, - gint xdest, - gint ydest, - gint width, - gint height) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - - gdk_draw_image (real_drawable, - gc, - image, - xsrc, - ysrc, - xdest, - ydest, - width, - height); - - add_damage (offscreen, xdest, ydest, width, height); -} - - -static void -gdk_offscreen_window_draw_pixbuf (GdkDrawable *drawable, - GdkGC *gc, - GdkPixbuf *pixbuf, - gint src_x, - gint src_y, - gint dest_x, - gint dest_y, - gint width, - gint height, - GdkRgbDither dither, - gint x_dither, - gint y_dither) -{ - GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = get_real_drawable (offscreen); - - gdk_draw_pixbuf (real_drawable, - gc, - pixbuf, - src_x, - src_y, - dest_x, - dest_y, - width, - height, - dither, - x_dither, - y_dither); - - add_damage (offscreen, dest_x, dest_y, width, height); - -} - -void +void _gdk_offscreen_window_new (GdkWindow *window, GdkScreen *screen, GdkVisual *visual, GdkWindowAttr *attributes, gint attributes_mask) { - GdkWindowObject *parent_private; GdkWindowObject *private; GdkOffscreenWindow *offscreen; @@ -611,13 +318,12 @@ _gdk_offscreen_window_new (GdkWindow *window, if (attributes->wclass != GDK_INPUT_OUTPUT) return; /* Can't support input only offscreens */ - + private = (GdkWindowObject *)window; if (private->parent != NULL && GDK_WINDOW_DESTROYED (private->parent)) return; - parent_private = (GdkWindowObject*) private->parent; private->impl = g_object_new (GDK_TYPE_OFFSCREEN_WINDOW, NULL); offscreen = GDK_OFFSCREEN_WINDOW (private->impl); offscreen->wrapper = window; @@ -641,6 +347,7 @@ _gdk_offscreen_window_new (GdkWindow *window, private->width, private->height, private->depth); + gdk_drawable_set_colormap (offscreen->pixmap, offscreen->colormap); } static gboolean @@ -652,7 +359,6 @@ gdk_offscreen_window_reparent (GdkWindow *window, GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowObject *new_parent_private = (GdkWindowObject *)new_parent; GdkWindowObject *old_parent; - GdkOffscreenWindow *offscreen; gboolean was_mapped; if (new_parent) @@ -660,14 +366,12 @@ gdk_offscreen_window_reparent (GdkWindow *window, /* No input-output children of input-only windows */ if (new_parent_private->input_only && !private->input_only) return FALSE; - + /* Don't create loops in hierarchy */ if (is_parent_of (window, new_parent)) return FALSE; } - offscreen = GDK_OFFSCREEN_WINDOW (private->impl); - was_mapped = GDK_WINDOW_IS_MAPPED (window); gdk_window_hide (window); @@ -683,47 +387,177 @@ gdk_offscreen_window_reparent (GdkWindow *window, if (new_parent_private) private->parent->children = g_list_prepend (private->parent->children, window); - _gdk_syntesize_crossing_events_for_geometry_change (window); + _gdk_synthesize_crossing_events_for_geometry_change (window); if (old_parent) - _gdk_syntesize_crossing_events_for_geometry_change (GDK_WINDOW (old_parent)); - + _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (old_parent)); + return was_mapped; } +static void +from_embedder (GdkWindow *window, + double embedder_x, double embedder_y, + double *offscreen_x, double *offscreen_y) +{ + GdkWindowObject *private; + + private = (GdkWindowObject *)window; + + g_signal_emit_by_name (private->impl_window, + "from-embedder", + embedder_x, embedder_y, + offscreen_x, offscreen_y, + NULL); +} + +static void +to_embedder (GdkWindow *window, + double offscreen_x, double offscreen_y, + double *embedder_x, double *embedder_y) +{ + GdkWindowObject *private; + + private = (GdkWindowObject *)window; + + g_signal_emit_by_name (private->impl_window, + "to-embedder", + offscreen_x, offscreen_y, + embedder_x, embedder_y, + NULL); +} + static gint -gdk_offscreen_window_get_origin (GdkWindow *window, - gint *x, - gint *y) +gdk_offscreen_window_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) { + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + int tmpx, tmpy; + + tmpx = x; + tmpy = y; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + if (offscreen->embedder) + { + double dx, dy; + to_embedder (window, + x, y, + &dx, &dy); + tmpx = floor (dx + 0.5); + tmpy = floor (dy + 0.5); + gdk_window_get_root_coords (offscreen->embedder, + tmpx, tmpy, + &tmpx, &tmpy); + + } + + if (root_x) + *root_x = tmpx; + if (root_y) + *root_y = tmpy; + + return TRUE; +} + +static gint +gdk_offscreen_window_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + int tmpx, tmpy; + + tmpx = 0; + tmpy = 0; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + if (offscreen->embedder) + { + double dx, dy; + gdk_window_get_deskrelative_origin (offscreen->embedder, + &tmpx, &tmpy); + + to_embedder (window, + 0, 0, + &dx, &dy); + tmpx = floor (tmpx + dx + 0.5); + tmpy = floor (tmpy + dy + 0.5); + } + + if (x) - *x = 0; + *x = tmpx; if (y) - *y = 0; + *y = tmpy; return TRUE; } +static gboolean +gdk_offscreen_window_get_device_state (GdkWindow *window, + GdkDevice *device, + gint *x, + gint *y, + GdkModifierType *mask) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + int tmpx, tmpy; + double dtmpx, dtmpy; + GdkModifierType tmpmask; + + tmpx = 0; + tmpy = 0; + tmpmask = 0; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + if (offscreen->embedder != NULL) + { + gdk_window_get_device_position (offscreen->embedder, device, &tmpx, &tmpy, &tmpmask); + from_embedder (window, + tmpx, tmpy, + &dtmpx, &dtmpy); + tmpx = floor (dtmpx + 0.5); + tmpy = floor (dtmpy + 0.5); + } + + if (x) + *x = tmpx; + if (y) + *y = tmpy; + if (mask) + *mask = tmpmask; + return TRUE; +} + /** - * gdk_window_get_offscreen_pixmap: + * gdk_offscreen_window_get_pixmap: * @window: a #GdkWindow * - * Gets the offscreen pixmap that an offscreen window renders into. If - * you need to keep this around over window resizes, you need to add a - * reference to it. + * Gets the offscreen pixmap that an offscreen window renders into. + * If you need to keep this around over window resizes, you need to + * add a reference to it. + * + * Returns: The offscreen pixmap, or %NULL if not offscreen * - * Returns: The offscreen pixmap, or NULL if not offscreen - **/ + * Since: 2.18 + */ GdkPixmap * -gdk_window_get_offscreen_pixmap (GdkWindow *window) +gdk_offscreen_window_get_pixmap (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; GdkOffscreenWindow *offscreen; - + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); if (!GDK_IS_OFFSCREEN_WINDOW (private->impl)) return NULL; - + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); return offscreen->pixmap; } @@ -732,14 +566,14 @@ static void gdk_offscreen_window_raise (GdkWindow *window) { /* gdk_window_raise already changed the stacking order */ - _gdk_syntesize_crossing_events_for_geometry_change (window); + _gdk_synthesize_crossing_events_for_geometry_change (window); } static void gdk_offscreen_window_lower (GdkWindow *window) { /* gdk_window_lower already changed the stacking order */ - _gdk_syntesize_crossing_events_for_geometry_change (window); + _gdk_synthesize_crossing_events_for_geometry_change (window); } static void @@ -777,39 +611,38 @@ gdk_offscreen_window_move_resize_internal (GdkWindow *window, if (private->width != width || private->height != height) { + cairo_t *cr; + private->width = width; private->height = height; - + old_pixmap = offscreen->pixmap; offscreen->pixmap = gdk_pixmap_new (GDK_DRAWABLE (old_pixmap), width, height, private->depth); - gc = _gdk_drawable_get_scratch_gc (offscreen->pixmap, FALSE); - gdk_draw_drawable (offscreen->pixmap, - gc, - old_pixmap, - 0,0, 0, 0, - -1, -1); - g_object_unref (old_pixmap); + cr = gdk_cairo_create (offscreen->pixmap); + gdk_cairo_set_source_pixmap (cr, old_pixmap, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); } - + if (GDK_WINDOW_IS_MAPPED (private)) { // TODO: Only invalidate new area, i.e. for larger windows gdk_window_invalidate_rect (window, NULL, TRUE); - _gdk_syntesize_crossing_events_for_geometry_change (window); + _gdk_synthesize_crossing_events_for_geometry_change (window); } } static void gdk_offscreen_window_move_resize (GdkWindow *window, - gboolean with_move, + gboolean with_move, gint x, - gint y, + gint y, gint width, - gint height) + gint height) { GdkWindowObject *private = (GdkWindowObject *)window; GdkOffscreenWindow *offscreen; @@ -834,29 +667,11 @@ gdk_offscreen_window_move_resize (GdkWindow *window, } static void -gdk_offscreen_window_show (GdkWindow *window, gboolean raise) +gdk_offscreen_window_show (GdkWindow *window, + gboolean already_mapped) { GdkWindowObject *private = (GdkWindowObject *)window; - GdkOffscreenWindow *offscreen; - if (GDK_WINDOW_IS_MAPPED (window)) - return; - - offscreen = GDK_OFFSCREEN_WINDOW (private->impl); - - private->state = 0; - - /* gdk_window_show already changed the stacking order if needed */ - - if (private->event_mask & GDK_STRUCTURE_MASK) - _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE); - - if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) - _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE); - - if (gdk_window_is_viewable (window)) - _gdk_syntesize_crossing_events_for_geometry_change (window); - gdk_window_clear_area_e (window, 0, 0, private->width, private->height); } @@ -874,12 +689,11 @@ gdk_offscreen_window_hide (GdkWindow *window) private = (GdkWindowObject*) window; offscreen = GDK_OFFSCREEN_WINDOW (private->impl); - if (!GDK_WINDOW_IS_MAPPED (private)) - return; - /* May need to break grabs on children */ display = gdk_drawable_get_display (window); - + + /* TODO: This needs updating to the new grab world */ +#if 0 if (display->pointer_grab.window != NULL) { if (is_parent_of (window, display->pointer_grab.window)) @@ -894,16 +708,7 @@ gdk_offscreen_window_hide (GdkWindow *window) gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); } } - - if (private->event_mask & GDK_STRUCTURE_MASK) - _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); - - if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) - _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); - - private->state = GDK_WINDOW_STATE_WITHDRAWN; - - _gdk_syntesize_crossing_events_for_geometry_change (window); +#endif } static void @@ -923,81 +728,6 @@ gdk_offscreen_window_set_events (GdkWindow *window, { } -static GdkGC * -setup_backing_rect_gc (GdkWindow *window, int x_offset, int y_offset) -{ - GdkWindowObject *private = (GdkWindowObject *)window; - GdkGC *gc; - - if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent) - { - x_offset += private->x; - y_offset += private->y; - - return setup_backing_rect_gc (GDK_WINDOW (private->parent), x_offset, y_offset); - } - else if (private->bg_pixmap && - private->bg_pixmap != GDK_PARENT_RELATIVE_BG && - private->bg_pixmap != GDK_NO_BG) - { - guint gc_mask; - GdkGCValues gc_values; - - gc_values.fill = GDK_TILED; - gc_values.tile = private->bg_pixmap; - gc_values.ts_x_origin = -x_offset; - gc_values.ts_y_origin = -y_offset; - - gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN; - - return gdk_gc_new_with_values (window, &gc_values, gc_mask); - } - else - { - gc = _gdk_drawable_get_scratch_gc (window, FALSE); - g_object_ref (gc); - gdk_gc_set_foreground (gc, &private->bg_color); - return gc; - } -} - -static void -gdk_offscreen_window_clear_area (GdkWindow *window, - gint x, - gint y, - gint width, - gint height, - gboolean send_expose) -{ - GdkGC *gc; - - if (GDK_WINDOW_DESTROYED (window)) - return; - - /* Actual drawing is done by gdkwindow.c */ - - gc = setup_backing_rect_gc (window, 0, 0); - gdk_draw_rectangle (window, gc, TRUE, x, y, width, height); - g_object_unref (gc); - - if (send_expose) - { - GdkRectangle visible, rect; - - visible.x = visible.y = 0; - gdk_drawable_get_size (GDK_DRAWABLE (window), &visible.width, &visible.height); - - rect.x = x; - rect.y = x; - rect.width = width; - rect.height = height; - - gdk_rectangle_intersect (&rect, &visible, &rect); - - gdk_window_invalidate_rect (window, &rect, TRUE); - } -} - static void gdk_offscreen_window_set_background (GdkWindow *window, const GdkColor *color) @@ -1044,29 +774,19 @@ gdk_offscreen_window_set_back_pixmap (GdkWindow *window, g_object_ref (pixmap); } -static void -gdk_offscreen_window_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y) -{ -} - static void gdk_offscreen_window_shape_combine_region (GdkWindow *window, - const GdkRegion *shape_region, - gint offset_x, - gint offset_y) + const cairo_region_t *shape_region, + gint offset_x, + gint offset_y) { } static void -gdk_offscreen_window_set_child_shapes (GdkWindow *window) -{ -} - -static void -gdk_offscreen_window_merge_child_shapes (GdkWindow *window) +gdk_offscreen_window_input_shape_combine_region (GdkWindow *window, + const cairo_region_t *shape_region, + gint offset_x, + gint offset_y) { } @@ -1077,27 +797,6 @@ gdk_offscreen_window_set_static_gravities (GdkWindow *window, return TRUE; } -static void -gdk_offscreen_window_set_cursor (GdkWindow *window, - GdkCursor *cursor) -{ - GdkWindowObject *private = (GdkWindowObject *)window; - GdkOffscreenWindow *offscreen; - - offscreen = GDK_OFFSCREEN_WINDOW (private->impl); - - if (offscreen->cursor) - { - gdk_cursor_unref (offscreen->cursor); - offscreen->cursor = NULL; - } - - if (cursor) - offscreen->cursor = gdk_cursor_ref (cursor); - - /* TODO: The cursor is never actually used... */ -} - static void gdk_offscreen_window_get_geometry (GdkWindow *window, gint *x, @@ -1107,9 +806,6 @@ gdk_offscreen_window_get_geometry (GdkWindow *window, gint *depth) { GdkWindowObject *private = (GdkWindowObject *)window; - GdkOffscreenWindow *offscreen; - - offscreen = GDK_OFFSCREEN_WINDOW (private->impl); g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); @@ -1128,39 +824,90 @@ gdk_offscreen_window_get_geometry (GdkWindow *window, } } +static gboolean +gdk_offscreen_window_queue_antiexpose (GdkWindow *window, + cairo_region_t *area) +{ + return FALSE; +} + +static void +gdk_offscreen_window_queue_translation (GdkWindow *window, + GdkGC *gc, + cairo_region_t *area, + gint dx, + gint dy) +{ +} + /** - * gdk_window_set_offscreen_hooks: - * @offscreen_window: a offscreen #GdkWindow - * @hooks: a table of pointers to functions for handling offscreen - * window coordinates translations + * gdk_offscreen_window_set_embedder: + * @window: a #GdkWindow + * @embedder: the #GdkWindow that @window gets embedded in * - * Sets the parent-to-offscreen-child and offscreen-child-to-parent coordinate - * translation functions for offscreen windows. + * Sets @window to be embedded in @embedder. * - * This function is useful for complex widgets employing - * offscreen windows. + * To fully embed an offscreen window, in addition to calling this + * function, it is also necessary to handle the #GdkWindow::pick-embedded-child + * signal on the @embedder and the #GdkWindow::to-embedder and + * #GdkWindow::from-embedder signals on @window. * - * Since: 2.16 + * Since: 2.18 */ void -gdk_window_set_offscreen_hooks (GdkWindow *offscreen_window, - const GdkOffscreenChildHooks *hooks) +gdk_offscreen_window_set_embedder (GdkWindow *window, + GdkWindow *embedder) { - GdkWindowObject *private; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; - g_return_if_fail (GDK_IS_WINDOW (offscreen_window)); - g_return_if_fail (hooks != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); - private = (GdkWindowObject *) offscreen_window; + if (!GDK_IS_OFFSCREEN_WINDOW (private->impl)) + return; - private->offscreen_hooks = hooks; + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + if (embedder) + { + g_object_ref (embedder); + GDK_WINDOW_OBJECT (embedder)->num_offscreen_children++; + } + + if (offscreen->embedder) + { + g_object_unref (offscreen->embedder); + GDK_WINDOW_OBJECT (offscreen->embedder)->num_offscreen_children--; + } + + offscreen->embedder = embedder; } -static gboolean -gdk_offscreen_window_queue_antiexpose (GdkWindow *window, - GdkRegion *area) +/** + * gdk_offscreen_window_get_embedder: + * @window: a #GdkWindow + * + * Gets the window that @window is embedded in. + * + * Returns: the embedding #GdkWindow, or %NULL if @window is not an + * embedded offscreen window + * + * Since: 2.18 + */ +GdkWindow * +gdk_offscreen_window_get_embedder (GdkWindow *window) { - return FALSE; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + if (!GDK_IS_OFFSCREEN_WINDOW (private->impl)) + return NULL; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + return offscreen->embedder; } static void @@ -1172,7 +919,6 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass) object_class->finalize = gdk_offscreen_window_finalize; drawable_class->create_gc = gdk_offscreen_window_create_gc; - drawable_class->_copy_to_image = gdk_offscreen_window_copy_to_image; drawable_class->ref_cairo_surface = gdk_offscreen_window_ref_cairo_surface; drawable_class->set_colormap = gdk_offscreen_window_set_colormap; drawable_class->get_colormap = gdk_offscreen_window_get_colormap; @@ -1182,17 +928,7 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass) drawable_class->get_source_drawable = gdk_offscreen_window_get_source_drawable; drawable_class->get_composite_drawable = gdk_offscreen_window_get_composite_drawable; - drawable_class->draw_rectangle = gdk_offscreen_window_draw_rectangle; - drawable_class->draw_arc = gdk_offscreen_window_draw_arc; - drawable_class->draw_polygon = gdk_offscreen_window_draw_polygon; - drawable_class->draw_text = gdk_offscreen_window_draw_text; - drawable_class->draw_text_wc = gdk_offscreen_window_draw_text_wc; - drawable_class->draw_drawable = gdk_offscreen_window_draw_drawable; - drawable_class->draw_points = gdk_offscreen_window_draw_points; - drawable_class->draw_segments = gdk_offscreen_window_draw_segments; - drawable_class->draw_lines = gdk_offscreen_window_draw_lines; - drawable_class->draw_image = gdk_offscreen_window_draw_image; - drawable_class->draw_pixbuf = gdk_offscreen_window_draw_pixbuf; + drawable_class->draw_drawable_with_src = gdk_offscreen_window_draw_drawable; } static void @@ -1208,18 +944,15 @@ gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface) iface->set_back_pixmap = gdk_offscreen_window_set_back_pixmap; iface->get_events = gdk_offscreen_window_get_events; iface->set_events = gdk_offscreen_window_set_events; - iface->clear_area = gdk_offscreen_window_clear_area; iface->reparent = gdk_offscreen_window_reparent; - iface->set_cursor = gdk_offscreen_window_set_cursor; iface->get_geometry = gdk_offscreen_window_get_geometry; - iface->shape_combine_mask = gdk_offscreen_window_shape_combine_mask; iface->shape_combine_region = gdk_offscreen_window_shape_combine_region; - iface->set_child_shapes = gdk_offscreen_window_set_child_shapes; - iface->merge_child_shapes = gdk_offscreen_window_merge_child_shapes; + iface->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region; iface->set_static_gravities = gdk_offscreen_window_set_static_gravities; iface->queue_antiexpose = gdk_offscreen_window_queue_antiexpose; - iface->get_origin = gdk_offscreen_window_get_origin; + iface->queue_translation = gdk_offscreen_window_queue_translation; + iface->get_root_coords = gdk_offscreen_window_get_root_coords; + iface->get_deskrelative_origin = gdk_offscreen_window_get_deskrelative_origin; + iface->get_device_state = gdk_offscreen_window_get_device_state; + iface->destroy = gdk_offscreen_window_destroy; } - -#define __GDK_OFFSCREEN_WINDOW_C__ -#include "gdkaliasdef.c"