Add _gdk_pixmap_set_as_backing which is a way to get GraphicsExposures on pixmaps reported to the window they are backing store for

This commit is contained in:
Alexander Larsson 2008-12-09 20:10:59 +01:00 committed by Alexander Larsson
parent 5587130d48
commit 1f5e104495
4 changed files with 63 additions and 4 deletions

View File

@ -265,6 +265,11 @@ GdkPixmap *_gdk_bitmap_create_from_data (GdkDrawable *drawable,
const gchar *data,
gint width,
gint height);
void _gdk_pixmap_set_as_backing (GdkPixmap *pixmap,
GdkWindow *window,
int x_offset,
int y_offset);
void _gdk_window_impl_new (GdkWindow *window,
GdkWindow *real_parent,

View File

@ -226,6 +226,9 @@ gdk_pixmap_finalize (GObject *object)
g_object_unref (obj->impl);
obj->impl = NULL;
if (obj->backing_for)
g_object_unref (obj->backing_for);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -277,6 +280,30 @@ gdk_pixmap_create_from_data (GdkDrawable *drawable,
}
/* Make GraphicsExposures and NoExposures and similar things report
* events on this window. Make sure to ref the pixmap for each operation
* that will result in a GraphicsExposure, because the core code will unref
* if for each such event. This is so that the pixmap live long enought to
* get the events on the window.
*/
void
_gdk_pixmap_set_as_backing (GdkPixmap *pixmap,
GdkWindow *window,
int x_offset,
int y_offset)
{
GdkPixmapObject *private = (GdkPixmapObject *)pixmap;
if (private->backing_for)
g_object_unref (private->backing_for);
private->backing_for = window;
if (private->backing_for)
g_object_ref (private->backing_for);
private->backing_x_offset = x_offset;
private->backing_y_offset = y_offset;
}
static GdkGC *
gdk_pixmap_create_gc (GdkDrawable *drawable,
GdkGCValues *values,

View File

@ -54,6 +54,9 @@ struct _GdkPixmapObject
GdkDrawable *impl; /* window-system-specific delegate object */
gint depth;
GdkWindow *backing_for;
int backing_x_offset;
int backing_y_offset;
};
struct _GdkPixmapObjectClass

View File

@ -902,6 +902,9 @@ gdk_event_translate (GdkDisplay *display,
GdkToplevelX11 *toplevel = NULL;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
Window xwindow, filter_xwindow;
int exposure_x_offset = 0;
int exposure_y_offset = 0;
GdkWindow *unref_pixmap = NULL;
return_val = FALSE;
@ -931,11 +934,29 @@ gdk_event_translate (GdkDisplay *display,
get_real_window (display, xevent, &xwindow, &filter_xwindow);
window = gdk_window_lookup_for_display (display, xwindow);
/* We may receive events such as NoExpose/GraphicsExpose
* and ShmCompletion for pixmaps
*/
if (window && !GDK_IS_WINDOW (window))
{
GdkPixmapObject *pixmap = (GdkPixmapObject *)window;
if ((xevent->type == GraphicsExpose ||
xevent->type == NoExpose) &&
GDK_IS_PIXMAP (window) &&
pixmap->backing_for != NULL)
{
/* Unref the pixmap once for each finished set of GraphicsExposes */
if (xevent->type == NoExpose ||
xevent->xgraphicsexpose.count == 0)
unref_pixmap = window;
window = g_object_ref (pixmap->backing_for);
exposure_x_offset = pixmap->backing_x_offset;
exposure_y_offset = pixmap->backing_x_offset;
}
else
window = NULL;
}
window_private = (GdkWindowObject *) window;
/* We always run the filters for the window where the event
@ -1660,8 +1681,8 @@ gdk_event_translate (GdkDisplay *display,
break;
}
expose_rect.x = xevent->xgraphicsexpose.x;
expose_rect.y = xevent->xgraphicsexpose.y;
expose_rect.x = xevent->xgraphicsexpose.x + exposure_x_offset;
expose_rect.y = xevent->xgraphicsexpose.y + exposure_y_offset;
expose_rect.width = xevent->xgraphicsexpose.width;
expose_rect.height = xevent->xgraphicsexpose.height;
@ -2203,6 +2224,9 @@ gdk_event_translate (GdkDisplay *display,
if (window)
g_object_unref (window);
if (unref_pixmap)
g_object_unref (unref_pixmap);
return return_val;
}