/thirdparty/libqnetwm/libqnetwm/netwm.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 735 lines · 576 code · 136 blank · 23 comment · 120 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. #include <QX11Info>
  21. #include <climits>
  22. #include <cstring>
  23. #include <cstdio>
  24. #include <cstdlib>
  25. #include <strings.h>
  26. #include <unistd.h>
  27. #include <X11/Xutil.h>
  28. #if 0
  29. #include <X11/extensions/Xcomposite.h>
  30. #endif
  31. #include "netwm.h"
  32. #define DBG(...) //fprintf(stderr, ##__VA_ARGS__)
  33. Atom NETWM::UTF8_STRING = 0;
  34. Atom NETWM::XROOTPMAP_ID = 0;
  35. Atom NETWM::WM_STATE = 0;
  36. Atom NETWM::WM_CLASS = 0;
  37. Atom NETWM::WM_NAME = 0;
  38. Atom NETWM::WM_DELETE_WINDOW = 0;
  39. Atom NETWM::WM_PROTOCOLS = 0;
  40. Atom NETWM::WM_CHANGE_STATE = 0;
  41. Atom NETWM::WM_WINDOW_ROLE = 0;
  42. Atom NETWM::NET_WORKAREA = 0;
  43. Atom NETWM::NET_CLIENT_LIST = 0;
  44. Atom NETWM::NET_CLIENT_LIST_STACKING = 0;
  45. Atom NETWM::NET_NUMBER_OF_DESKTOPS = 0;
  46. Atom NETWM::NET_CURRENT_DESKTOP = 0;
  47. Atom NETWM::NET_DESKTOP_NAMES = 0;
  48. Atom NETWM::NET_ACTIVE_WINDOW = 0;
  49. Atom NETWM::NET_CLOSE_WINDOW = 0;
  50. Atom NETWM::NET_SUPPORTED = 0;
  51. Atom NETWM::NET_WM_DESKTOP = 0;
  52. Atom NETWM::NET_SHOWING_DESKTOP = 0;
  53. Atom NETWM::NET_WM_STATE = 0;
  54. Atom NETWM::NET_WM_STATE_MODAL = 0;
  55. Atom NETWM::NET_WM_STATE_STICKY = 0;
  56. Atom NETWM::NET_WM_STATE_MAXIMIZED_VERT = 0;
  57. Atom NETWM::NET_WM_STATE_MAXIMIZED_HORZ = 0;
  58. Atom NETWM::NET_WM_STATE_SHADED = 0;
  59. Atom NETWM::NET_WM_STATE_SKIP_TASKBAR = 0;
  60. Atom NETWM::NET_WM_STATE_SKIP_PAGER = 0;
  61. Atom NETWM::NET_WM_STATE_HIDDEN = 0;
  62. Atom NETWM::NET_WM_STATE_FULLSCREEN = 0;
  63. Atom NETWM::NET_WM_STATE_ABOVE = 0;
  64. Atom NETWM::NET_WM_STATE_BELOW = 0;
  65. Atom NETWM::NET_WM_STATE_STAYS_ON_TOP = 0;
  66. Atom NETWM::NET_WM_STATE_STAYS_ON_BOTTOM = 0;
  67. Atom NETWM::NET_WM_STATE_DEMANDS_ATTENTION = 0;
  68. Atom NETWM::NET_WM_WINDOW_TYPE = 0;
  69. Atom NETWM::NET_WM_WINDOW_TYPE_DESKTOP = 0;
  70. Atom NETWM::NET_WM_WINDOW_TYPE_DOCK = 0;
  71. Atom NETWM::MODERRO_WINDOW_TYPE_DOCK = 0;
  72. Atom NETWM::NET_WM_WINDOW_TYPE_TOOLBAR = 0;
  73. Atom NETWM::NET_WM_WINDOW_TYPE_MENU = 0;
  74. Atom NETWM::NET_WM_WINDOW_TYPE_UTILITY = 0;
  75. Atom NETWM::NET_WM_WINDOW_TYPE_SPLASH = 0;
  76. Atom NETWM::NET_WM_WINDOW_TYPE_DIALOG = 0;
  77. Atom NETWM::NET_WM_WINDOW_TYPE_DROPDOWN_MENU = 0;
  78. Atom NETWM::NET_WM_WINDOW_TYPE_POPUP_MENU = 0;
  79. Atom NETWM::NET_WM_WINDOW_TYPE_TOOLTIP = 0;
  80. Atom NETWM::NET_WM_WINDOW_TYPE_NOTIFICATION = 0;
  81. Atom NETWM::NET_WM_WINDOW_TYPE_COMBO = 0;
  82. Atom NETWM::NET_WM_WINDOW_TYPE_DND = 0;
  83. Atom NETWM::NET_WM_WINDOW_TYPE_NORMAL = 0;
  84. Atom NETWM::NET_WM_WINDOW_OPACITY = 0;
  85. Atom NETWM::NET_WM_NAME = 0;
  86. Atom NETWM::NET_WM_VISIBLE_NAME = 0;
  87. Atom NETWM::NET_WM_STRUT = 0;
  88. Atom NETWM::NET_WM_STRUT_PARTIAL = 0;
  89. Atom NETWM::NET_WM_ICON = 0;
  90. Atom NETWM::NET_WM_PID = 0;
  91. NETWM::net_wm_state::net_wm_state()
  92. : modal(0), sticky(0), maximized_vert(0),
  93. maximized_horz(0), shaded(0), skip_taskbar(0),
  94. skip_pager(0), hidden(0), fullscreen(0),
  95. above(0), below(0), stays_on_top(0), stays_on_bottom(0),
  96. demands_attention(0), valid(false)
  97. {}
  98. NETWM::net_wm_window_type::net_wm_window_type()
  99. : desktop(0), dock(0), toolbar(0),
  100. menu(0), utility(0), splash(0), dialog(0),
  101. dropdown(0), popup(0), tooltip(0), notification(0),
  102. combo(0), dnd(0), normal(0), valid(false)
  103. {}
  104. /**********************************************************/
  105. void NETWM::init()
  106. {
  107. Display *dpy = QX11Info::display();
  108. UTF8_STRING = XInternAtom(dpy, "UTF8_STRING", False);
  109. XROOTPMAP_ID = XInternAtom(dpy, "_XROOTPMAP_ID", False);
  110. WM_STATE = XInternAtom(dpy, "WM_STATE", False);
  111. WM_CLASS = XInternAtom(dpy, "WM_CLASS", False);
  112. WM_NAME = XInternAtom(dpy, "WM_NAME", False);
  113. WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  114. WM_CHANGE_STATE = XInternAtom(dpy, "WM_CHANGE_STATE", False);
  115. WM_WINDOW_ROLE = XInternAtom(dpy, "WM_WINDOW_ROLE", False);
  116. WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False);
  117. NET_WORKAREA = XInternAtom(dpy, "_NET_WORKAREA", False);
  118. NET_CLIENT_LIST = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
  119. NET_CLIENT_LIST_STACKING = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
  120. NET_NUMBER_OF_DESKTOPS = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
  121. NET_CURRENT_DESKTOP = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
  122. NET_DESKTOP_NAMES = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False);
  123. NET_ACTIVE_WINDOW = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
  124. NET_CLOSE_WINDOW = XInternAtom(dpy, "_NET_CLOSE_WINDOW", False);
  125. NET_SUPPORTED = XInternAtom(dpy, "_NET_SUPPORTED", False);
  126. NET_WM_DESKTOP = XInternAtom(dpy, "_NET_WM_DESKTOP", False);
  127. NET_SHOWING_DESKTOP = XInternAtom(dpy, "_NET_SHOWING_DESKTOP", False);
  128. NET_WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", False);
  129. NET_WM_STATE_MODAL = XInternAtom(dpy, "_NET_WM_STATE_MODAL", False);
  130. NET_WM_STATE_STICKY = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False);
  131. NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_VERT", False);
  132. NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
  133. NET_WM_STATE_SHADED = XInternAtom(dpy, "_NET_WM_STATE_SHADED", False);
  134. NET_WM_STATE_SKIP_TASKBAR = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
  135. NET_WM_STATE_SKIP_PAGER = XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False);
  136. NET_WM_STATE_HIDDEN = XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False);
  137. NET_WM_STATE_FULLSCREEN = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
  138. NET_WM_STATE_ABOVE = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", False);
  139. NET_WM_STATE_BELOW = XInternAtom(dpy, "_NET_WM_STATE_BELOW", False);
  140. NET_WM_STATE_STAYS_ON_TOP = XInternAtom(dpy, "_NET_WM_STATE_STAYS_ON_TOP", False);
  141. NET_WM_STATE_STAYS_ON_BOTTOM = XInternAtom(dpy, "_NET_WM_STATE_STAYS_ON_BOTTOM", False);
  142. NET_WM_STATE_DEMANDS_ATTENTION = XInternAtom(dpy, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
  143. NET_WM_WINDOW_TYPE = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
  144. NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
  145. NET_WM_WINDOW_TYPE_DOCK = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
  146. MODERRO_WINDOW_TYPE_DOCK = XInternAtom(dpy, "_MODERRO_WINDOW_TYPE_DOCK", False);
  147. NET_WM_WINDOW_TYPE_TOOLBAR = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
  148. NET_WM_WINDOW_TYPE_MENU = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_MENU", False);
  149. NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_UTILITY", False);
  150. NET_WM_WINDOW_TYPE_SPLASH = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_SPLASH", False);
  151. NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
  152. NET_WM_WINDOW_TYPE_DROPDOWN_MENU = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
  153. NET_WM_WINDOW_TYPE_POPUP_MENU = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
  154. NET_WM_WINDOW_TYPE_TOOLTIP = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_TOOLTIP", False);
  155. NET_WM_WINDOW_TYPE_NOTIFICATION = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
  156. NET_WM_WINDOW_TYPE_COMBO = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_COMBO", False);
  157. NET_WM_WINDOW_TYPE_DND = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DND", False);
  158. NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False);
  159. NET_WM_WINDOW_OPACITY = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
  160. NET_WM_NAME = XInternAtom(dpy, "_NET_WM_NAME", False);
  161. NET_WM_VISIBLE_NAME = XInternAtom(dpy, "_NET_WM_VISIBLE_NAME", False);
  162. NET_WM_STRUT = XInternAtom(dpy, "_NET_WM_STRUT", False);
  163. NET_WM_STRUT_PARTIAL = XInternAtom(dpy, "_NET_WM_STRUT_PARTIAL", False);
  164. NET_WM_ICON = XInternAtom(dpy, "_NET_WM_ICON", False);
  165. NET_WM_PID = XInternAtom(dpy, "_NET_WM_PID", False);
  166. }
  167. int NETWM::setProperty(Window window, Atom atom, long offset, uchar *data, int nelem)
  168. {
  169. NETWM::checkInit();
  170. return XChangeProperty(QX11Info::display(), window, atom, offset, 32, PropModeReplace, data, nelem);
  171. }
  172. int NETWM::setPropertySkipTaskbar(Window window)
  173. {
  174. NETWM::checkInit();
  175. Atom state[3];
  176. state[0] = NETWM::NET_WM_STATE_SKIP_PAGER;
  177. state[1] = NETWM::NET_WM_STATE_SKIP_TASKBAR;
  178. state[2] = NETWM::NET_WM_STATE_STICKY;
  179. return NETWM::setProperty(window, NETWM::NET_WM_STATE, XA_ATOM, (uchar *)&state, 3);
  180. }
  181. int NETWM::setPropertyOnTop(Window window)
  182. {
  183. NETWM::checkInit();
  184. Atom state[2];
  185. state[0] = NETWM::NET_WM_STATE_ABOVE;
  186. state[1] = NETWM::NET_WM_STATE_STAYS_ON_TOP;
  187. return NETWM::setProperty(window, NETWM::NET_WM_STATE, XA_ATOM, (uchar *)&state, 2);
  188. }
  189. void* NETWM::property(Window win, Atom prop, Atom type, int *nitems, bool *ok)
  190. {
  191. NETWM::checkInit();
  192. Atom type_ret;
  193. int format_ret;
  194. unsigned long items_ret;
  195. unsigned long after_ret;
  196. unsigned char *prop_data = 0;
  197. if(XGetWindowProperty(QX11Info::display(),
  198. win,
  199. prop,
  200. 0,
  201. 0x7fffffff,
  202. False,
  203. type,
  204. &type_ret,
  205. &format_ret,
  206. &items_ret,
  207. &after_ret,
  208. &prop_data) != Success)
  209. {
  210. if(ok)
  211. *ok = false;
  212. return 0;
  213. }
  214. if(nitems)
  215. *nitems = items_ret;
  216. if(ok)
  217. *ok = true;
  218. return prop_data;
  219. }
  220. bool NETWM::climsg(Window win, long type, long l0, long l1, long l2, long l3, long l4)
  221. {
  222. NETWM::checkInit();
  223. XClientMessageEvent xev;
  224. xev.type = ClientMessage;
  225. xev.window = win;
  226. xev.message_type = type;
  227. xev.format = 32;
  228. xev.data.l[0] = l0;
  229. xev.data.l[1] = l1;
  230. xev.data.l[2] = l2;
  231. xev.data.l[3] = l3;
  232. xev.data.l[4] = l4;
  233. return (XSendEvent(QX11Info::display(), QX11Info::appRootWindow(), False,
  234. (SubstructureNotifyMask | SubstructureRedirectMask),
  235. (XEvent *)&xev) == Success);
  236. }
  237. bool NETWM::climsgwm(Window win, Atom type, Atom arg)
  238. {
  239. NETWM::checkInit();
  240. XClientMessageEvent xev;
  241. xev.type = ClientMessage;
  242. xev.window = win;
  243. xev.message_type = type;
  244. xev.format = 32;
  245. xev.data.l[0] = arg;
  246. xev.data.l[1] = CurrentTime;
  247. return (XSendEvent(QX11Info::display(), win, False, 0L, (XEvent *)&xev) == Success);
  248. }
  249. uint NETWM::netwmDesktopsNumber()
  250. {
  251. NETWM::checkInit();
  252. uint desknum;
  253. quint32 *data;
  254. data = (quint32 *)NETWM::property(QX11Info::appRootWindow(), NETWM::NET_NUMBER_OF_DESKTOPS, XA_CARDINAL, 0);
  255. if(!data)
  256. return 0;
  257. desknum = *data;
  258. XFree(data);
  259. return desknum;
  260. }
  261. uint NETWM::netwmCurrentDesktop()
  262. {
  263. NETWM::checkInit();
  264. uint desk;
  265. quint32 *data;
  266. data = (quint32 *)NETWM::property(QX11Info::appRootWindow(), NETWM::NET_CURRENT_DESKTOP, XA_CARDINAL, 0);
  267. if(!data)
  268. return 0;
  269. desk = *data;
  270. XFree(data);
  271. return desk;
  272. }
  273. qint64 NETWM::netwmPid(Window win)
  274. {
  275. NETWM::checkInit();
  276. qint64 pid = -1;
  277. ulong *data;
  278. data = (ulong *)NETWM::property(win, NETWM::NET_WM_PID, XA_CARDINAL, 0);
  279. if(data)
  280. {
  281. pid = *data;
  282. XFree(data);
  283. }
  284. return pid;
  285. }
  286. bool NETWM::netwmActivateWindow(Window win)
  287. {
  288. NETWM::checkInit();
  289. return NETWM::climsg(win, NETWM::NET_ACTIVE_WINDOW, 2, CurrentTime);
  290. }
  291. QList<Window> NETWM::netwmWindowList()
  292. {
  293. NETWM::checkInit();
  294. QList<Window> list;
  295. int num;
  296. Window *win = reinterpret_cast<Window *>(NETWM::property(QX11Info::appRootWindow(), NETWM::NET_CLIENT_LIST, XA_WINDOW, &num));
  297. if(!win)
  298. {
  299. qDebug("NETWM: Cannot get window list");
  300. return list;
  301. }
  302. for(int i = 0;i < num;i++)
  303. list.append(win[i]);
  304. XFree(win);
  305. return list;
  306. }
  307. int NETWM::netwmDesktop(Window win)
  308. {
  309. NETWM::checkInit();
  310. int desk = 0;
  311. ulong *data;
  312. data = (ulong *)NETWM::property(win, NETWM::NET_WM_DESKTOP, XA_CARDINAL, 0);
  313. if(data)
  314. {
  315. desk = *data;
  316. XFree(data);
  317. }
  318. return desk;
  319. }
  320. NETWM::net_wm_state NETWM::netwmState(Window win)
  321. {
  322. NETWM::checkInit();
  323. net_wm_state nws;
  324. Atom *state;
  325. int num3;
  326. if(!(state = (Atom *)NETWM::property(win, NETWM::NET_WM_STATE, XA_ATOM, &num3)))
  327. return nws;
  328. while(--num3 >= 0)
  329. {
  330. if(state[num3] == NETWM::NET_WM_STATE_MODAL)
  331. {
  332. DBG("NET_WM_STATE_MODAL\n");
  333. nws.modal = 1;
  334. }
  335. else if(state[num3] == NETWM::NET_WM_STATE_STICKY)
  336. {
  337. DBG("NET_WM_STATE_STICKY\n");
  338. nws.sticky = 1;
  339. }
  340. else if(state[num3] == NETWM::NET_WM_STATE_MAXIMIZED_VERT)
  341. {
  342. DBG("NET_WM_STATE_MAXIMIZED_VERT\n");
  343. nws.maximized_vert = 1;
  344. }
  345. else if(state[num3] == NETWM::NET_WM_STATE_MAXIMIZED_HORZ)
  346. {
  347. DBG("NET_WM_STATE_MAXIMIZED_HORZ\n");
  348. nws.maximized_horz = 1;
  349. }
  350. else if(state[num3] == NETWM::NET_WM_STATE_SHADED)
  351. {
  352. DBG("NET_WM_STATE_SHADED\n");
  353. nws.shaded = 1;
  354. }
  355. else if(state[num3] == NETWM::NET_WM_STATE_SKIP_TASKBAR)
  356. {
  357. DBG("NET_WM_STATE_SKIP_TASKBAR\n");
  358. nws.skip_taskbar = 1;
  359. }
  360. else if(state[num3] == NETWM::NET_WM_STATE_SKIP_PAGER)
  361. {
  362. DBG("NET_WM_STATE_SKIP_PAGER\n");
  363. nws.skip_pager = 1;
  364. }
  365. else if(state[num3] == NETWM::NET_WM_STATE_HIDDEN)
  366. {
  367. DBG("NET_WM_STATE_HIDDEN\n");
  368. nws.hidden = 1;
  369. }
  370. else if(state[num3] == NETWM::NET_WM_STATE_FULLSCREEN)
  371. {
  372. DBG("NET_WM_STATE_FULLSCREEN\n");
  373. nws.fullscreen = 1;
  374. }
  375. else if(state[num3] == NETWM::NET_WM_STATE_ABOVE)
  376. {
  377. DBG("NET_WM_STATE_ABOVE\n");
  378. nws.above = 1;
  379. }
  380. else if(state[num3] == NETWM::NET_WM_STATE_BELOW)
  381. {
  382. DBG("NET_WM_STATE_BELOW\n");
  383. nws.below = 1;
  384. }
  385. else if(state[num3] == NETWM::NET_WM_STATE_STAYS_ON_TOP)
  386. {
  387. DBG("NET_WM_STATE_STAYS_ON_TOP\n");
  388. nws.stays_on_top = 1;
  389. }
  390. else if(state[num3] == NETWM::NET_WM_STATE_STAYS_ON_BOTTOM)
  391. {
  392. DBG("NET_WM_STATE_STAYS_ON_BOTTOM\n");
  393. nws.stays_on_bottom = 1;
  394. }
  395. else if(state[num3] == NETWM::NET_WM_STATE_DEMANDS_ATTENTION)
  396. {
  397. DBG("NET_WM_STATE_DEMANDS_ATTENTION\n");
  398. nws.demands_attention = 1;
  399. }
  400. }
  401. nws.valid = true;
  402. XFree(state);
  403. return nws;
  404. }
  405. NETWM::net_wm_window_type NETWM::netwmWindowType(Window win)
  406. {
  407. NETWM::checkInit();
  408. net_wm_window_type nwwt;
  409. Atom *state;
  410. int num3;
  411. bool ok;
  412. if(!(state = (Atom *)NETWM::property(win, NETWM::NET_WM_WINDOW_TYPE, XA_ATOM, &num3, &ok)))
  413. {
  414. if(ok)
  415. {
  416. nwwt.valid = true;
  417. nwwt.normal = 1;
  418. }
  419. return nwwt;
  420. }
  421. nwwt.valid = true;
  422. while(--num3 >= 0)
  423. {
  424. if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DESKTOP)
  425. {
  426. DBG("NET_WM_WINDOW_TYPE_DESKTOP\n");
  427. nwwt.desktop = 1;
  428. }
  429. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DOCK)
  430. {
  431. DBG("NET_WM_WINDOW_TYPE_DOCK\n");
  432. nwwt.dock = 1;
  433. }
  434. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_TOOLBAR)
  435. {
  436. DBG("NET_WM_WINDOW_TYPE_TOOLBAR\n");
  437. nwwt.toolbar = 1;
  438. }
  439. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_MENU)
  440. {
  441. DBG("NET_WM_WINDOW_TYPE_MENU\n");
  442. nwwt.menu = 1;
  443. }
  444. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_UTILITY)
  445. {
  446. DBG("NET_WM_WINDOW_TYPE_UTILITY\n");
  447. nwwt.utility = 1;
  448. }
  449. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_SPLASH)
  450. {
  451. DBG("NET_WM_WINDOW_TYPE_SPLASH\n");
  452. nwwt.splash = 1;
  453. }
  454. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DIALOG)
  455. {
  456. DBG("NET_WM_WINDOW_TYPE_DIALOG\n");
  457. nwwt.dialog = 1;
  458. }
  459. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
  460. {
  461. DBG("NET_WM_WINDOW_TYPE_DROPDOWN_MENU\n");
  462. nwwt.dropdown = 1;
  463. }
  464. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_POPUP_MENU)
  465. {
  466. DBG("NET_WM_WINDOW_TYPE_POPUP_MENU\n");
  467. nwwt.popup = 1;
  468. }
  469. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_TOOLTIP)
  470. {
  471. DBG("NET_WM_WINDOW_TYPE_TOOLTIP\n");
  472. nwwt.tooltip = 1;
  473. }
  474. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_NOTIFICATION)
  475. {
  476. DBG("NET_WM_WINDOW_TYPE_NOTIFICATION\n");
  477. nwwt.notification = 1;
  478. }
  479. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_COMBO)
  480. {
  481. DBG("NET_WM_WINDOW_TYPE_COMBO\n");
  482. nwwt.combo = 1;
  483. }
  484. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DND)
  485. {
  486. DBG("NET_WM_WINDOW_TYPE_DND\n");
  487. nwwt.dnd = 1;
  488. }
  489. else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_NORMAL)
  490. {
  491. DBG("NET_WM_WINDOW_TYPE_NORMAL\n");
  492. nwwt.normal = 1;
  493. }
  494. }
  495. XFree(state);
  496. return nwwt;
  497. }
  498. QString NETWM::icccmString(Window win, Atom atom)
  499. {
  500. NETWM::checkInit();
  501. QString s;
  502. char *data;
  503. if(!(data = (char *)NETWM::property(win, atom, XA_STRING)))
  504. return s;
  505. s = QString::fromUtf8(data);
  506. XFree(data);
  507. return s;
  508. }
  509. QString NETWM::icccmUtf8String(Window win, Atom atom)
  510. {
  511. NETWM::checkInit();
  512. Atom type;
  513. int format;
  514. ulong nitems;
  515. ulong bytes_after;
  516. int result;
  517. uchar *tmp = 0;
  518. QString val;
  519. type = None;
  520. result = XGetWindowProperty(QX11Info::display(), win, atom, 0, LONG_MAX, False,
  521. NETWM::UTF8_STRING, &type, &format, &nitems,
  522. &bytes_after, &tmp);
  523. if(result != Success || type == None || !tmp)
  524. return val;
  525. if(type == NETWM::UTF8_STRING && format == 8 && nitems != 0)
  526. val = QString::fromUtf8(reinterpret_cast<char *>(tmp));
  527. XFree(tmp);
  528. return val;
  529. }
  530. QString NETWM::icccmWindowRole(Window win)
  531. {
  532. NETWM::checkInit();
  533. return NETWM::icccmString(win, NETWM::WM_WINDOW_ROLE);
  534. }
  535. QStringList NETWM::icccmClass(Window win)
  536. {
  537. NETWM::checkInit();
  538. QStringList l;
  539. char *data;
  540. if(!(data = (char *)NETWM::property(win, NETWM::WM_CLASS, XA_STRING)))
  541. return l;
  542. l.append(QString::fromUtf8(data));
  543. l.append(QString::fromUtf8(data+strlen(data)+1));
  544. XFree(data);
  545. return l;
  546. }
  547. QString NETWM::icccmName(Window win)
  548. {
  549. NETWM::checkInit();
  550. return NETWM::icccmString(win, NETWM::WM_NAME);
  551. }
  552. QStringList NETWM::icccmCommand(Window win)
  553. {
  554. NETWM::checkInit();
  555. QStringList list;
  556. char **argv;
  557. int argc;
  558. if(!XGetCommand(QX11Info::display(), win, &argv, &argc))
  559. return list;
  560. for(int i = 0;i < argc;i++)
  561. list.append(argv[i]);
  562. XFreeStringList(argv);
  563. return list;
  564. }
  565. #define MO_NETWM_OPAQUE 0xffffffff
  566. void NETWM::transset(Window window, double d)
  567. {
  568. NETWM::checkInit();
  569. Display *dpy = QX11Info::display();
  570. uint opacity = (uint)(d * MO_NETWM_OPAQUE);
  571. if(opacity == MO_NETWM_OPAQUE)
  572. XDeleteProperty(dpy, window, NETWM::NET_WM_WINDOW_OPACITY);
  573. else
  574. XChangeProperty(dpy, window, NETWM::NET_WM_WINDOW_OPACITY,
  575. XA_CARDINAL, 32, PropModeReplace, (uchar *)&opacity, 1L);
  576. XSync(dpy, False);
  577. }
  578. #if 0
  579. bool NETWM::isComposite()
  580. {
  581. int event_base, error_base;
  582. Display *dpy = QX11Info::display();
  583. // extension is not supported
  584. if(!XCompositeQueryExtension(dpy, &event_base, &error_base))
  585. {
  586. qDebug("NETWM: Composite extension is not supported");
  587. return false;
  588. }
  589. // NETWM-compliant composite manager MUST set selection owner
  590. // of _NET_WM_CM_Sn
  591. Window owner = XGetSelectionOwner(dpy, XInternAtom(dpy, "_NET_WM_CM_S0", False));
  592. return (owner != None);
  593. }
  594. #endif
  595. void NETWM::checkInit()
  596. {
  597. if(!NETWM::WM_STATE)
  598. NETWM::init();
  599. }