2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
29 #include "gdkdrawable-x11.h"
32 #include "gdkprivate-x11.h"
33 #include "gdkscreen-x11.h"
34 #include "gdkdisplay-x11.h"
36 #include <cairo-xlib.h>
42 static cairo_surface_t *gdk_x11_ref_cairo_surface (GdkDrawable *drawable);
43 static cairo_surface_t *gdk_x11_create_cairo_surface (GdkDrawable *drawable,
47 static const cairo_user_data_key_t gdk_x11_cairo_key;
49 G_DEFINE_TYPE (GdkDrawableImplX11, _gdk_drawable_impl_x11, GDK_TYPE_DRAWABLE)
52 _gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
54 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
56 drawable_class->ref_cairo_surface = gdk_x11_ref_cairo_surface;
57 drawable_class->create_cairo_surface = gdk_x11_create_cairo_surface;
61 _gdk_drawable_impl_x11_init (GdkDrawableImplX11 *impl)
66 * _gdk_x11_drawable_finish:
67 * @drawable: a #GdkDrawableImplX11.
69 * Performs necessary cleanup prior to destroying a window.
72 _gdk_x11_drawable_finish (GdkDrawable *drawable)
74 GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
76 if (impl->cairo_surface)
78 cairo_surface_finish (impl->cairo_surface);
79 cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key,
85 * _gdk_x11_drawable_update_size:
86 * @drawable: a #GdkDrawableImplX11.
88 * Updates the state of the drawable (in particular the drawable's
89 * cairo surface) when its size has changed.
92 _gdk_x11_drawable_update_size (GdkDrawable *drawable)
94 GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
96 if (impl->cairo_surface)
98 cairo_xlib_surface_set_size (impl->cairo_surface,
99 gdk_window_get_width (impl->wrapper),
100 gdk_window_get_height (impl->wrapper));
104 /*****************************************************
105 * X11 specific implementations of generic functions *
106 *****************************************************/
109 get_impl_drawable (GdkDrawable *drawable)
111 if (GDK_IS_WINDOW (drawable))
112 return ((GdkWindowObject *)drawable)->impl;
115 g_warning (G_STRLOC " drawable is not a window");
121 * gdk_x11_drawable_get_xdisplay:
122 * @drawable: a #GdkDrawable.
124 * Returns the display of a #GdkDrawable.
126 * Return value: an Xlib <type>Display*</type>.
129 gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable)
131 if (GDK_IS_DRAWABLE_IMPL_X11 (drawable))
132 return GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (drawable)->screen);
134 return GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (get_impl_drawable (drawable))->screen);
138 * gdk_x11_drawable_get_xid:
139 * @drawable: a #GdkDrawable.
141 * Returns the X resource (window) belonging to a #GdkDrawable.
143 * Return value: the ID of @drawable's X resource.
146 gdk_x11_drawable_get_xid (GdkDrawable *drawable)
150 if (GDK_IS_WINDOW (drawable))
152 GdkWindow *window = (GdkWindow *)drawable;
154 /* Try to ensure the window has a native window */
155 if (!_gdk_window_has_impl (window))
157 gdk_window_ensure_native (window);
159 /* We sync here to ensure the window is created in the Xserver when
160 * this function returns. This is required because the returned XID
161 * for this window must be valid immediately, even with another
162 * connection to the Xserver */
163 gdk_display_sync (gdk_window_get_display (window));
166 if (!GDK_WINDOW_IS_X11 (window))
168 g_warning (G_STRLOC " drawable is not a native X11 window");
172 impl = ((GdkWindowObject *)drawable)->impl;
176 g_warning (G_STRLOC " drawable is not a window");
180 return ((GdkDrawableImplX11 *)impl)->xid;
184 gdk_x11_window_get_drawable_impl (GdkWindow *window)
186 return ((GdkWindowObject *)window)->impl;
190 gdk_x11_cairo_surface_destroy (void *data)
192 GdkDrawableImplX11 *impl = data;
194 impl->cairo_surface = NULL;
197 static cairo_surface_t *
198 gdk_x11_create_cairo_surface (GdkDrawable *drawable,
202 GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
205 visual = gdk_window_get_visual (impl->wrapper);
206 return cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (impl->screen),
208 GDK_VISUAL_XVISUAL (visual),
212 static cairo_surface_t *
213 gdk_x11_ref_cairo_surface (GdkDrawable *drawable)
215 GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
217 if (GDK_IS_WINDOW_IMPL_X11 (drawable) &&
218 GDK_WINDOW_DESTROYED (impl->wrapper))
221 if (!impl->cairo_surface)
223 impl->cairo_surface = gdk_x11_create_cairo_surface (drawable,
224 gdk_window_get_width (impl->wrapper),
225 gdk_window_get_height (impl->wrapper));
227 if (impl->cairo_surface)
228 cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key,
229 drawable, gdk_x11_cairo_surface_destroy);
232 cairo_surface_reference (impl->cairo_surface);
234 return impl->cairo_surface;