~ubuntu-branches/ubuntu/trusty/tomahawk/trusty-proposed

« back to all changes in this revision

Viewing changes to thirdparty/libqnetwm/libqnetwm/netwm.cpp

  • Committer: Package Import Robot
  • Author(s): Harald Sitter
  • Date: 2013-03-07 21:50:13 UTC
  • Revision ID: package-import@ubuntu.com-20130307215013-6gdjkdds7i9uenvs
Tags: upstream-0.6.0+dfsg
ImportĀ upstreamĀ versionĀ 0.6.0+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2010 by Dmitry 'Krasu' Baryshev                         *
 
3
 *   ksquirrel.iv@gmail.com                                                *
 
4
 *                                                                         *
 
5
 *   This program is free software; you can redistribute it and/or modify  *
 
6
 *   it under the terms of the GNU General Public License as published by  *
 
7
 *   the Free Software Foundation; either version 3 of the License, or     *
 
8
 *   (at your option) any later version.                                   *
 
9
 *                                                                         *
 
10
 *   This program is distributed in the hope that it will be useful,       *
 
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
13
 *   GNU General Public License for more details.                          *
 
14
 *                                                                         *
 
15
 *   You should have received a copy of the GNU General Public License     *
 
16
 *   along with this program; if not, write to the                         *
 
17
 *   Free Software Foundation, Inc.,                                       *
 
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 
19
 ***************************************************************************/
 
20
 
 
21
#include <QX11Info>
 
22
 
 
23
#include <climits>
 
24
#include <cstring>
 
25
#include <cstdio>
 
26
#include <cstdlib>
 
27
 
 
28
#include <strings.h>
 
29
 
 
30
#include <unistd.h>
 
31
 
 
32
#include <X11/Xutil.h>
 
33
 
 
34
#if 0
 
35
#include <X11/extensions/Xcomposite.h>
 
36
#endif
 
37
 
 
38
#include "netwm.h"
 
39
 
 
40
#define DBG(...) //fprintf(stderr, ##__VA_ARGS__)
 
41
 
 
42
Atom NETWM::UTF8_STRING = 0;
 
43
Atom NETWM::XROOTPMAP_ID = 0;
 
44
 
 
45
Atom NETWM::WM_STATE = 0;
 
46
Atom NETWM::WM_CLASS = 0;
 
47
Atom NETWM::WM_NAME = 0;
 
48
Atom NETWM::WM_DELETE_WINDOW = 0;
 
49
Atom NETWM::WM_PROTOCOLS = 0;
 
50
Atom NETWM::WM_CHANGE_STATE = 0;
 
51
Atom NETWM::WM_WINDOW_ROLE = 0;
 
52
 
 
53
Atom NETWM::NET_WORKAREA = 0;
 
54
Atom NETWM::NET_CLIENT_LIST = 0;
 
55
Atom NETWM::NET_CLIENT_LIST_STACKING = 0;
 
56
Atom NETWM::NET_NUMBER_OF_DESKTOPS = 0;
 
57
Atom NETWM::NET_CURRENT_DESKTOP = 0;
 
58
Atom NETWM::NET_DESKTOP_NAMES = 0;
 
59
Atom NETWM::NET_ACTIVE_WINDOW = 0;
 
60
Atom NETWM::NET_CLOSE_WINDOW = 0;
 
61
Atom NETWM::NET_SUPPORTED = 0;
 
62
Atom NETWM::NET_WM_DESKTOP = 0;
 
63
Atom NETWM::NET_SHOWING_DESKTOP = 0;
 
64
 
 
65
Atom NETWM::NET_WM_STATE = 0;
 
66
Atom NETWM::NET_WM_STATE_MODAL = 0;
 
67
Atom NETWM::NET_WM_STATE_STICKY = 0;
 
68
Atom NETWM::NET_WM_STATE_MAXIMIZED_VERT = 0;
 
69
Atom NETWM::NET_WM_STATE_MAXIMIZED_HORZ = 0;
 
70
Atom NETWM::NET_WM_STATE_SHADED = 0;
 
71
Atom NETWM::NET_WM_STATE_SKIP_TASKBAR = 0;
 
72
Atom NETWM::NET_WM_STATE_SKIP_PAGER = 0;
 
73
Atom NETWM::NET_WM_STATE_HIDDEN = 0;
 
74
Atom NETWM::NET_WM_STATE_FULLSCREEN = 0;
 
75
Atom NETWM::NET_WM_STATE_ABOVE = 0;
 
76
Atom NETWM::NET_WM_STATE_BELOW = 0;
 
77
Atom NETWM::NET_WM_STATE_STAYS_ON_TOP = 0;
 
78
Atom NETWM::NET_WM_STATE_STAYS_ON_BOTTOM = 0;
 
79
Atom NETWM::NET_WM_STATE_DEMANDS_ATTENTION = 0;
 
80
 
 
81
Atom NETWM::NET_WM_WINDOW_TYPE = 0;
 
82
Atom NETWM::NET_WM_WINDOW_TYPE_DESKTOP = 0;
 
83
Atom NETWM::NET_WM_WINDOW_TYPE_DOCK = 0;
 
84
Atom NETWM::MODERRO_WINDOW_TYPE_DOCK = 0;
 
85
Atom NETWM::NET_WM_WINDOW_TYPE_TOOLBAR = 0;
 
86
Atom NETWM::NET_WM_WINDOW_TYPE_MENU = 0;
 
87
Atom NETWM::NET_WM_WINDOW_TYPE_UTILITY = 0;
 
88
Atom NETWM::NET_WM_WINDOW_TYPE_SPLASH = 0;
 
89
Atom NETWM::NET_WM_WINDOW_TYPE_DIALOG = 0;
 
90
Atom NETWM::NET_WM_WINDOW_TYPE_DROPDOWN_MENU = 0;
 
91
Atom NETWM::NET_WM_WINDOW_TYPE_POPUP_MENU = 0;
 
92
Atom NETWM::NET_WM_WINDOW_TYPE_TOOLTIP = 0;
 
93
Atom NETWM::NET_WM_WINDOW_TYPE_NOTIFICATION = 0;
 
94
Atom NETWM::NET_WM_WINDOW_TYPE_COMBO = 0;
 
95
Atom NETWM::NET_WM_WINDOW_TYPE_DND = 0;
 
96
Atom NETWM::NET_WM_WINDOW_TYPE_NORMAL = 0;
 
97
Atom NETWM::NET_WM_WINDOW_OPACITY = 0;
 
98
Atom NETWM::NET_WM_NAME = 0;
 
99
Atom NETWM::NET_WM_VISIBLE_NAME = 0;
 
100
Atom NETWM::NET_WM_STRUT = 0;
 
101
Atom NETWM::NET_WM_STRUT_PARTIAL = 0;
 
102
Atom NETWM::NET_WM_ICON = 0;
 
103
Atom NETWM::NET_WM_PID = 0;
 
104
 
 
105
NETWM::net_wm_state::net_wm_state()
 
106
        : modal(0), sticky(0), maximized_vert(0),
 
107
        maximized_horz(0), shaded(0), skip_taskbar(0),
 
108
        skip_pager(0), hidden(0), fullscreen(0),
 
109
        above(0), below(0), stays_on_top(0), stays_on_bottom(0),
 
110
        demands_attention(0), valid(false)
 
111
{}
 
112
 
 
113
NETWM::net_wm_window_type::net_wm_window_type()
 
114
    : desktop(0), dock(0), toolbar(0),
 
115
    menu(0), utility(0), splash(0), dialog(0),
 
116
    dropdown(0), popup(0), tooltip(0), notification(0),
 
117
    combo(0), dnd(0), normal(0), valid(false)
 
118
{}
 
119
 
 
120
/**********************************************************/
 
121
                
 
122
void NETWM::init()
 
123
{
 
124
    Display *dpy = QX11Info::display();
 
125
 
 
126
    UTF8_STRING                = XInternAtom(dpy, "UTF8_STRING", False);
 
127
    XROOTPMAP_ID               = XInternAtom(dpy, "_XROOTPMAP_ID", False);
 
128
    WM_STATE                   = XInternAtom(dpy, "WM_STATE", False);
 
129
    WM_CLASS                   = XInternAtom(dpy, "WM_CLASS", False);
 
130
    WM_NAME                    = XInternAtom(dpy, "WM_NAME", False);
 
131
    WM_DELETE_WINDOW           = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
 
132
    WM_CHANGE_STATE            = XInternAtom(dpy, "WM_CHANGE_STATE", False);
 
133
    WM_WINDOW_ROLE             = XInternAtom(dpy, "WM_WINDOW_ROLE", False);
 
134
 
 
135
    WM_PROTOCOLS               = XInternAtom(dpy, "WM_PROTOCOLS", False);
 
136
    NET_WORKAREA               = XInternAtom(dpy, "_NET_WORKAREA", False);
 
137
    NET_CLIENT_LIST            = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
 
138
    NET_CLIENT_LIST_STACKING   = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
 
139
    NET_NUMBER_OF_DESKTOPS     = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
 
140
    NET_CURRENT_DESKTOP        = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
 
141
    NET_DESKTOP_NAMES          = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False);
 
142
    NET_ACTIVE_WINDOW          = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
 
143
    NET_CLOSE_WINDOW           = XInternAtom(dpy, "_NET_CLOSE_WINDOW", False);
 
144
    NET_SUPPORTED              = XInternAtom(dpy, "_NET_SUPPORTED", False);
 
145
    NET_WM_DESKTOP             = XInternAtom(dpy, "_NET_WM_DESKTOP", False);
 
146
    NET_SHOWING_DESKTOP        = XInternAtom(dpy, "_NET_SHOWING_DESKTOP", False);
 
147
 
 
148
    NET_WM_STATE                     = XInternAtom(dpy, "_NET_WM_STATE", False);
 
149
    NET_WM_STATE_MODAL               = XInternAtom(dpy, "_NET_WM_STATE_MODAL", False);
 
150
    NET_WM_STATE_STICKY              = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False);
 
151
    NET_WM_STATE_MAXIMIZED_VERT      = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_VERT", False);
 
152
    NET_WM_STATE_MAXIMIZED_HORZ      = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
 
153
    NET_WM_STATE_SHADED              = XInternAtom(dpy, "_NET_WM_STATE_SHADED", False);
 
154
    NET_WM_STATE_SKIP_TASKBAR        = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
 
155
    NET_WM_STATE_SKIP_PAGER          = XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False);
 
156
    NET_WM_STATE_HIDDEN              = XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False);
 
157
    NET_WM_STATE_FULLSCREEN          = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
 
158
    NET_WM_STATE_ABOVE               = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", False);
 
159
    NET_WM_STATE_BELOW               = XInternAtom(dpy, "_NET_WM_STATE_BELOW", False);
 
160
    NET_WM_STATE_STAYS_ON_TOP        = XInternAtom(dpy, "_NET_WM_STATE_STAYS_ON_TOP", False);
 
161
    NET_WM_STATE_STAYS_ON_BOTTOM     = XInternAtom(dpy, "_NET_WM_STATE_STAYS_ON_BOTTOM", False);
 
162
    NET_WM_STATE_DEMANDS_ATTENTION   = XInternAtom(dpy, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
 
163
 
 
164
    NET_WM_WINDOW_TYPE               = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
 
165
    NET_WM_WINDOW_TYPE_DESKTOP       = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
 
166
    NET_WM_WINDOW_TYPE_DOCK          = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
 
167
    MODERRO_WINDOW_TYPE_DOCK         = XInternAtom(dpy, "_MODERRO_WINDOW_TYPE_DOCK", False);
 
168
    NET_WM_WINDOW_TYPE_TOOLBAR       = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
 
169
    NET_WM_WINDOW_TYPE_MENU          = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_MENU", False);
 
170
    NET_WM_WINDOW_TYPE_UTILITY       = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_UTILITY", False);
 
171
    NET_WM_WINDOW_TYPE_SPLASH        = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_SPLASH", False);
 
172
    NET_WM_WINDOW_TYPE_DIALOG        = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
 
173
    NET_WM_WINDOW_TYPE_DROPDOWN_MENU = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
 
174
    NET_WM_WINDOW_TYPE_POPUP_MENU    = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
 
175
    NET_WM_WINDOW_TYPE_TOOLTIP       = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_TOOLTIP", False);
 
176
    NET_WM_WINDOW_TYPE_NOTIFICATION  = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
 
177
    NET_WM_WINDOW_TYPE_COMBO         = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_COMBO", False);
 
178
    NET_WM_WINDOW_TYPE_DND           = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DND", False);
 
179
    NET_WM_WINDOW_TYPE_NORMAL        = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False);
 
180
 
 
181
    NET_WM_WINDOW_OPACITY      = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
 
182
    NET_WM_NAME                = XInternAtom(dpy, "_NET_WM_NAME", False);
 
183
    NET_WM_VISIBLE_NAME        = XInternAtom(dpy, "_NET_WM_VISIBLE_NAME", False);
 
184
    NET_WM_STRUT               = XInternAtom(dpy, "_NET_WM_STRUT", False);
 
185
    NET_WM_STRUT_PARTIAL       = XInternAtom(dpy, "_NET_WM_STRUT_PARTIAL", False);
 
186
    NET_WM_ICON                = XInternAtom(dpy, "_NET_WM_ICON", False);
 
187
    NET_WM_PID                 = XInternAtom(dpy, "_NET_WM_PID", False);
 
188
}
 
189
 
 
190
int NETWM::setProperty(Window window, Atom atom, long offset, uchar *data, int nelem)
 
191
{
 
192
    NETWM::checkInit();
 
193
 
 
194
    return XChangeProperty(QX11Info::display(), window, atom, offset, 32, PropModeReplace, data, nelem);
 
195
}
 
196
 
 
197
int NETWM::setPropertySkipTaskbar(Window window)
 
198
{
 
199
    NETWM::checkInit();
 
200
 
 
201
    Atom state[3];
 
202
 
 
203
    state[0] = NETWM::NET_WM_STATE_SKIP_PAGER;
 
204
    state[1] = NETWM::NET_WM_STATE_SKIP_TASKBAR;
 
205
    state[2] = NETWM::NET_WM_STATE_STICKY;
 
206
 
 
207
    return NETWM::setProperty(window, NETWM::NET_WM_STATE, XA_ATOM, (uchar *)&state, 3);
 
208
}
 
209
 
 
210
int NETWM::setPropertyOnTop(Window window)
 
211
{
 
212
    NETWM::checkInit();
 
213
 
 
214
    Atom state[2];
 
215
 
 
216
    state[0] = NETWM::NET_WM_STATE_ABOVE;
 
217
    state[1] = NETWM::NET_WM_STATE_STAYS_ON_TOP;
 
218
 
 
219
    return NETWM::setProperty(window, NETWM::NET_WM_STATE, XA_ATOM, (uchar *)&state, 2);
 
220
}
 
221
 
 
222
void* NETWM::property(Window win, Atom prop, Atom type, int *nitems, bool *ok)
 
223
{
 
224
    NETWM::checkInit();
 
225
 
 
226
    Atom type_ret;
 
227
    int format_ret;
 
228
    unsigned long items_ret;
 
229
    unsigned long after_ret;
 
230
    unsigned char *prop_data = 0;
 
231
 
 
232
    if(XGetWindowProperty(QX11Info::display(),
 
233
                            win,
 
234
                            prop,
 
235
                            0,
 
236
                            0x7fffffff,
 
237
                            False,
 
238
                            type,
 
239
                            &type_ret,
 
240
                            &format_ret,
 
241
                            &items_ret,
 
242
                            &after_ret,
 
243
                            &prop_data) != Success)
 
244
    {
 
245
        if(ok)
 
246
            *ok = false;
 
247
 
 
248
        return 0;
 
249
    }
 
250
 
 
251
    if(nitems)
 
252
        *nitems = items_ret;
 
253
 
 
254
    if(ok)
 
255
        *ok = true;
 
256
 
 
257
    return prop_data;
 
258
}
 
259
 
 
260
bool NETWM::climsg(Window win, long type, long l0, long l1, long l2, long l3, long l4)
 
261
{
 
262
    NETWM::checkInit();
 
263
 
 
264
    XClientMessageEvent xev;
 
265
 
 
266
    xev.type = ClientMessage;
 
267
    xev.window = win;
 
268
    xev.message_type = type;
 
269
    xev.format = 32;
 
270
    xev.data.l[0] = l0;
 
271
    xev.data.l[1] = l1;
 
272
    xev.data.l[2] = l2;
 
273
    xev.data.l[3] = l3;
 
274
    xev.data.l[4] = l4;
 
275
 
 
276
    return (XSendEvent(QX11Info::display(), QX11Info::appRootWindow(), False,
 
277
            (SubstructureNotifyMask | SubstructureRedirectMask),
 
278
            (XEvent *)&xev) == Success);
 
279
}
 
280
 
 
281
bool NETWM::climsgwm(Window win, Atom type, Atom arg)
 
282
{
 
283
    NETWM::checkInit();
 
284
 
 
285
    XClientMessageEvent xev;
 
286
 
 
287
    xev.type = ClientMessage;
 
288
    xev.window = win;
 
289
    xev.message_type = type;
 
290
    xev.format = 32;
 
291
    xev.data.l[0] = arg;
 
292
    xev.data.l[1] = CurrentTime;
 
293
 
 
294
    return (XSendEvent(QX11Info::display(), win, False, 0L, (XEvent *)&xev) == Success);
 
295
}
 
296
 
 
297
uint NETWM::netwmDesktopsNumber()
 
298
{
 
299
    NETWM::checkInit();
 
300
 
 
301
    uint desknum;
 
302
    quint32 *data;
 
303
 
 
304
    data = (quint32 *)NETWM::property(QX11Info::appRootWindow(), NETWM::NET_NUMBER_OF_DESKTOPS, XA_CARDINAL, 0);
 
305
 
 
306
    if(!data)
 
307
        return 0;
 
308
 
 
309
    desknum = *data;
 
310
    XFree(data);
 
311
 
 
312
    return desknum;
 
313
}
 
314
 
 
315
uint NETWM::netwmCurrentDesktop()
 
316
{
 
317
    NETWM::checkInit();
 
318
 
 
319
    uint desk;
 
320
    quint32 *data;
 
321
 
 
322
    data = (quint32 *)NETWM::property(QX11Info::appRootWindow(), NETWM::NET_CURRENT_DESKTOP, XA_CARDINAL, 0);
 
323
 
 
324
    if(!data)
 
325
        return 0;
 
326
 
 
327
    desk = *data;
 
328
    XFree(data);
 
329
 
 
330
    return desk;
 
331
}
 
332
 
 
333
qint64 NETWM::netwmPid(Window win)
 
334
{
 
335
    NETWM::checkInit();
 
336
 
 
337
    qint64 pid = -1;
 
338
    ulong *data;
 
339
 
 
340
    data = (ulong *)NETWM::property(win, NETWM::NET_WM_PID, XA_CARDINAL, 0);
 
341
 
 
342
    if(data)
 
343
    {
 
344
        pid = *data;
 
345
        XFree(data);
 
346
    }
 
347
 
 
348
    return pid;
 
349
}
 
350
 
 
351
bool NETWM::netwmActivateWindow(Window win)
 
352
{
 
353
    NETWM::checkInit();
 
354
 
 
355
    return NETWM::climsg(win, NETWM::NET_ACTIVE_WINDOW, 2, CurrentTime);
 
356
}
 
357
 
 
358
QList<Window> NETWM::netwmWindowList()
 
359
{
 
360
    NETWM::checkInit();
 
361
 
 
362
    QList<Window> list;
 
363
    int num;
 
364
 
 
365
    Window *win = reinterpret_cast<Window *>(NETWM::property(QX11Info::appRootWindow(), NETWM::NET_CLIENT_LIST, XA_WINDOW, &num));
 
366
 
 
367
    if(!win)
 
368
    {
 
369
        qDebug("NETWM: Cannot get window list");
 
370
        return list;
 
371
    }
 
372
 
 
373
    for(int i = 0;i < num;i++)
 
374
        list.append(win[i]);
 
375
 
 
376
    XFree(win);
 
377
 
 
378
    return list;
 
379
}
 
380
 
 
381
int NETWM::netwmDesktop(Window win)
 
382
{
 
383
    NETWM::checkInit();
 
384
 
 
385
    int desk = 0;
 
386
    ulong *data;
 
387
 
 
388
    data = (ulong *)NETWM::property(win, NETWM::NET_WM_DESKTOP, XA_CARDINAL, 0);
 
389
 
 
390
    if(data)
 
391
    {
 
392
        desk = *data;
 
393
        XFree(data);
 
394
    }
 
395
 
 
396
    return desk;
 
397
}
 
398
 
 
399
NETWM::net_wm_state NETWM::netwmState(Window win)
 
400
{
 
401
    NETWM::checkInit();
 
402
 
 
403
    net_wm_state nws;
 
404
    Atom *state;
 
405
    int num3;
 
406
 
 
407
    if(!(state = (Atom *)NETWM::property(win, NETWM::NET_WM_STATE, XA_ATOM, &num3)))
 
408
        return nws;
 
409
 
 
410
    while(--num3 >= 0)
 
411
    {
 
412
        if(state[num3] == NETWM::NET_WM_STATE_MODAL)
 
413
        {
 
414
            DBG("NET_WM_STATE_MODAL\n");
 
415
            nws.modal = 1;
 
416
        }
 
417
        else if(state[num3] == NETWM::NET_WM_STATE_STICKY)
 
418
        {
 
419
            DBG("NET_WM_STATE_STICKY\n");
 
420
            nws.sticky = 1;
 
421
        }
 
422
        else if(state[num3] == NETWM::NET_WM_STATE_MAXIMIZED_VERT)
 
423
        {
 
424
            DBG("NET_WM_STATE_MAXIMIZED_VERT\n");
 
425
            nws.maximized_vert = 1;
 
426
        }
 
427
        else if(state[num3] == NETWM::NET_WM_STATE_MAXIMIZED_HORZ)
 
428
        {
 
429
            DBG("NET_WM_STATE_MAXIMIZED_HORZ\n");
 
430
            nws.maximized_horz = 1;
 
431
        }
 
432
        else if(state[num3] == NETWM::NET_WM_STATE_SHADED)
 
433
        {
 
434
            DBG("NET_WM_STATE_SHADED\n");
 
435
            nws.shaded = 1;
 
436
        }
 
437
        else if(state[num3] == NETWM::NET_WM_STATE_SKIP_TASKBAR)
 
438
        {
 
439
            DBG("NET_WM_STATE_SKIP_TASKBAR\n");
 
440
            nws.skip_taskbar = 1;
 
441
        }
 
442
        else if(state[num3] == NETWM::NET_WM_STATE_SKIP_PAGER)
 
443
        {
 
444
            DBG("NET_WM_STATE_SKIP_PAGER\n");
 
445
            nws.skip_pager = 1;
 
446
        }
 
447
        else if(state[num3] == NETWM::NET_WM_STATE_HIDDEN)
 
448
        {
 
449
            DBG("NET_WM_STATE_HIDDEN\n");
 
450
            nws.hidden = 1;
 
451
        }
 
452
        else if(state[num3] == NETWM::NET_WM_STATE_FULLSCREEN)
 
453
        {
 
454
            DBG("NET_WM_STATE_FULLSCREEN\n");
 
455
            nws.fullscreen = 1;
 
456
        }
 
457
        else if(state[num3] == NETWM::NET_WM_STATE_ABOVE)
 
458
        {
 
459
            DBG("NET_WM_STATE_ABOVE\n");
 
460
            nws.above = 1;
 
461
        }
 
462
        else if(state[num3] == NETWM::NET_WM_STATE_BELOW)
 
463
        {
 
464
            DBG("NET_WM_STATE_BELOW\n");
 
465
            nws.below = 1;
 
466
        }
 
467
        else if(state[num3] == NETWM::NET_WM_STATE_STAYS_ON_TOP)
 
468
        {
 
469
            DBG("NET_WM_STATE_STAYS_ON_TOP\n");
 
470
            nws.stays_on_top = 1;
 
471
        }
 
472
        else if(state[num3] == NETWM::NET_WM_STATE_STAYS_ON_BOTTOM)
 
473
        {
 
474
            DBG("NET_WM_STATE_STAYS_ON_BOTTOM\n");
 
475
            nws.stays_on_bottom = 1;
 
476
        }
 
477
        else if(state[num3] == NETWM::NET_WM_STATE_DEMANDS_ATTENTION)
 
478
        {
 
479
            DBG("NET_WM_STATE_DEMANDS_ATTENTION\n");
 
480
            nws.demands_attention = 1;
 
481
        }
 
482
    }
 
483
 
 
484
    nws.valid = true;
 
485
 
 
486
    XFree(state);
 
487
 
 
488
    return nws;
 
489
}
 
490
 
 
491
NETWM::net_wm_window_type NETWM::netwmWindowType(Window win)
 
492
{
 
493
    NETWM::checkInit();
 
494
 
 
495
    net_wm_window_type nwwt;
 
496
    Atom *state;
 
497
    int num3;
 
498
    bool ok;
 
499
 
 
500
 
 
501
    if(!(state = (Atom *)NETWM::property(win, NETWM::NET_WM_WINDOW_TYPE, XA_ATOM, &num3, &ok)))
 
502
    {
 
503
        if(ok)
 
504
        {
 
505
            nwwt.valid = true;
 
506
            nwwt.normal = 1;
 
507
        }
 
508
 
 
509
        return nwwt;
 
510
    }
 
511
 
 
512
    nwwt.valid = true;
 
513
 
 
514
    while(--num3 >= 0)
 
515
    {
 
516
        if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DESKTOP)
 
517
        {
 
518
            DBG("NET_WM_WINDOW_TYPE_DESKTOP\n");
 
519
            nwwt.desktop = 1;
 
520
        }
 
521
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DOCK)
 
522
        {
 
523
            DBG("NET_WM_WINDOW_TYPE_DOCK\n");
 
524
            nwwt.dock = 1;
 
525
        }
 
526
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_TOOLBAR)
 
527
        {
 
528
            DBG("NET_WM_WINDOW_TYPE_TOOLBAR\n");
 
529
            nwwt.toolbar = 1;
 
530
        }
 
531
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_MENU)
 
532
        {
 
533
            DBG("NET_WM_WINDOW_TYPE_MENU\n");
 
534
            nwwt.menu = 1;
 
535
        }
 
536
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_UTILITY)
 
537
        {
 
538
            DBG("NET_WM_WINDOW_TYPE_UTILITY\n");
 
539
            nwwt.utility = 1;
 
540
        }
 
541
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_SPLASH)
 
542
        {
 
543
            DBG("NET_WM_WINDOW_TYPE_SPLASH\n");
 
544
            nwwt.splash = 1;
 
545
        }
 
546
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DIALOG)
 
547
        {
 
548
            DBG("NET_WM_WINDOW_TYPE_DIALOG\n");
 
549
            nwwt.dialog = 1;
 
550
        }
 
551
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
 
552
        {
 
553
            DBG("NET_WM_WINDOW_TYPE_DROPDOWN_MENU\n");
 
554
            nwwt.dropdown = 1;
 
555
        }
 
556
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_POPUP_MENU)
 
557
        {
 
558
            DBG("NET_WM_WINDOW_TYPE_POPUP_MENU\n");
 
559
            nwwt.popup = 1;
 
560
        }
 
561
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_TOOLTIP)
 
562
        {
 
563
            DBG("NET_WM_WINDOW_TYPE_TOOLTIP\n");
 
564
            nwwt.tooltip = 1;
 
565
        }
 
566
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_NOTIFICATION)
 
567
        {
 
568
            DBG("NET_WM_WINDOW_TYPE_NOTIFICATION\n");
 
569
            nwwt.notification = 1;
 
570
        }
 
571
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_COMBO)
 
572
        {
 
573
            DBG("NET_WM_WINDOW_TYPE_COMBO\n");
 
574
            nwwt.combo = 1;
 
575
        }
 
576
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DND)
 
577
        {
 
578
            DBG("NET_WM_WINDOW_TYPE_DND\n");
 
579
            nwwt.dnd = 1;
 
580
        }
 
581
        else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_NORMAL)
 
582
        {
 
583
            DBG("NET_WM_WINDOW_TYPE_NORMAL\n");
 
584
            nwwt.normal = 1;
 
585
        }
 
586
    }
 
587
 
 
588
    XFree(state);
 
589
 
 
590
    return nwwt;
 
591
}
 
592
 
 
593
QString NETWM::icccmString(Window win, Atom atom)
 
594
{
 
595
    NETWM::checkInit();
 
596
 
 
597
    QString s;
 
598
    char *data;
 
599
 
 
600
    if(!(data = (char *)NETWM::property(win, atom, XA_STRING)))
 
601
        return s;
 
602
 
 
603
    s = QString::fromUtf8(data);
 
604
 
 
605
    XFree(data);
 
606
 
 
607
    return s;
 
608
}
 
609
 
 
610
QString NETWM::icccmUtf8String(Window win, Atom atom)
 
611
{
 
612
    NETWM::checkInit();
 
613
 
 
614
    Atom type;
 
615
    int format;
 
616
    ulong nitems;
 
617
    ulong bytes_after;
 
618
    int result;
 
619
    uchar *tmp = 0;
 
620
    QString val;
 
621
 
 
622
    type = None;
 
623
 
 
624
    result = XGetWindowProperty(QX11Info::display(), win, atom, 0, LONG_MAX, False,
 
625
                                     NETWM::UTF8_STRING, &type, &format, &nitems,
 
626
                                     &bytes_after, &tmp);
 
627
 
 
628
    if(result != Success || type == None || !tmp)
 
629
        return val;
 
630
 
 
631
    if(type == NETWM::UTF8_STRING && format == 8 && nitems != 0)
 
632
        val = QString::fromUtf8(reinterpret_cast<char *>(tmp));
 
633
 
 
634
    XFree(tmp);
 
635
 
 
636
    return val;
 
637
}
 
638
 
 
639
QString NETWM::icccmWindowRole(Window win)
 
640
{
 
641
    NETWM::checkInit();
 
642
 
 
643
    return NETWM::icccmString(win, NETWM::WM_WINDOW_ROLE);
 
644
}
 
645
 
 
646
QStringList NETWM::icccmClass(Window win)
 
647
{
 
648
    NETWM::checkInit();
 
649
 
 
650
    QStringList l;
 
651
    char *data;
 
652
 
 
653
    if(!(data = (char *)NETWM::property(win, NETWM::WM_CLASS, XA_STRING)))
 
654
        return l;
 
655
 
 
656
    l.append(QString::fromUtf8(data));
 
657
    l.append(QString::fromUtf8(data+strlen(data)+1));
 
658
 
 
659
    XFree(data);
 
660
 
 
661
    return l;
 
662
}
 
663
 
 
664
QString NETWM::icccmName(Window win)
 
665
{
 
666
    NETWM::checkInit();
 
667
 
 
668
    return NETWM::icccmString(win, NETWM::WM_NAME);
 
669
}
 
670
 
 
671
QStringList NETWM::icccmCommand(Window win)
 
672
{
 
673
    NETWM::checkInit();
 
674
 
 
675
    QStringList list;
 
676
    char **argv;
 
677
    int argc;
 
678
 
 
679
    if(!XGetCommand(QX11Info::display(), win, &argv, &argc))
 
680
        return list;
 
681
 
 
682
    for(int i = 0;i < argc;i++)
 
683
        list.append(argv[i]);
 
684
 
 
685
    XFreeStringList(argv);
 
686
 
 
687
    return list;
 
688
}
 
689
 
 
690
#define MO_NETWM_OPAQUE 0xffffffff
 
691
 
 
692
void NETWM::transset(Window window, double d)
 
693
{
 
694
    NETWM::checkInit();
 
695
 
 
696
    Display *dpy = QX11Info::display();
 
697
 
 
698
    uint opacity = (uint)(d * MO_NETWM_OPAQUE);
 
699
 
 
700
    if(opacity == MO_NETWM_OPAQUE)
 
701
        XDeleteProperty(dpy, window, NETWM::NET_WM_WINDOW_OPACITY);
 
702
    else
 
703
        XChangeProperty(dpy, window, NETWM::NET_WM_WINDOW_OPACITY,
 
704
                        XA_CARDINAL, 32, PropModeReplace, (uchar *)&opacity, 1L);
 
705
 
 
706
    XSync(dpy, False);
 
707
}
 
708
 
 
709
#if 0
 
710
bool NETWM::isComposite()
 
711
{
 
712
    int event_base, error_base;
 
713
 
 
714
    Display *dpy = QX11Info::display();
 
715
 
 
716
    // extension is not supported
 
717
    if(!XCompositeQueryExtension(dpy, &event_base, &error_base))
 
718
    {
 
719
        qDebug("NETWM: Composite extension is not supported");
 
720
        return false;
 
721
    }
 
722
 
 
723
    // NETWM-compliant composite manager MUST set selection owner
 
724
    // of _NET_WM_CM_Sn
 
725
    Window owner = XGetSelectionOwner(dpy, XInternAtom(dpy, "_NET_WM_CM_S0", False));
 
726
 
 
727
    return (owner != None);
 
728
}
 
729
#endif
 
730
 
 
731
void NETWM::checkInit()
 
732
{
 
733
    if(!NETWM::WM_STATE)
 
734
        NETWM::init();
 
735
}