Getting backing pixmap
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Cc: andersca gnu org
- Subject: Getting backing pixmap
- Date: 13 Jul 2001 15:42:53 -0400
Anders Carlsson pointed out to me (http://bugzilla.gnome.org/show_bug.cgi?id=57212)
that there is currently no way of drawing onto a GdkWindow with X functions directly,
since the backing pixmap is hidden inside private structures.
I think this is a fairly serious defect, so I'd like to apply the
following patch which adds a somewhat clumsy, but workable, way to get
the necessary information:
With this patch, an X only emulation of gdk_draw_line() would be something like:
void
my_draw_line (GdkDrawable *drawable, GdkGC *gc,
gint x1, gint y1, gint x2, gint y2)
{
GdkDrawable *real_drawable;
gint x_off, y_off;
if (GDK_IS_WINDOW (drawable))
{
gdk_window_get_internal_paint_info (drawable, &real_drawable, &x_off, &y_off);
}
else if (GDK_IS_PIXMAP (drawable))
{
real_drawable = drawable;
x_off = y_off = 0;
}
else
{
g_warning ("my_draw_line() called on non-X drawable");
return;
}
gdk_gc_offset (gc, x_off, y_off);
XDrawLine (GDK_DRAWABLE_XDISPLAY (real_drawable),
GDK_DRAWABLE_XID (real_drawable),
GDK_GC_XGC (gc),
x1 - x_off, y1 - y_off, x2 - x_off, y2 - y_off);
gdk_gc_offset (gc, -x_off, -y_off);
}
The use of GDK_IS_WINDOW() could be eliminated by making this a virtualized
operation on GdkDrawable, but I avoided doing this on the principle
of keeping hacks localized.
This change does not affect either source or binary compatibility.
Regards,
Owen
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.2120
diff -u -r1.2120 ChangeLog
--- ChangeLog 2001/07/12 22:45:03 1.2120
+++ ChangeLog 2001/07/13 19:40:03
@@ -1,3 +1,13 @@
+Fri Jul 13 15:33:32 2001 Owen Taylor <otaylor redhat com>
+
+ * gdk/gdkwindow.[ch]: Add a function gdk_window_get_internal_paint_info(),
+ so that using X functions on a GdkWindow is possible, if
+ a little hairy.
+
+ * gdk/gdkgc.c (gdk_gc_offset): Add a function to offset the clip
+ and ts_origin of a GC, so that external parties can offset/restore
+ a GC, when using gdk_window_get_internal_paint_info().
+
Thu Jul 12 18:29:40 2001 Owen Taylor <otaylor redhat com>
* gtk/gtkradiomenuitem.[ch] (gtk_radio_menu_item_group):
Index: gdk/gdkgc.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkgc.c,v
retrieving revision 1.32
diff -u -r1.32 gdkgc.c
--- gdk/gdkgc.c 2001/02/20 05:21:44 1.32
+++ gdk/gdkgc.c 2001/07/13 19:40:03
@@ -367,6 +367,35 @@
}
/**
+ * gdk_gc_offset:
+ * @gc: a #GdkGC
+ * @x_offset: amount by which to offset the GC in the X direction
+ * @y_offset: amount by which to offset the GC in the Y direction
+ *
+ * Offset attributes such as the clip and tile-stipple origins
+ * of the GC so that drawing at x - x_offset, y - y_offset with
+ * the offset GC has the same effect as drawing at x, y with the original
+ * GC.
+ **/
+void
+gdk_gc_offset (GdkGC *gc,
+ gint x_offset,
+ gint y_offset)
+{
+ if (x_offset != 0 || y_offset != 0)
+ {
+ gint clip_x_origin, clip_y_origin;
+ gint ts_x_origin, ts_y_origin;
+
+ gdk_gc_get_clip_offset (gc, &clip_x_origin, &clip_y_origin);
+ gdk_gc_get_ts_offset (gc, &ts_x_origin, &ts_y_origin);
+
+ gdk_gc_set_clip_offset (gc, clip_x_origin - x_offset, clip_y_origin - y_offset);
+ gdk_gc_set_ts_offset (gc, ts_x_origin - x_offset, _y_origin - y_offset);
+ }
+}
+
+/**
* gdk_gc_set_colormap:
* @gc: a #GdkGC
* @colormap: a #GdkColormap
Index: gdk/gdkgc.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkgc.h,v
retrieving revision 1.7
diff -u -r1.7 gdkgc.h
--- gdk/gdkgc.h 2000/08/30 00:33:35 1.7
+++ gdk/gdkgc.h 2001/07/13 19:40:03
@@ -237,6 +237,9 @@
gint dash_offset,
gint8 dash_list[],
gint n);
+void gdk_gc_offset (GdkGC *gc,
+ gint x_offset,
+ gint y_offset);
void gdk_gc_copy (GdkGC *dst_gc,
GdkGC *src_gc);
Index: gdk/gdkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.c,v
retrieving revision 1.119
diff -u -r1.119 gdkwindow.c
--- gdk/gdkwindow.c 2001/07/05 13:41:33 1.119
+++ gdk/gdkwindow.c 2001/07/13 19:40:03
@@ -979,6 +979,59 @@
_gdk_windowing_window_get_offsets (window, x_offset, y_offset);
}
+/**
+ * gdk_window_get_internal_paint_info:
+ * @window: a #GdkWindow
+ * @real_drawable: location to store the drawable to which drawing should be done.
+ * @x_offset: location to store the X offset between coordinates in @window, and
+ * the underlying window system primitive coordinates for * real_drawable
+ * @y_offset: location to store the Y offset between coordinates in @window, and
+ * the underlying window system primitive coordinates for * real_drawable
+ *
+ * If you bypass the GDK layer and use windowing system primitives to
+ * draw directly onto a #GdkWindow, then you need to deal with two
+ * details: there may be an offset between GDK coordinates and windowing
+ * system coordinates, and GDK may have redirected drawing to a offscreen
+ * pixmap as the result of a gdk_window_begin_paint_region() calls.
+ * This function allows retrieving the information you need to compensate
+ * for these effects.
+ *
+ * This function exposes details of the GDK implementation, and is thus
+ * likely to change in future releases of GDK.
+ **/
+void
+gdk_window_get_internal_paint_info (GdkWindow *window,
+ GdkDrawable **real_drawable,
+ gint *x_offset,
+ gint *y_offset)
+{
+ gint x_off, y_off;
+
+ GdkWindowObject *private;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ private = (GdkWindowObject *)window;
+
+ if (real_drawable)
+ {
+ if (private->paint_stack)
+ {
+ GdkWindowPaint *paint = private->paint_stack->data;
+ *real_drawable = paint->pixmap;
+ }
+ else
+ *real_drawable = window;
+ }
+
+ gdk_window_get_offsets (window, &x_off, &y_off);
+
+ if (x_offset)
+ *x_offset = x_off;
+ if (y_offset)
+ *y_offset = y_off;
+}
+
#define OFFSET_GC(gc) \
gint x_offset, y_offset; \
gint old_clip_x = gc->clip_x_origin; \
Index: gdk/gdkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.h,v
retrieving revision 1.26
diff -u -r1.26 gdkwindow.h
--- gdk/gdkwindow.h 2001/07/05 13:41:33 1.26
+++ gdk/gdkwindow.h 2001/07/13 19:40:03
@@ -507,6 +507,11 @@
gint *new_width,
gint *new_height);
+void gdk_window_get_internal_paint_info (GdkWindow *window,
+ GdkDrawable **real_drawable,
+ gint *x_offset,
+ gint *y_offset);
+
GdkPointerHooks *gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks);
#ifdef __cplusplus
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]