* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#include <config.h>
-#include <math.h>
-#include "gdk.h"
+#include "config.h"
+
#include "gdkwindow.h"
#include "gdkinternals.h"
#include "gdkwindowimpl.h"
-#include "gdkpixmap.h"
-#include "gdkdrawable.h"
-#include "gdktypes.h"
-#include "gdkscreen.h"
-#include "gdkgc.h"
-#include "gdkcolor.h"
-#include "gdkcursor.h"
-#include "gdkalias.h"
+
+#include <math.h>
/* LIMITATIONS:
*
GdkDrawable parent_instance;
GdkWindow *wrapper;
- GdkCursor *cursor;
- GdkColormap *colormap;
- GdkScreen *screen;
- GdkPixmap *pixmap;
+ cairo_surface_t *surface;
+ GdkWindow *embedder;
};
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));
{
GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (object);
- if (offscreen->cursor)
- gdk_cursor_unref (offscreen->cursor);
-
- offscreen->cursor = NULL;
+ if (offscreen->surface)
+ cairo_surface_destroy (offscreen->surface);
- gdk_pixmap_unref (offscreen->pixmap);
-
G_OBJECT_CLASS (gdk_offscreen_window_parent_class)->finalize (object);
}
{
}
-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);
+}
- g_object_unref (offscreen->colormap);
- offscreen->colormap = NULL;
+static cairo_surface_t *
+get_surface (GdkOffscreenWindow *offscreen)
+{
+ if (! offscreen->surface)
+ {
+ GdkWindowObject *private = (GdkWindowObject *) offscreen->wrapper;
+
+ g_signal_emit_by_name (private, "create-surface",
+ private->width,
+ private->height,
+ &offscreen->surface);
+ }
+
+ return offscreen->surface;
}
static gboolean
is_parent_of (GdkWindow *parent,
- GdkWindow *child)
+ GdkWindow *child)
{
GdkWindow *w;
return FALSE;
}
-static GdkGC *
-gdk_offscreen_window_create_gc (GdkDrawable *drawable,
- GdkGCValues *values,
- GdkGCValuesMask values_mask)
-{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (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);
-}
-static GdkColormap*
-gdk_offscreen_window_get_colormap (GdkDrawable *drawable)
-{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
- return offscreen->colormap;
+ return cairo_surface_reference (get_surface (offscreen));
}
-static void
-gdk_offscreen_window_set_colormap (GdkDrawable *drawable,
- GdkColormap*colormap)
+cairo_surface_t *
+_gdk_offscreen_window_create_surface (GdkWindow *offscreen,
+ gint width,
+ gint height)
{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
+ GdkWindowObject *private = (GdkWindowObject *) offscreen;
+ cairo_surface_t *similar;
+ cairo_surface_t *surface;
+ cairo_content_t content = CAIRO_CONTENT_COLOR;
- if (colormap && GDK_WINDOW_DESTROYED (offscreen->wrapper))
- return;
-
- if (offscreen->colormap == colormap)
- return;
-
- if (offscreen->colormap)
- g_object_unref (offscreen->colormap);
-
- offscreen->colormap = colormap;
- if (offscreen->colormap)
- g_object_ref (offscreen->colormap);
-}
+ g_return_val_if_fail (GDK_IS_OFFSCREEN_WINDOW (private->impl), NULL);
+ similar = _gdk_drawable_ref_cairo_surface ((GdkWindow *)private->parent);
-static gint
-gdk_offscreen_window_get_depth (GdkDrawable *drawable)
-{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
- return gdk_drawable_get_depth (offscreen->wrapper);
-}
-
-static GdkDrawable *
-gdk_offscreen_window_get_source_drawable (GdkDrawable *drawable)
-{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
- return _gdk_drawable_get_source_drawable (offscreen->pixmap);
-}
-
-static GdkDrawable *
-gdk_offscreen_window_get_composite_drawable (GdkDrawable *drawable,
- gint x,
- gint y,
- gint width,
- gint height,
- gint *composite_x_offset,
- gint *composite_y_offset)
-{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
- return g_object_ref (offscreen->pixmap);
-}
-
-static GdkScreen*
-gdk_offscreen_window_get_screen (GdkDrawable *drawable)
-{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
- return offscreen->screen;
-}
-
-static GdkVisual*
-gdk_offscreen_window_get_visual (GdkDrawable *drawable)
-{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
- return gdk_drawable_get_visual (offscreen->wrapper);
-}
-
-static void
-add_damage (GdkOffscreenWindow *offscreen,
- int x, int y,
- int w, int h)
-{
- GdkRectangle rect;
- GdkRegion *damage;
-
- rect.x = x;
- rect.y = y;
- rect.width = w;
- rect.height = h;
-
- damage = gdk_region_rectangle (&rect);
- _gdk_window_add_damage (offscreen->wrapper, damage);
- gdk_region_destroy (damage);
-}
-
-static void
-gdk_offscreen_window_draw_drawable (GdkDrawable *drawable,
- GdkGC *gc,
- GdkPixmap *src,
- gint xsrc,
- gint ysrc,
- gint xdest,
- gint ydest,
- gint width,
- gint height)
-{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
- GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap);
-
- gdk_draw_drawable (real_drawable, gc,
- src, xsrc, ysrc,
- xdest, ydest,
- width, height);
-
- add_damage (offscreen, xdest, ydest, width, height);
-}
-
-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 = GDK_DRAWABLE (offscreen->pixmap);
-
- 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 = GDK_DRAWABLE (offscreen->pixmap);
-
- 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 = GDK_DRAWABLE (offscreen->pixmap);
-
- 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 = GDK_DRAWABLE (offscreen->pixmap);
- 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 = GDK_DRAWABLE (offscreen->pixmap);
- 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 = GDK_DRAWABLE (offscreen->pixmap);
-
- 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 = GDK_DRAWABLE (offscreen->pixmap);
-
- gdk_draw_segments (real_drawable,
- gc,
- segs,
- nsegs);
-
- if (nsegs > 0)
+ if (gdk_window_get_visual (offscreen) ==
+ gdk_screen_get_rgba_visual (gdk_window_get_screen (offscreen)))
{
- 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);
+ content = CAIRO_CONTENT_COLOR_ALPHA;
}
-}
-
-static void
-gdk_offscreen_window_draw_lines (GdkDrawable *drawable,
- GdkGC *gc,
- GdkPoint *points,
- gint npoints)
-{
- GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
- GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap);
- 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 = GDK_DRAWABLE (offscreen->pixmap);
-
- gdk_draw_image (real_drawable,
- gc,
- image,
- xsrc,
- ysrc,
- xdest,
- ydest,
- width,
- height);
-
- add_damage (offscreen, xdest, ydest, width, height);
-}
-
+ surface = cairo_surface_create_similar (similar, content, 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 = GDK_DRAWABLE (offscreen->pixmap);
-
- 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);
+ cairo_surface_destroy (similar);
+ return surface;
}
-void
+void
_gdk_offscreen_window_new (GdkWindow *window,
- GdkScreen *screen,
- GdkVisual *visual,
GdkWindowAttr *attributes,
gint attributes_mask)
{
- GdkWindowObject *parent_private;
GdkWindowObject *private;
GdkOffscreenWindow *offscreen;
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;
-
- offscreen->screen = screen;
-
- if (attributes_mask & GDK_WA_COLORMAP)
- offscreen->colormap = g_object_ref (attributes->colormap);
- else
- {
- if (gdk_screen_get_system_visual (screen) == visual)
- {
- offscreen->colormap = gdk_screen_get_system_colormap (screen);
- g_object_ref (offscreen->colormap);
- }
- else
- offscreen->colormap = gdk_colormap_new (visual, FALSE);
- }
-
- offscreen->pixmap = gdk_pixmap_new ((GdkDrawable *)private->parent,
- private->width,
- private->height,
- private->depth);
}
static gboolean
GdkWindowObject *private = (GdkWindowObject *)window;
GdkWindowObject *new_parent_private = (GdkWindowObject *)new_parent;
GdkWindowObject *old_parent;
- GdkOffscreenWindow *offscreen;
gboolean was_mapped;
if (new_parent)
/* 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);
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 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 = 0;
+ *x = tmpx;
if (y)
- *y = 0;
-
+ *y = tmpy;
+ if (mask)
+ *mask = tmpmask;
return TRUE;
}
/**
- * gdk_window_get_offscreen_pixmap:
+ * gdk_offscreen_window_get_surface:
* @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 surface 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
- **/
-GdkPixmap *
-gdk_window_get_offscreen_pixmap (GdkWindow *window)
+ * Returns: The offscreen surface, or %NULL if not offscreen
+ */
+cairo_surface_t *
+gdk_offscreen_window_get_surface (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;
+
+ return get_surface (offscreen);
}
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
GdkWindowObject *private = (GdkWindowObject *)window;
GdkOffscreenWindow *offscreen;
gint dx, dy, dw, dh;
- GdkGC *gc;
- GdkPixmap *old_pixmap;
offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
{
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);
+
+ if (offscreen->surface)
+ {
+ cairo_surface_t *old_surface;
+ cairo_t *cr;
+
+ old_surface = offscreen->surface;
+ offscreen->surface = NULL;
+
+ offscreen->surface = get_surface (offscreen);
+
+ cr = cairo_create (offscreen->surface);
+ cairo_set_source_surface (cr, old_surface, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (old_surface);
+ }
}
-
+
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;
}
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;
+ GdkRectangle area = { 0, 0, private->width, private->height };
- 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);
+ gdk_window_invalidate_rect (window, &area, FALSE);
}
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);
-
+ display = gdk_window_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))
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
{
}
-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)
-{
- GdkWindowObject *private = (GdkWindowObject *)window;
- GdkColormap *colormap = gdk_drawable_get_colormap (window);
-
- private->bg_color = *color;
- gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color);
-
- if (private->bg_pixmap &&
- private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
- private->bg_pixmap != GDK_NO_BG)
- g_object_unref (private->bg_pixmap);
-
- private->bg_pixmap = NULL;
-}
-
-static void
-gdk_offscreen_window_set_back_pixmap (GdkWindow *window,
- GdkPixmap *pixmap)
-{
- GdkWindowObject *private = (GdkWindowObject *)window;
-
- if (pixmap &&
- private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
- private->bg_pixmap != GDK_NO_BG &&
- !gdk_drawable_get_colormap (pixmap))
- {
- g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
- return;
- }
-
- if (private->bg_pixmap &&
- private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
- private->bg_pixmap != GDK_NO_BG)
- g_object_unref (private->bg_pixmap);
-
- private->bg_pixmap = pixmap;
-
- if (pixmap &&
- private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
- private->bg_pixmap != GDK_NO_BG)
- g_object_ref (pixmap);
-}
-
-static void
-gdk_offscreen_window_shape_combine_mask (GdkWindow *window,
- GdkBitmap *mask,
- gint x,
- gint y)
+ cairo_pattern_t *pattern)
{
}
static void
gdk_offscreen_window_shape_combine_region (GdkWindow *window,
- const GdkRegion *shape_region,
- gint offset_x,
- gint offset_y)
-{
-}
-
-static void
-gdk_offscreen_window_set_child_shapes (GdkWindow *window)
+ const cairo_region_t *shape_region,
+ gint offset_x,
+ gint offset_y)
{
}
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)
{
}
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,
gint *depth)
{
GdkWindowObject *private = (GdkWindowObject *)window;
- GdkOffscreenWindow *offscreen;
-
- offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
}
}
+static gboolean
+gdk_offscreen_window_queue_antiexpose (GdkWindow *window,
+ cairo_region_t *area)
+{
+ return FALSE;
+}
+
+static void
+gdk_offscreen_window_translate (GdkWindow *window,
+ cairo_region_t *area,
+ gint dx,
+ gint dy)
+{
+ GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (((GdkWindowObject *) window)->impl);
+
+ if (offscreen->surface)
+ {
+ cairo_t *cr;
+
+ cr = cairo_create (offscreen->surface);
+
+ area = cairo_region_copy (area);
+
+ gdk_cairo_region (cr, area);
+ cairo_clip (cr);
+
+ /* NB: This is a self-copy and Cairo doesn't support that yet.
+ * So we do a litle trick.
+ */
+ cairo_push_group (cr);
+
+ cairo_set_source_surface (cr, offscreen->surface, dx, dy);
+ cairo_paint (cr);
+
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+ }
+
+ _gdk_window_add_damage (window, area);
+}
+
+static cairo_surface_t *
+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 surface;
+}
+
/**
- * 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 (window));
- g_return_if_fail (GDK_IS_WINDOW (offscreen_window));
- g_return_if_fail (hooks != NULL);
+ if (!GDK_IS_OFFSCREEN_WINDOW (private->impl))
+ return;
+
+ offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
+
+ if (embedder)
+ {
+ g_object_ref (embedder);
+ GDK_WINDOW_OBJECT (embedder)->num_offscreen_children++;
+ }
- private = (GdkWindowObject *) offscreen_window;
+ if (offscreen->embedder)
+ {
+ g_object_unref (offscreen->embedder);
+ GDK_WINDOW_OBJECT (offscreen->embedder)->num_offscreen_children--;
+ }
- private->offscreen_hooks = hooks;
+ 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
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;
- drawable_class->get_depth = gdk_offscreen_window_get_depth;
- drawable_class->get_screen = gdk_offscreen_window_get_screen;
- drawable_class->get_visual = gdk_offscreen_window_get_visual;
- 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;
}
static void
iface->lower = gdk_offscreen_window_lower;
iface->move_resize = gdk_offscreen_window_move_resize;
iface->set_background = gdk_offscreen_window_set_background;
- 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->translate = gdk_offscreen_window_translate;
+ iface->get_root_coords = gdk_offscreen_window_get_root_coords;
+ iface->get_device_state = gdk_offscreen_window_get_device_state;
+ iface->destroy = gdk_offscreen_window_destroy;
+ iface->resize_cairo_surface = gdk_offscreen_window_resize_cairo_surface;
}
-
-#define __GDK_OFFSCREEN_WINDOW_C__
-#include "gdkaliasdef.c"