~ubuntu-branches/ubuntu/oneiric/cairo-dock/oneiric

« back to all changes in this revision

Viewing changes to src/gldit/cairo-dock-X-utilities.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mto: (18.1.1 cairo-dock) (19.1.1 cairo-dock)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20100809232612-pocdxliaxjdetm37
Tags: upstream-2.2.0~0beta4
ImportĀ upstreamĀ versionĀ 2.2.0~0beta4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
#include <math.h>
 
21
#include <string.h>
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
#include <signal.h>
 
25
 
 
26
#include <gdk/gdkx.h>
 
27
#include <X11/Xlib.h>
 
28
#include <X11/Xatom.h>
 
29
#include <X11/Xutil.h>
 
30
#include "../config.h"
 
31
#ifdef HAVE_XEXTEND
 
32
#include <X11/extensions/Xcomposite.h>
 
33
//#include <X11/extensions/Xdamage.h>
 
34
#include <X11/extensions/XTest.h>
 
35
#include <X11/extensions/Xinerama.h>
 
36
#include <X11/extensions/shape.h>
 
37
#endif
 
38
 
 
39
#include "cairo-dock-log.h"
 
40
#include "cairo-dock-X-manager.h"
 
41
#include "cairo-dock-X-utilities.h"
 
42
 
 
43
extern CairoDockDesktopGeometry g_desktopGeometry;
 
44
 
 
45
static gboolean s_bUseXComposite = TRUE;
 
46
static gboolean s_bUseXTest = TRUE;
 
47
static gboolean s_bUseXinerama = TRUE;
 
48
//extern int g_iDamageEvent;
 
49
 
 
50
static Display *s_XDisplay = NULL;
 
51
// Atoms pour le bureau
 
52
static Atom s_aNetWmWindowType;
 
53
static Atom s_aNetWmWindowTypeNormal;
 
54
static Atom s_aNetWmWindowTypeUtility;
 
55
static Atom s_aNetWmWindowTypeDock;
 
56
static Atom s_aNetWmIconGeometry;
 
57
static Atom s_aNetCurrentDesktop;
 
58
static Atom s_aNetDesktopViewport;
 
59
static Atom s_aNetDesktopGeometry;
 
60
static Atom s_aNetNbDesktops;
 
61
static Atom s_aRootMapID;
 
62
// Atoms pour les fenetres
 
63
static Atom s_aNetClientList;  // z-order
 
64
static Atom s_aNetClientListStacking;  // age-order
 
65
static Atom s_aNetActiveWindow;
 
66
static Atom s_aNetWmState;
 
67
static Atom s_aNetWmSticky;
 
68
static Atom s_aNetWmBelow;
 
69
static Atom s_aNetWmAbove;
 
70
static Atom s_aNetWmHidden;
 
71
static Atom s_aNetWmFullScreen;
 
72
static Atom s_aNetWmSkipTaskbar;
 
73
static Atom s_aNetWmMaximizedHoriz;
 
74
static Atom s_aNetWmMaximizedVert;
 
75
static Atom s_aNetWmDemandsAttention;
 
76
static Atom s_aNetWmDesktop;
 
77
static Atom s_aNetWmName;
 
78
static Atom s_aWmName;
 
79
static Atom s_aUtf8String;
 
80
static Atom s_aString;
 
81
 
 
82
static int _cairo_dock_xerror_handler (Display * pDisplay, XErrorEvent *pXError)
 
83
{
 
84
        cd_debug ("Error (%d, %d, %d) during an X request on %d", pXError->error_code, pXError->request_code, pXError->minor_code, pXError->resourceid);
 
85
        return 0;
 
86
}
 
87
Display *cairo_dock_initialize_X_desktop_support (void)
 
88
{
 
89
        if (s_XDisplay != NULL)
 
90
                return s_XDisplay;
 
91
        s_XDisplay = XOpenDisplay (0);
 
92
        g_return_val_if_fail (s_XDisplay != NULL, NULL);
 
93
        
 
94
        XSetErrorHandler (_cairo_dock_xerror_handler);
 
95
        
 
96
        cairo_dock_support_X_extension ();
 
97
        
 
98
        s_aNetWmWindowType              = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE", False);
 
99
        s_aNetWmWindowTypeNormal        = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False);
 
100
        s_aNetWmWindowTypeUtility       = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_UTILITY", False);
 
101
        s_aNetWmWindowTypeDock          = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
 
102
        s_aNetWmIconGeometry            = XInternAtom (s_XDisplay, "_NET_WM_ICON_GEOMETRY", False);
 
103
        s_aNetCurrentDesktop            = XInternAtom (s_XDisplay, "_NET_CURRENT_DESKTOP", False);
 
104
        s_aNetDesktopViewport           = XInternAtom (s_XDisplay, "_NET_DESKTOP_VIEWPORT", False);
 
105
        s_aNetDesktopGeometry           = XInternAtom (s_XDisplay, "_NET_DESKTOP_GEOMETRY", False);
 
106
        s_aNetNbDesktops                        = XInternAtom (s_XDisplay, "_NET_NUMBER_OF_DESKTOPS", False);
 
107
        s_aRootMapID                    = XInternAtom (s_XDisplay, "_XROOTPMAP_ID", False);
 
108
        
 
109
        s_aNetClientListStacking        = XInternAtom (s_XDisplay, "_NET_CLIENT_LIST_STACKING", False);
 
110
        s_aNetClientList                        = XInternAtom (s_XDisplay, "_NET_CLIENT_LIST", False);
 
111
        s_aNetActiveWindow              = XInternAtom (s_XDisplay, "_NET_ACTIVE_WINDOW", False);
 
112
        s_aNetWmState                   = XInternAtom (s_XDisplay, "_NET_WM_STATE", False);
 
113
        s_aNetWmFullScreen              = XInternAtom (s_XDisplay, "_NET_WM_STATE_FULLSCREEN", False);
 
114
        s_aNetWmAbove                   = XInternAtom (s_XDisplay, "_NET_WM_STATE_ABOVE", False);
 
115
        s_aNetWmBelow                   = XInternAtom (s_XDisplay, "_NET_WM_STATE_BELOW", False);
 
116
        s_aNetWmSticky                  = XInternAtom (s_XDisplay, "_NET_WM_STATE_STICKY", False);
 
117
        s_aNetWmHidden                  = XInternAtom (s_XDisplay, "_NET_WM_STATE_HIDDEN", False);
 
118
        s_aNetWmSkipTaskbar             = XInternAtom (s_XDisplay, "_NET_WM_STATE_SKIP_TASKBAR", False);
 
119
        s_aNetWmMaximizedHoriz          = XInternAtom (s_XDisplay, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
 
120
        s_aNetWmMaximizedVert           = XInternAtom (s_XDisplay, "_NET_WM_STATE_MAXIMIZED_VERT", False);
 
121
        s_aNetWmDemandsAttention        = XInternAtom (s_XDisplay, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
 
122
        s_aNetWmDesktop                 = XInternAtom (s_XDisplay, "_NET_WM_DESKTOP", False);
 
123
        s_aNetWmName                    = XInternAtom (s_XDisplay, "_NET_WM_NAME", False);
 
124
        s_aWmName                               = XInternAtom (s_XDisplay, "WM_NAME", False);
 
125
        s_aUtf8String                   = XInternAtom (s_XDisplay, "UTF8_STRING", False);
 
126
        s_aString                               = XInternAtom (s_XDisplay, "STRING", False);
 
127
        
 
128
        Screen *XScreen = XDefaultScreenOfDisplay (s_XDisplay);
 
129
        g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] = WidthOfScreen (XScreen);
 
130
        g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] = HeightOfScreen (XScreen);
 
131
        g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
132
        g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
133
        
 
134
        g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL] = WidthOfScreen (XScreen);
 
135
        g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL] = HeightOfScreen (XScreen);
 
136
        g_desktopGeometry.iScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
137
        g_desktopGeometry.iScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
138
        
 
139
        return s_XDisplay;
 
140
}
 
141
 
 
142
Display *cairo_dock_get_Xdisplay (void)
 
143
{
 
144
        return s_XDisplay;
 
145
}
 
146
 
 
147
guint cairo_dock_get_root_id (void)
 
148
{
 
149
        return DefaultRootWindow (s_XDisplay);
 
150
}
 
151
 
 
152
 
 
153
gboolean cairo_dock_update_screen_geometry (void)
 
154
{
 
155
        Window root = DefaultRootWindow (s_XDisplay);
 
156
        Window root_return;
 
157
        int x_return=1, y_return=1;
 
158
        unsigned int width_return, height_return, border_width_return, depth_return;
 
159
        XGetGeometry (s_XDisplay, root,
 
160
                &root_return,
 
161
                &x_return, &y_return,
 
162
                &width_return, &height_return,
 
163
                &border_width_return, &depth_return);
 
164
        if ((int)width_return != g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] || (int)height_return != g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL])  // on n'utilise pas WidthOfScreen() et HeightOfScreen() car leurs valeurs ne sont pas mises a jour immediatement apres les changements de resolution.
 
165
        {
 
166
                g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] = width_return;
 
167
                g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] = height_return;
 
168
                g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
169
                g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
170
                
 
171
                g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL] = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
172
                g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL] = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
173
                g_desktopGeometry.iScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
174
                g_desktopGeometry.iScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL];  // si on utilise Xinerama, on mettra les valeurs correctes plus tard.
 
175
                
 
176
                cd_message ("new screen size : %dx%d\n", g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL], g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL]);
 
177
                return TRUE;
 
178
        }
 
179
        else
 
180
                return FALSE;
 
181
        /*Atom aNetWorkArea = XInternAtom (s_XDisplay, "_NET_WORKAREA", False);
 
182
        iBufferNbElements = 0;
 
183
        gulong *pXWorkArea = NULL;
 
184
        XGetWindowProperty (s_XDisplay, root, aNetWorkArea, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXWorkArea);
 
185
        int i;
 
186
        for (i = 0; i < iBufferNbElements/4; i ++)
 
187
        {
 
188
                cd_message ("work area : (%d;%d) %dx%d\n", pXWorkArea[4*i], pXWorkArea[4*i+1], pXWorkArea[4*i+2], pXWorkArea[4*i+3]);
 
189
        }
 
190
        XFree (pXWorkArea);*/
 
191
}
 
192
 
 
193
 
 
194
gboolean cairo_dock_property_is_present_on_root (const gchar *cPropertyName)
 
195
{
 
196
        g_return_val_if_fail (s_XDisplay != NULL, FALSE);
 
197
        Atom atom = XInternAtom (s_XDisplay, cPropertyName, False);
 
198
        Window root = DefaultRootWindow (s_XDisplay);
 
199
        int iNbProperties;
 
200
        Atom *pAtomList = XListProperties (s_XDisplay, root, &iNbProperties);
 
201
        int i;
 
202
        for (i = 0; i < iNbProperties; i ++)
 
203
        {
 
204
                if (pAtomList[i] == atom)
 
205
                        break;
 
206
        }
 
207
        XFree (pAtomList);
 
208
        return (i != iNbProperties);
 
209
}
 
210
 
 
211
 
 
212
int cairo_dock_get_current_desktop (void)
 
213
{
 
214
        Window root = DefaultRootWindow (s_XDisplay);
 
215
        Atom aReturnedType = 0;
 
216
        int aReturnedFormat = 0;
 
217
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
218
        gulong *pXDesktopNumberBuffer = NULL;
 
219
        XGetWindowProperty (s_XDisplay, root, s_aNetCurrentDesktop, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXDesktopNumberBuffer);
 
220
 
 
221
        int iDesktopNumber;
 
222
        if (iBufferNbElements > 0)
 
223
                iDesktopNumber = *pXDesktopNumberBuffer;
 
224
        else
 
225
                iDesktopNumber = 0;
 
226
        
 
227
        XFree (pXDesktopNumberBuffer);
 
228
        return iDesktopNumber;
 
229
}
 
230
 
 
231
void cairo_dock_get_current_viewport (int *iCurrentViewPortX, int *iCurrentViewPortY)
 
232
{
 
233
        Window root = DefaultRootWindow (s_XDisplay);
 
234
        
 
235
        Window root_return;
 
236
        int x_return=1, y_return=1;
 
237
        unsigned int width_return, height_return, border_width_return, depth_return;
 
238
        XGetGeometry (s_XDisplay, root,
 
239
                &root_return,
 
240
                &x_return, &y_return,
 
241
                &width_return, &height_return,
 
242
                &border_width_return, &depth_return);
 
243
        *iCurrentViewPortX = x_return;
 
244
        *iCurrentViewPortY = y_return;
 
245
        
 
246
        Atom aReturnedType = 0;
 
247
        int aReturnedFormat = 0;
 
248
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
249
        gulong *pViewportsXY = NULL;
 
250
        XGetWindowProperty (s_XDisplay, root, s_aNetDesktopViewport, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pViewportsXY);
 
251
        if (iBufferNbElements > 0)
 
252
        {
 
253
                *iCurrentViewPortX = pViewportsXY[0];
 
254
                *iCurrentViewPortY = pViewportsXY[1];
 
255
                XFree (pViewportsXY);
 
256
        }
 
257
        
 
258
}
 
259
 
 
260
int cairo_dock_get_nb_desktops (void)
 
261
{
 
262
        Window root = DefaultRootWindow (s_XDisplay);
 
263
        Atom aReturnedType = 0;
 
264
        int aReturnedFormat = 0;
 
265
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
266
        gulong *pXDesktopNumberBuffer = NULL;
 
267
        XGetWindowProperty (s_XDisplay, root, s_aNetNbDesktops, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXDesktopNumberBuffer);
 
268
        
 
269
        int iNumberOfDesktops;
 
270
        if (iBufferNbElements > 0)
 
271
                iNumberOfDesktops = *pXDesktopNumberBuffer;
 
272
        else
 
273
                iNumberOfDesktops = 0;
 
274
        
 
275
        return iNumberOfDesktops;
 
276
}
 
277
 
 
278
void cairo_dock_get_nb_viewports (int *iNbViewportX, int *iNbViewportY)
 
279
{
 
280
        Window root = DefaultRootWindow (s_XDisplay);
 
281
        Atom aReturnedType = 0;
 
282
        int aReturnedFormat = 0;
 
283
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
284
        gulong *pVirtualScreenSizeBuffer = NULL;
 
285
        XGetWindowProperty (s_XDisplay, root, s_aNetDesktopGeometry, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pVirtualScreenSizeBuffer);
 
286
        if (iBufferNbElements > 0)
 
287
        {
 
288
                Screen *scr = XDefaultScreenOfDisplay (s_XDisplay);
 
289
                cd_debug ("pVirtualScreenSizeBuffer : %dx%d ; screen : %dx%d", pVirtualScreenSizeBuffer[0], pVirtualScreenSizeBuffer[1], g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL], g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
 
290
                *iNbViewportX = pVirtualScreenSizeBuffer[0] / g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
291
                *iNbViewportY = pVirtualScreenSizeBuffer[1] / g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
292
                XFree (pVirtualScreenSizeBuffer);
 
293
        }
 
294
}
 
295
 
 
296
 
 
297
 
 
298
gboolean cairo_dock_desktop_is_visible (void)
 
299
{
 
300
        Atom aNetShowingDesktop = XInternAtom (s_XDisplay, "_NET_SHOWING_DESKTOP", False);
 
301
        gulong iLeftBytes, iBufferNbElements = 0;
 
302
        Atom aReturnedType = 0;
 
303
        int aReturnedFormat = 0;
 
304
        gulong *pXBuffer = NULL;
 
305
        Window root = DefaultRootWindow (s_XDisplay);
 
306
        XGetWindowProperty (s_XDisplay, root, aNetShowingDesktop, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXBuffer);
 
307
 
 
308
        gboolean bDesktopIsShown = (iBufferNbElements > 0 && pXBuffer != NULL ? *pXBuffer : FALSE);
 
309
        XFree (pXBuffer);
 
310
        return bDesktopIsShown;
 
311
}
 
312
 
 
313
void cairo_dock_show_hide_desktop (gboolean bShow)
 
314
{
 
315
        XEvent xClientMessage;
 
316
        Window root = DefaultRootWindow (s_XDisplay);
 
317
 
 
318
        xClientMessage.xclient.type = ClientMessage;
 
319
        xClientMessage.xclient.serial = 0;
 
320
        xClientMessage.xclient.send_event = True;
 
321
        xClientMessage.xclient.display = s_XDisplay;
 
322
        xClientMessage.xclient.window = root;
 
323
        xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_SHOWING_DESKTOP", False);
 
324
        xClientMessage.xclient.format = 32;
 
325
        xClientMessage.xclient.data.l[0] = bShow;
 
326
        xClientMessage.xclient.data.l[1] = 0;
 
327
        xClientMessage.xclient.data.l[2] = 0;
 
328
        xClientMessage.xclient.data.l[3] = 2;
 
329
        xClientMessage.xclient.data.l[4] = 0;
 
330
        
 
331
        cd_debug ("%s (%d)\n", __func__, bShow);
 
332
        XSendEvent (s_XDisplay,
 
333
                root,
 
334
                False,
 
335
                SubstructureRedirectMask | SubstructureNotifyMask,
 
336
                &xClientMessage);
 
337
}
 
338
 
 
339
static void cairo_dock_move_current_viewport_to (int iDesktopViewportX, int iDesktopViewportY)
 
340
{
 
341
        XEvent xClientMessage;
 
342
        Window root = DefaultRootWindow (s_XDisplay);
 
343
        
 
344
        xClientMessage.xclient.type = ClientMessage;
 
345
        xClientMessage.xclient.serial = 0;
 
346
        xClientMessage.xclient.send_event = True;
 
347
        xClientMessage.xclient.display = s_XDisplay;
 
348
        xClientMessage.xclient.window = root;
 
349
        xClientMessage.xclient.message_type = s_aNetDesktopViewport;
 
350
        xClientMessage.xclient.format = 32;
 
351
        xClientMessage.xclient.data.l[0] = iDesktopViewportX;
 
352
        xClientMessage.xclient.data.l[1] = iDesktopViewportY;
 
353
        xClientMessage.xclient.data.l[2] = 0;
 
354
        xClientMessage.xclient.data.l[3] = 0;
 
355
        xClientMessage.xclient.data.l[4] = 0;
 
356
        
 
357
        XSendEvent (s_XDisplay,
 
358
                root,
 
359
                False,
 
360
                SubstructureRedirectMask | SubstructureNotifyMask,
 
361
                &xClientMessage);
 
362
}
 
363
void cairo_dock_set_current_viewport (int iViewportNumberX, int iViewportNumberY)
 
364
{
 
365
        cairo_dock_move_current_viewport_to (iViewportNumberX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL], iViewportNumberY * g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
 
366
}
 
367
void cairo_dock_set_current_desktop (int iDesktopNumber)
 
368
{
 
369
        Window root = DefaultRootWindow (s_XDisplay);
 
370
        int iTimeStamp = cairo_dock_get_xwindow_timestamp (root);
 
371
        XEvent xClientMessage;
 
372
        
 
373
        xClientMessage.xclient.type = ClientMessage;
 
374
        xClientMessage.xclient.serial = 0;
 
375
        xClientMessage.xclient.send_event = True;
 
376
        xClientMessage.xclient.display = s_XDisplay;
 
377
        xClientMessage.xclient.window = root;
 
378
        xClientMessage.xclient.message_type = s_aNetCurrentDesktop;
 
379
        xClientMessage.xclient.format = 32;
 
380
        xClientMessage.xclient.data.l[0] = iDesktopNumber;
 
381
        xClientMessage.xclient.data.l[1] = iTimeStamp;
 
382
        xClientMessage.xclient.data.l[2] = 0;
 
383
        xClientMessage.xclient.data.l[3] = 0;
 
384
        xClientMessage.xclient.data.l[4] = 0;
 
385
 
 
386
        XSendEvent (s_XDisplay,
 
387
                root,
 
388
                False,
 
389
                SubstructureRedirectMask | SubstructureNotifyMask,
 
390
                &xClientMessage);
 
391
}
 
392
 
 
393
Pixmap cairo_dock_get_window_background_pixmap (Window Xid)
 
394
{
 
395
        g_return_val_if_fail (Xid > 0, None);
 
396
        //cd_debug ("%s (%d)", __func__, Xid);
 
397
        
 
398
        Pixmap iPixmapID;
 
399
        Atom aReturnedType = 0;
 
400
        int aReturnedFormat = 0;
 
401
        unsigned long iLeftBytes, iBufferNbElements;
 
402
        Pixmap *pPixmapIdBuffer = NULL;
 
403
        Pixmap iBgPixmapID = 0;
 
404
        XGetWindowProperty (s_XDisplay, Xid, s_aRootMapID, 0, G_MAXULONG, False, XA_PIXMAP, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pPixmapIdBuffer);
 
405
        if (iBufferNbElements != 0)
 
406
        {
 
407
                iBgPixmapID = *pPixmapIdBuffer;
 
408
                XFree (pPixmapIdBuffer);
 
409
        }
 
410
        else
 
411
                iBgPixmapID = None;
 
412
        cd_debug (" => rootmapid : %d", iBgPixmapID);
 
413
        return iBgPixmapID;
 
414
}
 
415
 
 
416
GdkPixbuf *cairo_dock_get_pixbuf_from_pixmap (int XPixmapID, gboolean bAddAlpha)  // cette fonction est inspiree par celle de libwnck.
 
417
{
 
418
        //\__________________ On recupere la taille telle qu'elle est actuellement sur le serveur X.
 
419
        Window root;  // inutile.
 
420
        int x, y;  // inutile.
 
421
        guint border_width;  // inutile.
 
422
        guint iWidth, iHeight, iDepth;
 
423
        if (! XGetGeometry (s_XDisplay,
 
424
                XPixmapID, &root, &x, &y,
 
425
                &iWidth, &iHeight, &border_width, &iDepth))
 
426
                return NULL;
 
427
        cd_debug ("%s (%d) : %ux%ux%u (%d;%d)", __func__, XPixmapID, iWidth, iHeight, iDepth, x, y);
 
428
 
 
429
        //\__________________ On recupere le drawable associe.
 
430
        GdkDrawable *pGdkDrawable = gdk_xid_table_lookup (XPixmapID);
 
431
        if (pGdkDrawable)
 
432
                g_object_ref (G_OBJECT (pGdkDrawable));
 
433
        else
 
434
        {
 
435
                cd_debug ("pas d'objet GDK present, on en alloue un nouveau");
 
436
                GdkScreen* pScreen = gdk_screen_get_default ();
 
437
                pGdkDrawable = gdk_pixmap_foreign_new_for_screen (pScreen, XPixmapID, iWidth, iHeight, iDepth);
 
438
        }
 
439
 
 
440
        //\__________________ On recupere la colormap.
 
441
        GdkColormap* pColormap = gdk_drawable_get_colormap (pGdkDrawable);
 
442
        if (pColormap == NULL && gdk_drawable_get_depth (pGdkDrawable) > 1)  // pour les bitmaps, on laisse la colormap a NULL, ils n'en ont pas besoin.
 
443
        {
 
444
                GdkScreen *pScreen = gdk_drawable_get_screen (GDK_DRAWABLE (pGdkDrawable));
 
445
                if (gdk_drawable_get_depth (pGdkDrawable) == 32)
 
446
                        pColormap = gdk_screen_get_rgba_colormap (pScreen);
 
447
                else
 
448
                        pColormap = gdk_screen_get_rgb_colormap (pScreen);  // au pire on a un colormap nul.
 
449
                cd_debug ("  pColormap : %x  (pScreen:%x)", pColormap, pScreen);
 
450
        }
 
451
 
 
452
        //\__________________ On recupere le buffer dans un GdkPixbuf.
 
453
        GdkPixbuf *pIconPixbuf = gdk_pixbuf_get_from_drawable (NULL,
 
454
                pGdkDrawable,
 
455
                pColormap,
 
456
                0,
 
457
                0,
 
458
                0,
 
459
                0,
 
460
                iWidth,
 
461
                iHeight);
 
462
        g_object_unref (G_OBJECT (pGdkDrawable));
 
463
        g_return_val_if_fail (pIconPixbuf != NULL, NULL);
 
464
 
 
465
        //\__________________ On lui ajoute un canal alpha si necessaire.
 
466
        if (! gdk_pixbuf_get_has_alpha (pIconPixbuf) && bAddAlpha)
 
467
        {
 
468
                cd_debug ("  on lui ajoute de la transparence");
 
469
                GdkPixbuf *tmp_pixbuf = gdk_pixbuf_add_alpha (pIconPixbuf, FALSE, 255, 255, 255);
 
470
                g_object_unref (pIconPixbuf);
 
471
                pIconPixbuf = tmp_pixbuf;
 
472
        }
 
473
        return pIconPixbuf;
 
474
}
 
475
 
 
476
 
 
477
void cairo_dock_set_nb_viewports (int iNbViewportX, int iNbViewportY)
 
478
{
 
479
        XEvent xClientMessage;
 
480
        Window root = DefaultRootWindow (s_XDisplay);
 
481
        
 
482
        xClientMessage.xclient.type = ClientMessage;
 
483
        xClientMessage.xclient.serial = 0;
 
484
        xClientMessage.xclient.send_event = True;
 
485
        xClientMessage.xclient.display = s_XDisplay;
 
486
        xClientMessage.xclient.window = root;
 
487
        xClientMessage.xclient.message_type = s_aNetDesktopGeometry;
 
488
        xClientMessage.xclient.format = 32;
 
489
        xClientMessage.xclient.data.l[0] = iNbViewportX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
490
        xClientMessage.xclient.data.l[1] = iNbViewportY * g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
491
        xClientMessage.xclient.data.l[2] = 0;
 
492
        xClientMessage.xclient.data.l[3] = 2;
 
493
        xClientMessage.xclient.data.l[4] = 0;
 
494
 
 
495
        XSendEvent (s_XDisplay,
 
496
                root,
 
497
                False,
 
498
                SubstructureRedirectMask | SubstructureNotifyMask,
 
499
                &xClientMessage);
 
500
}
 
501
 
 
502
void cairo_dock_set_nb_desktops (gulong iNbDesktops)
 
503
{
 
504
        XEvent xClientMessage;
 
505
        Window root = DefaultRootWindow (s_XDisplay);
 
506
        
 
507
        xClientMessage.xclient.type = ClientMessage;
 
508
        xClientMessage.xclient.serial = 0;
 
509
        xClientMessage.xclient.send_event = True;
 
510
        xClientMessage.xclient.display = s_XDisplay;
 
511
        xClientMessage.xclient.window = root;
 
512
        xClientMessage.xclient.message_type = s_aNetNbDesktops;
 
513
        xClientMessage.xclient.format = 32;
 
514
        xClientMessage.xclient.data.l[0] = iNbDesktops;
 
515
        xClientMessage.xclient.data.l[1] = 0;
 
516
        xClientMessage.xclient.data.l[2] = 0;
 
517
        xClientMessage.xclient.data.l[3] = 2;
 
518
        xClientMessage.xclient.data.l[4] = 0;
 
519
 
 
520
        XSendEvent (s_XDisplay,
 
521
                root,
 
522
                False,
 
523
                SubstructureRedirectMask | SubstructureNotifyMask,
 
524
                &xClientMessage);
 
525
}
 
526
 
 
527
 
 
528
gboolean cairo_dock_support_X_extension (void)
 
529
{
 
530
#ifdef HAVE_XEXTEND
 
531
        int event_base, error_base, major, minor;
 
532
        if (! XCompositeQueryExtension (s_XDisplay, &event_base, &error_base))  // on regarde si le serveur X supporte l'extension.
 
533
        {
 
534
                cd_warning ("XComposite extension not available.");
 
535
                s_bUseXComposite = FALSE;
 
536
        }
 
537
        else
 
538
        {
 
539
                major = 0, minor = 2;  // La version minimale requise pour avoir XCompositeNameWindowPixmap().
 
540
                XCompositeQueryVersion (s_XDisplay, &major, &minor);  // on regarde si on est au moins dans cette version.
 
541
                if (! (major > 0 || minor >= 2))
 
542
                {
 
543
                        cd_warning ("XComposite extension too old.");
 
544
                        s_bUseXComposite = FALSE;
 
545
                }
 
546
        }
 
547
        /*int iDamageError=0;
 
548
        if (! XDamageQueryExtension (s_XDisplay, &g_iDamageEvent, &iDamageError))
 
549
        {
 
550
                cd_warning ("XDamage extension not supported");
 
551
                return FALSE;
 
552
        }*/
 
553
        
 
554
        major = 0, minor = 0;
 
555
        if (! XTestQueryExtension (s_XDisplay, &event_base, &error_base, &major, &minor))
 
556
        {
 
557
                cd_warning ("XTest extension not available.");
 
558
                s_bUseXTest = FALSE;
 
559
        }
 
560
        
 
561
        if (! XineramaQueryExtension (s_XDisplay, &event_base, &error_base))
 
562
        {
 
563
                cd_warning ("Xinerama extension not supported");
 
564
                s_bUseXinerama = FALSE;
 
565
        }
 
566
        else
 
567
        {
 
568
                major = 0, minor = 0;
 
569
                if (XineramaQueryVersion (s_XDisplay, &major, &minor) == 0)
 
570
                {
 
571
                        cd_warning ("Xinerama extension too old");
 
572
                        s_bUseXinerama = FALSE;
 
573
                }
 
574
        }
 
575
        
 
576
        return TRUE;
 
577
#else
 
578
        cd_warning ("The dock was not compiled with the X extensions (XComposite, xinerama, xtst, XDamage, etc).");
 
579
        s_bUseXComposite = FALSE;
 
580
        s_bUseXTest = FALSE;
 
581
        s_bUseXinerama = FALSE;
 
582
        return FALSE;
 
583
#endif
 
584
}
 
585
 
 
586
gboolean cairo_dock_xcomposite_is_available (void)
 
587
{
 
588
        return s_bUseXComposite;
 
589
}
 
590
 
 
591
gboolean cairo_dock_xtest_is_available (void)
 
592
{
 
593
        return s_bUseXTest;
 
594
}
 
595
 
 
596
gboolean cairo_dock_xinerama_is_available (void)
 
597
{
 
598
        return s_bUseXinerama;
 
599
}
 
600
 
 
601
 
 
602
void cairo_dock_get_screen_offsets (int iNumScreen, int *iScreenOffsetX, int *iScreenOffsetY)
 
603
{
 
604
#ifdef HAVE_XEXTEND
 
605
        g_return_if_fail (s_bUseXinerama);
 
606
        int iNbScreens = 0;
 
607
        XineramaScreenInfo *pScreens = XineramaQueryScreens (s_XDisplay, &iNbScreens);
 
608
        if (pScreens != NULL)
 
609
        {
 
610
                if (iNumScreen >= iNbScreens)
 
611
                {
 
612
                        cd_warning ("the number of screen where to place the dock is too big, we'll choose the last one.");
 
613
                        iNumScreen = iNbScreens - 1;
 
614
                }
 
615
                *iScreenOffsetX = pScreens[iNumScreen].x_org;
 
616
                *iScreenOffsetY = pScreens[iNumScreen].y_org;
 
617
                g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL] = pScreens[iNumScreen].width;
 
618
                g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL] = pScreens[iNumScreen].height;
 
619
                
 
620
                g_desktopGeometry.iScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
621
                g_desktopGeometry.iScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
622
                cd_message (" * screen %d => (%d;%d) %dx%d\n", iNumScreen, *iScreenOffsetX, *iScreenOffsetY, g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL], g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL]);
 
623
                
 
624
                XFree (pScreens);
 
625
        }
 
626
        else
 
627
        {
 
628
                cd_warning ("No screen found from Xinerama, is it really active ?");
 
629
                *iScreenOffsetX = *iScreenOffsetY = 0;
 
630
                g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL] = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
631
                g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL] = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
632
                g_desktopGeometry.iScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
633
                g_desktopGeometry.iScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
634
        }
 
635
#else
 
636
        cd_warning ("The dock was not compiled with the support of Xinerama.");
 
637
#endif
 
638
}
 
639
 
 
640
 
 
641
 
 
642
 
 
643
 
 
644
 
 
645
void cairo_dock_set_xwindow_timestamp (Window Xid, gulong iTimeStamp)
 
646
{
 
647
        g_return_if_fail (Xid > 0);
 
648
        Atom aNetWmUserTime = XInternAtom (s_XDisplay, "_NET_WM_USER_TIME", False);
 
649
        XChangeProperty (s_XDisplay,
 
650
                Xid,
 
651
                aNetWmUserTime,
 
652
                XA_CARDINAL, 32, PropModeReplace,
 
653
                (guchar *)&iTimeStamp, 1);
 
654
}
 
655
 
 
656
void cairo_dock_set_strut_partial (int Xid, int left, int right, int top, int bottom, int left_start_y, int left_end_y, int right_start_y, int right_end_y, int top_start_x, int top_end_x, int bottom_start_x, int bottom_end_x)
 
657
{
 
658
        g_return_if_fail (Xid > 0);
 
659
 
 
660
        cd_debug ("%s (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", __func__, left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x);
 
661
        gulong iGeometryStrut[12] = {left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x};
 
662
 
 
663
        XChangeProperty (s_XDisplay,
 
664
                Xid,
 
665
                XInternAtom (s_XDisplay, "_NET_WM_STRUT_PARTIAL", False),
 
666
                XA_CARDINAL, 32, PropModeReplace,
 
667
                (guchar *) iGeometryStrut, 12);
 
668
        
 
669
        Window root = DefaultRootWindow (s_XDisplay);
 
670
        cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
 
671
}
 
672
 
 
673
void cairo_dock_set_xwindow_mask (Window Xid, long iMask)
 
674
{
 
675
        //StructureNotifyMask | /*ResizeRedirectMask*/
 
676
        //SubstructureRedirectMask |
 
677
        //SubstructureNotifyMask |  // place sur le root, donne les evenements Map, Unmap, Destroy, Create de chaque fenetre.
 
678
        //PropertyChangeMask
 
679
        XSelectInput (s_XDisplay, Xid, iMask);  // c'est le 'event_mask' d'un XSetWindowAttributes.
 
680
}
 
681
 
 
682
void cairo_dock_set_xwindow_type_hint (int Xid, const gchar *cWindowTypeName)
 
683
{
 
684
        g_return_if_fail (Xid > 0);
 
685
        
 
686
        gulong iWindowType = XInternAtom (s_XDisplay, cWindowTypeName, False);
 
687
        cd_debug ("%s (%d, %s=%d)", __func__, Xid, cWindowTypeName, iWindowType);
 
688
        
 
689
        XChangeProperty (s_XDisplay,
 
690
                Xid,
 
691
                s_aNetWmWindowType,
 
692
                XA_ATOM, 32, PropModeReplace,
 
693
                (guchar *) &iWindowType, 1);
 
694
}
 
695
 
 
696
 
 
697
void cairo_dock_set_xicon_geometry (int Xid, int iX, int iY, int iWidth, int iHeight)
 
698
{
 
699
        g_return_if_fail (Xid > 0);
 
700
 
 
701
        gulong iIconGeometry[4] = {iX, iY, iWidth, iHeight};
 
702
        
 
703
        if (iWidth == 0 || iHeight == 0)
 
704
                XDeleteProperty (s_XDisplay,
 
705
                        Xid,
 
706
                        s_aNetWmIconGeometry);
 
707
        else
 
708
                XChangeProperty (s_XDisplay,
 
709
                        Xid,
 
710
                        s_aNetWmIconGeometry,
 
711
                        XA_CARDINAL, 32, PropModeReplace,
 
712
                        (guchar *) iIconGeometry, 4);
 
713
}
 
714
 
 
715
 
 
716
 
 
717
void cairo_dock_close_xwindow (Window Xid)
 
718
{
 
719
        //g_print ("%s (%d)\n", __func__, Xid);
 
720
        g_return_if_fail (Xid > 0);
 
721
        
 
722
        XEvent xClientMessage;
 
723
        
 
724
        xClientMessage.xclient.type = ClientMessage;
 
725
        xClientMessage.xclient.serial = 0;
 
726
        xClientMessage.xclient.send_event = True;
 
727
        xClientMessage.xclient.display = s_XDisplay;
 
728
        xClientMessage.xclient.window = Xid;
 
729
        xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_CLOSE_WINDOW", False);
 
730
        xClientMessage.xclient.format = 32;
 
731
        xClientMessage.xclient.data.l[0] = cairo_dock_get_xwindow_timestamp (Xid);  // timestamp
 
732
        xClientMessage.xclient.data.l[1] = 2;  // 2 <=> pagers and other Clients that represent direct user actions.
 
733
        xClientMessage.xclient.data.l[2] = 0;
 
734
        xClientMessage.xclient.data.l[3] = 0;
 
735
        xClientMessage.xclient.data.l[4] = 0;
 
736
 
 
737
        Window root = DefaultRootWindow (s_XDisplay);
 
738
        XSendEvent (s_XDisplay,
 
739
                root,
 
740
                False,
 
741
                SubstructureRedirectMask | SubstructureNotifyMask,
 
742
                &xClientMessage);
 
743
        //cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
 
744
}
 
745
 
 
746
void cairo_dock_kill_xwindow (Window Xid)
 
747
{
 
748
        g_return_if_fail (Xid > 0);
 
749
        XKillClient (s_XDisplay, Xid);
 
750
}
 
751
 
 
752
void cairo_dock_show_xwindow (Window Xid)
 
753
{
 
754
        g_return_if_fail (Xid > 0);
 
755
        XEvent xClientMessage;
 
756
        Window root = DefaultRootWindow (s_XDisplay);
 
757
 
 
758
        //\______________ On se deplace sur le bureau de la fenetre a afficher (autrement Metacity deplacera la fenetre sur le bureau actuel).
 
759
        int iDesktopNumber = cairo_dock_get_xwindow_desktop (Xid);
 
760
        cairo_dock_set_current_desktop (iDesktopNumber);
 
761
 
 
762
        //\______________ On active la fenetre.
 
763
        //XMapRaised (s_XDisplay, Xid);  // on la mappe, pour les cas ou elle etait en zone de notification. Malheuresement, la zone de notif de gnome est bugguee, et reduit la fenetre aussitot qu'on l'a mappee :-(
 
764
        xClientMessage.xclient.type = ClientMessage;
 
765
        xClientMessage.xclient.serial = 0;
 
766
        xClientMessage.xclient.send_event = True;
 
767
        xClientMessage.xclient.display = s_XDisplay;
 
768
        xClientMessage.xclient.window = Xid;
 
769
        xClientMessage.xclient.message_type = s_aNetActiveWindow;
 
770
        xClientMessage.xclient.format = 32;
 
771
        xClientMessage.xclient.data.l[0] = 2;  // source indication
 
772
        xClientMessage.xclient.data.l[1] = 0;  // timestamp
 
773
        xClientMessage.xclient.data.l[2] = 0;  // requestor's currently active window, 0 if none
 
774
        xClientMessage.xclient.data.l[3] = 0;
 
775
        xClientMessage.xclient.data.l[4] = 0;
 
776
        
 
777
        XSendEvent (s_XDisplay,
 
778
                root,
 
779
                False,
 
780
                SubstructureRedirectMask | SubstructureNotifyMask,
 
781
                &xClientMessage);
 
782
 
 
783
        //cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
 
784
}
 
785
 
 
786
void cairo_dock_minimize_xwindow (Window Xid)
 
787
{
 
788
        g_return_if_fail (Xid > 0);
 
789
        XIconifyWindow (s_XDisplay, Xid, DefaultScreen (s_XDisplay));
 
790
        //Window root = DefaultRootWindow (s_XDisplay);
 
791
        //cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
 
792
}
 
793
 
 
794
 
 
795
 
 
796
static void _cairo_dock_change_window_state (Window Xid, gulong iNewValue, Atom iProperty1, Atom iProperty2)
 
797
{
 
798
        g_return_if_fail (Xid > 0);
 
799
        XEvent xClientMessage;
 
800
 
 
801
        xClientMessage.xclient.type = ClientMessage;
 
802
        xClientMessage.xclient.serial = 0;
 
803
        xClientMessage.xclient.send_event = True;
 
804
        xClientMessage.xclient.display = s_XDisplay;
 
805
        xClientMessage.xclient.window = Xid;
 
806
        xClientMessage.xclient.message_type = s_aNetWmState;
 
807
        xClientMessage.xclient.format = 32;
 
808
        xClientMessage.xclient.data.l[0] = iNewValue;
 
809
        xClientMessage.xclient.data.l[1] = iProperty1;
 
810
        xClientMessage.xclient.data.l[2] = iProperty2;
 
811
        xClientMessage.xclient.data.l[3] = 2;
 
812
        xClientMessage.xclient.data.l[4] = 0;
 
813
 
 
814
        Window root = DefaultRootWindow (s_XDisplay);
 
815
        XSendEvent (s_XDisplay,
 
816
                root,
 
817
                False,
 
818
                SubstructureRedirectMask | SubstructureNotifyMask,
 
819
                &xClientMessage);
 
820
 
 
821
        cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
 
822
}
 
823
void cairo_dock_maximize_xwindow (Window Xid, gboolean bMaximize)
 
824
{
 
825
        _cairo_dock_change_window_state (Xid, bMaximize, s_aNetWmMaximizedVert, s_aNetWmMaximizedHoriz);
 
826
}
 
827
 
 
828
void cairo_dock_set_xwindow_fullscreen (Window Xid, gboolean bFullScreen)
 
829
{
 
830
        _cairo_dock_change_window_state (Xid, bFullScreen, s_aNetWmFullScreen, 0);
 
831
}
 
832
 
 
833
void cairo_dock_set_xwindow_above (Window Xid, gboolean bAbove)
 
834
{
 
835
        _cairo_dock_change_window_state (Xid, bAbove, s_aNetWmAbove, 0);
 
836
}
 
837
 
 
838
 
 
839
void cairo_dock_move_xwindow_to_absolute_position (Window Xid, int iDesktopNumber, int iPositionX, int iPositionY)  // dans le referentiel du viewport courant.
 
840
{
 
841
        g_return_if_fail (Xid > 0);
 
842
        XEvent xClientMessage;
 
843
 
 
844
        xClientMessage.xclient.type = ClientMessage;
 
845
        xClientMessage.xclient.serial = 0;
 
846
        xClientMessage.xclient.send_event = True;
 
847
        xClientMessage.xclient.display = s_XDisplay;
 
848
        xClientMessage.xclient.window = Xid;
 
849
        xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_WM_DESKTOP", False);
 
850
        xClientMessage.xclient.format = 32;
 
851
        xClientMessage.xclient.data.l[0] = iDesktopNumber;
 
852
        xClientMessage.xclient.data.l[1] = 2;
 
853
        xClientMessage.xclient.data.l[2] = 0;
 
854
        xClientMessage.xclient.data.l[3] = 0;
 
855
        xClientMessage.xclient.data.l[4] = 0;
 
856
 
 
857
        Window root = DefaultRootWindow (s_XDisplay);
 
858
        XSendEvent (s_XDisplay,
 
859
                root,
 
860
                False,
 
861
                SubstructureRedirectMask | SubstructureNotifyMask,
 
862
                &xClientMessage);
 
863
        
 
864
        xClientMessage.xclient.type = ClientMessage;
 
865
        xClientMessage.xclient.serial = 0;
 
866
        xClientMessage.xclient.send_event = True;
 
867
        xClientMessage.xclient.display = s_XDisplay;
 
868
        xClientMessage.xclient.window = Xid;
 
869
        xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_MOVERESIZE_WINDOW", False);
 
870
        xClientMessage.xclient.format = 32;
 
871
        xClientMessage.xclient.data.l[0] = StaticGravity | (1 << 8) | (1 << 9) | (0 << 10) | (0 << 11);
 
872
        xClientMessage.xclient.data.l[1] =  iPositionX;  // coordonnees dans le referentiel du viewport desire.
 
873
        xClientMessage.xclient.data.l[2] =  iPositionY;
 
874
        xClientMessage.xclient.data.l[3] = 0;
 
875
        xClientMessage.xclient.data.l[4] = 0;
 
876
        XSendEvent (s_XDisplay,
 
877
                root,
 
878
                False,
 
879
                SubstructureRedirectMask | SubstructureNotifyMask,
 
880
                &xClientMessage);
 
881
 
 
882
        //cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
 
883
}
 
884
 
 
885
void cairo_dock_move_xwindow_to_nth_desktop (Window Xid, int iDesktopNumber, int iDesktopViewportX, int iDesktopViewportY)
 
886
{
 
887
        g_return_if_fail (Xid > 0);
 
888
        int iRelativePositionX, iRelativePositionY;
 
889
        cairo_dock_get_xwindow_position_on_its_viewport (Xid, &iRelativePositionX, &iRelativePositionY);
 
890
        
 
891
        cairo_dock_move_xwindow_to_absolute_position (Xid, iDesktopNumber, iDesktopViewportX + iRelativePositionX, iDesktopViewportY + iRelativePositionY);
 
892
}
 
893
 
 
894
 
 
895
 
 
896
gulong cairo_dock_get_xwindow_timestamp (Window Xid)
 
897
{
 
898
        g_return_val_if_fail (Xid > 0, 0);
 
899
        Atom aNetWmUserTime = XInternAtom (s_XDisplay, "_NET_WM_USER_TIME", False);
 
900
        gulong iLeftBytes, iBufferNbElements = 0;
 
901
        Atom aReturnedType = 0;
 
902
        int aReturnedFormat = 0;
 
903
        gulong *pTimeBuffer = NULL;
 
904
        XGetWindowProperty (s_XDisplay, Xid, aNetWmUserTime, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pTimeBuffer);
 
905
        gulong iTimeStamp = 0;
 
906
        if (iBufferNbElements > 0)
 
907
                iTimeStamp = *pTimeBuffer;
 
908
        XFree (pTimeBuffer);
 
909
        return iTimeStamp;
 
910
}
 
911
 
 
912
gchar *cairo_dock_get_xwindow_name (Window Xid, gboolean bSearchWmName)
 
913
{
 
914
        Atom aReturnedType = 0;
 
915
        int aReturnedFormat = 0;
 
916
        unsigned long iLeftBytes, iBufferNbElements=0;
 
917
        guchar *pNameBuffer = NULL;
 
918
        XGetWindowProperty (s_XDisplay, Xid, s_aNetWmName, 0, G_MAXULONG, False, s_aUtf8String, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);  // on cherche en priorite le nom en UTF8, car on est notifie des 2, mais il vaut mieux eviter le WM_NAME qui, ne l'etant pas, contient des caracteres bizarres qu'on ne peut pas convertir avec g_locale_to_utf8, puisque notre locale _est_ UTF8.
 
919
        if (iBufferNbElements == 0 && bSearchWmName)
 
920
                XGetWindowProperty (s_XDisplay, Xid, s_aWmName, 0, G_MAXULONG, False, s_aString, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);
 
921
        
 
922
        gchar *cName = NULL;
 
923
        if (iBufferNbElements > 0)
 
924
        {
 
925
                cName = g_strdup (pNameBuffer);
 
926
                XFree (pNameBuffer);
 
927
        }
 
928
        return cName;
 
929
}
 
930
 
 
931
gboolean cairo_dock_xwindow_is_maximized (Window Xid)
 
932
{
 
933
        g_return_val_if_fail (Xid > 0, FALSE);
 
934
 
 
935
        Atom aReturnedType = 0;
 
936
        int aReturnedFormat = 0;
 
937
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
938
        gulong *pXStateBuffer = NULL;
 
939
        XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
 
940
        int iIsMaximized = 0;
 
941
        if (iBufferNbElements > 0)
 
942
        {
 
943
                guint i;
 
944
                for (i = 0; i < iBufferNbElements && iIsMaximized < 2; i ++)
 
945
                {
 
946
                        if (pXStateBuffer[i] == s_aNetWmMaximizedVert)
 
947
                                iIsMaximized ++;
 
948
                        if (pXStateBuffer[i] == s_aNetWmMaximizedHoriz)
 
949
                                iIsMaximized ++;
 
950
                }
 
951
        }
 
952
        XFree (pXStateBuffer);
 
953
 
 
954
        return (iIsMaximized == 2);
 
955
}
 
956
 
 
957
static gboolean _cairo_dock_window_is_in_state (Window Xid, Atom iState)
 
958
{
 
959
        g_return_val_if_fail (Xid > 0, FALSE);
 
960
        Atom aReturnedType = 0;
 
961
        int aReturnedFormat = 0;
 
962
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
963
        gulong *pXStateBuffer = NULL;
 
964
        XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
 
965
 
 
966
        gboolean bIsInState = FALSE;
 
967
        if (iBufferNbElements > 0)
 
968
        {
 
969
                guint i;
 
970
                for (i = 0; i < iBufferNbElements; i ++)
 
971
                {
 
972
                        if (pXStateBuffer[i] == iState)
 
973
                        {
 
974
                                bIsInState = TRUE;
 
975
                                break;
 
976
                        }
 
977
                }
 
978
        }
 
979
 
 
980
        XFree (pXStateBuffer);
 
981
        return bIsInState;
 
982
}
 
983
 
 
984
gboolean cairo_dock_xwindow_is_fullscreen (Window Xid)
 
985
{
 
986
        return _cairo_dock_window_is_in_state (Xid, s_aNetWmFullScreen);
 
987
}
 
988
gboolean cairo_dock_xwindow_skip_taskbar (Window Xid)
 
989
{
 
990
        return _cairo_dock_window_is_in_state (Xid, s_aNetWmSkipTaskbar);
 
991
}
 
992
void cairo_dock_xwindow_is_above_or_below (Window Xid, gboolean *bIsAbove, gboolean *bIsBelow)
 
993
{
 
994
        g_return_if_fail (Xid > 0);
 
995
        Atom aReturnedType = 0;
 
996
        int aReturnedFormat = 0;
 
997
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
998
        gulong *pXStateBuffer = NULL;
 
999
        XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
 
1000
 
 
1001
        if (iBufferNbElements > 0)
 
1002
        {
 
1003
                guint i;
 
1004
                //g_print ("iBufferNbElements : %d (%d;%d)\n", iBufferNbElements, s_aNetWmAbove, s_aNetWmBelow);
 
1005
                for (i = 0; i < iBufferNbElements; i ++)
 
1006
                {
 
1007
                        //g_print (" - %d\n", pXStateBuffer[i]);
 
1008
                        if (pXStateBuffer[i] == s_aNetWmAbove)
 
1009
                        {
 
1010
                                *bIsAbove = TRUE;
 
1011
                                *bIsBelow = FALSE;
 
1012
                                break;
 
1013
                        }
 
1014
                        else if (pXStateBuffer[i] == s_aNetWmBelow)
 
1015
                        {
 
1016
                                *bIsAbove = FALSE;
 
1017
                                *bIsBelow = TRUE;
 
1018
                                break;
 
1019
                        }
 
1020
                }
 
1021
        }
 
1022
 
 
1023
        XFree (pXStateBuffer);
 
1024
}
 
1025
 
 
1026
gboolean cairo_dock_xwindow_is_fullscreen_or_hidden_or_maximized (Window Xid, gboolean *bIsFullScreen, gboolean *bIsHidden, gboolean *bIsMaximized, gboolean *bDemandsAttention)
 
1027
{
 
1028
        g_return_val_if_fail (Xid > 0, FALSE);
 
1029
        //cd_debug ("%s (%d)", __func__, Xid);
 
1030
        Atom aReturnedType = 0;
 
1031
        int aReturnedFormat = 0;
 
1032
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
1033
        gulong *pXStateBuffer = NULL;
 
1034
        XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
 
1035
        
 
1036
        gboolean bValid = TRUE;
 
1037
        *bIsFullScreen = FALSE;
 
1038
        *bIsHidden = FALSE;
 
1039
        *bIsMaximized = FALSE;
 
1040
        if (bDemandsAttention != NULL)
 
1041
                *bDemandsAttention = FALSE;
 
1042
        if (iBufferNbElements > 0)
 
1043
        {
 
1044
                guint i, iNbMaximizedDimensions = 0;
 
1045
                for (i = 0; i < iBufferNbElements; i ++)
 
1046
                {
 
1047
                        if (pXStateBuffer[i] == s_aNetWmFullScreen)
 
1048
                        {
 
1049
                                *bIsFullScreen = TRUE;
 
1050
                        }
 
1051
                        else if (pXStateBuffer[i] == s_aNetWmHidden)
 
1052
                        {
 
1053
                                *bIsHidden = TRUE;
 
1054
                        }
 
1055
                        else if (pXStateBuffer[i] == s_aNetWmMaximizedVert)
 
1056
                        {
 
1057
                                iNbMaximizedDimensions ++;
 
1058
                                if (iNbMaximizedDimensions == 2)
 
1059
                                        *bIsMaximized = TRUE;
 
1060
                        }
 
1061
                        else if (pXStateBuffer[i] == s_aNetWmMaximizedHoriz)
 
1062
                        {
 
1063
                                iNbMaximizedDimensions ++;
 
1064
                                if (iNbMaximizedDimensions == 2)
 
1065
                                        *bIsMaximized = TRUE;
 
1066
                        }
 
1067
                        else if (pXStateBuffer[i] == s_aNetWmDemandsAttention && bDemandsAttention != NULL)
 
1068
                        {
 
1069
                                *bDemandsAttention = TRUE;
 
1070
                        }
 
1071
                        
 
1072
                        else if (pXStateBuffer[i] == s_aNetWmSkipTaskbar)
 
1073
                        {
 
1074
                                cd_debug ("this appli should not be in taskbar anymore");
 
1075
                                bValid = FALSE;
 
1076
                        }
 
1077
                }
 
1078
        }
 
1079
        
 
1080
        XFree (pXStateBuffer);
 
1081
        return bValid;
 
1082
}
 
1083
 
 
1084
gboolean cairo_dock_xwindow_is_sticky (Window Xid)
 
1085
{
 
1086
        g_return_val_if_fail (Xid > 0, FALSE);
 
1087
        Atom aReturnedType = 0;
 
1088
        int aReturnedFormat = 0;
 
1089
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
1090
        gulong *pXStateBuffer = NULL;
 
1091
        XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
 
1092
        
 
1093
        gboolean bIsSticky = FALSE;
 
1094
        if (iBufferNbElements > 0)
 
1095
        {
 
1096
                guint i;
 
1097
                //g_print ("iBufferNbElements : %d (%d;%d)\n", iBufferNbElements, s_aNetWmAbove, s_aNetWmBelow);
 
1098
                for (i = 0; i < iBufferNbElements; i ++)
 
1099
                {
 
1100
                        //g_print (" - %d\n", pXStateBuffer[i]);
 
1101
                        if (pXStateBuffer[i] == s_aNetWmSticky)
 
1102
                        {
 
1103
                                bIsSticky = TRUE;
 
1104
                                break;
 
1105
                        }
 
1106
                }
 
1107
        }
 
1108
 
 
1109
        XFree (pXStateBuffer);
 
1110
        return bIsSticky;
 
1111
}
 
1112
 
 
1113
static inline gboolean _cairo_dock_window_has_type (int Xid, Atom iType)
 
1114
{
 
1115
        g_return_val_if_fail (Xid > 0, FALSE);
 
1116
        
 
1117
        gboolean bIsType;
 
1118
        Atom aReturnedType = 0;
 
1119
        int aReturnedFormat = 0;
 
1120
        unsigned long iLeftBytes, iBufferNbElements;
 
1121
        gulong *pTypeBuffer = NULL;
 
1122
        XGetWindowProperty (s_XDisplay, Xid, s_aNetWmWindowType, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pTypeBuffer);
 
1123
        if (iBufferNbElements != 0)
 
1124
        {
 
1125
                bIsType = (*pTypeBuffer == iType);
 
1126
                XFree (pTypeBuffer);
 
1127
        }
 
1128
        else
 
1129
                bIsType = FALSE;
 
1130
        return bIsType;
 
1131
}
 
1132
gboolean cairo_dock_window_is_utility (int Xid)
 
1133
{
 
1134
        return _cairo_dock_window_has_type (Xid, s_aNetWmWindowTypeUtility);
 
1135
}
 
1136
 
 
1137
gboolean cairo_dock_window_is_dock (int Xid)
 
1138
{
 
1139
        return _cairo_dock_window_has_type (Xid, s_aNetWmWindowTypeDock);
 
1140
}
 
1141
 
 
1142
int cairo_dock_get_xwindow_desktop (Window Xid)
 
1143
{
 
1144
        int iDesktopNumber;
 
1145
        gulong iLeftBytes, iBufferNbElements = 0;
 
1146
        Atom aReturnedType = 0;
 
1147
        int aReturnedFormat = 0;
 
1148
        gulong *pBuffer = NULL;
 
1149
        XGetWindowProperty (s_XDisplay, Xid, s_aNetWmDesktop, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pBuffer);
 
1150
        if (iBufferNbElements > 0)
 
1151
                iDesktopNumber = *pBuffer;
 
1152
        else
 
1153
                iDesktopNumber = 0;
 
1154
        
 
1155
        XFree (pBuffer);
 
1156
        return iDesktopNumber;
 
1157
}
 
1158
 
 
1159
void cairo_dock_get_xwindow_geometry (Window Xid, int *iLocalPositionX, int *iLocalPositionY, int *iWidthExtent, int *iHeightExtent)  // renvoie les coordonnees du coin haut gauche dans le referentiel du viewport actuel. // sous KDE, x et y sont toujours nuls ! (meme avec XGetWindowAttributes).
 
1160
{
 
1161
        Window root_return;
 
1162
        int x_return=1, y_return=1;
 
1163
        unsigned int width_return, height_return, border_width_return, depth_return;
 
1164
        XGetGeometry (s_XDisplay, Xid,
 
1165
                &root_return,
 
1166
                &x_return, &y_return,
 
1167
                &width_return, &height_return,
 
1168
                &border_width_return, &depth_return);  // renvoie les coordonnees du coin haut gauche dans le referentiel du viewport actuel.
 
1169
        
 
1170
        *iLocalPositionX = x_return;  // on pourrait tenir compte de border_width_return...
 
1171
        *iLocalPositionY = y_return;  // idem.
 
1172
        *iWidthExtent = width_return;  // idem.
 
1173
        *iHeightExtent = height_return;  // idem.
 
1174
        //g_print ("%s () -> %d;%d %dx%d / %d,%d\n", __func__, x_return, y_return, *iWidthExtent, *iHeightExtent, border_width_return, depth_return);
 
1175
}
 
1176
 
 
1177
void cairo_dock_get_xwindow_position_on_its_viewport (Window Xid, int *iRelativePositionX, int *iRelativePositionY)
 
1178
{
 
1179
        int iLocalPositionX, iLocalPositionY, iWidthExtent, iHeightExtent;
 
1180
        cairo_dock_get_xwindow_geometry (Xid, &iLocalPositionX, &iLocalPositionY, &iWidthExtent, &iHeightExtent);
 
1181
        
 
1182
        while (iLocalPositionX < 0)  // on passe au referentiel du viewport de la fenetre; inutile de connaitre sa position, puisqu'ils ont tous la meme taille.
 
1183
                iLocalPositionX += g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
1184
        while (iLocalPositionX >= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL])
 
1185
                iLocalPositionX -= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
1186
        while (iLocalPositionY < 0)
 
1187
                iLocalPositionY += g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
1188
        while (iLocalPositionY >= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
 
1189
                iLocalPositionY -= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
1190
        
 
1191
        *iRelativePositionX = iLocalPositionX;
 
1192
        *iRelativePositionY = iLocalPositionY;
 
1193
        //cd_debug ("position relative : (%d;%d) taille : %dx%d", *iRelativePositionX, *iRelativePositionY, iWidthExtent, iHeightExtent);
 
1194
}
 
1195
 
 
1196
gboolean cairo_dock_xwindow_is_on_current_desktop (Window Xid)
 
1197
{
 
1198
        int iWindowDesktopNumber, iLocalPositionX, iLocalPositionY, iWidthExtent, iHeightExtent;  // coordonnees du coin haut gauche dans le referentiel du viewport actuel.
 
1199
        iWindowDesktopNumber = cairo_dock_get_xwindow_desktop (Xid);
 
1200
        cairo_dock_get_xwindow_geometry (Xid, &iLocalPositionX, &iLocalPositionY, &iWidthExtent, &iHeightExtent);
 
1201
 
 
1202
        //cd_debug (" -> %d/%d ; (%d ; %d)", iWindowDesktopNumber, iDesktopNumber, iGlobalPositionX, iGlobalPositionY);
 
1203
        return ( (iWindowDesktopNumber == g_desktopGeometry.iCurrentDesktop || iWindowDesktopNumber == -1) &&
 
1204
                iLocalPositionX + iWidthExtent > 0 &&
 
1205
                iLocalPositionX < g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] &&
 
1206
                iLocalPositionY + iHeightExtent > 0 &&
 
1207
                iLocalPositionY < g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] );  // -1 <=> 0xFFFFFFFF en unsigned.
 
1208
}
 
1209
 
 
1210
 
 
1211
Window *cairo_dock_get_windows_list (gulong *iNbWindows, gboolean bStackOrder)
 
1212
{
 
1213
        Atom aReturnedType = 0;
 
1214
        int aReturnedFormat = 0;
 
1215
        Window *XidList = NULL;
 
1216
 
 
1217
        Window root = DefaultRootWindow (s_XDisplay);
 
1218
        gulong iLeftBytes;
 
1219
        XGetWindowProperty (s_XDisplay, root, (bStackOrder ? s_aNetClientListStacking : s_aNetClientList), 0, G_MAXLONG, False, XA_WINDOW, &aReturnedType, &aReturnedFormat, iNbWindows, &iLeftBytes, (guchar **)&XidList);
 
1220
        return XidList;
 
1221
}
 
1222
 
 
1223
Window cairo_dock_get_active_xwindow (void)
 
1224
{
 
1225
        Atom aReturnedType = 0;
 
1226
        int aReturnedFormat = 0;
 
1227
        unsigned long iLeftBytes, iBufferNbElements = 0;
 
1228
        Window *pXBuffer = NULL;
 
1229
        Window root = DefaultRootWindow (s_XDisplay);
 
1230
        XGetWindowProperty (s_XDisplay, root, s_aNetActiveWindow, 0, G_MAXULONG, False, XA_WINDOW, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXBuffer);
 
1231
 
 
1232
        Window xActiveWindow = (iBufferNbElements > 0 && pXBuffer != NULL ? pXBuffer[0] : 0);
 
1233
        XFree (pXBuffer);
 
1234
        return xActiveWindow;
 
1235
}