gdk: Move scratch GC handling to X11

... and implement it directly instead of using GdkGC, as GdkGC is about
to be deleted, but we need this code.
This commit is contained in:
Benjamin Otte
2010-07-22 02:26:05 +02:00
parent 9c026fb32e
commit f7608c33ac
7 changed files with 57 additions and 83 deletions

View File

@ -269,52 +269,6 @@ _gdk_drawable_ref_cairo_surface (GdkDrawable *drawable)
/************************************************************************/
/**
* _gdk_drawable_get_subwindow_scratch_gc:
* @drawable: A #GdkDrawable
*
* Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has
* the standard values for @drawable, except for the graphics_exposures
* field which is %TRUE and the subwindow mode which is %GDK_INCLUDE_INFERIORS.
*
* The foreground color of the returned #GdkGC is undefined. The #GdkGC
* must not be altered in any way, except to change its foreground color.
*
* Return value: A #GdkGC suitable for drawing on @drawable
*
* Since: 2.18
**/
GdkGC *
_gdk_drawable_get_subwindow_scratch_gc (GdkDrawable *drawable)
{
GdkScreen *screen;
gint depth;
g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
screen = gdk_drawable_get_screen (drawable);
g_return_val_if_fail (!screen->closed, NULL);
depth = gdk_drawable_get_depth (drawable) - 1;
if (!screen->subwindow_gcs[depth])
{
GdkGCValues values;
GdkGCValuesMask mask;
values.graphics_exposures = TRUE;
values.subwindow_mode = GDK_INCLUDE_INFERIORS;
mask = GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW;
screen->subwindow_gcs[depth] =
gdk_gc_new_with_values (drawable, &values, mask);
}
return screen->subwindow_gcs[depth];
}
/*
* _gdk_drawable_get_source_drawable:
* @drawable: a #GdkDrawable

View File

@ -324,9 +324,6 @@ cairo_surface_t * _gdk_drawable_create_cairo_surface (GdkDrawable *drawable,
int width,
int height);
/* GC caching */
GdkGC *_gdk_drawable_get_subwindow_scratch_gc (GdkDrawable *drawable);
/*************************************
* Interfaces used by windowing code *
*************************************/

View File

@ -29,7 +29,6 @@
#include "gdkintl.h"
static void gdk_screen_dispose (GObject *object);
static void gdk_screen_finalize (GObject *object);
static void gdk_screen_set_property (GObject *object,
guint prop_id,
@ -64,7 +63,6 @@ gdk_screen_class_init (GdkScreenClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gdk_screen_dispose;
object_class->finalize = gdk_screen_finalize;
object_class->set_property = gdk_screen_set_property;
object_class->get_property = gdk_screen_get_property;
@ -155,24 +153,6 @@ gdk_screen_init (GdkScreen *screen)
screen->resolution = -1.;
}
static void
gdk_screen_dispose (GObject *object)
{
GdkScreen *screen = GDK_SCREEN (object);
gint i;
for (i = 0; i < 32; ++i)
{
if (screen->subwindow_gcs[i])
{
g_object_unref (screen->subwindow_gcs[i]);
screen->subwindow_gcs[i] = NULL;
}
}
G_OBJECT_CLASS (gdk_screen_parent_class)->dispose (object);
}
static void
gdk_screen_finalize (GObject *object)
{

View File

@ -49,8 +49,6 @@ struct _GdkScreen
guint GSEAL (closed) : 1;
GdkGC *GSEAL (subwindow_gcs[32]);
cairo_font_options_t *GSEAL (font_options);
double GSEAL (resolution); /* pixels/points scale factor for fonts */
};

View File

@ -225,6 +225,47 @@ gdk_window_queue (GdkWindow *window,
g_queue_push_tail (display_x11->translate_queue, item);
}
static GC
_get_scratch_gc (GdkWindowObject *window, cairo_region_t *clip_region)
{
GdkScreenX11 *screen;
XRectangle *rectangles;
gint n_rects;
gint depth;
screen = GDK_SCREEN_X11 (gdk_drawable_get_screen (GDK_DRAWABLE (window)));
depth = gdk_drawable_get_depth (GDK_DRAWABLE (window)) - 1;
if (!screen->subwindow_gcs[depth])
{
XGCValues values;
values.graphics_exposures = True;
values.subwindow_mode = IncludeInferiors;
screen->subwindow_gcs[depth] = XCreateGC (screen->xdisplay,
GDK_WINDOW_XID (window),
GCSubwindowMode | GCGraphicsExposures,
&values);
}
_gdk_region_get_xrectangles (clip_region,
0, 0,
&rectangles,
&n_rects);
XSetClipRectangles (screen->xdisplay,
screen->subwindow_gcs[depth],
0, 0,
rectangles, n_rects,
YXBanded);
g_free (rectangles);
return screen->subwindow_gcs[depth];
}
void
_gdk_x11_window_translate (GdkWindow *window,
cairo_region_t *area,
@ -232,7 +273,7 @@ _gdk_x11_window_translate (GdkWindow *window,
gint dy)
{
GdkWindowQueueItem *item;
GdkGC *tmp_gc;
GC xgc;
GdkRectangle extents;
GdkWindowObject *private, *impl;
int px, py;
@ -255,17 +296,10 @@ _gdk_x11_window_translate (GdkWindow *window,
cairo_region_get_extents (area, &extents);
tmp_gc = _gdk_drawable_get_subwindow_scratch_gc ((GdkWindow *)private);
gdk_gc_set_clip_region (tmp_gc, area);
xgc = _get_scratch_gc (impl, area);
cairo_region_translate (area, -dx, -dy); /* Move to source region */
/* Ensure that the gc is flushed so that we get the right
serial from NextRequest in gdk_window_queue, i.e. the
the serial for the XCopyArea, not the ones from flushing
the gc. */
_gdk_x11_gc_flush (tmp_gc);
item = g_new (GdkWindowQueueItem, 1);
item->type = GDK_WINDOW_QUEUE_TRANSLATE;
item->u.translate.area = cairo_region_copy (area);
@ -276,12 +310,10 @@ _gdk_x11_window_translate (GdkWindow *window,
XCopyArea (GDK_WINDOW_XDISPLAY (impl),
GDK_DRAWABLE_IMPL_X11 (private->impl)->xid,
GDK_DRAWABLE_IMPL_X11 (impl->impl)->xid,
GDK_GC_GET_XGC (tmp_gc),
xgc,
extents.x - dx, extents.y - dy,
extents.width, extents.height,
extents.x, extents.y);
gdk_gc_set_clip_region (tmp_gc, NULL);
}
gboolean

View File

@ -297,6 +297,16 @@ static void
gdk_screen_x11_dispose (GObject *object)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (object);
int i;
for (i = 0; i < 32; ++i)
{
if (screen_x11->subwindow_gcs[i])
{
XFreeGC (screen_x11->xdisplay, screen_x11->subwindow_gcs[i]);
screen_x11->subwindow_gcs[i] = 0;
}
}
_gdk_screen_x11_events_uninit (GDK_SCREEN (object));

View File

@ -95,6 +95,9 @@ struct _GdkScreenX11
GdkX11Monitor *monitors;
gint primary_monitor;
/* cache for window->translate vfunc */
GC subwindow_gcs[32];
/* Xft resources for the display, used for default values for
* the Xft/ XSETTINGS
*/