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:
@ -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
|
||||
|
||||
@ -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 *
|
||||
*************************************/
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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 */
|
||||
};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user