5
#include <glib-object.h>
10
#include <X11/extensions/shape.h>
12
G_DEFINE_TYPE (WsWindow, ws_window, WS_TYPE_DRAWABLE);
14
static WsFormat ws_window_get_format (WsDrawable *drawable);
17
ws_window_finalize (GObject *object)
19
G_OBJECT_CLASS (ws_window_parent_class)->finalize (object);
23
ws_window_class_init (WsWindowClass *class)
25
GObjectClass *object_class = G_OBJECT_CLASS (class);
26
WsDrawableClass *drawable_class = WS_DRAWABLE_CLASS (class);
28
object_class->finalize = ws_window_finalize;
29
drawable_class->get_format = ws_window_get_format;
33
ws_window_init (WsWindow *window)
39
ws_window_get_format (WsDrawable *drawable)
41
XWindowAttributes attrs;
43
Display *xdisplay = WS_RESOURCE_XDISPLAY (drawable);
44
Window xwindow = WS_RESOURCE_XID (drawable);
46
if (!XGetWindowAttributes (xdisplay, xwindow, &attrs))
47
return WS_FORMAT_UNKNOWN;
49
if (attrs.class == InputOnly)
51
return WS_FORMAT_INPUT_ONLY;
53
else if (attrs.depth == 16 &&
54
attrs.visual->red_mask == 0xf800 &&
55
attrs.visual->green_mask == 0x7e0 &&
56
attrs.visual->blue_mask == 0x1f)
58
return WS_FORMAT_RGB_16;
60
else if (attrs.depth == 24 &&
61
attrs.visual->red_mask == 0xff0000 &&
62
attrs.visual->green_mask == 0xff00 &&
63
attrs.visual->blue_mask == 0xff)
65
return WS_FORMAT_RGB_24;
67
else if (attrs.depth == 32 &&
68
attrs.visual->red_mask == 0xff0000 &&
69
attrs.visual->green_mask == 0xff00 &&
70
attrs.visual->blue_mask == 0xff)
72
return WS_FORMAT_ARGB_32;
76
g_warning ("Unknown visual format depth=%d, r=%#lx/g=%#lx/b=%#lx",
77
attrs.depth, attrs.visual->red_mask,
78
attrs.visual->green_mask, attrs.visual->blue_mask);
80
return WS_FORMAT_UNKNOWN;
85
window_new (WsDisplay *display,
88
g_assert (!g_hash_table_lookup (display->xresources, (gpointer)xwindow));
90
WsWindow *window = g_object_new (WS_TYPE_WINDOW,
95
g_assert (xwindow == WS_RESOURCE_XID (window));
97
ws_display_begin_error_trap (display);
99
XSelectInput (display->xdisplay, xwindow,
100
StructureNotifyMask);
102
ws_display_end_error_trap (display);
108
_ws_window_ensure (WsDisplay *display,
116
window = g_hash_table_lookup (display->xresources, (gpointer)xwindow);
119
window = window_new (display, xwindow);
125
ws_window_set_input_shape (WsWindow *window,
128
Display *xdisplay = WS_RESOURCE_XDISPLAY (window);
130
XFixesSetWindowShapeRegion (xdisplay,
131
WS_RESOURCE_XID (window),
133
0, 0, WS_RESOURCE_XID (shape));
136
/* Create a window and make it the active GL window
137
* The right way forward here is most likely to have a new
138
* subclass "GlWindow" with methods
140
* begin() // make it active if it isn't
146
ws_window_redirect_subwindows (WsWindow *window)
148
g_return_if_fail (WS_RESOURCE (window)->display->composite.available);
150
XCompositeRedirectSubwindows (
151
WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window),
152
CompositeRedirectManual);
156
ws_window_unredirect_subwindows (WsWindow *window)
158
g_return_if_fail (WS_RESOURCE (window)->display->composite.available);
160
XCompositeUnredirectSubwindows (
161
WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window),
162
CompositeRedirectManual);
166
ws_window_map (WsWindow *window)
170
g_return_if_fail (window != NULL);
172
xdisplay = WS_RESOURCE_XDISPLAY (window);
174
XMapWindow (xdisplay, WS_RESOURCE_XID (window));
178
ws_window_unmap (WsWindow *window)
182
g_return_if_fail (window != NULL);
184
XUnmapWindow (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window));
188
ws_window_raise (WsWindow *window)
190
g_return_if_fail (window != NULL);
192
XRaiseWindow (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window));
196
ws_window_lower (WsWindow *window)
198
g_return_if_fail (window != NULL);
200
XLowerWindow (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window));
204
ws_window_gl_swap_buffers (WsWindow *window)
206
glXSwapBuffers (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window));
210
ws_window_unredirect (WsWindow *window)
212
XCompositeUnredirectWindow (
213
WS_RESOURCE_XDISPLAY (window),
214
WS_RESOURCE_XID (window), CompositeRedirectManual);
218
ws_window_set_override_redirect (WsWindow *window, gboolean override_redirect)
220
XSetWindowAttributes attrs;
222
attrs.override_redirect = !!override_redirect;
224
XChangeWindowAttributes (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window),
225
CWOverrideRedirect, &attrs);
229
ws_window_query_input_only (WsWindow *window)
231
XWindowAttributes attrs;
233
if (!XGetWindowAttributes (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window), &attrs))
236
return attrs.class == InputOnly;
240
ws_window_query_mapped (WsWindow *window)
242
XWindowAttributes attrs;
244
if (!XGetWindowAttributes (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window), &attrs))
247
return attrs.map_state == IsUnviewable || attrs.map_state == IsViewable;
251
ws_window_query_viewable (WsWindow *window)
253
XWindowAttributes attrs;
255
if (!XGetWindowAttributes (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window), &attrs))
258
return attrs.map_state == IsViewable;
262
ws_window_query_subwindows (WsWindow *window)
264
Window root, parent; /* dummies */
268
GList *result = NULL;
270
if (XQueryTree (WS_RESOURCE_XDISPLAY (window),
271
WS_RESOURCE_XID (window), &root, &parent,
272
&children, &n_children))
274
for (i = 0; i < n_children; ++i)
276
WsWindow *child = _ws_window_ensure (WS_RESOURCE (window)->display,
279
result = g_list_prepend (result, child);
288
/* FIXME: This function just uses XFetchName - it should do the
289
* _NET_WM stuff. If this function should exist at all, which maybe it
294
ws_window_query_title (WsWindow *window)
299
if (XFetchName (WS_RESOURCE_XDISPLAY (window),
300
WS_RESOURCE_XID (window), &name))
302
result = g_strdup (name);
307
result = g_strdup ("No title");
314
ws_window_lookup (WsDisplay *display,
317
return _ws_window_ensure (display, xwindow);
322
ws_window_name_pixmap (WsWindow *window)
324
Pixmap xpixmap = XCompositeNameWindowPixmap (WS_RESOURCE_XDISPLAY (window),
325
WS_RESOURCE_XID (window));
327
return _ws_pixmap_ensure (WS_RESOURCE (window)->display,
329
ws_drawable_get_format (WS_DRAWABLE (window)));
333
ws_window_set_configure_callback (WsWindow *window,
334
WsConfigureCallback cb,
337
window->configure_callback = cb;
338
window->configure_data = data;
342
_ws_window_process_event (WsWindow *window,
345
if (xevent->type == ConfigureNotify)
347
XConfigureEvent *configure = &xevent->xconfigure;
350
above = _ws_window_ensure (WS_RESOURCE (window)->display,
353
if (window->configure_callback)
355
window->configure_callback (window,
356
configure->x, configure->y,
357
configure->width, configure->height,
358
configure->border_width,
360
configure->override_redirect,
361
window->configure_data);