~ubuntu-branches/ubuntu/hardy/libcm/hardy

« back to all changes in this revision

Viewing changes to src/wswindow.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-17 14:28:18 UTC
  • Revision ID: james.westby@ubuntu.com-20060217142818-1ho3qr7jbh2m400r
Tags: upstream-0.0.16
ImportĀ upstreamĀ versionĀ 0.0.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <GL/gl.h>
 
2
#include <GL/glu.h>
 
3
#include <GL/glx.h>
 
4
 
 
5
#include <glib-object.h>
 
6
 
 
7
#include "ws.h"
 
8
#include "wsint.h"
 
9
 
 
10
#include <X11/extensions/shape.h>
 
11
 
 
12
G_DEFINE_TYPE (WsWindow, ws_window, WS_TYPE_DRAWABLE);
 
13
 
 
14
static WsFormat ws_window_get_format (WsDrawable *drawable);
 
15
 
 
16
static void
 
17
ws_window_finalize (GObject *object)
 
18
{
 
19
    G_OBJECT_CLASS (ws_window_parent_class)->finalize (object);
 
20
}
 
21
 
 
22
static void
 
23
ws_window_class_init (WsWindowClass *class)
 
24
{
 
25
    GObjectClass *object_class = G_OBJECT_CLASS (class);
 
26
    WsDrawableClass *drawable_class = WS_DRAWABLE_CLASS (class);
 
27
    
 
28
    object_class->finalize = ws_window_finalize;
 
29
    drawable_class->get_format = ws_window_get_format;
 
30
}
 
31
 
 
32
static void
 
33
ws_window_init (WsWindow *window)
 
34
{
 
35
    
 
36
}
 
37
 
 
38
static WsFormat
 
39
ws_window_get_format (WsDrawable *drawable)
 
40
{
 
41
    XWindowAttributes attrs;
 
42
 
 
43
    Display *xdisplay = WS_RESOURCE_XDISPLAY (drawable);
 
44
    Window xwindow = WS_RESOURCE_XID (drawable);
 
45
    
 
46
    if (!XGetWindowAttributes (xdisplay, xwindow, &attrs))
 
47
        return WS_FORMAT_UNKNOWN;
 
48
 
 
49
    if (attrs.class == InputOnly)
 
50
    {
 
51
        return WS_FORMAT_INPUT_ONLY;
 
52
    }
 
53
    else if (attrs.depth == 16 &&
 
54
             attrs.visual->red_mask == 0xf800 &&
 
55
             attrs.visual->green_mask == 0x7e0 &&
 
56
             attrs.visual->blue_mask == 0x1f)
 
57
    {
 
58
        return WS_FORMAT_RGB_16;
 
59
    }
 
60
    else if (attrs.depth == 24 &&
 
61
             attrs.visual->red_mask == 0xff0000 &&
 
62
             attrs.visual->green_mask == 0xff00 &&
 
63
             attrs.visual->blue_mask == 0xff)
 
64
    {
 
65
        return WS_FORMAT_RGB_24;
 
66
    }
 
67
    else if (attrs.depth == 32 &&
 
68
             attrs.visual->red_mask == 0xff0000 &&
 
69
             attrs.visual->green_mask == 0xff00 &&
 
70
             attrs.visual->blue_mask == 0xff)
 
71
    {
 
72
        return WS_FORMAT_ARGB_32;
 
73
    }
 
74
    else
 
75
    {
 
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);
 
79
 
 
80
        return WS_FORMAT_UNKNOWN;
 
81
    }
 
82
}
 
83
 
 
84
static WsWindow *
 
85
window_new (WsDisplay *display,
 
86
            Window xwindow)
 
87
{
 
88
    g_assert (!g_hash_table_lookup (display->xresources, (gpointer)xwindow));
 
89
    
 
90
    WsWindow *window = g_object_new (WS_TYPE_WINDOW,
 
91
                                     "display", display,
 
92
                                     "xid", xwindow,
 
93
                                     NULL);
 
94
 
 
95
    g_assert (xwindow == WS_RESOURCE_XID (window));
 
96
    
 
97
    ws_display_begin_error_trap (display);
 
98
    
 
99
    XSelectInput (display->xdisplay, xwindow,
 
100
                  StructureNotifyMask);
 
101
 
 
102
    ws_display_end_error_trap (display);
 
103
    
 
104
    return window;
 
105
}
 
106
 
 
107
WsWindow *
 
108
_ws_window_ensure (WsDisplay *display,
 
109
                   Window  xwindow)
 
110
{
 
111
    WsWindow *window;
 
112
 
 
113
    if (!xwindow)
 
114
        return NULL;
 
115
 
 
116
    window = g_hash_table_lookup (display->xresources, (gpointer)xwindow);
 
117
    
 
118
    if (!window)
 
119
        window = window_new (display, xwindow);
 
120
 
 
121
    return window;
 
122
}
 
123
 
 
124
void
 
125
ws_window_set_input_shape         (WsWindow    *window,
 
126
                                   WsRegion    *shape)
 
127
{
 
128
    Display *xdisplay = WS_RESOURCE_XDISPLAY (window);
 
129
    
 
130
    XFixesSetWindowShapeRegion (xdisplay,
 
131
                                WS_RESOURCE_XID (window),
 
132
                                ShapeInput,
 
133
                                0, 0, WS_RESOURCE_XID (shape));
 
134
}
 
135
 
 
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
 
139
 *
 
140
 *         begin()                              // make it active if it isn't
 
141
 *         end()                                // 
 
142
 *         swap_buffers();                      // 
 
143
 *
 
144
 */
 
145
void
 
146
ws_window_redirect_subwindows (WsWindow *window)
 
147
{
 
148
    g_return_if_fail (WS_RESOURCE (window)->display->composite.available);
 
149
    
 
150
    XCompositeRedirectSubwindows (
 
151
        WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window),
 
152
        CompositeRedirectManual);
 
153
}
 
154
 
 
155
void
 
156
ws_window_unredirect_subwindows (WsWindow *window)
 
157
{
 
158
    g_return_if_fail (WS_RESOURCE (window)->display->composite.available);
 
159
 
 
160
    XCompositeUnredirectSubwindows (
 
161
        WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window),
 
162
        CompositeRedirectManual);
 
163
}
 
164
 
 
165
void
 
166
ws_window_map (WsWindow *window)
 
167
{
 
168
    Display *xdisplay;
 
169
    
 
170
    g_return_if_fail (window != NULL);
 
171
    
 
172
    xdisplay = WS_RESOURCE_XDISPLAY (window);
 
173
    
 
174
    XMapWindow (xdisplay, WS_RESOURCE_XID (window));
 
175
}
 
176
 
 
177
void
 
178
ws_window_unmap (WsWindow *window)
 
179
{
 
180
    Display *xdisplay;
 
181
 
 
182
    g_return_if_fail (window != NULL);
 
183
 
 
184
    XUnmapWindow (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window));
 
185
}
 
186
 
 
187
void
 
188
ws_window_raise (WsWindow *window)
 
189
{
 
190
    g_return_if_fail (window != NULL);
 
191
    
 
192
    XRaiseWindow (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window));
 
193
}
 
194
 
 
195
void
 
196
ws_window_lower (WsWindow *window)
 
197
{
 
198
    g_return_if_fail (window != NULL);
 
199
 
 
200
    XLowerWindow (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window));
 
201
}
 
202
 
 
203
void
 
204
ws_window_gl_swap_buffers (WsWindow *window)
 
205
{
 
206
    glXSwapBuffers (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window));
 
207
}
 
208
 
 
209
void
 
210
ws_window_unredirect (WsWindow *window)
 
211
{
 
212
    XCompositeUnredirectWindow (
 
213
        WS_RESOURCE_XDISPLAY (window),
 
214
        WS_RESOURCE_XID (window), CompositeRedirectManual);
 
215
}
 
216
 
 
217
void
 
218
ws_window_set_override_redirect (WsWindow *window, gboolean override_redirect)
 
219
{
 
220
    XSetWindowAttributes attrs;
 
221
    
 
222
    attrs.override_redirect = !!override_redirect;
 
223
    
 
224
    XChangeWindowAttributes (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window),
 
225
                             CWOverrideRedirect, &attrs);
 
226
}
 
227
 
 
228
gboolean
 
229
ws_window_query_input_only (WsWindow *window)
 
230
{
 
231
    XWindowAttributes attrs;
 
232
 
 
233
    if (!XGetWindowAttributes (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window), &attrs))
 
234
        return FALSE;
 
235
 
 
236
    return attrs.class == InputOnly;
 
237
}
 
238
 
 
239
gboolean
 
240
ws_window_query_mapped (WsWindow *window)
 
241
{
 
242
    XWindowAttributes attrs;
 
243
 
 
244
    if (!XGetWindowAttributes (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window), &attrs))
 
245
        return FALSE;
 
246
 
 
247
    return attrs.map_state == IsUnviewable || attrs.map_state == IsViewable;
 
248
}
 
249
 
 
250
gboolean
 
251
ws_window_query_viewable (WsWindow *window)
 
252
{
 
253
    XWindowAttributes attrs;
 
254
 
 
255
    if (!XGetWindowAttributes (WS_RESOURCE_XDISPLAY (window), WS_RESOURCE_XID (window), &attrs))
 
256
        return FALSE;
 
257
 
 
258
    return attrs.map_state == IsViewable;
 
259
}
 
260
 
 
261
GList *
 
262
ws_window_query_subwindows (WsWindow *window)
 
263
{
 
264
    Window root, parent;                /* dummies */
 
265
    Window *children;
 
266
    guint n_children;
 
267
    int i;
 
268
    GList *result = NULL;
 
269
    
 
270
    if (XQueryTree (WS_RESOURCE_XDISPLAY (window),
 
271
                    WS_RESOURCE_XID (window), &root, &parent,
 
272
                    &children, &n_children))
 
273
    {
 
274
        for (i = 0; i < n_children; ++i)
 
275
        {
 
276
            WsWindow *child = _ws_window_ensure (WS_RESOURCE (window)->display,
 
277
                                                 children[i]);
 
278
            
 
279
            result = g_list_prepend (result, child);
 
280
        }
 
281
 
 
282
        XFree (children);
 
283
    }
 
284
    
 
285
    return result;
 
286
}
 
287
 
 
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
 
290
 * shouldn't
 
291
 */
 
292
 
 
293
gchar *
 
294
ws_window_query_title (WsWindow *window)
 
295
{
 
296
    char *result = NULL;
 
297
    char *name;
 
298
    
 
299
    if (XFetchName (WS_RESOURCE_XDISPLAY (window),
 
300
                    WS_RESOURCE_XID (window), &name))
 
301
    {
 
302
        result = g_strdup (name);
 
303
        XFree (name);
 
304
    }
 
305
    else
 
306
    {
 
307
        result = g_strdup ("No title");
 
308
    }
 
309
 
 
310
    return result;
 
311
}
 
312
 
 
313
WsWindow *
 
314
ws_window_lookup (WsDisplay *display,
 
315
                  Window     xwindow)
 
316
{
 
317
    return _ws_window_ensure (display, xwindow);
 
318
}
 
319
 
 
320
 
 
321
WsPixmap *
 
322
ws_window_name_pixmap (WsWindow *window)
 
323
{
 
324
    Pixmap xpixmap = XCompositeNameWindowPixmap (WS_RESOURCE_XDISPLAY (window),
 
325
                                                WS_RESOURCE_XID (window));
 
326
 
 
327
    return _ws_pixmap_ensure (WS_RESOURCE (window)->display,
 
328
                              xpixmap,
 
329
                              ws_drawable_get_format (WS_DRAWABLE (window)));
 
330
}
 
331
 
 
332
void
 
333
ws_window_set_configure_callback (WsWindow   *window,
 
334
                                  WsConfigureCallback cb,
 
335
                                  gpointer      data)
 
336
{
 
337
    window->configure_callback = cb;
 
338
    window->configure_data = data;
 
339
}
 
340
 
 
341
void
 
342
_ws_window_process_event (WsWindow   *window,
 
343
                          XEvent     *xevent)
 
344
{
 
345
    if (xevent->type == ConfigureNotify)
 
346
    {
 
347
        XConfigureEvent *configure = &xevent->xconfigure;
 
348
        WsWindow *above;
 
349
 
 
350
        above = _ws_window_ensure (WS_RESOURCE (window)->display,
 
351
                                   configure->above);
 
352
        
 
353
        if (window->configure_callback)
 
354
        {
 
355
            window->configure_callback (window,
 
356
                                        configure->x, configure->y,
 
357
                                        configure->width, configure->height,
 
358
                                        configure->border_width,
 
359
                                        above,
 
360
                                        configure->override_redirect,
 
361
                                        window->configure_data);
 
362
        }
 
363
    }
 
364
}