gdk: Rewrite background handling
Now the window background is a cairo_pattern_t. The backends will try to set this as good as they can on the windowing system, but no guarantees are made on wether the windowing system supports the pattern. Also gets rid of GDK_NO_BG as undefined behavior is not a good idea to support, and GDK_NO_BG effectively made the window's contents undefined. It wasn't effectively used in GTK anyway.
This commit is contained in:
@ -474,7 +474,7 @@ gdk_window_merge_child_input_shapes
|
||||
gdk_window_set_static_gravities
|
||||
gdk_window_set_title
|
||||
gdk_window_set_background
|
||||
gdk_window_set_back_pixmap
|
||||
gdk_window_set_background_pattern
|
||||
gdk_window_get_background_pattern
|
||||
GDK_PARENT_RELATIVE
|
||||
gdk_window_set_cursor
|
||||
|
||||
@ -593,6 +593,7 @@ gdk_window_get_support_multidevice
|
||||
gdk_window_has_native
|
||||
gdk_window_set_background
|
||||
gdk_window_set_back_pixmap
|
||||
gdk_window_set_background_pattern
|
||||
gdk_window_set_cursor
|
||||
gdk_window_shape_combine_region
|
||||
gdk_window_set_child_shapes
|
||||
|
||||
@ -203,8 +203,6 @@ struct _GdkWindowObject
|
||||
GList *filters;
|
||||
GList *children;
|
||||
|
||||
GdkColor bg_color;
|
||||
GdkPixmap *bg_pixmap;
|
||||
cairo_pattern_t *background;
|
||||
|
||||
GSList *paint_stack;
|
||||
|
||||
@ -35,7 +35,6 @@
|
||||
#include "gdktypes.h"
|
||||
#include "gdkscreen.h"
|
||||
#include "gdkcolor.h"
|
||||
#include "gdkcursor.h"
|
||||
|
||||
|
||||
/* LIMITATIONS:
|
||||
@ -53,7 +52,6 @@ struct _GdkOffscreenWindow
|
||||
GdkDrawable parent_instance;
|
||||
|
||||
GdkWindow *wrapper;
|
||||
GdkCursor *cursor;
|
||||
GdkColormap *colormap;
|
||||
GdkScreen *screen;
|
||||
|
||||
@ -88,11 +86,6 @@ gdk_offscreen_window_finalize (GObject *object)
|
||||
{
|
||||
GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (object);
|
||||
|
||||
if (offscreen->cursor)
|
||||
gdk_cursor_unref (offscreen->cursor);
|
||||
|
||||
offscreen->cursor = NULL;
|
||||
|
||||
g_object_unref (offscreen->pixmap);
|
||||
|
||||
G_OBJECT_CLASS (gdk_offscreen_window_parent_class)->finalize (object);
|
||||
@ -601,46 +594,8 @@ gdk_offscreen_window_set_events (GdkWindow *window,
|
||||
|
||||
static void
|
||||
gdk_offscreen_window_set_background (GdkWindow *window,
|
||||
const GdkColor *color)
|
||||
cairo_pattern_t *pattern)
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||
|
||||
private->bg_color = *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
|
||||
@ -832,7 +787,6 @@ gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface)
|
||||
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->reparent = gdk_offscreen_window_reparent;
|
||||
|
||||
166
gdk/gdkwindow.c
166
gdk/gdkwindow.c
@ -1406,10 +1406,8 @@ gdk_window_new (GdkWindow *parent,
|
||||
private->input_only = FALSE;
|
||||
private->depth = visual->depth;
|
||||
|
||||
private->bg_color.pixel = 0; /* TODO: BlackPixel (xdisplay, screen_x11->screen_num); */
|
||||
private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
|
||||
|
||||
private->bg_pixmap = NULL;
|
||||
/* XXX: Cache this somehow? */
|
||||
private->background = cairo_pattern_create_rgb (0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1899,9 +1897,7 @@ gdk_window_ensure_native (GdkWindow *window)
|
||||
|
||||
if (!private->input_only)
|
||||
{
|
||||
impl_iface->set_background (window, &private->bg_color);
|
||||
if (private->bg_pixmap != NULL)
|
||||
impl_iface->set_back_pixmap (window, private->bg_pixmap);
|
||||
impl_iface->set_background (window, private->background);
|
||||
}
|
||||
|
||||
impl_iface->input_shape_combine_region (window,
|
||||
@ -2056,13 +2052,7 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
|
||||
|
||||
gdk_window_free_paint_stack (window);
|
||||
|
||||
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;
|
||||
}
|
||||
gdk_window_set_background_pattern (window, NULL);
|
||||
|
||||
if (private->background)
|
||||
{
|
||||
@ -3684,7 +3674,7 @@ setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo
|
||||
cairo_translate (cr, x_offset, y_offset);
|
||||
}
|
||||
else
|
||||
gdk_cairo_set_source_color (cr, &private->bg_color);
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
|
||||
return cr;
|
||||
}
|
||||
@ -4285,8 +4275,7 @@ _gdk_window_process_updates_recurse (GdkWindow *window,
|
||||
|
||||
g_object_unref (window);
|
||||
}
|
||||
else if (private->bg_pixmap != GDK_NO_BG &&
|
||||
private->window_type != GDK_WINDOW_FOREIGN)
|
||||
else if (private->window_type != GDK_WINDOW_FOREIGN)
|
||||
{
|
||||
/* No exposure mask set, so nothing will be drawn, the
|
||||
* app relies on the background being what it specified
|
||||
@ -6952,120 +6941,96 @@ gdk_window_move_region (GdkWindow *window,
|
||||
/**
|
||||
* gdk_window_set_background:
|
||||
* @window: a #GdkWindow
|
||||
* @color: an allocated #GdkColor
|
||||
* @color: a #GdkColor
|
||||
*
|
||||
* Sets the background color of @window. (However, when using GTK+,
|
||||
* set the background of a widget with gtk_widget_modify_bg() - if
|
||||
* you're an application - or gtk_style_set_background() - if you're
|
||||
* implementing a custom widget.)
|
||||
*
|
||||
* See also gdk_window_set_background_pixmap().
|
||||
* See also gdk_window_set_background_pattern().
|
||||
*/
|
||||
void
|
||||
gdk_window_set_background (GdkWindow *window,
|
||||
const GdkColor *color)
|
||||
{
|
||||
GdkWindowObject *private;
|
||||
GdkWindowImplIface *impl_iface;
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
private = (GdkWindowObject *) window;
|
||||
pattern = cairo_pattern_create_rgb (color->red / 65535.,
|
||||
color->green / 65535.,
|
||||
color->blue / 65535.);
|
||||
|
||||
private->bg_color = *color;
|
||||
gdk_window_set_background_pattern (window, pattern);
|
||||
|
||||
if (private->bg_pixmap &&
|
||||
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
|
||||
private->bg_pixmap != GDK_NO_BG)
|
||||
g_object_unref (private->bg_pixmap);
|
||||
cairo_pattern_destroy (pattern);
|
||||
}
|
||||
|
||||
private->bg_pixmap = NULL;
|
||||
/* NB: This is more or less a hack now and about to go away. */
|
||||
void
|
||||
gdk_window_set_back_pixmap (GdkWindow *window,
|
||||
GdkPixmap *pixmap,
|
||||
gboolean parent_relative)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
if (private->background)
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
g_return_if_fail (pixmap == NULL || !parent_relative);
|
||||
|
||||
if (parent_relative || pixmap == NULL)
|
||||
pattern = NULL;
|
||||
else
|
||||
{
|
||||
cairo_pattern_destroy (private->background);
|
||||
private->background = NULL;
|
||||
static cairo_user_data_key_t key;
|
||||
cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (pixmap);
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
|
||||
g_object_ref (pixmap);
|
||||
cairo_pattern_set_user_data (pattern, &key, pixmap, g_object_unref);
|
||||
}
|
||||
|
||||
if (!GDK_WINDOW_DESTROYED (window) &&
|
||||
gdk_window_has_impl (private) &&
|
||||
!private->input_only)
|
||||
{
|
||||
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
|
||||
impl_iface->set_background (window, &private->bg_color);
|
||||
}
|
||||
gdk_window_set_background_pattern (window, pattern);
|
||||
|
||||
if (pattern)
|
||||
cairo_pattern_destroy (pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_window_set_back_pixmap:
|
||||
* gdk_window_set_background_pattern:
|
||||
* @window: a #GdkWindow
|
||||
* @pixmap: (allow-none): a #GdkPixmap, or %NULL
|
||||
* @parent_relative: whether the tiling origin is at the origin of
|
||||
* @window's parent
|
||||
* @pattern: (allow-none): a pattern to use, or %NULL
|
||||
*
|
||||
* Sets the background pixmap of @window. May also be used to set a
|
||||
* background of "None" on @window, by setting a background pixmap
|
||||
* of %NULL.
|
||||
* Sets the background of @window.
|
||||
*
|
||||
* A background pixmap will be tiled, positioning the first tile at
|
||||
* the origin of @window, or if @parent_relative is %TRUE, the tiling
|
||||
* will be done based on the origin of the parent window (useful to
|
||||
* align tiles in a parent with tiles in a child).
|
||||
*
|
||||
* A background pixmap of %NULL means that the window will have no
|
||||
* background. A window with no background will never have its
|
||||
* background filled by the windowing system, instead the window will
|
||||
* contain whatever pixels were already in the corresponding area of
|
||||
* the display.
|
||||
* A background of %NULL means that the window will inherit its
|
||||
* background form its parent window.
|
||||
*
|
||||
* The windowing system will normally fill a window with its background
|
||||
* when the window is obscured then exposed, and when you call
|
||||
* gdk_window_clear().
|
||||
*/
|
||||
void
|
||||
gdk_window_set_back_pixmap (GdkWindow *window,
|
||||
GdkPixmap *pixmap,
|
||||
gboolean parent_relative)
|
||||
gdk_window_set_background_pattern (GdkWindow *window,
|
||||
cairo_pattern_t *pattern)
|
||||
{
|
||||
GdkWindowObject *private;
|
||||
GdkWindowImplIface *impl_iface;
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
g_return_if_fail (pixmap == NULL || !parent_relative);
|
||||
g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
|
||||
|
||||
private = (GdkWindowObject *) window;
|
||||
|
||||
if (pixmap && !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);
|
||||
|
||||
if (pattern)
|
||||
cairo_pattern_reference (pattern);
|
||||
if (private->background)
|
||||
{
|
||||
cairo_pattern_destroy (private->background);
|
||||
private->background = NULL;
|
||||
}
|
||||
cairo_pattern_destroy (private->background);
|
||||
private->background = pattern;
|
||||
|
||||
if (parent_relative)
|
||||
private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
|
||||
else if (pixmap)
|
||||
private->bg_pixmap = g_object_ref (pixmap);
|
||||
else
|
||||
private->bg_pixmap = GDK_NO_BG;
|
||||
|
||||
if (!GDK_WINDOW_DESTROYED (window) &&
|
||||
gdk_window_has_impl (private) &&
|
||||
if (gdk_window_has_impl (private) &&
|
||||
!private->input_only)
|
||||
{
|
||||
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
|
||||
impl_iface->set_back_pixmap (window, private->bg_pixmap);
|
||||
GdkWindowImplIface *impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
|
||||
impl_iface->set_background (window, pattern);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7089,33 +7054,6 @@ gdk_window_get_background_pattern (GdkWindow *window)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
|
||||
|
||||
if (private->background == NULL)
|
||||
{
|
||||
if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG)
|
||||
private->background = NULL;
|
||||
else if (private->bg_pixmap != GDK_NO_BG &&
|
||||
private->bg_pixmap != NULL)
|
||||
{
|
||||
static cairo_user_data_key_t key;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
|
||||
private->background = cairo_pattern_create_for_surface (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
cairo_pattern_set_extend (private->background, CAIRO_EXTEND_REPEAT);
|
||||
cairo_pattern_set_user_data (private->background,
|
||||
&key,
|
||||
g_object_ref (private->bg_pixmap),
|
||||
g_object_unref);
|
||||
}
|
||||
else
|
||||
private->background =
|
||||
cairo_pattern_create_rgb (private->bg_color.red / 65535.,
|
||||
private->bg_color.green / 65535.,
|
||||
private->bg_color.blue / 65535.);
|
||||
}
|
||||
|
||||
return private->background;
|
||||
}
|
||||
|
||||
|
||||
@ -678,6 +678,8 @@ void gdk_window_set_background (GdkWindow *window,
|
||||
void gdk_window_set_back_pixmap (GdkWindow *window,
|
||||
GdkPixmap *pixmap,
|
||||
gboolean parent_relative);
|
||||
void gdk_window_set_background_pattern (GdkWindow *window,
|
||||
cairo_pattern_t *pattern);
|
||||
cairo_pattern_t *gdk_window_get_background_pattern (GdkWindow *window);
|
||||
|
||||
void gdk_window_set_cursor (GdkWindow *window,
|
||||
|
||||
@ -62,9 +62,7 @@ struct _GdkWindowImplIface
|
||||
gint width,
|
||||
gint height);
|
||||
void (* set_background) (GdkWindow *window,
|
||||
const GdkColor *color);
|
||||
void (* set_back_pixmap) (GdkWindow *window,
|
||||
GdkPixmap *pixmap);
|
||||
cairo_pattern_t *pattern);
|
||||
|
||||
GdkEventMask (* get_events) (GdkWindow *window);
|
||||
void (* set_events) (GdkWindow *window,
|
||||
|
||||
@ -228,13 +228,10 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
|
||||
GdkWindowObject *private = (GdkWindowObject*)window;
|
||||
GdkPixmap *bg_pixmap;
|
||||
GdkWindowObject *private = (GdkWindowObject*) window;
|
||||
cairo_region_t *clipped_and_offset_region;
|
||||
cairo_t *cr;
|
||||
|
||||
bg_pixmap = private->bg_pixmap;
|
||||
|
||||
clipped_and_offset_region = cairo_region_copy (region);
|
||||
|
||||
cairo_region_intersect (clipped_and_offset_region,
|
||||
@ -249,8 +246,7 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
|
||||
|
||||
impl->begin_paint_count++;
|
||||
|
||||
if (bg_pixmap == GDK_NO_BG ||
|
||||
cairo_region_is_empty (clipped_and_offset_region))
|
||||
if (cairo_region_is_empty (clipped_and_offset_region))
|
||||
goto done;
|
||||
|
||||
cr = gdk_cairo_create (window);
|
||||
@ -260,40 +256,16 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
|
||||
gdk_cairo_region (cr, clipped_and_offset_region);
|
||||
cairo_clip (cr);
|
||||
|
||||
if (bg_pixmap == NULL)
|
||||
while (private->background == NULL && private->parent)
|
||||
{
|
||||
gdk_cairo_set_source_color (cr, &private->bg_color);
|
||||
cairo_translate (cr, -private->x, private->y);
|
||||
private = private->parent;
|
||||
}
|
||||
|
||||
if (private->background)
|
||||
cairo_set_source (cr, private->background);
|
||||
else
|
||||
{
|
||||
int x_offset, y_offset;
|
||||
|
||||
x_offset = y_offset = 0;
|
||||
|
||||
while (window && bg_pixmap == GDK_PARENT_RELATIVE_BG)
|
||||
{
|
||||
/* If this window should have the same background as the parent,
|
||||
* fetch the parent. (And if the same goes for the parent, fetch
|
||||
* the grandparent, etc.)
|
||||
*/
|
||||
x_offset += ((GdkWindowObject *) window)->x;
|
||||
y_offset += ((GdkWindowObject *) window)->y;
|
||||
window = GDK_WINDOW (((GdkWindowObject *) window)->parent);
|
||||
bg_pixmap = ((GdkWindowObject *) window)->bg_pixmap;
|
||||
}
|
||||
|
||||
/* If we have a parent relative background or we don't have a pixmap,
|
||||
* clear the area to transparent.
|
||||
*/
|
||||
if (bg_pixmap == NULL || bg_pixmap == GDK_NO_BG || bg_pixmap == GDK_PARENT_RELATIVE_BG)
|
||||
{
|
||||
cairo_destroy (cr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
gdk_cairo_set_source_pixmap (cr, bg_pixmap, x_offset, y_offset);
|
||||
cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
|
||||
}
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
||||
|
||||
/* Can use cairo_paint() here, we clipped above */
|
||||
cairo_paint (cr);
|
||||
@ -1648,23 +1620,14 @@ gdk_window_quartz_restack_toplevel (GdkWindow *window,
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_quartz_set_background (GdkWindow *window,
|
||||
const GdkColor *color)
|
||||
gdk_window_quartz_set_background (GdkWindow *window,
|
||||
cairo_pattern_t *pattern)
|
||||
{
|
||||
/* FIXME: We could theoretically set the background color for toplevels
|
||||
* here. (Currently we draw the background before emitting expose events)
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_quartz_set_back_pixmap (GdkWindow *window,
|
||||
GdkPixmap *pixmap)
|
||||
{
|
||||
/* FIXME: Could theoretically set some background image here. (Currently
|
||||
* the back pixmap is drawn before emitting expose events.
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_quartz_set_device_cursor (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
@ -3027,7 +2990,6 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
|
||||
iface->restack_toplevel = gdk_window_quartz_restack_toplevel;
|
||||
iface->move_resize = gdk_window_quartz_move_resize;
|
||||
iface->set_background = gdk_window_quartz_set_background;
|
||||
iface->set_back_pixmap = gdk_window_quartz_set_back_pixmap;
|
||||
iface->reparent = gdk_window_quartz_reparent;
|
||||
iface->set_device_cursor = gdk_window_quartz_set_device_cursor;
|
||||
iface->get_geometry = gdk_window_quartz_get_geometry;
|
||||
|
||||
@ -152,18 +152,6 @@ tmp_unset_bg (GdkWindow *window)
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
|
||||
|
||||
impl->no_bg = TRUE;
|
||||
|
||||
/*
|
||||
* The X version sets background = None to avoid updateing for a moment.
|
||||
* Not sure if this could really emulate it.
|
||||
*/
|
||||
if (obj->bg_pixmap != GDK_NO_BG)
|
||||
{
|
||||
///* handled in WM_ERASEBKGRND proceesing */;
|
||||
|
||||
//HDC hdc = GetDC (GDK_WINDOW_HWND (window));
|
||||
//erase_background (window, hdc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -1790,23 +1790,9 @@ _gdk_modal_current (void)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_window_set_background (GdkWindow *window,
|
||||
const GdkColor *color)
|
||||
gdk_win32_window_set_background (GdkWindow *window,
|
||||
cairo_pattern_t *pattern)
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_win32_window_set_background: %p: %s\n",
|
||||
GDK_WINDOW_HWND (window),
|
||||
_gdk_win32_color_to_string (color)));
|
||||
|
||||
private->bg_color = *color;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_window_set_back_pixmap (GdkWindow *window,
|
||||
GdkPixmap *pixmap)
|
||||
{
|
||||
/* TODO_CSW? but win32 has no XSetWindowBackgroundPixmap */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3365,7 +3351,6 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
|
||||
iface->restack_toplevel = gdk_win32_window_restack_toplevel;
|
||||
iface->move_resize = gdk_win32_window_move_resize;
|
||||
iface->set_background = gdk_win32_window_set_background;
|
||||
iface->set_back_pixmap = gdk_win32_window_set_back_pixmap;
|
||||
iface->reparent = gdk_win32_window_reparent;
|
||||
iface->set_device_cursor = gdk_win32_window_set_device_cursor;
|
||||
iface->get_geometry = gdk_win32_window_get_geometry;
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
|
||||
#include <cairo-xlib.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -106,6 +108,8 @@ static void set_wm_name (GdkDisplay *display,
|
||||
Window xwindow,
|
||||
const gchar *name);
|
||||
static void move_to_current_desktop (GdkWindow *window);
|
||||
static void gdk_window_x11_set_background (GdkWindow *window,
|
||||
cairo_pattern_t *pattern);
|
||||
|
||||
static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable);
|
||||
static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
|
||||
@ -228,9 +232,8 @@ tmp_unset_bg (GdkWindow *window)
|
||||
|
||||
impl->no_bg = TRUE;
|
||||
|
||||
if (obj->bg_pixmap != GDK_NO_BG)
|
||||
XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window), None);
|
||||
XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window), None);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -244,27 +247,7 @@ tmp_reset_bg (GdkWindow *window)
|
||||
|
||||
impl->no_bg = FALSE;
|
||||
|
||||
if (obj->bg_pixmap == GDK_NO_BG)
|
||||
return;
|
||||
|
||||
if (obj->bg_pixmap)
|
||||
{
|
||||
Pixmap xpixmap;
|
||||
|
||||
if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG)
|
||||
xpixmap = ParentRelative;
|
||||
else
|
||||
xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap);
|
||||
|
||||
XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window), xpixmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window),
|
||||
obj->bg_color.pixel);
|
||||
}
|
||||
gdk_window_x11_set_background (window, obj->background);
|
||||
}
|
||||
|
||||
/* Unsetting and resetting window backgrounds.
|
||||
@ -749,7 +732,7 @@ _gdk_window_impl_new (GdkWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
xattributes.background_pixel = private->bg_color.pixel;
|
||||
xattributes.background_pixel = BlackPixel (xdisplay, screen_x11->screen_num);
|
||||
|
||||
xattributes.border_pixel = BlackPixel (xdisplay, screen_x11->screen_num);
|
||||
xattributes_mask |= CWBorderPixel | CWBackPixel;
|
||||
@ -2594,8 +2577,8 @@ gdk_window_set_transient_for (GdkWindow *window,
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_x11_set_background (GdkWindow *window,
|
||||
const GdkColor *color)
|
||||
gdk_window_x11_set_back_color (GdkWindow *window,
|
||||
GdkColor *color)
|
||||
{
|
||||
GdkColor allocated = *color;
|
||||
|
||||
@ -2610,22 +2593,70 @@ gdk_window_x11_set_background (GdkWindow *window,
|
||||
gdk_colormap_free_colors (gdk_drawable_get_colormap (window), &allocated, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_x11_set_back_pixmap (GdkWindow *window,
|
||||
GdkPixmap *pixmap)
|
||||
static gboolean
|
||||
matrix_is_identity (cairo_matrix_t *matrix)
|
||||
{
|
||||
Pixmap xpixmap;
|
||||
return matrix->xx == 1.0 && matrix->yy == 1.0 &&
|
||||
matrix->yx == 0.0 && matrix->xy == 0.0 &&
|
||||
matrix->x0 == 0.0 && matrix->y0 == 0.0;
|
||||
}
|
||||
|
||||
if (pixmap == GDK_PARENT_RELATIVE_BG)
|
||||
xpixmap = ParentRelative;
|
||||
else if (pixmap == GDK_NO_BG)
|
||||
xpixmap = None;
|
||||
else
|
||||
xpixmap = GDK_PIXMAP_XID (pixmap);
|
||||
static void
|
||||
gdk_window_x11_set_background (GdkWindow *window,
|
||||
cairo_pattern_t *pattern)
|
||||
{
|
||||
GdkColor color = { 0, };
|
||||
double r, g, b, a;
|
||||
cairo_surface_t *surface;
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
if (!GDK_WINDOW_DESTROYED (window))
|
||||
XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window), xpixmap);
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
return;
|
||||
|
||||
if (pattern == NULL)
|
||||
{
|
||||
XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window), ParentRelative);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cairo_pattern_get_type (pattern))
|
||||
{
|
||||
case CAIRO_PATTERN_TYPE_SOLID:
|
||||
cairo_pattern_get_rgba (pattern, &r, &g, &b, &a);
|
||||
color.red = r * 65535;
|
||||
color.green = g * 65535;
|
||||
color.blue = b * 65535;
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_SURFACE:
|
||||
cairo_pattern_get_matrix (pattern, &matrix);
|
||||
if (cairo_pattern_get_surface (pattern, &surface) == CAIRO_STATUS_SUCCESS &&
|
||||
matrix_is_identity (&matrix) &&
|
||||
cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB &&
|
||||
cairo_xlib_surface_get_display (surface) == GDK_WINDOW_XDISPLAY (window))
|
||||
{
|
||||
double x, y;
|
||||
|
||||
cairo_surface_get_device_offset (surface, &x, &y);
|
||||
/* XXX: This still bombs for non-pixmaps, but there's no way to
|
||||
* detect we're not a pixmap in Cairo... */
|
||||
if (x == 0.0 && y == 0.0)
|
||||
{
|
||||
XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
cairo_xlib_surface_get_drawable (surface));
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
case CAIRO_PATTERN_TYPE_RADIAL:
|
||||
default:
|
||||
/* fallback: just use black */
|
||||
break;
|
||||
}
|
||||
|
||||
gdk_window_x11_set_back_color (window, &color);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -5452,7 +5483,6 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
|
||||
iface->restack_toplevel = gdk_window_x11_restack_toplevel;
|
||||
iface->move_resize = gdk_window_x11_move_resize;
|
||||
iface->set_background = gdk_window_x11_set_background;
|
||||
iface->set_back_pixmap = gdk_window_x11_set_back_pixmap;
|
||||
iface->reparent = gdk_window_x11_reparent;
|
||||
iface->set_device_cursor = gdk_window_x11_set_device_cursor;
|
||||
iface->get_geometry = gdk_window_x11_get_geometry;
|
||||
|
||||
Reference in New Issue
Block a user