2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
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.
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/>.
28
#include <X11/Xatom.h>
29
#include <X11/Xutil.h>
31
#include <X11/extensions/Xcomposite.h>
32
//#include <X11/extensions/Xdamage.h>
33
#include <X11/extensions/XTest.h>
34
#include <X11/extensions/Xinerama.h>
35
#include <X11/extensions/shape.h>
38
#include "cairo-dock-container.h"
39
#include "cairo-dock-applications-manager.h"
40
#include "cairo-dock-application-factory.h"
41
#include "cairo-dock-class-manager.h"
42
#include "cairo-dock-log.h"
43
#include "cairo-dock-internal-position.h"
44
#include "cairo-dock-X-utilities.h"
46
extern int g_iNbDesktops;
47
extern int g_iNbViewportX,g_iNbViewportY ;
48
extern int g_iScreenWidth[2], g_iScreenHeight[2]; // dimension de l'ecran sur lequel est place le dock.
49
extern int g_iXScreenWidth[2], g_iXScreenHeight[2]; // dimension de l'ecran logique compose eventuellement de plusieurs moniteurs.
50
extern CairoDock *g_pMainDock;
52
static gboolean s_bUseXComposite = TRUE;
53
static gboolean s_bUseXTest = TRUE;
54
static gboolean s_bUseXinerama = TRUE;
55
//extern int g_iDamageEvent;
57
static Display *s_XDisplay = NULL;
58
// Atoms pour le bureau
59
static Atom s_aNetWmWindowType;
60
static Atom s_aNetWmWindowTypeNormal;
61
static Atom s_aNetWmWindowTypeUtility;
62
static Atom s_aNetWmWindowTypeDock;
63
static Atom s_aNetWmIconGeometry;
64
static Atom s_aNetCurrentDesktop;
65
static Atom s_aNetDesktopViewport;
66
static Atom s_aNetDesktopGeometry;
67
static Atom s_aNetNbDesktops;
68
static Atom s_aRootMapID;
69
// Atoms pour les fenetres
70
static Atom s_aNetClientList; // z-order
71
static Atom s_aNetClientListStacking; // age-order
72
static Atom s_aNetActiveWindow;
73
static Atom s_aNetWmState;
74
static Atom s_aNetWmSticky;
75
static Atom s_aNetWmBelow;
76
static Atom s_aNetWmAbove;
77
static Atom s_aNetWmHidden;
78
static Atom s_aNetWmFullScreen;
79
static Atom s_aNetWmSkipTaskbar;
80
static Atom s_aNetWmMaximizedHoriz;
81
static Atom s_aNetWmMaximizedVert;
82
static Atom s_aNetWmDemandsAttention;
83
static Atom s_aNetWmDesktop;
84
static Atom s_aNetWmName;
85
static Atom s_aWmName;
86
static Atom s_aUtf8String;
87
static Atom s_aString;
89
static int _cairo_dock_xerror_handler (Display * pDisplay, XErrorEvent *pXError)
91
cd_debug ("Erreur (%d, %d, %d) lors d'une requete X sur %d", pXError->error_code, pXError->request_code, pXError->minor_code, pXError->resourceid);
94
Display *cairo_dock_initialize_X_desktop_support (void)
96
s_XDisplay = XOpenDisplay (0);
97
g_return_val_if_fail (s_XDisplay != NULL, NULL);
99
XSetErrorHandler (_cairo_dock_xerror_handler);
101
cairo_dock_support_X_extension ();
103
s_aNetWmWindowType = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE", False);
104
s_aNetWmWindowTypeNormal = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False);
105
s_aNetWmWindowTypeUtility = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_UTILITY", False);
106
s_aNetWmWindowTypeDock = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
107
s_aNetWmIconGeometry = XInternAtom (s_XDisplay, "_NET_WM_ICON_GEOMETRY", False);
108
s_aNetCurrentDesktop = XInternAtom (s_XDisplay, "_NET_CURRENT_DESKTOP", False);
109
s_aNetDesktopViewport = XInternAtom (s_XDisplay, "_NET_DESKTOP_VIEWPORT", False);
110
s_aNetDesktopGeometry = XInternAtom (s_XDisplay, "_NET_DESKTOP_GEOMETRY", False);
111
s_aNetNbDesktops = XInternAtom (s_XDisplay, "_NET_NUMBER_OF_DESKTOPS", False);
112
s_aRootMapID = XInternAtom (s_XDisplay, "_XROOTPMAP_ID", False);
114
s_aNetClientListStacking = XInternAtom (s_XDisplay, "_NET_CLIENT_LIST_STACKING", False);
115
s_aNetClientList = XInternAtom (s_XDisplay, "_NET_CLIENT_LIST", False);
116
s_aNetActiveWindow = XInternAtom (s_XDisplay, "_NET_ACTIVE_WINDOW", False);
117
s_aNetWmState = XInternAtom (s_XDisplay, "_NET_WM_STATE", False);
118
s_aNetWmFullScreen = XInternAtom (s_XDisplay, "_NET_WM_STATE_FULLSCREEN", False);
119
s_aNetWmAbove = XInternAtom (s_XDisplay, "_NET_WM_STATE_ABOVE", False);
120
s_aNetWmBelow = XInternAtom (s_XDisplay, "_NET_WM_STATE_BELOW", False);
121
s_aNetWmSticky = XInternAtom (s_XDisplay, "_NET_WM_STATE_STICKY", False);
122
s_aNetWmHidden = XInternAtom (s_XDisplay, "_NET_WM_STATE_HIDDEN", False);
123
s_aNetWmSkipTaskbar = XInternAtom (s_XDisplay, "_NET_WM_STATE_SKIP_TASKBAR", False);
124
s_aNetWmMaximizedHoriz = XInternAtom (s_XDisplay, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
125
s_aNetWmMaximizedVert = XInternAtom (s_XDisplay, "_NET_WM_STATE_MAXIMIZED_VERT", False);
126
s_aNetWmDemandsAttention = XInternAtom (s_XDisplay, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
127
s_aNetWmDesktop = XInternAtom (s_XDisplay, "_NET_WM_DESKTOP", False);
128
s_aNetWmName = XInternAtom (s_XDisplay, "_NET_WM_NAME", False);
129
s_aWmName = XInternAtom (s_XDisplay, "WM_NAME", False);
130
s_aUtf8String = XInternAtom (s_XDisplay, "UTF8_STRING", False);
131
s_aString = XInternAtom (s_XDisplay, "STRING", False);
133
Screen *XScreen = XDefaultScreenOfDisplay (s_XDisplay);
134
g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] = WidthOfScreen (XScreen);
135
g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] = HeightOfScreen (XScreen);
136
g_iXScreenWidth[CAIRO_DOCK_VERTICAL] = g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
137
g_iXScreenHeight[CAIRO_DOCK_VERTICAL] = g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
139
g_iScreenWidth[CAIRO_DOCK_HORIZONTAL] = WidthOfScreen (XScreen);
140
g_iScreenHeight[CAIRO_DOCK_HORIZONTAL] = HeightOfScreen (XScreen);
141
g_iScreenWidth[CAIRO_DOCK_VERTICAL] = g_iScreenHeight[CAIRO_DOCK_HORIZONTAL];
142
g_iScreenHeight[CAIRO_DOCK_VERTICAL] = g_iScreenWidth[CAIRO_DOCK_HORIZONTAL];
144
g_iNbDesktops = cairo_dock_get_nb_desktops ();
145
cairo_dock_get_nb_viewports (&g_iNbViewportX, &g_iNbViewportY);
150
void cairo_dock_initialize_X_support (void)
152
Display *disp = cairo_dock_initialize_X_desktop_support ();
153
g_return_if_fail (disp != NULL);
154
cairo_dock_initialize_class_manager ();
155
cairo_dock_initialize_application_manager (s_XDisplay);
156
cairo_dock_initialize_application_factory (s_XDisplay);
159
Display *cairo_dock_get_Xdisplay (void)
164
guint cairo_dock_get_root_id (void)
166
return DefaultRootWindow (s_XDisplay);
170
gboolean cairo_dock_update_screen_geometry (void)
172
Window root = DefaultRootWindow (s_XDisplay);
174
int x_return=1, y_return=1;
175
unsigned int width_return, height_return, border_width_return, depth_return;
176
XGetGeometry (s_XDisplay, root,
178
&x_return, &y_return,
179
&width_return, &height_return,
180
&border_width_return, &depth_return);
181
if (width_return != g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] || height_return != g_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.
183
g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] = width_return;
184
g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] = height_return;
185
g_iXScreenWidth[CAIRO_DOCK_VERTICAL] = g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
186
g_iXScreenHeight[CAIRO_DOCK_VERTICAL] = g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
188
if (myPosition.bUseXinerama)
190
cairo_dock_get_screen_offsets (myPosition.iNumScreen, &g_pMainDock->iScreenOffsetX, &g_pMainDock->iScreenOffsetY); /// on le fait ici pour avoir g_iScreenWidth et g_iScreenHeight, mais il faudrait en faire un parametre par dock...
194
g_iScreenWidth[CAIRO_DOCK_HORIZONTAL] = g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
195
g_iScreenHeight[CAIRO_DOCK_HORIZONTAL] = g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
196
g_iScreenWidth[CAIRO_DOCK_VERTICAL] = g_iScreenHeight[CAIRO_DOCK_HORIZONTAL];
197
g_iScreenHeight[CAIRO_DOCK_VERTICAL] = g_iScreenWidth[CAIRO_DOCK_HORIZONTAL];
199
cd_message ("new screen size : %dx%d\n", g_iScreenWidth[CAIRO_DOCK_HORIZONTAL], g_iScreenHeight[CAIRO_DOCK_HORIZONTAL]);
204
/*Atom aNetWorkArea = XInternAtom (s_XDisplay, "_NET_WORKAREA", False);
205
iBufferNbElements = 0;
206
gulong *pXWorkArea = NULL;
207
XGetWindowProperty (s_XDisplay, root, aNetWorkArea, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXWorkArea);
209
for (i = 0; i < iBufferNbElements/4; i ++)
211
cd_message ("work area : (%d;%d) %dx%d\n", pXWorkArea[4*i], pXWorkArea[4*i+1], pXWorkArea[4*i+2], pXWorkArea[4*i+3]);
213
XFree (pXWorkArea);*/
217
gboolean cairo_dock_property_is_present_on_root (const gchar *cPropertyName)
219
g_return_val_if_fail (s_XDisplay != NULL, FALSE);
220
Atom atom = XInternAtom (s_XDisplay, cPropertyName, False);
221
Window root = DefaultRootWindow (s_XDisplay);
223
Atom *pAtomList = XListProperties (s_XDisplay, root, &iNbProperties);
225
for (i = 0; i < iNbProperties; i ++)
227
if (pAtomList[i] == atom)
231
return (i != iNbProperties);
235
int cairo_dock_get_current_desktop (void)
237
Window root = DefaultRootWindow (s_XDisplay);
238
Atom aReturnedType = 0;
239
int aReturnedFormat = 0;
240
unsigned long iLeftBytes, iBufferNbElements = 0;
241
gulong *pXDesktopNumberBuffer = NULL;
242
XGetWindowProperty (s_XDisplay, root, s_aNetCurrentDesktop, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXDesktopNumberBuffer);
245
if (iBufferNbElements > 0)
246
iDesktopNumber = *pXDesktopNumberBuffer;
250
XFree (pXDesktopNumberBuffer);
251
return iDesktopNumber;
254
void cairo_dock_get_current_viewport (int *iCurrentViewPortX, int *iCurrentViewPortY)
256
Window root = DefaultRootWindow (s_XDisplay);
259
int x_return=1, y_return=1;
260
unsigned int width_return, height_return, border_width_return, depth_return;
261
XGetGeometry (s_XDisplay, root,
263
&x_return, &y_return,
264
&width_return, &height_return,
265
&border_width_return, &depth_return);
266
*iCurrentViewPortX = x_return;
267
*iCurrentViewPortY = y_return;
269
Atom aReturnedType = 0;
270
int aReturnedFormat = 0;
271
unsigned long iLeftBytes, iBufferNbElements = 0;
272
gulong *pViewportsXY = NULL;
273
XGetWindowProperty (s_XDisplay, root, s_aNetDesktopViewport, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pViewportsXY);
274
if (iBufferNbElements > 0)
276
*iCurrentViewPortX = pViewportsXY[0];
277
*iCurrentViewPortY = pViewportsXY[1];
278
XFree (pViewportsXY);
283
int cairo_dock_get_nb_desktops (void)
285
Window root = DefaultRootWindow (s_XDisplay);
286
Atom aReturnedType = 0;
287
int aReturnedFormat = 0;
288
unsigned long iLeftBytes, iBufferNbElements = 0;
289
gulong *pXDesktopNumberBuffer = NULL;
290
XGetWindowProperty (s_XDisplay, root, s_aNetNbDesktops, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXDesktopNumberBuffer);
292
int iNumberOfDesktops;
293
if (iBufferNbElements > 0)
294
iNumberOfDesktops = *pXDesktopNumberBuffer;
296
iNumberOfDesktops = 0;
298
return iNumberOfDesktops;
301
void cairo_dock_get_nb_viewports (int *iNbViewportX, int *iNbViewportY)
303
Window root = DefaultRootWindow (s_XDisplay);
304
Atom aReturnedType = 0;
305
int aReturnedFormat = 0;
306
unsigned long iLeftBytes, iBufferNbElements = 0;
307
gulong *pVirtualScreenSizeBuffer = NULL;
308
XGetWindowProperty (s_XDisplay, root, s_aNetDesktopGeometry, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pVirtualScreenSizeBuffer);
309
if (iBufferNbElements > 0)
311
Screen *scr = XDefaultScreenOfDisplay (s_XDisplay);
312
cd_debug ("pVirtualScreenSizeBuffer : %dx%d ; screen : %dx%d", pVirtualScreenSizeBuffer[0], pVirtualScreenSizeBuffer[1], g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL], g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
313
*iNbViewportX = pVirtualScreenSizeBuffer[0] / g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
314
*iNbViewportY = pVirtualScreenSizeBuffer[1] / g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
315
XFree (pVirtualScreenSizeBuffer);
321
gboolean cairo_dock_desktop_is_visible (void)
323
Atom aNetShowingDesktop = XInternAtom (s_XDisplay, "_NET_SHOWING_DESKTOP", False);
324
gulong iLeftBytes, iBufferNbElements = 0;
325
Atom aReturnedType = 0;
326
int aReturnedFormat = 0;
327
gulong *pXBuffer = NULL;
328
Window root = DefaultRootWindow (s_XDisplay);
329
XGetWindowProperty (s_XDisplay, root, aNetShowingDesktop, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXBuffer);
331
gboolean bDesktopIsShown = (iBufferNbElements > 0 && pXBuffer != NULL ? *pXBuffer : FALSE);
333
return bDesktopIsShown;
336
void cairo_dock_show_hide_desktop (gboolean bShow)
338
XEvent xClientMessage;
339
Window root = DefaultRootWindow (s_XDisplay);
341
xClientMessage.xclient.type = ClientMessage;
342
xClientMessage.xclient.serial = 0;
343
xClientMessage.xclient.send_event = True;
344
xClientMessage.xclient.display = s_XDisplay;
345
xClientMessage.xclient.window = root;
346
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_SHOWING_DESKTOP", False);
347
xClientMessage.xclient.format = 32;
348
xClientMessage.xclient.data.l[0] = bShow;
349
xClientMessage.xclient.data.l[1] = 0;
350
xClientMessage.xclient.data.l[2] = 0;
351
xClientMessage.xclient.data.l[3] = 2;
352
xClientMessage.xclient.data.l[4] = 0;
354
g_print ("%s (%d)\n", __func__, bShow);
355
XSendEvent (s_XDisplay,
358
SubstructureRedirectMask | SubstructureNotifyMask,
362
static void cairo_dock_move_current_viewport_to (int iDesktopViewportX, int iDesktopViewportY)
364
XEvent xClientMessage;
365
Window root = DefaultRootWindow (s_XDisplay);
367
xClientMessage.xclient.type = ClientMessage;
368
xClientMessage.xclient.serial = 0;
369
xClientMessage.xclient.send_event = True;
370
xClientMessage.xclient.display = s_XDisplay;
371
xClientMessage.xclient.window = root;
372
xClientMessage.xclient.message_type = s_aNetDesktopViewport;
373
xClientMessage.xclient.format = 32;
374
xClientMessage.xclient.data.l[0] = iDesktopViewportX;
375
xClientMessage.xclient.data.l[1] = iDesktopViewportY;
376
xClientMessage.xclient.data.l[2] = 0;
377
xClientMessage.xclient.data.l[3] = 0;
378
xClientMessage.xclient.data.l[4] = 0;
380
XSendEvent (s_XDisplay,
383
SubstructureRedirectMask | SubstructureNotifyMask,
386
void cairo_dock_set_current_viewport (int iViewportNumberX, int iViewportNumberY)
388
cairo_dock_move_current_viewport_to (iViewportNumberX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL], iViewportNumberY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
390
void cairo_dock_set_current_desktop (int iDesktopNumber)
392
Window root = DefaultRootWindow (s_XDisplay);
393
int iTimeStamp = cairo_dock_get_xwindow_timestamp (root);
394
XEvent xClientMessage;
396
xClientMessage.xclient.type = ClientMessage;
397
xClientMessage.xclient.serial = 0;
398
xClientMessage.xclient.send_event = True;
399
xClientMessage.xclient.display = s_XDisplay;
400
xClientMessage.xclient.window = root;
401
xClientMessage.xclient.message_type = s_aNetCurrentDesktop;
402
xClientMessage.xclient.format = 32;
403
xClientMessage.xclient.data.l[0] = iDesktopNumber;
404
xClientMessage.xclient.data.l[1] = iTimeStamp;
405
xClientMessage.xclient.data.l[2] = 0;
406
xClientMessage.xclient.data.l[3] = 0;
407
xClientMessage.xclient.data.l[4] = 0;
409
XSendEvent (s_XDisplay,
412
SubstructureRedirectMask | SubstructureNotifyMask,
416
Pixmap cairo_dock_get_window_background_pixmap (Window Xid)
418
g_return_val_if_fail (Xid > 0, None);
419
//cd_debug ("%s (%d)", __func__, Xid);
422
Atom aReturnedType = 0;
423
int aReturnedFormat = 0;
424
unsigned long iLeftBytes, iBufferNbElements;
425
Pixmap *pPixmapIdBuffer = NULL;
426
Pixmap iBgPixmapID = 0;
427
XGetWindowProperty (s_XDisplay, Xid, s_aRootMapID, 0, G_MAXULONG, False, XA_PIXMAP, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pPixmapIdBuffer);
428
if (iBufferNbElements != 0)
430
iBgPixmapID = *pPixmapIdBuffer;
431
XFree (pPixmapIdBuffer);
435
cd_debug (" => rootmapid : %d", iBgPixmapID);
439
GdkPixbuf *cairo_dock_get_pixbuf_from_pixmap (int XPixmapID, gboolean bAddAlpha) // cette fonction est inspiree par celle de libwnck.
441
//\__________________ On recupere la taille telle qu'elle est actuellement sur le serveur X.
442
Window root; // inutile.
443
int x, y; // inutile.
444
guint border_width; // inutile.
445
guint iWidth, iHeight, iDepth;
446
if (! XGetGeometry (s_XDisplay,
447
XPixmapID, &root, &x, &y,
448
&iWidth, &iHeight, &border_width, &iDepth))
450
cd_debug ("%s (%d) : %ux%ux%u (%d;%d)", __func__, XPixmapID, iWidth, iHeight, iDepth, x, y);
452
//\__________________ On recupere le drawable associe.
453
GdkDrawable *pGdkDrawable = gdk_xid_table_lookup (XPixmapID);
455
g_object_ref (G_OBJECT (pGdkDrawable));
458
cd_debug ("pas d'objet GDK present, on en alloue un nouveau");
459
GdkScreen* pScreen = gdk_screen_get_default ();
460
pGdkDrawable = gdk_pixmap_foreign_new_for_screen (pScreen, XPixmapID, iWidth, iHeight, iDepth);
463
//\__________________ On recupere la colormap.
464
GdkColormap* pColormap = gdk_drawable_get_colormap (pGdkDrawable);
465
if (pColormap == NULL && gdk_drawable_get_depth (pGdkDrawable) > 1) // pour les bitmaps, on laisse la colormap a NULL, ils n'en ont pas besoin.
467
GdkScreen *pScreen = gdk_drawable_get_screen (GDK_DRAWABLE (pGdkDrawable));
468
if (gdk_drawable_get_depth (pGdkDrawable) == 32)
469
pColormap = gdk_screen_get_rgba_colormap (pScreen);
471
pColormap = gdk_screen_get_rgb_colormap (pScreen); // au pire on a un colormap nul.
472
cd_debug (" pColormap : %x (pScreen:%x)", pColormap, pScreen);
475
//\__________________ On recupere le buffer dans un GdkPixbuf.
476
GdkPixbuf *pIconPixbuf = gdk_pixbuf_get_from_drawable (NULL,
485
g_object_unref (G_OBJECT (pGdkDrawable));
486
g_return_val_if_fail (pIconPixbuf != NULL, NULL);
488
//\__________________ On lui ajoute un canal alpha si necessaire.
489
if (! gdk_pixbuf_get_has_alpha (pIconPixbuf) && bAddAlpha)
491
cd_debug (" on lui ajoute de la transparence");
492
GdkPixbuf *tmp_pixbuf = gdk_pixbuf_add_alpha (pIconPixbuf, FALSE, 255, 255, 255);
493
g_object_unref (pIconPixbuf);
494
pIconPixbuf = tmp_pixbuf;
500
void cairo_dock_set_nb_viewports (int iNbViewportX, int iNbViewportY)
502
XEvent xClientMessage;
503
Window root = DefaultRootWindow (s_XDisplay);
505
xClientMessage.xclient.type = ClientMessage;
506
xClientMessage.xclient.serial = 0;
507
xClientMessage.xclient.send_event = True;
508
xClientMessage.xclient.display = s_XDisplay;
509
xClientMessage.xclient.window = root;
510
xClientMessage.xclient.message_type = s_aNetDesktopGeometry;
511
xClientMessage.xclient.format = 32;
512
xClientMessage.xclient.data.l[0] = iNbViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
513
xClientMessage.xclient.data.l[1] = iNbViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
514
xClientMessage.xclient.data.l[2] = 0;
515
xClientMessage.xclient.data.l[3] = 2;
516
xClientMessage.xclient.data.l[4] = 0;
518
XSendEvent (s_XDisplay,
521
SubstructureRedirectMask | SubstructureNotifyMask,
525
void cairo_dock_set_nb_desktops (gulong iNbDesktops)
527
XEvent xClientMessage;
528
Window root = DefaultRootWindow (s_XDisplay);
530
xClientMessage.xclient.type = ClientMessage;
531
xClientMessage.xclient.serial = 0;
532
xClientMessage.xclient.send_event = True;
533
xClientMessage.xclient.display = s_XDisplay;
534
xClientMessage.xclient.window = root;
535
xClientMessage.xclient.message_type = s_aNetNbDesktops;
536
xClientMessage.xclient.format = 32;
537
xClientMessage.xclient.data.l[0] = iNbDesktops;
538
xClientMessage.xclient.data.l[1] = 0;
539
xClientMessage.xclient.data.l[2] = 0;
540
xClientMessage.xclient.data.l[3] = 2;
541
xClientMessage.xclient.data.l[4] = 0;
543
XSendEvent (s_XDisplay,
546
SubstructureRedirectMask | SubstructureNotifyMask,
551
gboolean cairo_dock_support_X_extension (void)
554
int event_base, error_base, major, minor;
555
if (! XCompositeQueryExtension (s_XDisplay, &event_base, &error_base)) // on regarde si le serveur X supporte l'extension.
557
cd_warning ("XComposite extension not available.");
558
s_bUseXComposite = FALSE;
562
major = 0, minor = 2; // La version minimale requise pour avoir XCompositeNameWindowPixmap().
563
XCompositeQueryVersion (s_XDisplay, &major, &minor); // on regarde si on est au moins dans cette version.
564
if (! (major > 0 || minor >= 2))
566
cd_warning ("XComposite extension too old.");
567
s_bUseXComposite = FALSE;
570
/*int iDamageError=0;
571
if (! XDamageQueryExtension (s_XDisplay, &g_iDamageEvent, &iDamageError))
573
cd_warning ("XDamage extension not supported");
577
major = 0, minor = 0;
578
if (! XTestQueryExtension (s_XDisplay, &event_base, &error_base, &major, &minor))
580
cd_warning ("XTest extension not available.");
584
if (! XineramaQueryExtension (s_XDisplay, &event_base, &error_base))
586
cd_warning ("Xinerama extension not supported");
587
s_bUseXinerama = FALSE;
591
major = 0, minor = 0;
592
if (XineramaQueryVersion (s_XDisplay, &major, &minor) == 0)
594
cd_warning ("Xinerama extension too old");
595
s_bUseXinerama = FALSE;
601
cd_warning ("The dock was not compiled with the X extensions (XComposite, xinerama, xtst, XDamage, etc).");
602
s_bUseXComposite = FALSE;
604
s_bUseXinerama = FALSE;
609
gboolean cairo_dock_xcomposite_is_available (void)
611
return s_bUseXComposite;
614
gboolean cairo_dock_xtest_is_available (void)
619
gboolean cairo_dock_xinerama_is_available (void)
621
return s_bUseXinerama;
625
void cairo_dock_get_screen_offsets (int iNumScreen, int *iScreenOffsetX, int *iScreenOffsetY)
628
g_return_if_fail (s_bUseXinerama);
630
XineramaScreenInfo *pScreens = XineramaQueryScreens (s_XDisplay, &iNbScreens);
631
if (pScreens != NULL)
633
if (iNumScreen >= iNbScreens)
635
cd_warning ("the number of screen where to place the dock is too big, we'll choose the last one.");
636
iNumScreen = iNbScreens - 1;
638
*iScreenOffsetX = pScreens[iNumScreen].x_org;
639
*iScreenOffsetY = pScreens[iNumScreen].y_org;
640
g_iScreenWidth[CAIRO_DOCK_HORIZONTAL] = pScreens[iNumScreen].width;
641
g_iScreenHeight[CAIRO_DOCK_HORIZONTAL] = pScreens[iNumScreen].height;
643
g_iScreenWidth[CAIRO_DOCK_VERTICAL] = g_iScreenHeight[CAIRO_DOCK_HORIZONTAL];
644
g_iScreenHeight[CAIRO_DOCK_VERTICAL] = g_iScreenWidth[CAIRO_DOCK_HORIZONTAL];
645
cd_message (" * screen %d => (%d;%d) %dx%d\n", iNumScreen, *iScreenOffsetX, *iScreenOffsetY, g_iScreenWidth[CAIRO_DOCK_HORIZONTAL], g_iScreenHeight[CAIRO_DOCK_HORIZONTAL]);
651
cd_warning ("No screen found from Xinerama, is it really active ?");
652
*iScreenOffsetX = *iScreenOffsetY = 0;
653
g_iScreenWidth[CAIRO_DOCK_HORIZONTAL] = g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
654
g_iScreenHeight[CAIRO_DOCK_HORIZONTAL] = g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
655
g_iScreenWidth[CAIRO_DOCK_VERTICAL] = g_iScreenHeight[CAIRO_DOCK_HORIZONTAL];
656
g_iScreenHeight[CAIRO_DOCK_VERTICAL] = g_iScreenWidth[CAIRO_DOCK_HORIZONTAL];
659
cd_warning ("The dock was not compiled with the support of Xinerama.");
668
void cairo_dock_set_xwindow_timestamp (Window Xid, gulong iTimeStamp)
670
g_return_if_fail (Xid > 0);
671
Atom aNetWmUserTime = XInternAtom (s_XDisplay, "_NET_WM_USER_TIME", False);
672
XChangeProperty (s_XDisplay,
675
XA_CARDINAL, 32, PropModeReplace,
676
(guchar *)&iTimeStamp, 1);
679
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)
681
g_return_if_fail (Xid > 0);
683
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);
684
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};
686
XChangeProperty (s_XDisplay,
688
XInternAtom (s_XDisplay, "_NET_WM_STRUT_PARTIAL", False),
689
XA_CARDINAL, 32, PropModeReplace,
690
(guchar *) iGeometryStrut, 12);
692
Window root = DefaultRootWindow (s_XDisplay);
693
cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
696
void cairo_dock_set_xwindow_mask (Window Xid, long iMask)
698
//StructureNotifyMask | /*ResizeRedirectMask*/
699
//SubstructureRedirectMask |
700
//SubstructureNotifyMask | // place sur le root, donne les evenements Map, Unmap, Destroy, Create de chaque fenetre.
702
XSelectInput (s_XDisplay, Xid, iMask); // c'est le 'event_mask' d'un XSetWindowAttributes.
705
void cairo_dock_set_xwindow_type_hint (int Xid, const gchar *cWindowTypeName)
707
g_return_if_fail (Xid > 0);
709
gulong iWindowType = XInternAtom (s_XDisplay, cWindowTypeName, False);
710
cd_debug ("%s (%d, %s=%d)", __func__, Xid, cWindowTypeName, iWindowType);
712
XChangeProperty (s_XDisplay,
715
XA_ATOM, 32, PropModeReplace,
716
(guchar *) &iWindowType, 1);
720
void cairo_dock_set_xicon_geometry (int Xid, int iX, int iY, int iWidth, int iHeight)
722
g_return_if_fail (Xid > 0);
724
gulong iIconGeometry[4] = {iX, iY, iWidth, iHeight};
726
if (iWidth == 0 || iHeight == 0)
727
XDeleteProperty (s_XDisplay,
729
s_aNetWmIconGeometry);
731
XChangeProperty (s_XDisplay,
733
s_aNetWmIconGeometry,
734
XA_CARDINAL, 32, PropModeReplace,
735
(guchar *) iIconGeometry, 4);
740
void cairo_dock_close_xwindow (Window Xid)
742
//g_print ("%s (%d)\n", __func__, Xid);
743
g_return_if_fail (Xid > 0);
745
XEvent xClientMessage;
747
xClientMessage.xclient.type = ClientMessage;
748
xClientMessage.xclient.serial = 0;
749
xClientMessage.xclient.send_event = True;
750
xClientMessage.xclient.display = s_XDisplay;
751
xClientMessage.xclient.window = Xid;
752
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_CLOSE_WINDOW", False);
753
xClientMessage.xclient.format = 32;
754
xClientMessage.xclient.data.l[0] = cairo_dock_get_xwindow_timestamp (Xid); // timestamp
755
xClientMessage.xclient.data.l[1] = 2; // 2 <=> pagers and other Clients that represent direct user actions.
756
xClientMessage.xclient.data.l[2] = 0;
757
xClientMessage.xclient.data.l[3] = 0;
758
xClientMessage.xclient.data.l[4] = 0;
760
Window root = DefaultRootWindow (s_XDisplay);
761
XSendEvent (s_XDisplay,
764
SubstructureRedirectMask | SubstructureNotifyMask,
766
//cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
769
void cairo_dock_kill_xwindow (Window Xid)
771
g_return_if_fail (Xid > 0);
772
XKillClient (s_XDisplay, Xid);
775
void cairo_dock_show_xwindow (Window Xid)
777
g_return_if_fail (Xid > 0);
778
XEvent xClientMessage;
779
Window root = DefaultRootWindow (s_XDisplay);
781
//\______________ On se deplace sur le bureau de la fenetre a afficher (autrement Metacity deplacera la fenetre sur le bureau actuel).
782
int iDesktopNumber = cairo_dock_get_xwindow_desktop (Xid);
783
cairo_dock_set_current_desktop (iDesktopNumber);
785
//\______________ On active la fenetre.
786
//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 :-(
787
xClientMessage.xclient.type = ClientMessage;
788
xClientMessage.xclient.serial = 0;
789
xClientMessage.xclient.send_event = True;
790
xClientMessage.xclient.display = s_XDisplay;
791
xClientMessage.xclient.window = Xid;
792
xClientMessage.xclient.message_type = s_aNetActiveWindow;
793
xClientMessage.xclient.format = 32;
794
xClientMessage.xclient.data.l[0] = 2; // source indication
795
xClientMessage.xclient.data.l[1] = 0; // timestamp
796
xClientMessage.xclient.data.l[2] = 0; // requestor's currently active window, 0 if none
797
xClientMessage.xclient.data.l[3] = 0;
798
xClientMessage.xclient.data.l[4] = 0;
800
XSendEvent (s_XDisplay,
803
SubstructureRedirectMask | SubstructureNotifyMask,
806
//cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
809
void cairo_dock_minimize_xwindow (Window Xid)
811
g_return_if_fail (Xid > 0);
812
XIconifyWindow (s_XDisplay, Xid, DefaultScreen (s_XDisplay));
813
//Window root = DefaultRootWindow (s_XDisplay);
814
//cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
819
static void _cairo_dock_change_window_state (Window Xid, gulong iNewValue, Atom iProperty1, Atom iProperty2)
821
g_return_if_fail (Xid > 0);
822
XEvent xClientMessage;
824
xClientMessage.xclient.type = ClientMessage;
825
xClientMessage.xclient.serial = 0;
826
xClientMessage.xclient.send_event = True;
827
xClientMessage.xclient.display = s_XDisplay;
828
xClientMessage.xclient.window = Xid;
829
xClientMessage.xclient.message_type = s_aNetWmState;
830
xClientMessage.xclient.format = 32;
831
xClientMessage.xclient.data.l[0] = iNewValue;
832
xClientMessage.xclient.data.l[1] = iProperty1;
833
xClientMessage.xclient.data.l[2] = iProperty2;
834
xClientMessage.xclient.data.l[3] = 2;
835
xClientMessage.xclient.data.l[4] = 0;
837
Window root = DefaultRootWindow (s_XDisplay);
838
XSendEvent (s_XDisplay,
841
SubstructureRedirectMask | SubstructureNotifyMask,
844
cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
846
void cairo_dock_maximize_xwindow (Window Xid, gboolean bMaximize)
848
_cairo_dock_change_window_state (Xid, bMaximize, s_aNetWmMaximizedVert, s_aNetWmMaximizedHoriz);
851
void cairo_dock_set_xwindow_fullscreen (Window Xid, gboolean bFullScreen)
853
_cairo_dock_change_window_state (Xid, bFullScreen, s_aNetWmFullScreen, 0);
856
void cairo_dock_set_xwindow_above (Window Xid, gboolean bAbove)
858
_cairo_dock_change_window_state (Xid, bAbove, s_aNetWmAbove, 0);
862
void cairo_dock_move_xwindow_to_absolute_position (Window Xid, int iDesktopNumber, int iPositionX, int iPositionY) // dans le referentiel du viewport courant.
864
g_return_if_fail (Xid > 0);
865
XEvent xClientMessage;
867
xClientMessage.xclient.type = ClientMessage;
868
xClientMessage.xclient.serial = 0;
869
xClientMessage.xclient.send_event = True;
870
xClientMessage.xclient.display = s_XDisplay;
871
xClientMessage.xclient.window = Xid;
872
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_WM_DESKTOP", False);
873
xClientMessage.xclient.format = 32;
874
xClientMessage.xclient.data.l[0] = iDesktopNumber;
875
xClientMessage.xclient.data.l[1] = 2;
876
xClientMessage.xclient.data.l[2] = 0;
877
xClientMessage.xclient.data.l[3] = 0;
878
xClientMessage.xclient.data.l[4] = 0;
880
Window root = DefaultRootWindow (s_XDisplay);
881
XSendEvent (s_XDisplay,
884
SubstructureRedirectMask | SubstructureNotifyMask,
887
xClientMessage.xclient.type = ClientMessage;
888
xClientMessage.xclient.serial = 0;
889
xClientMessage.xclient.send_event = True;
890
xClientMessage.xclient.display = s_XDisplay;
891
xClientMessage.xclient.window = Xid;
892
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_MOVERESIZE_WINDOW", False);
893
xClientMessage.xclient.format = 32;
894
xClientMessage.xclient.data.l[0] = StaticGravity | (1 << 8) | (1 << 9) | (0 << 10) | (0 << 11);
895
xClientMessage.xclient.data.l[1] = iPositionX; // coordonnees dans le referentiel du viewport desire.
896
xClientMessage.xclient.data.l[2] = iPositionY;
897
xClientMessage.xclient.data.l[3] = 0;
898
xClientMessage.xclient.data.l[4] = 0;
899
XSendEvent (s_XDisplay,
902
SubstructureRedirectMask | SubstructureNotifyMask,
905
//cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
908
void cairo_dock_move_xwindow_to_nth_desktop (Window Xid, int iDesktopNumber, int iDesktopViewportX, int iDesktopViewportY)
910
g_return_if_fail (Xid > 0);
911
XEvent xClientMessage;
913
xClientMessage.xclient.type = ClientMessage;
914
xClientMessage.xclient.serial = 0;
915
xClientMessage.xclient.send_event = True;
916
xClientMessage.xclient.display = s_XDisplay;
917
xClientMessage.xclient.window = Xid;
918
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_WM_DESKTOP", False);
919
xClientMessage.xclient.format = 32;
920
xClientMessage.xclient.data.l[0] = iDesktopNumber;
921
xClientMessage.xclient.data.l[1] = 2;
922
xClientMessage.xclient.data.l[2] = 0;
923
xClientMessage.xclient.data.l[3] = 0;
924
xClientMessage.xclient.data.l[4] = 0;
926
Window root = DefaultRootWindow (s_XDisplay);
927
XSendEvent (s_XDisplay,
930
SubstructureRedirectMask | SubstructureNotifyMask,
933
int iRelativePositionX, iRelativePositionY;
934
cairo_dock_get_xwindow_position_on_its_viewport (Xid, &iRelativePositionX, &iRelativePositionY);
936
g_print ("* move to %d+%d\n", iDesktopViewportX, iRelativePositionX);
938
xClientMessage.xclient.type = ClientMessage;
939
xClientMessage.xclient.serial = 0;
940
xClientMessage.xclient.send_event = True;
941
xClientMessage.xclient.display = s_XDisplay;
942
xClientMessage.xclient.window = Xid;
943
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_MOVERESIZE_WINDOW", False);
944
xClientMessage.xclient.format = 32;
945
xClientMessage.xclient.data.l[0] = StaticGravity | (1 << 8) | (1 << 9) | (0 << 10) | (0 << 11);
946
xClientMessage.xclient.data.l[1] = iDesktopViewportX + iRelativePositionX; // coordonnees dans le referentiel du viewport desire.
947
xClientMessage.xclient.data.l[2] = iDesktopViewportY + iRelativePositionY;
948
xClientMessage.xclient.data.l[3] = 0;
949
xClientMessage.xclient.data.l[4] = 0;
950
XSendEvent (s_XDisplay,
953
SubstructureRedirectMask | SubstructureNotifyMask,
956
//cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
961
gulong cairo_dock_get_xwindow_timestamp (Window Xid)
963
g_return_val_if_fail (Xid > 0, 0);
964
Atom aNetWmUserTime = XInternAtom (s_XDisplay, "_NET_WM_USER_TIME", False);
965
gulong iLeftBytes, iBufferNbElements = 0;
966
Atom aReturnedType = 0;
967
int aReturnedFormat = 0;
968
gulong *pTimeBuffer = NULL;
969
XGetWindowProperty (s_XDisplay, Xid, aNetWmUserTime, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pTimeBuffer);
970
gulong iTimeStamp = 0;
971
if (iBufferNbElements > 0)
972
iTimeStamp = *pTimeBuffer;
977
gchar *cairo_dock_get_xwindow_name (Window Xid, gboolean bSearchWmName)
979
Atom aReturnedType = 0;
980
int aReturnedFormat = 0;
981
unsigned long iLeftBytes, iBufferNbElements=0;
982
guchar *pNameBuffer = NULL;
983
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.
984
if (iBufferNbElements == 0 && bSearchWmName)
985
XGetWindowProperty (s_XDisplay, Xid, s_aWmName, 0, G_MAXULONG, False, s_aString, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);
988
if (iBufferNbElements > 0)
990
cName = g_strdup (pNameBuffer);
996
gboolean cairo_dock_xwindow_is_maximized (Window Xid)
998
g_return_val_if_fail (Xid > 0, FALSE);
1000
Atom aReturnedType = 0;
1001
int aReturnedFormat = 0;
1002
unsigned long iLeftBytes, iBufferNbElements = 0;
1003
gulong *pXStateBuffer = NULL;
1004
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
1005
int iIsMaximized = 0;
1006
if (iBufferNbElements > 0)
1009
for (i = 0; i < iBufferNbElements && iIsMaximized < 2; i ++)
1011
if (pXStateBuffer[i] == s_aNetWmMaximizedVert)
1013
if (pXStateBuffer[i] == s_aNetWmMaximizedHoriz)
1017
XFree (pXStateBuffer);
1019
return (iIsMaximized == 2);
1022
static gboolean _cairo_dock_window_is_in_state (Window Xid, Atom iState)
1024
g_return_val_if_fail (Xid > 0, FALSE);
1025
Atom aReturnedType = 0;
1026
int aReturnedFormat = 0;
1027
unsigned long iLeftBytes, iBufferNbElements = 0;
1028
gulong *pXStateBuffer = NULL;
1029
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
1031
gboolean bIsInState = FALSE;
1032
if (iBufferNbElements > 0)
1035
for (i = 0; i < iBufferNbElements; i ++)
1037
if (pXStateBuffer[i] == iState)
1045
XFree (pXStateBuffer);
1049
gboolean cairo_dock_xwindow_is_fullscreen (Window Xid)
1051
return _cairo_dock_window_is_in_state (Xid, s_aNetWmFullScreen);
1053
gboolean cairo_dock_xwindow_skip_taskbar (Window Xid)
1055
return _cairo_dock_window_is_in_state (Xid, s_aNetWmSkipTaskbar);
1057
void cairo_dock_xwindow_is_above_or_below (Window Xid, gboolean *bIsAbove, gboolean *bIsBelow)
1059
g_return_if_fail (Xid > 0);
1060
Atom aReturnedType = 0;
1061
int aReturnedFormat = 0;
1062
unsigned long iLeftBytes, iBufferNbElements = 0;
1063
gulong *pXStateBuffer = NULL;
1064
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
1066
if (iBufferNbElements > 0)
1069
//g_print ("iBufferNbElements : %d (%d;%d)\n", iBufferNbElements, s_aNetWmAbove, s_aNetWmBelow);
1070
for (i = 0; i < iBufferNbElements; i ++)
1072
//g_print (" - %d\n", pXStateBuffer[i]);
1073
if (pXStateBuffer[i] == s_aNetWmAbove)
1079
else if (pXStateBuffer[i] == s_aNetWmBelow)
1088
XFree (pXStateBuffer);
1091
gboolean cairo_dock_xwindow_is_fullscreen_or_hidden_or_maximized (Window Xid, gboolean *bIsFullScreen, gboolean *bIsHidden, gboolean *bIsMaximized, gboolean *bDemandsAttention)
1093
g_return_val_if_fail (Xid > 0, FALSE);
1094
//cd_debug ("%s (%d)", __func__, Xid);
1095
Atom aReturnedType = 0;
1096
int aReturnedFormat = 0;
1097
unsigned long iLeftBytes, iBufferNbElements = 0;
1098
gulong *pXStateBuffer = NULL;
1099
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
1101
gboolean bValid = TRUE;
1102
*bIsFullScreen = FALSE;
1104
*bIsMaximized = FALSE;
1105
if (bDemandsAttention != NULL)
1106
*bDemandsAttention = FALSE;
1107
if (iBufferNbElements > 0)
1109
guint i, iNbMaximizedDimensions = 0;
1110
for (i = 0; i < iBufferNbElements; i ++)
1112
if (pXStateBuffer[i] == s_aNetWmFullScreen)
1114
*bIsFullScreen = TRUE;
1116
else if (pXStateBuffer[i] == s_aNetWmHidden)
1120
else if (pXStateBuffer[i] == s_aNetWmMaximizedVert)
1122
iNbMaximizedDimensions ++;
1123
if (iNbMaximizedDimensions == 2)
1124
*bIsMaximized = TRUE;
1126
else if (pXStateBuffer[i] == s_aNetWmMaximizedHoriz)
1128
iNbMaximizedDimensions ++;
1129
if (iNbMaximizedDimensions == 2)
1130
*bIsMaximized = TRUE;
1132
else if (pXStateBuffer[i] == s_aNetWmDemandsAttention && bDemandsAttention != NULL)
1134
*bDemandsAttention = TRUE;
1137
else if (pXStateBuffer[i] == s_aNetWmSkipTaskbar)
1139
cd_warning ("this appli should not be in taskbar anymore !");
1145
XFree (pXStateBuffer);
1149
gboolean cairo_dock_xwindow_is_sticky (Window Xid)
1151
g_return_val_if_fail (Xid > 0, FALSE);
1152
Atom aReturnedType = 0;
1153
int aReturnedFormat = 0;
1154
unsigned long iLeftBytes, iBufferNbElements = 0;
1155
gulong *pXStateBuffer = NULL;
1156
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
1158
gboolean bIsSticky = FALSE;
1159
if (iBufferNbElements > 0)
1162
//g_print ("iBufferNbElements : %d (%d;%d)\n", iBufferNbElements, s_aNetWmAbove, s_aNetWmBelow);
1163
for (i = 0; i < iBufferNbElements; i ++)
1165
//g_print (" - %d\n", pXStateBuffer[i]);
1166
if (pXStateBuffer[i] == s_aNetWmSticky)
1174
XFree (pXStateBuffer);
1178
static inline gboolean _cairo_dock_window_has_type (int Xid, Atom iType)
1180
g_return_val_if_fail (Xid > 0, FALSE);
1183
Atom aReturnedType = 0;
1184
int aReturnedFormat = 0;
1185
unsigned long iLeftBytes, iBufferNbElements;
1186
gulong *pTypeBuffer = NULL;
1187
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmWindowType, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pTypeBuffer);
1188
if (iBufferNbElements != 0)
1190
bIsType = (*pTypeBuffer == iType);
1191
XFree (pTypeBuffer);
1197
gboolean cairo_dock_window_is_utility (int Xid)
1199
return _cairo_dock_window_has_type (Xid, s_aNetWmWindowTypeUtility);
1202
gboolean cairo_dock_window_is_dock (int Xid)
1204
return _cairo_dock_window_has_type (Xid, s_aNetWmWindowTypeDock);
1207
int cairo_dock_get_xwindow_desktop (Window Xid)
1210
gulong iLeftBytes, iBufferNbElements = 0;
1211
Atom aReturnedType = 0;
1212
int aReturnedFormat = 0;
1213
gulong *pBuffer = NULL;
1214
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmDesktop, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pBuffer);
1215
if (iBufferNbElements > 0)
1216
iDesktopNumber = *pBuffer;
1221
return iDesktopNumber;
1224
void cairo_dock_get_xwindow_geometry (Window Xid, int *iGlobalPositionX, int *iGlobalPositionY, 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).
1227
int x_return=1, y_return=1;
1228
unsigned int width_return, height_return, border_width_return, depth_return;
1229
XGetGeometry (s_XDisplay, Xid,
1231
&x_return, &y_return,
1232
&width_return, &height_return,
1233
&border_width_return, &depth_return); // renvoie les coordonnees du coin haut gauche dans le referentiel du viewport actuel.
1235
*iGlobalPositionX = x_return; // on pourrait tenir compte de border_width_return...
1236
*iGlobalPositionY = y_return; // idem.
1237
*iWidthExtent = width_return; // idem.
1238
*iHeightExtent = height_return; // idem.
1239
//g_print ("%s () -> %d;%d %dx%d / %d,%d\n", __func__, x_return, y_return, *iWidthExtent, *iHeightExtent, border_width_return, depth_return);
1242
void cairo_dock_get_xwindow_position_on_its_viewport (Window Xid, int *iRelativePositionX, int *iRelativePositionY)
1244
int iGlobalPositionX, iGlobalPositionY, iWidthExtent, iHeightExtent;
1245
cairo_dock_get_xwindow_geometry (Xid, &iGlobalPositionX, &iGlobalPositionY, &iWidthExtent, &iHeightExtent);
1247
while (iGlobalPositionX < 0) // on passe au referentiel du viewport de la fenetre; inutile de connaitre sa position, puisqu'ils ont tous la meme taille.
1248
iGlobalPositionX += g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
1249
while (iGlobalPositionX >= g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL])
1250
iGlobalPositionX -= g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
1251
while (iGlobalPositionY < 0)
1252
iGlobalPositionY += g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
1253
while (iGlobalPositionY >= g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
1254
iGlobalPositionY -= g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
1256
*iRelativePositionX = iGlobalPositionX;
1257
*iRelativePositionY = iGlobalPositionY;
1258
//cd_debug ("position relative : (%d;%d) taille : %dx%d", *iRelativePositionX, *iRelativePositionY, iWidthExtent, iHeightExtent);
1262
gboolean cairo_dock_xwindow_is_on_this_desktop (Window Xid, int iDesktopNumber)
1264
int iWindowDesktopNumber, iGlobalPositionX, iGlobalPositionY, iWidthExtent, iHeightExtent; // coordonnees du coin haut gauche dans le referentiel du viewport actuel.
1265
iWindowDesktopNumber = cairo_dock_get_xwindow_desktop (Xid);
1266
cairo_dock_get_xwindow_geometry (Xid, &iGlobalPositionX, &iGlobalPositionY, &iWidthExtent, &iHeightExtent);
1268
//cd_debug (" -> %d/%d ; (%d ; %d)", iWindowDesktopNumber, iDesktopNumber, iGlobalPositionX, iGlobalPositionY);
1269
return ( (iWindowDesktopNumber == iDesktopNumber || iWindowDesktopNumber == -1) &&
1270
iGlobalPositionX + iWidthExtent > 0 &&
1271
iGlobalPositionX < g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] &&
1272
iGlobalPositionY + iHeightExtent > 0 &&
1273
iGlobalPositionY < g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] ); // -1 <=> 0xFFFFFFFF en unsigned.
1276
gboolean cairo_dock_xwindow_is_on_current_desktop (Window Xid)
1278
int iDesktopNumber, iDesktopViewportX, iDesktopViewportY;
1279
iDesktopNumber = cairo_dock_get_current_desktop ();
1281
return cairo_dock_xwindow_is_on_this_desktop (Xid, iDesktopNumber);
1285
Window *cairo_dock_get_windows_list (gulong *iNbWindows, gboolean bStackOrder)
1287
Atom aReturnedType = 0;
1288
int aReturnedFormat = 0;
1289
Window *XidList = NULL;
1291
Window root = DefaultRootWindow (s_XDisplay);
1293
XGetWindowProperty (s_XDisplay, root, (bStackOrder ? s_aNetClientListStacking : s_aNetClientList), 0, G_MAXLONG, False, XA_WINDOW, &aReturnedType, &aReturnedFormat, iNbWindows, &iLeftBytes, (guchar **)&XidList);
1297
Window cairo_dock_get_active_xwindow (void)
1299
Atom aReturnedType = 0;
1300
int aReturnedFormat = 0;
1301
unsigned long iLeftBytes, iBufferNbElements = 0;
1302
Window *pXBuffer = NULL;
1303
Window root = DefaultRootWindow (s_XDisplay);
1304
XGetWindowProperty (s_XDisplay, root, s_aNetActiveWindow, 0, G_MAXULONG, False, XA_WINDOW, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXBuffer);
1306
Window xActiveWindow = (iBufferNbElements > 0 && pXBuffer != NULL ? pXBuffer[0] : 0);
1308
return xActiveWindow;