PageRenderTime 118ms CodeModel.GetById 61ms app.highlight 51ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/libqnetwm/libqnetwm/netwm.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 735 lines | 576 code | 136 blank | 23 comment | 118 complexity | 6911ea03b4e2e8809f3cf0bd8b39036f MD5 | raw file
  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
 42Atom NETWM::UTF8_STRING = 0;
 43Atom NETWM::XROOTPMAP_ID = 0;
 44
 45Atom NETWM::WM_STATE = 0;
 46Atom NETWM::WM_CLASS = 0;
 47Atom NETWM::WM_NAME = 0;
 48Atom NETWM::WM_DELETE_WINDOW = 0;
 49Atom NETWM::WM_PROTOCOLS = 0;
 50Atom NETWM::WM_CHANGE_STATE = 0;
 51Atom NETWM::WM_WINDOW_ROLE = 0;
 52
 53Atom NETWM::NET_WORKAREA = 0;
 54Atom NETWM::NET_CLIENT_LIST = 0;
 55Atom NETWM::NET_CLIENT_LIST_STACKING = 0;
 56Atom NETWM::NET_NUMBER_OF_DESKTOPS = 0;
 57Atom NETWM::NET_CURRENT_DESKTOP = 0;
 58Atom NETWM::NET_DESKTOP_NAMES = 0;
 59Atom NETWM::NET_ACTIVE_WINDOW = 0;
 60Atom NETWM::NET_CLOSE_WINDOW = 0;
 61Atom NETWM::NET_SUPPORTED = 0;
 62Atom NETWM::NET_WM_DESKTOP = 0;
 63Atom NETWM::NET_SHOWING_DESKTOP = 0;
 64
 65Atom NETWM::NET_WM_STATE = 0;
 66Atom NETWM::NET_WM_STATE_MODAL = 0;
 67Atom NETWM::NET_WM_STATE_STICKY = 0;
 68Atom NETWM::NET_WM_STATE_MAXIMIZED_VERT = 0;
 69Atom NETWM::NET_WM_STATE_MAXIMIZED_HORZ = 0;
 70Atom NETWM::NET_WM_STATE_SHADED = 0;
 71Atom NETWM::NET_WM_STATE_SKIP_TASKBAR = 0;
 72Atom NETWM::NET_WM_STATE_SKIP_PAGER = 0;
 73Atom NETWM::NET_WM_STATE_HIDDEN = 0;
 74Atom NETWM::NET_WM_STATE_FULLSCREEN = 0;
 75Atom NETWM::NET_WM_STATE_ABOVE = 0;
 76Atom NETWM::NET_WM_STATE_BELOW = 0;
 77Atom NETWM::NET_WM_STATE_STAYS_ON_TOP = 0;
 78Atom NETWM::NET_WM_STATE_STAYS_ON_BOTTOM = 0;
 79Atom NETWM::NET_WM_STATE_DEMANDS_ATTENTION = 0;
 80
 81Atom NETWM::NET_WM_WINDOW_TYPE = 0;
 82Atom NETWM::NET_WM_WINDOW_TYPE_DESKTOP = 0;
 83Atom NETWM::NET_WM_WINDOW_TYPE_DOCK = 0;
 84Atom NETWM::MODERRO_WINDOW_TYPE_DOCK = 0;
 85Atom NETWM::NET_WM_WINDOW_TYPE_TOOLBAR = 0;
 86Atom NETWM::NET_WM_WINDOW_TYPE_MENU = 0;
 87Atom NETWM::NET_WM_WINDOW_TYPE_UTILITY = 0;
 88Atom NETWM::NET_WM_WINDOW_TYPE_SPLASH = 0;
 89Atom NETWM::NET_WM_WINDOW_TYPE_DIALOG = 0;
 90Atom NETWM::NET_WM_WINDOW_TYPE_DROPDOWN_MENU = 0;
 91Atom NETWM::NET_WM_WINDOW_TYPE_POPUP_MENU = 0;
 92Atom NETWM::NET_WM_WINDOW_TYPE_TOOLTIP = 0;
 93Atom NETWM::NET_WM_WINDOW_TYPE_NOTIFICATION = 0;
 94Atom NETWM::NET_WM_WINDOW_TYPE_COMBO = 0;
 95Atom NETWM::NET_WM_WINDOW_TYPE_DND = 0;
 96Atom NETWM::NET_WM_WINDOW_TYPE_NORMAL = 0;
 97Atom NETWM::NET_WM_WINDOW_OPACITY = 0;
 98Atom NETWM::NET_WM_NAME = 0;
 99Atom NETWM::NET_WM_VISIBLE_NAME = 0;
100Atom NETWM::NET_WM_STRUT = 0;
101Atom NETWM::NET_WM_STRUT_PARTIAL = 0;
102Atom NETWM::NET_WM_ICON = 0;
103Atom NETWM::NET_WM_PID = 0;
104
105NETWM::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
113NETWM::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                
122void 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
190int 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
197int 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
210int 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
222void* 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
260bool 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
281bool 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
297uint 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
315uint 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
333qint64 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
351bool NETWM::netwmActivateWindow(Window win)
352{
353    NETWM::checkInit();
354
355    return NETWM::climsg(win, NETWM::NET_ACTIVE_WINDOW, 2, CurrentTime);
356}
357
358QList<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
381int 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
399NETWM::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
491NETWM::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
593QString 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
610QString 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
639QString NETWM::icccmWindowRole(Window win)
640{
641    NETWM::checkInit();
642
643    return NETWM::icccmString(win, NETWM::WM_WINDOW_ROLE);
644}
645
646QStringList 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
664QString NETWM::icccmName(Window win)
665{
666    NETWM::checkInit();
667
668    return NETWM::icccmString(win, NETWM::WM_NAME);
669}
670
671QStringList 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
692void 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
710bool 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
731void NETWM::checkInit()
732{
733    if(!NETWM::WM_STATE)
734        NETWM::init();
735}