00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <qwidget.h>
00028 #ifdef Q_WS_X11 //FIXME
00029
00030 #include "netwm.h"
00031
00032 #include <string.h>
00033 #include <stdio.h>
00034
00035 #include <X11/Xlibint.h>
00036 #include <X11/Xmd.h>
00037
00038 typedef Bool X11Bool;
00039
00040 #include "netwm_p.h"
00041
00042
00043
00044 static Atom UTF8_STRING = 0;
00045
00046
00047 static Atom net_supported = 0;
00048 static Atom net_client_list = 0;
00049 static Atom net_client_list_stacking = 0;
00050 static Atom net_desktop_geometry = 0;
00051 static Atom net_desktop_viewport = 0;
00052 static Atom net_current_desktop = 0;
00053 static Atom net_desktop_names = 0;
00054 static Atom net_number_of_desktops = 0;
00055 static Atom net_active_window = 0;
00056 static Atom net_workarea = 0;
00057 static Atom net_supporting_wm_check = 0;
00058 static Atom net_virtual_roots = 0;
00059
00060
00061 static Atom net_close_window = 0;
00062 static Atom net_wm_moveresize = 0;
00063
00064
00065 static Atom net_wm_name = 0;
00066 static Atom net_wm_visible_name = 0;
00067 static Atom net_wm_icon_name = 0;
00068 static Atom net_wm_visible_icon_name = 0;
00069 static Atom net_wm_desktop = 0;
00070 static Atom net_wm_window_type = 0;
00071 static Atom net_wm_state = 0;
00072 static Atom net_wm_strut = 0;
00073 static Atom net_wm_icon_geometry = 0;
00074 static Atom net_wm_icon = 0;
00075 static Atom net_wm_pid = 0;
00076 static Atom net_wm_handled_icons = 0;
00077
00078
00079 static Atom kde_net_system_tray_windows = 0;
00080 static Atom kde_net_wm_system_tray_window_for = 0;
00081 static Atom kde_net_wm_frame_strut = 0;
00082 static Atom kde_net_wm_window_type_override = 0;
00083 static Atom kde_net_wm_window_type_topmenu = 0;
00084
00085
00086 static Atom net_wm_ping = 0;
00087
00088
00089 static Atom net_wm_window_type_normal = 0;
00090 static Atom net_wm_window_type_desktop = 0;
00091 static Atom net_wm_window_type_dock = 0;
00092 static Atom net_wm_window_type_toolbar = 0;
00093 static Atom net_wm_window_type_menu = 0;
00094 static Atom net_wm_window_type_dialog = 0;
00095
00096
00097 static Atom net_wm_state_modal = 0;
00098 static Atom net_wm_state_sticky = 0;
00099 static Atom net_wm_state_max_vert = 0;
00100 static Atom net_wm_state_max_horiz = 0;
00101 static Atom net_wm_state_shaded = 0;
00102 static Atom net_wm_state_skip_taskbar = 0;
00103 static Atom net_wm_state_skip_pager = 0;
00104 static Atom net_wm_state_fullscreen = 0;
00105
00106
00107 static Atom net_wm_state_stays_on_top = 0;
00108
00109
00110 static Atom xa_wm_state = 0;
00111
00112 static Bool netwm_atoms_created = False;
00113 const unsigned long netwm_sendevent_mask = (SubstructureRedirectMask|
00114 SubstructureNotifyMask);
00115
00116
00117 static char *nstrdup(const char *s1) {
00118 if (! s1) return (char *) 0;
00119
00120 int l = strlen(s1) + 1;
00121 char *s2 = new char[l];
00122 strncpy(s2, s1, l);
00123 return s2;
00124 }
00125
00126
00127 static char *nstrndup(const char *s1, int l) {
00128 if (! s1 || l == 0) return (char *) 0;
00129
00130 char *s2 = new char[l+1];
00131 strncpy(s2, s1, l);
00132 s2[l] = '\0';
00133 return s2;
00134 }
00135
00136
00137 static Window *nwindup(Window *w1, int n) {
00138 if (! w1 || n == 0) return (Window *) 0;
00139
00140 Window *w2 = new Window[n];
00141 while (n--) w2[n] = w1[n];
00142 return w2;
00143 }
00144
00145
00146 static void refdec_nri(NETRootInfoPrivate *p) {
00147
00148 #ifdef NETWMDEBUG
00149 fprintf(stderr, "NET: decrementing NETRootInfoPrivate::ref (%d)\n", p->ref - 1);
00150 #endif
00151
00152 if (! --p->ref) {
00153
00154 #ifdef NETWMDEBUG
00155 fprintf(stderr, "NET: \tno more references, deleting\n");
00156 #endif
00157
00158 if (p->name) delete [] p->name;
00159 if (p->stacking) delete [] p->stacking;
00160 if (p->clients) delete [] p->clients;
00161 if (p->virtual_roots) delete [] p->virtual_roots;
00162 if (p->kde_system_tray_windows) delete [] p->kde_system_tray_windows;
00163
00164 int i;
00165 for (i = 0; i < p->desktop_names.size(); i++)
00166 if (p->desktop_names[i]) delete [] p->desktop_names[i];
00167 }
00168 }
00169
00170
00171 static void refdec_nwi(NETWinInfoPrivate *p) {
00172
00173 #ifdef NETWMDEBUG
00174 fprintf(stderr, "NET: decrementing NETWinInfoPrivate::ref (%d)\n", p->ref - 1);
00175 #endif
00176
00177 if (! --p->ref) {
00178
00179 #ifdef NETWMDEBUG
00180 fprintf(stderr, "NET: \tno more references, deleting\n");
00181 #endif
00182
00183 if (p->name) delete [] p->name;
00184 if (p->visible_name) delete [] p->visible_name;
00185 if (p->icon_name) delete [] p->icon_name;
00186 if (p->visible_icon_name) delete [] p->visible_icon_name;
00187
00188 int i;
00189 for (i = 0; i < p->icons.size(); i++)
00190 if (p->icons[i].data) delete [] p->icons[i].data;
00191 }
00192 }
00193
00194
00195 static int wcmp(const void *a, const void *b) {
00196 return *((Window *) a) - *((Window *) b);
00197 }
00198
00199
00200 static const int netAtomCount = 49;
00201 static void create_atoms(Display *d) {
00202 static const char * const names[netAtomCount] =
00203 {
00204 "UTF8_STRING",
00205 "_NET_SUPPORTED",
00206 "_NET_SUPPORTING_WM_CHECK",
00207 "_NET_CLIENT_LIST",
00208 "_NET_CLIENT_LIST_STACKING",
00209 "_NET_NUMBER_OF_DESKTOPS",
00210 "_NET_DESKTOP_GEOMETRY",
00211 "_NET_DESKTOP_VIEWPORT",
00212 "_NET_CURRENT_DESKTOP",
00213 "_NET_DESKTOP_NAMES",
00214 "_NET_ACTIVE_WINDOW",
00215 "_NET_WORKAREA",
00216 "_NET_VIRTUAL_ROOTS",
00217 "_NET_CLOSE_WINDOW",
00218
00219 "_NET_WM_MOVERESIZE",
00220 "_NET_WM_NAME",
00221 "_NET_WM_VISIBLE_NAME",
00222 "_NET_WM_ICON_NAME",
00223 "_NET_WM_VISIBLE_ICON_NAME",
00224 "_NET_WM_DESKTOP",
00225 "_NET_WM_WINDOW_TYPE",
00226 "_NET_WM_STATE",
00227 "_NET_WM_STRUT",
00228 "_NET_WM_ICON_GEOMETRY",
00229 "_NET_WM_ICON",
00230 "_NET_WM_PID",
00231 "_NET_WM_HANDLED_ICONS",
00232 "_NET_WM_PING",
00233
00234 "_NET_WM_WINDOW_TYPE_NORMAL",
00235 "_NET_WM_WINDOW_TYPE_DESKTOP",
00236 "_NET_WM_WINDOW_TYPE_DOCK",
00237 "_NET_WM_WINDOW_TYPE_TOOLBAR",
00238 "_NET_WM_WINDOW_TYPE_MENU",
00239 "_NET_WM_WINDOW_TYPE_DIALOG",
00240
00241 "_NET_WM_STATE_MODAL",
00242 "_NET_WM_STATE_STICKY",
00243 "_NET_WM_STATE_MAXIMIZED_VERT",
00244 "_NET_WM_STATE_MAXIMIZED_HORZ",
00245 "_NET_WM_STATE_SHADED",
00246 "_NET_WM_STATE_SKIP_TASKBAR",
00247 "_NET_WM_STATE_SKIP_PAGER",
00248 "_NET_WM_STATE_FULLSCREEN",
00249 "_NET_WM_STATE_STAYS_ON_TOP",
00250
00251 "_KDE_NET_SYSTEM_TRAY_WINDOWS",
00252 "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
00253 "_KDE_NET_WM_FRAME_STRUT",
00254 "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE",
00255 "_KDE_NET_WM_WINDOW_TYPE_TOPMENU",
00256
00257 "WM_STATE"
00258 };
00259
00260 Atom atoms[netAtomCount], *atomsp[netAtomCount] =
00261 {
00262 &UTF8_STRING,
00263 &net_supported,
00264 &net_supporting_wm_check,
00265 &net_client_list,
00266 &net_client_list_stacking,
00267 &net_number_of_desktops,
00268 &net_desktop_geometry,
00269 &net_desktop_viewport,
00270 &net_current_desktop,
00271 &net_desktop_names,
00272 &net_active_window,
00273 &net_workarea,
00274 &net_virtual_roots,
00275 &net_close_window,
00276
00277 &net_wm_moveresize,
00278 &net_wm_name,
00279 &net_wm_visible_name,
00280 &net_wm_icon_name,
00281 &net_wm_visible_icon_name,
00282 &net_wm_desktop,
00283 &net_wm_window_type,
00284 &net_wm_state,
00285 &net_wm_strut,
00286 &net_wm_icon_geometry,
00287 &net_wm_icon,
00288 &net_wm_pid,
00289 &net_wm_handled_icons,
00290 &net_wm_ping,
00291
00292 &net_wm_window_type_normal,
00293 &net_wm_window_type_desktop,
00294 &net_wm_window_type_dock,
00295 &net_wm_window_type_toolbar,
00296 &net_wm_window_type_menu,
00297 &net_wm_window_type_dialog,
00298
00299 &net_wm_state_modal,
00300 &net_wm_state_sticky,
00301 &net_wm_state_max_vert,
00302 &net_wm_state_max_horiz,
00303 &net_wm_state_shaded,
00304 &net_wm_state_skip_taskbar,
00305 &net_wm_state_skip_pager,
00306 &net_wm_state_fullscreen,
00307 &net_wm_state_stays_on_top,
00308
00309 &kde_net_system_tray_windows,
00310 &kde_net_wm_system_tray_window_for,
00311 &kde_net_wm_frame_strut,
00312 &kde_net_wm_window_type_override,
00313 &kde_net_wm_window_type_topmenu,
00314
00315 &xa_wm_state,
00316 };
00317
00318 int i = netAtomCount;
00319 while (i--)
00320 atoms[i] = 0;
00321
00322 XInternAtoms(d, (char **) names, netAtomCount, False, atoms);
00323
00324 i = netAtomCount;
00325 while (i--)
00326 *atomsp[i] = atoms[i];
00327
00328 netwm_atoms_created = True;
00329 }
00330
00331
00332 static void readIcon(NETWinInfoPrivate *p) {
00333
00334 #ifdef NETWMDEBUG
00335 fprintf(stderr, "NET: readIcon\n");
00336 #endif
00337
00338 Atom type_ret;
00339 int format_ret;
00340 unsigned long nitems_ret = 0, after_ret = 0;
00341 unsigned char *data_ret = 0;
00342
00343
00344 unsigned char *buffer = 0;
00345 unsigned long offset = 0;
00346 unsigned long buffer_offset = 0;
00347 unsigned long bufsize = 0;
00348
00349
00350 do {
00351 if (XGetWindowProperty(p->display, p->window, net_wm_icon, offset,
00352 BUFSIZE, False, XA_CARDINAL, &type_ret,
00353 &format_ret, &nitems_ret, &after_ret, &data_ret)
00354 == Success) {
00355 if (!bufsize)
00356 {
00357 if (nitems_ret < 3 || type_ret != XA_CARDINAL ||
00358 format_ret != 32) {
00359
00360
00361
00362
00363 if ( data_ret )
00364 XFree(data_ret);
00365 return;
00366 }
00367
00368 bufsize = nitems_ret * sizeof(long) + after_ret;
00369 buffer = (unsigned char *) malloc(bufsize);
00370 }
00371 else if (buffer_offset + nitems_ret*sizeof(long) > bufsize)
00372 {
00373 fprintf(stderr, "NETWM: Warning readIcon() needs buffer adjustment!\n");
00374 bufsize = buffer_offset + nitems_ret * sizeof(long) + after_ret;
00375 buffer = (unsigned char *) realloc(buffer, bufsize);
00376 }
00377 memcpy((buffer + buffer_offset), data_ret, nitems_ret * sizeof(long));
00378 buffer_offset += nitems_ret * sizeof(long);
00379 offset += nitems_ret;
00380
00381 if ( data_ret )
00382 XFree(data_ret);
00383 } else {
00384 if (buffer)
00385 free(buffer);
00386 return;
00387 }
00388 }
00389 while (after_ret > 0);
00390
00391 CARD32 *data32;
00392 unsigned long i, j, k, sz, s;
00393 unsigned long *d = (unsigned long *) buffer;
00394 for (i = 0, j = 0; i < bufsize; i++) {
00395 p->icons[j].size.width = *d++;
00396 i += sizeof(long);
00397 p->icons[j].size.height = *d++;
00398 i += sizeof(long);
00399
00400 sz = p->icons[j].size.width * p->icons[j].size.height;
00401 s = sz * sizeof(long);
00402
00403 if ( i + s - 1 > bufsize ) {
00404 break;
00405 }
00406
00407 if (p->icons[j].data) delete [] p->icons[j].data;
00408 data32 = new CARD32[sz];
00409 p->icons[j].data = (unsigned char *) data32;
00410 for (k = 0; k < sz; k++, i += sizeof(long)) {
00411 *data32++ = (CARD32) *d++;
00412 }
00413 j++;
00414 }
00415
00416 #ifdef NETWMDEBUG
00417 fprintf(stderr, "NET: readIcon got %d icons\n", p->icons.size());
00418 #endif
00419
00420 free(buffer);
00421 }
00422
00423
00424 template <class Z>
00425 RArray<Z>::RArray() {
00426 sz = 0;
00427 d = 0;
00428 }
00429
00430
00431 template <class Z>
00432 RArray<Z>::~RArray() {
00433 if (d) delete [] d;
00434 }
00435
00436
00437 template <class Z>
00438 Z &RArray<Z>::operator[](int index) {
00439 if (!d) {
00440 d = new Z[index + 1];
00441 memset( (void*) &d[0], 0, sizeof(Z) );
00442 sz = 1;
00443 } else if (index >= sz) {
00444
00445 Z *newdata = new Z[index + 1];
00446
00447
00448 int i;
00449 for (i = 0; i < sz; i++)
00450 newdata[i] = d[i];
00451 for (; i <= index; i++ )
00452 memset( (void*) &newdata[i], 0, sizeof(Z) );
00453
00454 sz = index + 1;
00455
00456
00457 delete [] d;
00458 d = newdata;
00459 }
00460
00461 return d[index];
00462 }
00463
00464
00465
00466
00467 NETRootInfo::NETRootInfo(Display *display, Window supportWindow, const char *wmName,
00468 unsigned long properties, int screen, bool doActivate)
00469 {
00470
00471 #ifdef NETWMDEBUG
00472 fprintf(stderr, "NETRootInfo::NETRootInfo: using window manager constructor\n");
00473 #endif
00474
00475 p = new NETRootInfoPrivate;
00476 p->ref = 1;
00477
00478 p->display = display;
00479 p->name = nstrdup(wmName);
00480
00481 if (screen != -1) {
00482 p->screen = screen;
00483 } else {
00484 p->screen = DefaultScreen(p->display);
00485 }
00486
00487 p->root = RootWindow(p->display, p->screen);
00488 p->supportwindow = supportWindow;
00489 p->protocols = properties;
00490 p->number_of_desktops = p->current_desktop = 0;
00491 p->active = None;
00492 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00493 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00494 p->kde_system_tray_windows = 0;
00495 p->kde_system_tray_windows_count = 0;
00496
00497 role = WindowManager;
00498
00499 if (! netwm_atoms_created) create_atoms(p->display);
00500
00501 if (doActivate) activate();
00502 }
00503
00504
00505 NETRootInfo::NETRootInfo(Display *display, unsigned long properties, int screen,
00506 bool doActivate)
00507 {
00508
00509 #ifdef NETWMDEBUG
00510 fprintf(stderr, "NETRootInfo::NETRootInfo: using Client constructor\n");
00511 #endif
00512
00513 p = new NETRootInfoPrivate;
00514 p->ref = 1;
00515
00516 p->name = 0;
00517
00518 p->display = display;
00519
00520 if (screen != -1) {
00521 p->screen = screen;
00522 } else {
00523 p->screen = DefaultScreen(p->display);
00524 }
00525
00526 p->root = RootWindow(p->display, p->screen);
00527 p->rootSize.width = WidthOfScreen(ScreenOfDisplay(p->display, p->screen));
00528 p->rootSize.height = HeightOfScreen(ScreenOfDisplay(p->display, p->screen));
00529
00530 p->supportwindow = None;
00531 p->protocols = properties;
00532 p->number_of_desktops = p->current_desktop = 0;
00533 p->active = None;
00534 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00535 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00536 p->kde_system_tray_windows = 0;
00537 p->kde_system_tray_windows_count = 0;
00538
00539 role = Client;
00540
00541 if (! netwm_atoms_created) create_atoms(p->display);
00542
00543 if (doActivate) activate();
00544 }
00545
00546
00547
00548
00549 NETRootInfo::NETRootInfo(const NETRootInfo &rootinfo) {
00550
00551 #ifdef NETWMDEBUG
00552 fprintf(stderr, "NETRootInfo::NETRootInfo: using copy constructor\n");
00553 #endif
00554
00555 p = rootinfo.p;
00556 role = rootinfo.role;
00557
00558 p->ref++;
00559 }
00560
00561
00562
00563
00564 NETRootInfo::~NETRootInfo() {
00565 refdec_nri(p);
00566
00567 if (! p->ref) delete p;
00568 }
00569
00570
00571 void NETRootInfo::activate() {
00572 if (role == WindowManager) {
00573
00574 #ifdef NETWMDEBUG
00575 fprintf(stderr,
00576 "NETRootInfo::activate: setting supported properties on root\n");
00577 #endif
00578
00579
00580 setSupported(p->protocols | Supported | SupportingWMCheck);
00581 } else {
00582
00583 #ifdef NETWMDEBUG
00584 fprintf(stderr, "NETRootInfo::activate: updating client information\n");
00585 #endif
00586
00587 update(p->protocols);
00588 }
00589 }
00590
00591
00592 void NETRootInfo::setClientList(Window *windows, unsigned int count) {
00593 if (role != WindowManager) return;
00594
00595 p->clients_count = count;
00596
00597 if (p->clients) delete [] p->clients;
00598 p->clients = nwindup(windows, count);
00599
00600 #ifdef NETWMDEBUG
00601 fprintf(stderr, "NETRootInfo::setClientList: setting list with %ld windows\n",
00602 p->clients_count);
00603 #endif
00604
00605 XChangeProperty(p->display, p->root, net_client_list, XA_WINDOW, 32,
00606 PropModeReplace, (unsigned char *)p->clients,
00607 p->clients_count);
00608 }
00609
00610
00611 void NETRootInfo::setClientListStacking(Window *windows, unsigned int count) {
00612 if (role != WindowManager) return;
00613
00614 p->stacking_count = count;
00615 if (p->stacking) delete [] p->stacking;
00616 p->stacking = nwindup(windows, count);
00617
00618 #ifdef NETWMDEBUG
00619 fprintf(stderr,
00620 "NETRootInfo::setClientListStacking: setting list with %ld windows\n",
00621 p->clients_count);
00622 #endif
00623
00624 XChangeProperty(p->display, p->root, net_client_list_stacking, XA_WINDOW, 32,
00625 PropModeReplace, (unsigned char *) p->stacking,
00626 p->stacking_count);
00627 }
00628
00629
00630 void NETRootInfo::setKDESystemTrayWindows(Window *windows, unsigned int count) {
00631 if (role != WindowManager) return;
00632
00633 p->kde_system_tray_windows_count = count;
00634 if (p->kde_system_tray_windows) delete [] p->kde_system_tray_windows;
00635 p->kde_system_tray_windows = nwindup(windows, count);
00636
00637 #ifdef NETWMDEBUG
00638 fprintf(stderr,
00639 "NETRootInfo::setKDESystemTrayWindows: setting list with %ld windows\n",
00640 p->kde_system_tray_windows_count);
00641 #endif
00642
00643 XChangeProperty(p->display, p->root, kde_net_system_tray_windows, XA_WINDOW, 32,
00644 PropModeReplace,
00645 (unsigned char *) p->kde_system_tray_windows,
00646 p->kde_system_tray_windows_count);
00647 }
00648
00649
00650 void NETRootInfo::setNumberOfDesktops(int numberOfDesktops) {
00651
00652 #ifdef NETWMDEBUG
00653 fprintf(stderr,
00654 "NETRootInfo::setNumberOfDesktops: setting desktop count to %d (%s)\n",
00655 numberOfDesktops, (role == WindowManager) ? "WM" : "Client");
00656 #endif
00657
00658 if (role == WindowManager) {
00659 p->number_of_desktops = numberOfDesktops;
00660 long d = numberOfDesktops;
00661 XChangeProperty(p->display, p->root, net_number_of_desktops, XA_CARDINAL, 32,
00662 PropModeReplace, (unsigned char *) &d, 1);
00663 } else {
00664 XEvent e;
00665
00666 e.xclient.type = ClientMessage;
00667 e.xclient.message_type = net_number_of_desktops;
00668 e.xclient.display = p->display;
00669 e.xclient.window = p->root;
00670 e.xclient.format = 32;
00671 e.xclient.data.l[0] = numberOfDesktops;
00672 e.xclient.data.l[1] = 0l;
00673 e.xclient.data.l[2] = 0l;
00674 e.xclient.data.l[3] = 0l;
00675 e.xclient.data.l[4] = 0l;
00676
00677 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
00678 }
00679 }
00680
00681
00682 void NETRootInfo::setCurrentDesktop(int desktop) {
00683
00684 #ifdef NETWMDEBUG
00685 fprintf(stderr,
00686 "NETRootInfo::setCurrentDesktop: setting current desktop = %d (%s)\n",
00687 desktop, (role == WindowManager) ? "WM" : "Client");
00688 #endif
00689
00690 if (role == WindowManager) {
00691 p->current_desktop = desktop;
00692 long d = p->current_desktop - 1;
00693 XChangeProperty(p->display, p->root, net_current_desktop, XA_CARDINAL, 32,
00694 PropModeReplace, (unsigned char *) &d, 1);
00695 } else {
00696 XEvent e;
00697
00698 e.xclient.type = ClientMessage;
00699 e.xclient.message_type = net_current_desktop;
00700 e.xclient.display = p->display;
00701 e.xclient.window = p->root;
00702 e.xclient.format = 32;
00703 e.xclient.data.l[0] = desktop - 1;
00704 e.xclient.data.l[1] = 0l;
00705 e.xclient.data.l[2] = 0l;
00706 e.xclient.data.l[3] = 0l;
00707 e.xclient.data.l[4] = 0l;
00708
00709 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
00710 }
00711 }
00712
00713
00714 void NETRootInfo::setDesktopName(int desktop, const char *desktopName) {
00715
00716 if (desktop < 1 || desktop > p->number_of_desktops) return;
00717
00718 if (p->desktop_names[desktop - 1]) delete [] p->desktop_names[desktop - 1];
00719 p->desktop_names[desktop - 1] = nstrdup(desktopName);
00720
00721 unsigned int i, proplen,
00722 num = ((p->number_of_desktops < p->desktop_names.size()) ?
00723 p->number_of_desktops : p->desktop_names.size());
00724 for (i = 0, proplen = 0; i < num; i++)
00725 proplen += (p->desktop_names[i] != 0 ? strlen(p->desktop_names[i]) : 1 ) + 1;
00726
00727 char *prop = new char[proplen], *propp = prop;
00728
00729 for (i = 0; i < num; i++)
00730 if (p->desktop_names[i]) {
00731 strcpy(propp, p->desktop_names[i]);
00732 propp += strlen(p->desktop_names[i]) + 1;
00733 } else
00734 *propp++ = '\0';
00735
00736 #ifdef NETWMDEBUG
00737 fprintf(stderr,
00738 "NETRootInfo::setDesktopName(%d, '%s')\n"
00739 "NETRootInfo::setDesktopName: total property length = %d",
00740 desktop, desktopName, proplen);
00741 #endif
00742
00743 XChangeProperty(p->display, p->root, net_desktop_names, UTF8_STRING, 8,
00744 PropModeReplace, (unsigned char *) prop, proplen);
00745
00746 delete [] prop;
00747 }
00748
00749
00750 void NETRootInfo::setDesktopGeometry(int , const NETSize &geometry) {
00751
00752 #ifdef NETWMDEBUG
00753 fprintf(stderr, "NETRootInfo::setDesktopGeometry( -- , { %d, %d }) (%s)\n",
00754 geometry.width, geometry.height, (role == WindowManager) ? "WM" : "Client");
00755 #endif
00756
00757 if (role == WindowManager) {
00758 p->geometry = geometry;
00759
00760 long data[2];
00761 data[0] = p->geometry.width;
00762 data[1] = p->geometry.height;
00763
00764 XChangeProperty(p->display, p->root, net_desktop_geometry, XA_CARDINAL, 32,
00765 PropModeReplace, (unsigned char *) data, 2);
00766 } else {
00767 XEvent e;
00768
00769 e.xclient.type = ClientMessage;
00770 e.xclient.message_type = net_desktop_geometry;
00771 e.xclient.display = p->display;
00772 e.xclient.window = p->root;
00773 e.xclient.format = 32;
00774 e.xclient.data.l[0] = geometry.width;
00775 e.xclient.data.l[1] = geometry.height;
00776 e.xclient.data.l[2] = 0l;
00777 e.xclient.data.l[3] = 0l;
00778 e.xclient.data.l[4] = 0l;
00779
00780 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
00781 }
00782 }
00783
00784
00785 void NETRootInfo::setDesktopViewport(int desktop, const NETPoint &viewport) {
00786
00787 #ifdef NETWMDEBUG
00788 fprintf(stderr, "NETRootInfo::setDesktopViewport(%d, { %d, %d }) (%s)\n",
00789 desktop, viewport.x, viewport.y, (role == WindowManager) ? "WM" : "Client");
00790 #endif
00791
00792 if (desktop < 1) return;
00793
00794 if (role == WindowManager) {
00795 p->viewport[desktop - 1] = viewport;
00796
00797 int d, i, l;
00798 l = p->viewport.size() * 2;
00799 long *data = new long[l];
00800 for (d = 0, i = 0; d < p->viewport.size(); d++) {
00801 data[i++] = p->viewport[d].x;
00802 data[i++] = p->viewport[d].y;
00803 }
00804
00805 XChangeProperty(p->display, p->root, net_desktop_viewport, XA_CARDINAL, 32,
00806 PropModeReplace, (unsigned char *) data, l);
00807
00808 delete [] data;
00809 } else {
00810 XEvent e;
00811
00812 e.xclient.type = ClientMessage;
00813 e.xclient.message_type = net_desktop_viewport;
00814 e.xclient.display = p->display;
00815 e.xclient.window = p->root;
00816 e.xclient.format = 32;
00817 e.xclient.data.l[0] = viewport.x;
00818 e.xclient.data.l[1] = viewport.y;
00819 e.xclient.data.l[2] = 0l;
00820 e.xclient.data.l[3] = 0l;
00821 e.xclient.data.l[4] = 0l;
00822
00823 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
00824 }
00825 }
00826
00827
00828 void NETRootInfo::setSupported(unsigned long pr) {
00829 p->protocols = pr;
00830
00831 if (role != WindowManager) {
00832 #ifdef NETWMDEBUG
00833 fprintf(stderr, "NETRootInfo::setSupported - role != WindowManager\n");
00834 #endif
00835
00836 return;
00837 }
00838
00839 Atom atoms[netAtomCount];
00840 int pnum = 2;
00841
00842
00843 atoms[0] = net_supported;
00844 atoms[1] = net_supporting_wm_check;
00845
00846 if (p->protocols & ClientList)
00847 atoms[pnum++] = net_client_list;
00848
00849 if (p->protocols & ClientListStacking)
00850 atoms[pnum++] = net_client_list_stacking;
00851
00852 if (p->protocols & NumberOfDesktops)
00853 atoms[pnum++] = net_number_of_desktops;
00854
00855 if (p->protocols & DesktopGeometry)
00856 atoms[pnum++] = net_desktop_geometry;
00857
00858 if (p->protocols & DesktopViewport)
00859 atoms[pnum++] = net_desktop_viewport;
00860
00861 if (p->protocols & CurrentDesktop)
00862 atoms[pnum++] = net_current_desktop;
00863
00864 if (p->protocols & DesktopNames)
00865 atoms[pnum++] = net_desktop_names;
00866
00867 if (p->protocols & ActiveWindow)
00868 atoms[pnum++] = net_active_window;
00869
00870 if (p->protocols & WorkArea)
00871 atoms[pnum++] = net_workarea;
00872
00873 if (p->protocols & VirtualRoots)
00874 atoms[pnum++] = net_virtual_roots;
00875
00876 if (p->protocols & CloseWindow)
00877 atoms[pnum++] = net_close_window;
00878
00879
00880
00881 if (p->protocols & WMMoveResize)
00882 atoms[pnum++] = net_wm_moveresize;
00883
00884 if (p->protocols & WMName)
00885 atoms[pnum++] = net_wm_name;
00886
00887 if (p->protocols & WMVisibleName)
00888 atoms[pnum++] = net_wm_visible_name;
00889
00890 if (p->protocols & WMIconName)
00891 atoms[pnum++] = net_wm_icon_name;
00892
00893 if (p->protocols & WMVisibleIconName)
00894 atoms[pnum++] = net_wm_visible_icon_name;
00895
00896 if (p->protocols & WMDesktop)
00897 atoms[pnum++] = net_wm_desktop;
00898
00899 if (p->protocols & WMWindowType) {
00900 atoms[pnum++] = net_wm_window_type;
00901
00902
00903 atoms[pnum++] = net_wm_window_type_normal;
00904 atoms[pnum++] = net_wm_window_type_desktop;
00905 atoms[pnum++] = net_wm_window_type_dock;
00906 atoms[pnum++] = net_wm_window_type_toolbar;
00907 atoms[pnum++] = net_wm_window_type_menu;
00908 atoms[pnum++] = net_wm_window_type_dialog;
00909 atoms[pnum++] = kde_net_wm_window_type_override;
00910 atoms[pnum++] = kde_net_wm_window_type_topmenu;
00911 }
00912
00913 if (p->protocols & WMState) {
00914 atoms[pnum++] = net_wm_state;
00915
00916
00917 atoms[pnum++] = net_wm_state_modal;
00918 atoms[pnum++] = net_wm_state_sticky;
00919 atoms[pnum++] = net_wm_state_max_vert;
00920 atoms[pnum++] = net_wm_state_max_horiz;
00921 atoms[pnum++] = net_wm_state_shaded;
00922 atoms[pnum++] = net_wm_state_skip_taskbar;
00923 atoms[pnum++] = net_wm_state_skip_pager;
00924 atoms[pnum++] = net_wm_state_fullscreen;
00925 atoms[pnum++] = net_wm_state_stays_on_top;
00926 }
00927
00928 if (p->protocols & WMStrut)
00929 atoms[pnum++] = net_wm_strut;
00930
00931 if (p->protocols & WMIconGeometry)
00932 atoms[pnum++] = net_wm_icon_geometry;
00933
00934 if (p->protocols & WMIcon)
00935 atoms[pnum++] = net_wm_icon;
00936
00937 if (p->protocols & WMPid)
00938 atoms[pnum++] = net_wm_pid;
00939
00940 if (p->protocols & WMHandledIcons)
00941 atoms[pnum++] = net_wm_handled_icons;
00942
00943 if (p->protocols & WMPing)
00944 atoms[pnum++] = net_wm_ping;
00945
00946
00947 if (p->protocols & KDESystemTrayWindows)
00948 atoms[pnum++] = kde_net_system_tray_windows;
00949
00950 if (p->protocols & WMKDESystemTrayWinFor)
00951 atoms[pnum++] = kde_net_wm_system_tray_window_for;
00952
00953 if (p->protocols & WMKDEFrameStrut)
00954 atoms[pnum++] = kde_net_wm_frame_strut;
00955
00956 XChangeProperty(p->display, p->root, net_supported, XA_ATOM, 32,
00957 PropModeReplace, (unsigned char *) atoms, pnum);
00958 XChangeProperty(p->display, p->root, net_supporting_wm_check, XA_WINDOW, 32,
00959 PropModeReplace, (unsigned char *) &(p->supportwindow), 1);
00960
00961 #ifdef NETWMDEBUG
00962 fprintf(stderr,
00963 "NETRootInfo::setSupported: _NET_SUPPORTING_WM_CHECK = 0x%lx on 0x%lx\n"
00964 " : _NET_WM_NAME = '%s' on 0x%lx\n",
00965 p->supportwindow, p->supportwindow, p->name, p->supportwindow);
00966 #endif
00967
00968 XChangeProperty(p->display, p->supportwindow, net_supporting_wm_check,
00969 XA_WINDOW, 32, PropModeReplace,
00970 (unsigned char *) &(p->supportwindow), 1);
00971 XChangeProperty(p->display, p->supportwindow, net_wm_name, UTF8_STRING, 8,
00972 PropModeReplace, (unsigned char *) p->name,
00973 strlen(p->name));
00974 }
00975
00976
00977 void NETRootInfo::setActiveWindow(Window window) {
00978
00979 #ifdef NETWMDEBUG
00980 fprintf(stderr, "NETRootInfo::setActiveWindow(0x%lx) (%s)\n",
00981 window, (role == WindowManager) ? "WM" : "Client");
00982 #endif
00983
00984 if (role == WindowManager) {
00985 p->active = window;
00986 XChangeProperty(p->display, p->root, net_active_window, XA_WINDOW, 32,
00987 PropModeReplace, (unsigned char *) &(p->active), 1);
00988 } else {
00989 XEvent e;
00990
00991 e.xclient.type = ClientMessage;
00992 e.xclient.message_type = net_active_window;
00993 e.xclient.display = p->display;
00994 e.xclient.window = window;
00995 e.xclient.format = 32;
00996 e.xclient.data.l[0] = 0l;
00997 e.xclient.data.l[1] = 0l;
00998 e.xclient.data.l[2] = 0l;
00999 e.xclient.data.l[3] = 0l;
01000 e.xclient.data.l[4] = 0l;
01001
01002 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01003 }
01004 }
01005
01006
01007 void NETRootInfo::setWorkArea(int desktop, const NETRect &workarea) {
01008
01009 #ifdef NETWMDEBUG
01010 fprintf(stderr, "NETRootInfo::setWorkArea(%d, { %d, %d, %d, %d }) (%s)\n",
01011 desktop, workarea.pos.x, workarea.pos.y, workarea.size.width, workarea.size.height,
01012 (role == WindowManager) ? "WM" : "Client");
01013 #endif
01014
01015 if (role != WindowManager || desktop < 1) return;
01016
01017 p->workarea[desktop - 1] = workarea;
01018
01019 long *wa = new long[p->number_of_desktops * 4];
01020 int i, o;
01021 for (i = 0, o = 0; i < p->number_of_desktops; i++) {
01022 wa[o++] = p->workarea[i].pos.x;
01023 wa[o++] = p->workarea[i].pos.y;
01024 wa[o++] = p->workarea[i].size.width;
01025 wa[o++] = p->workarea[i].size.height;
01026 }
01027
01028 XChangeProperty(p->display, p->root, net_workarea, XA_CARDINAL, 32,
01029 PropModeReplace, (unsigned char *) wa,
01030 p->number_of_desktops * 4);
01031
01032 delete [] wa;
01033 }
01034
01035
01036 void NETRootInfo::setVirtualRoots(Window *windows, unsigned int count) {
01037 if (role != WindowManager) return;
01038
01039 p->virtual_roots_count = count;
01040 p->virtual_roots = windows;
01041
01042 #ifdef NETWMDEBUG
01043 fprintf(stderr, "NETRootInfo::setVirtualRoots: setting list with %ld windows\n",
01044 p->virtual_roots_count);
01045 #endif
01046
01047 XChangeProperty(p->display, p->root, net_virtual_roots, XA_WINDOW, 32,
01048 PropModeReplace, (unsigned char *) p->virtual_roots,
01049 p->virtual_roots_count);
01050 }
01051
01052
01053 void NETRootInfo::closeWindowRequest(Window window) {
01054
01055 #ifdef NETWMDEBUG
01056 fprintf(stderr, "NETRootInfo::closeWindowRequest: requesting close for 0x%lx\n",
01057 window);
01058 #endif
01059
01060 XEvent e;
01061
01062 e.xclient.type = ClientMessage;
01063 e.xclient.message_type = net_close_window;
01064 e.xclient.display = p->display;
01065 e.xclient.window = window;
01066 e.xclient.format = 32;
01067 e.xclient.data.l[0] = 0l;
01068 e.xclient.data.l[1] = 0l;
01069 e.xclient.data.l[2] = 0l;
01070 e.xclient.data.l[3] = 0l;
01071 e.xclient.data.l[4] = 0l;
01072
01073 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01074 }
01075
01076
01077 void NETRootInfo::moveResizeRequest(Window window, int x_root, int y_root,
01078 Direction direction)
01079 {
01080
01081 #ifdef NETWMDEBUG
01082 fprintf(stderr,
01083 "NETRootInfo::moveResizeRequest: requesting resize/move for 0x%lx (%d, %d, %d)\n",
01084 window, x_root, y_root, direction);
01085 #endif
01086
01087 XEvent e;
01088
01089 e.xclient.type = ClientMessage;
01090 e.xclient.message_type = net_wm_moveresize;
01091 e.xclient.display = p->display;
01092 e.xclient.window = window,
01093 e.xclient.format = 32;
01094 e.xclient.data.l[0] = x_root;
01095 e.xclient.data.l[1] = y_root;
01096 e.xclient.data.l[2] = direction;
01097 e.xclient.data.l[3] = 0l;
01098 e.xclient.data.l[4] = 0l;
01099
01100 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01101 }
01102
01103
01104
01105
01106 const NETRootInfo &NETRootInfo::operator=(const NETRootInfo &rootinfo) {
01107
01108 #ifdef NETWMDEBUG
01109 fprintf(stderr, "NETRootInfo::operator=()\n");
01110 #endif
01111
01112 if (p != rootinfo.p) {
01113 refdec_nri(p);
01114
01115 if (! p->ref) delete p;
01116 }
01117
01118 p = rootinfo.p;
01119 role = rootinfo.role;
01120 p->ref++;
01121
01122 return *this;
01123 }
01124
01125
01126 unsigned long NETRootInfo::event(XEvent *event) {
01127 unsigned long dirty = 0;
01128
01129
01130
01131 if (role == WindowManager && event->type == ClientMessage &&
01132 event->xclient.format == 32) {
01133 #ifdef NETWMDEBUG
01134 fprintf(stderr, "NETRootInfo::event: handling ClientMessage event\n");
01135 #endif
01136
01137 if (event->xclient.message_type == net_number_of_desktops) {
01138 dirty = NumberOfDesktops;
01139
01140 #ifdef NETWMDEBUG
01141 fprintf(stderr, "NETRootInfo::event: changeNumberOfDesktops(%ld)\n",
01142 event->xclient.data.l[0]);
01143 #endif
01144
01145 changeNumberOfDesktops(event->xclient.data.l[0]);
01146 } else if (event->xclient.message_type == net_desktop_geometry) {
01147 dirty = DesktopGeometry;
01148
01149 NETSize sz;
01150 sz.width = event->xclient.data.l[0];
01151 sz.height = event->xclient.data.l[1];
01152
01153 #ifdef NETWMDEBUG
01154 fprintf(stderr, "NETRootInfo::event: changeDesktopGeometry( -- , { %d, %d })\n",
01155 sz.width, sz.height);
01156 #endif
01157
01158 changeDesktopGeometry(~0, sz);
01159 } else if (event->xclient.message_type == net_desktop_viewport) {
01160 dirty = DesktopViewport;
01161
01162 NETPoint pt;
01163 pt.x = event->xclient.data.l[0];
01164 pt.y = event->xclient.data.l[1];
01165
01166 #ifdef NETWMDEBUG
01167 fprintf(stderr, "NETRootInfo::event: changeDesktopViewport(%d, { %d, %d })\n",
01168 p->current_desktop, pt.x, pt.y);
01169 #endif
01170
01171 changeDesktopViewport(p->current_desktop, pt);
01172 } else if (event->xclient.message_type == net_current_desktop) {
01173 dirty = CurrentDesktop;
01174
01175 #ifdef NETWMDEBUG
01176 fprintf(stderr, "NETRootInfo::event: changeCurrentDesktop(%ld)\n",
01177 event->xclient.data.l[0] + 1);
01178 #endif
01179
01180 changeCurrentDesktop(event->xclient.data.l[0] + 1);
01181 } else if (event->xclient.message_type == net_active_window) {
01182 dirty = ActiveWindow;
01183
01184 #ifdef NETWMDEBUG
01185 fprintf(stderr, "NETRootInfo::event: changeActiveWindow(0x%lx)\n",
01186 event->xclient.window);
01187 #endif
01188
01189 changeActiveWindow(event->xclient.window);
01190 } else if (event->xclient.message_type == net_wm_moveresize) {
01191
01192 #ifdef NETWMDEBUG
01193 fprintf(stderr, "NETRootInfo::event: moveResize(%ld, %ld, %ld, %ld)\n",
01194 event->xclient.window,
01195 event->xclient.data.l[0],
01196 event->xclient.data.l[1],
01197 event->xclient.data.l[2]
01198 );
01199 #endif
01200
01201 moveResize(event->xclient.window,
01202 event->xclient.data.l[0],
01203 event->xclient.data.l[1],
01204 event->xclient.data.l[2]);
01205 } else if (event->xclient.message_type == net_close_window) {
01206
01207 #ifdef NETWMDEBUG
01208 fprintf(stderr, "NETRootInfo::event: closeWindow(0x%lx)\n",
01209 event->xclient.window);
01210 #endif
01211
01212 closeWindow(event->xclient.window);
01213 }
01214 }
01215
01216 if (event->type == PropertyNotify) {
01217
01218 #ifdef NETWMDEBUG
01219 fprintf(stderr, "NETRootInfo::event: handling PropertyNotify event\n");
01220 #endif
01221
01222 XEvent pe = *event;
01223
01224 Bool done = False;
01225 Bool compaction = False;
01226 while (! done) {
01227
01228 #ifdef NETWMDEBUG
01229 fprintf(stderr, "NETRootInfo::event: loop fire\n");
01230 #endif
01231
01232 if (pe.xproperty.atom == net_client_list)
01233 dirty |= ClientList;
01234 else if (pe.xproperty.atom == net_client_list_stacking)
01235 dirty |= ClientListStacking;
01236 else if (pe.xproperty.atom == kde_net_system_tray_windows)
01237 dirty |= KDESystemTrayWindows;
01238 else if (pe.xproperty.atom == net_desktop_names)
01239 dirty |= DesktopNames;
01240 else if (pe.xproperty.atom == net_workarea)
01241 dirty |= WorkArea;
01242 else if (pe.xproperty.atom == net_number_of_desktops)
01243 dirty |= NumberOfDesktops;
01244 else if (pe.xproperty.atom == net_desktop_geometry)
01245 dirty |= DesktopGeometry;
01246 else if (pe.xproperty.atom == net_desktop_viewport)
01247 dirty |= DesktopViewport;
01248 else if (pe.xproperty.atom == net_current_desktop)
01249 dirty |= CurrentDesktop;
01250 else if (pe.xproperty.atom == net_active_window)
01251 dirty |= ActiveWindow;
01252 else {
01253
01254 #ifdef NETWMDEBUG
01255 fprintf(stderr, "NETRootInfo::event: putting back event and breaking\n");
01256 #endif
01257
01258 if ( compaction )
01259 XPutBackEvent(p->display, &pe);
01260 break;
01261 }
01262
01263 if (XCheckTypedWindowEvent(p->display, p->root, PropertyNotify, &pe) )
01264 compaction = True;
01265 else
01266 break;
01267 }
01268
01269 update(dirty & p->protocols);
01270 }
01271
01272 #ifdef NETWMDEBUG
01273 fprintf(stderr, "NETRootInfo::event: handled events, returning dirty = 0x%lx\n",
01274 dirty & p->protocols);
01275 #endif
01276
01277 return dirty & p->protocols;
01278 }
01279
01280
01281
01282
01283 void NETRootInfo::update(unsigned long dirty) {
01284 Atom type_ret;
01285 int format_ret;
01286 unsigned char *data_ret;
01287 unsigned long nitems_ret, unused;
01288
01289 dirty &= p->protocols;
01290
01291 if (dirty & ClientList) {
01292 if (XGetWindowProperty(p->display, p->root, net_client_list,
01293 0l, (long) BUFSIZE, False, XA_WINDOW, &type_ret,
01294 &format_ret, &nitems_ret, &unused, &data_ret)
01295 == Success) {
01296 if (type_ret == XA_WINDOW && format_ret == 32) {
01297 Window *wins = (Window *) data_ret;
01298
01299 qsort(wins, nitems_ret, sizeof(Window), wcmp);
01300
01301 if (p->clients) {
01302 if (role == Client) {
01303 unsigned long new_index = 0, old_index = 0;
01304 unsigned long new_count = nitems_ret,
01305 old_count = p->clients_count;
01306
01307 while (old_index < old_count || new_index < new_count) {
01308 if (old_index == old_count) {
01309 addClient(wins[new_index++]);
01310 } else if (new_index == new_count) {
01311 removeClient(p->clients[old_index++]);
01312 } else {
01313 if (p->clients[old_index] <
01314 wins[new_index]) {
01315 removeClient(p->clients[old_index++]);
01316 } else if (wins[new_index] <
01317 p->clients[old_index]) {
01318 addClient(wins[new_index++]);
01319 } else {
01320 new_index++;
01321 old_index++;
01322 }
01323 }
01324 }
01325 }
01326
01327 delete [] p->clients;
01328 } else {
01329 #ifdef NETWMDEBUG
01330 fprintf(stderr, "NETRootInfo::update: client list null, creating\n");
01331 #endif
01332
01333 unsigned long n;
01334 for (n = 0; n < nitems_ret; n++) {
01335 addClient(wins[n]);
01336 }
01337 }
01338
01339 p->clients_count = nitems_ret;
01340 p->clients = nwindup(wins, p->clients_count);
01341 }
01342
01343 #ifdef NETWMDEBUG
01344 fprintf(stderr, "NETRootInfo::update: client list updated (%ld clients)\n",
01345 p->clients_count);
01346 #endif
01347 if ( data_ret )
01348 XFree(data_ret);
01349 }
01350 }
01351
01352 if (dirty & KDESystemTrayWindows) {
01353 if (XGetWindowProperty(p->display, p->root, kde_net_system_tray_windows,
01354 0l, (long) BUFSIZE, False, XA_WINDOW, &type_ret,
01355 &format_ret, &nitems_ret, &unused, &data_ret)
01356 == Success) {
01357 if (type_ret == XA_WINDOW && format_ret == 32) {
01358 Window *wins = (Window *) data_ret;
01359
01360 qsort(wins, nitems_ret, sizeof(Window), wcmp);
01361
01362 if (p->kde_system_tray_windows) {
01363 if (role == Client) {
01364 unsigned long new_index = 0, new_count = nitems_ret;
01365 unsigned long old_index = 0,
01366 old_count = p->kde_system_tray_windows_count;
01367
01368 while(old_index < old_count || new_index < new_count) {
01369 if (old_index == old_count) {
01370 addSystemTrayWin(wins[new_index++]);
01371 } else if (new_index == new_count) {
01372 removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
01373 } else {
01374 if (p->kde_system_tray_windows[old_index] <
01375 wins[new_index]) {
01376 removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
01377 } else if (wins[new_index] <
01378 p->kde_system_tray_windows[old_index]) {
01379 addSystemTrayWin(wins[new_index++]);
01380 } else {
01381 new_index++;
01382 old_index++;
01383 }
01384 }
01385 }
01386 }
01387
01388 } else {
01389 unsigned long n;
01390 for (n = 0; n < nitems_ret; n++) {
01391 addSystemTrayWin(wins[n]);
01392 }
01393 }
01394
01395 p->kde_system_tray_windows_count = nitems_ret;
01396 if (p->kde_system_tray_windows)
01397 delete [] p->kde_system_tray_windows;
01398 p->kde_system_tray_windows =
01399 nwindup(wins, p->kde_system_tray_windows_count);
01400 }
01401
01402 if ( data_ret )
01403 XFree(data_ret);
01404 }
01405 }
01406
01407 if (dirty & ClientListStacking) {
01408 if (XGetWindowProperty(p->display, p->root, net_client_list_stacking,
01409 0, (long) BUFSIZE, False, XA_WINDOW, &type_ret,
01410 &format_ret, &nitems_ret, &unused, &data_ret)
01411 == Success) {
01412 if (type_ret == XA_WINDOW && format_ret == 32) {
01413 Window *wins = (Window *) data_ret;
01414
01415 if (p->stacking) {
01416 delete [] p->stacking;
01417 }
01418
01419 p->stacking_count = nitems_ret;
01420 p->stacking = nwindup(wins, p->stacking_count);
01421 }
01422
01423 #ifdef NETWMDEBUG
01424 fprintf(stderr,"NETRootInfo::update: client stacking updated (%ld clients)\n",
01425 p->stacking_count);
01426 #endif
01427
01428 if ( data_ret )
01429 XFree(data_ret);
01430 }
01431 }
01432
01433 if (dirty & NumberOfDesktops) {
01434 p->number_of_desktops = 0;
01435
01436 if (XGetWindowProperty(p->display, p->root, net_number_of_desktops,
01437 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
01438 &nitems_ret, &unused, &data_ret)
01439 == Success) {
01440 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
01441 p->number_of_desktops = *((long *) data_ret);
01442 }
01443
01444 #ifdef NETWMDEBUG
01445 fprintf(stderr, "NETRootInfo::update: number of desktops = %d\n",
01446 p->number_of_desktops);
01447 #endif
01448 if ( data_ret )
01449 XFree(data_ret);
01450 }
01451 }
01452
01453 if (dirty & DesktopGeometry) {
01454 if (XGetWindowProperty(p->display, p->root, net_desktop_geometry,
01455 0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
01456 &nitems_ret, &unused, &data_ret)
01457 == Success) {
01458 if (type_ret == XA_CARDINAL && format_ret == 32 &&
01459 nitems_ret == 2) {
01460 long *data = (long *) data_ret;
01461
01462 p->geometry.width = data[0];
01463 p->geometry.height = data[1];
01464
01465 #ifdef NETWMDEBUG
01466 fprintf(stderr, "NETRootInfo::update: desktop geometry updated\n");
01467 #endif
01468 }
01469 if ( data_ret )
01470 XFree(data_ret);
01471 }
01472 } else {
01473
01474 p->geometry = p->rootSize;
01475 }
01476
01477 if (dirty & DesktopViewport) {
01478 if (XGetWindowProperty(p->display, p->root, net_desktop_viewport,
01479 0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
01480 &nitems_ret, &unused, &data_ret)
01481 == Success) {
01482 if (type_ret == XA_CARDINAL && format_ret == 32 &&
01483 nitems_ret == 2) {
01484 long *data = (long *) data_ret;
01485
01486 int d, i, n;
01487 n = nitems_ret / 2;
01488 for (d = 0, i = 0; d < n; d++) {
01489 p->viewport[d].x = data[i++];
01490 p->viewport[d].y = data[i++];
01491 }
01492
01493 #ifdef NETWMDEBUG
01494 fprintf(stderr,
01495 "NETRootInfo::update: desktop viewport array updated (%d entries)\n",
01496 p->viewport.size());
01497
01498 if (nitems_ret % 2 != 0) {
01499 fprintf(stderr,
01500 "NETRootInfo::update(): desktop viewport array "
01501 "size not a multipe of 2\n");
01502 }
01503 #endif
01504 }
01505 if ( data_ret )
01506 XFree(data_ret);
01507 }
01508 } else {
01509 int i;
01510 for (i = 0; i < p->viewport.size(); i++) {
01511 p->viewport[i].x = p->viewport[i].y = 0;
01512 }
01513 }
01514
01515 if (dirty & CurrentDesktop) {
01516 p->current_desktop = 0;
01517 if (XGetWindowProperty(p->display, p->root, net_current_desktop,
01518 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
01519 &nitems_ret, &unused, &data_ret)
01520 == Success) {
01521 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
01522 p->current_desktop = *((long *) data_ret) + 1;
01523 }
01524
01525 #ifdef NETWMDEBUG
01526 fprintf(stderr, "NETRootInfo::update: current desktop = %d\n",
01527 p->current_desktop);
01528 #endif
01529 if ( data_ret )
01530 XFree(data_ret);
01531 }
01532 }
01533
01534 if (dirty & DesktopNames) {
01535 if (XGetWindowProperty(p->display, p->root, net_desktop_names,
01536 0l, (long) BUFSIZE, False, UTF8_STRING, &type_ret,
01537 &format_ret, &nitems_ret, &unused, &data_ret)
01538 == Success) {
01539 if (type_ret == UTF8_STRING && format_ret == 8) {
01540 const char *d = (const char *) data_ret;
01541 unsigned int s, n, index;
01542
01543 for (s = 0, n = 0, index = 0; n < nitems_ret; n++) {
01544 if (d[n] == '\0') {
01545 if (p->desktop_names[index])
01546 delete [] p->desktop_names[index];
01547 p->desktop_names[index++] = nstrndup((d + s), n - s + 1);
01548 s = n + 1;
01549 }
01550 }
01551 }
01552
01553 #ifdef NETWMDEBUG
01554 fprintf(stderr, "NETRootInfo::update: desktop names array updated (%d entries)\n",
01555 p->desktop_names.size());
01556 #endif
01557 if ( data_ret )
01558 XFree(data_ret);
01559 }
01560 }
01561
01562 if (dirty & ActiveWindow) {
01563 if (XGetWindowProperty(p->display, p->root, net_active_window, 0l, 1l,
01564 False, XA_WINDOW, &type_ret, &format_ret,
01565 &nitems_ret, &unused, &data_ret)
01566 == Success) {
01567 if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
01568 p->active = *((Window *) data_ret);
01569 }
01570
01571 #ifdef NETWMDEBUG
01572 fprintf(stderr, "NETRootInfo::update: active window = 0x%lx\n",
01573 p->active);
01574 #endif
01575 if ( data_ret )
01576 XFree(data_ret);
01577 }
01578 }
01579
01580 if (dirty & WorkArea) {
01581 if (XGetWindowProperty(p->display, p->root, net_workarea, 0l,
01582 (p->number_of_desktops * 4), False, XA_CARDINAL,
01583 &type_ret, &format_ret, &nitems_ret, &unused,
01584 &data_ret)
01585 == Success) {
01586 if (type_ret == XA_CARDINAL && format_ret == 32 &&
01587 nitems_ret == (unsigned) (p->number_of_desktops * 4)) {
01588 long *d = (long *) data_ret;
01589 int i, j;
01590 for (i = 0, j = 0; i < p->number_of_desktops; i++) {
01591 p->workarea[i].pos.x = d[j++];
01592 p->workarea[i].pos.y = d[j++];
01593 p->workarea[i].size.width = d[j++];
01594 p->workarea[i].size.height = d[j++];
01595 }
01596 }
01597
01598 #ifdef NETWMDEBUG
01599 fprintf(stderr, "NETRootInfo::update: work area array updated (%d entries)\n",
01600 p->workarea.size());
01601 #endif
01602 if ( data_ret )
01603 XFree(data_ret);
01604 }
01605 }
01606
01607
01608 if (dirty & SupportingWMCheck) {
01609 if (XGetWindowProperty(p->display, p->root, net_supporting_wm_check,
01610 0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
01611 &nitems_ret, &unused, &data_ret)
01612 == Success) {
01613 if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
01614 p->supportwindow = *((Window *) data_ret);
01615
01616 unsigned char *name_ret;
01617 if (XGetWindowProperty(p->display, p->supportwindow,
01618 net_wm_name, 0l, (long) BUFSIZE, False,
01619 UTF8_STRING, &type_ret, &format_ret,
01620 &nitems_ret, &unused, &name_ret)
01621 == Success) {
01622 if (type_ret == UTF8_STRING && format_ret == 8)
01623 p->name = nstrndup((const char *) name_ret, nitems_ret);
01624
01625 if ( name_ret )
01626 XFree(name_ret);
01627 }
01628 }
01629
01630 #ifdef NETWMDEBUG
01631 fprintf(stderr,
01632 "NETRootInfo::update: supporting window manager = '%s'\n",
01633 p->name);
01634 #endif
01635 if ( data_ret )
01636 XFree(data_ret);
01637 }
01638 }
01639
01640 if (dirty & VirtualRoots) {
01641 if (XGetWindowProperty(p->display, p->root, net_virtual_roots,
01642 0, (long) BUFSIZE, False, XA_WINDOW, &type_ret,
01643 &format_ret, &nitems_ret, &unused, &data_ret)
01644 == Success) {
01645 if (type_ret == XA_WINDOW && format_ret == 32) {
01646 Window *wins = (Window *) data_ret;
01647
01648 if (p->virtual_roots) {
01649 delete [] p->virtual_roots;
01650 }
01651
01652 p->virtual_roots_count = nitems_ret;
01653 p->virtual_roots = nwindup(wins, p->virtual_roots_count);
01654 }
01655
01656 #ifdef NETWMDEBUG
01657 fprintf(stderr, "NETRootInfo::updated: virtual roots updated (%ld windows)\n",
01658 p->virtual_roots_count);
01659 #endif
01660 if ( data_ret )
01661 XFree(data_ret);
01662 }
01663 }
01664 }
01665
01666
01667 Display *NETRootInfo::x11Display() const {
01668 return p->display;
01669 }
01670
01671
01672 Window NETRootInfo::rootWindow() const {
01673 return p->root;
01674 }
01675
01676
01677 Window NETRootInfo::supportWindow() const {
01678 return p->supportwindow;
01679 }
01680
01681
01682 const char *NETRootInfo::wmName() const {
01683 return p->name; }
01684
01685
01686 int NETRootInfo::screenNumber() const {
01687 return p->screen;
01688 }
01689
01690
01691 unsigned long NETRootInfo::supported() const {
01692 return p->protocols;
01693 }
01694
01695
01696 const Window *NETRootInfo::clientList() const {
01697 return p->clients;
01698 }
01699
01700
01701 int NETRootInfo::clientListCount() const {
01702 return p->clients_count;
01703 }
01704
01705
01706 const Window *NETRootInfo::clientListStacking() const {
01707 return p->stacking;
01708 }
01709
01710
01711 int NETRootInfo::clientListStackingCount() const {
01712 return p->stacking_count;
01713 }
01714
01715
01716 const Window *NETRootInfo::kdeSystemTrayWindows() const {
01717 return p->kde_system_tray_windows;
01718 }
01719
01720
01721 int NETRootInfo::kdeSystemTrayWindowsCount() const {
01722 return p->kde_system_tray_windows_count;
01723 }
01724
01725
01726 NETSize NETRootInfo::desktopGeometry(int) const {
01727 return p->geometry;
01728 }
01729
01730
01731 NETPoint NETRootInfo::desktopViewport(int desktop) const {
01732 if (desktop < 1) {
01733 NETPoint pt;
01734 return pt;
01735 }
01736
01737 return p->viewport[desktop - 1];
01738 }
01739
01740
01741 NETRect NETRootInfo::workArea(int desktop) const {
01742 if (desktop < 1) {
01743 NETRect rt;
01744 return rt;
01745 }
01746
01747 return p->workarea[desktop - 1];
01748 }
01749
01750
01751 const char *NETRootInfo::desktopName(int desktop) const {
01752 if (desktop < 1) {
01753 return 0;
01754 }
01755
01756 return p->desktop_names[desktop - 1];
01757 }
01758
01759
01760 const Window *NETRootInfo::virtualRoots( ) const {
01761 return p->virtual_roots;
01762 }
01763
01764
01765 int NETRootInfo::virtualRootsCount() const {
01766 return p->virtual_roots_count;
01767 }
01768
01769
01770 int NETRootInfo::numberOfDesktops() const {
01771
01772 return p->number_of_desktops == 0 ? 1 : p->number_of_desktops;
01773 }
01774
01775
01776 int NETRootInfo::currentDesktop() const {
01777 return p->current_desktop;
01778 }
01779
01780
01781 Window NETRootInfo::activeWindow() const {
01782 return p->active;
01783 }
01784
01785
01786
01787
01788 const int NETWinInfo::OnAllDesktops = (int) -1;
01789
01790 NETWinInfo::NETWinInfo(Display *display, Window window, Window rootWindow,
01791 unsigned long properties, Role role)
01792 {
01793
01794 #ifdef NETWMDEBUG
01795 fprintf(stderr, "NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
01796 (role == WindowManager) ? "WindowManager" : "Client");
01797 #endif
01798
01799 p = new NETWinInfoPrivate;
01800 p->ref = 1;
01801
01802 p->display = display;
01803 p->window = window;
01804 p->root = rootWindow;
01805 p->mapping_state = Withdrawn;
01806 p->mapping_state_dirty = True;
01807 p->state = 0;
01808 p->type = Unknown;
01809 p->name = (char *) 0;
01810 p->visible_name = (char *) 0;
01811 p->icon_name = (char *) 0;
01812 p->visible_icon_name = (char *) 0;
01813 p->desktop = p->pid = p->handled_icons = 0;
01814
01815
01816
01817
01818
01819 p->kde_system_tray_win_for = 0;
01820
01821 p->properties = properties;
01822 p->icon_count = 0;
01823
01824 this->role = role;
01825
01826 if (! netwm_atoms_created) create_atoms(p->display);
01827
01828 if (p->properties) update(p->properties);
01829 }
01830
01831
01832 NETWinInfo::NETWinInfo(const NETWinInfo &wininfo) {
01833 p = wininfo.p;
01834 p->ref++;
01835 }
01836
01837
01838 NETWinInfo::~NETWinInfo() {
01839 refdec_nwi(p);
01840
01841 if (! p->ref) delete p;
01842 }
01843
01844
01845 void NETWinInfo::setIcon(NETIcon icon, Bool replace) {
01846 if (role != Client) return;
01847
01848 int proplen, i, sz, j;
01849
01850 if (replace) {
01851
01852 for (i = 0; i < p->icons.size(); i++) {
01853 if (p->icons[i].data) delete [] p->icons[i].data;
01854 p->icons[i].data = 0;
01855 p->icons[i].size.width = 0;
01856 p->icons[i].size.height = 0;
01857 }
01858
01859 p->icon_count = 0;
01860 }
01861
01862
01863 p->icons[p->icon_count] = icon;
01864 p->icon_count++;
01865
01866
01867 NETIcon &ni = p->icons[p->icon_count - 1];
01868 sz = ni.size.width * ni.size.height;
01869 CARD32 *d = new CARD32[sz];
01870 ni.data = (unsigned char *) d;
01871 memcpy(d, icon.data, sz * sizeof(CARD32));
01872
01873
01874 for (i = 0, proplen = 0; i < p->icon_count; i++) {
01875 proplen += 2 + (p->icons[i].size.width *
01876 p->icons[i].size.height);
01877 }
01878
01879 CARD32 *d32;
01880 long *prop = new long[proplen], *pprop = prop;
01881 for (i = 0; i < p->icon_count; i++) {
01882
01883 *pprop++ = p->icons[i].size.width;
01884 *pprop++ = p->icons[i].size.height;
01885
01886
01887 sz = (p->icons[i].size.width * p->icons[i].size.height);
01888 d32 = (CARD32 *) p->icons[i].data;
01889 for (j = 0; j < sz; j++) *pprop++ = *d32++;
01890 }
01891
01892 XChangeProperty(p->display, p->window, net_wm_icon, XA_CARDINAL, 32,
01893 PropModeReplace, (unsigned char *) prop, proplen);
01894
01895 delete [] prop;
01896 }
01897
01898
01899 void NETWinInfo::setIconGeometry(NETRect geometry) {
01900 if (role != Client) return;
01901
01902 p->icon_geom = geometry;
01903
01904 long data[4];
01905 data[0] = geometry.pos.x;
01906 data[1] = geometry.pos.y;
01907 data[2] = geometry.size.width;
01908 data[3] = geometry.size.height;
01909
01910 XChangeProperty(p->display, p->window, net_wm_icon_geometry, XA_CARDINAL,
01911 32, PropModeReplace, (unsigned char *) data, 4);
01912 }
01913
01914
01915 void NETWinInfo::setStrut(NETStrut strut) {
01916 if (role != Client) return;
01917
01918 p->strut = strut;
01919
01920 long data[4];
01921 data[0] = strut.left;
01922 data[1] = strut.right;
01923 data[2] = strut.top;
01924 data[3] = strut.bottom;
01925
01926 XChangeProperty(p->display, p->window, net_wm_strut, XA_CARDINAL, 32,
01927 PropModeReplace, (unsigned char *) data, 4);
01928 }
01929
01930
01931 void NETWinInfo::setState(unsigned long state, unsigned long mask) {
01932 if (p->mapping_state_dirty)
01933 update(XAWMState);
01934
01935 if (role == Client && p->mapping_state != Withdrawn) {
01936
01937 #ifdef NETWMDEBUG
01938 fprintf(stderr, "NETWinInfo::setState (0x%lx, 0x%lx) (Client)\n",
01939 state, mask);
01940 #endif // NETWMDEBUG
01941
01942 XEvent e;
01943 e.xclient.type = ClientMessage;
01944 e.xclient.message_type = net_wm_state;
01945 e.xclient.display = p->display;
01946 e.xclient.window = p->window;
01947 e.xclient.format = 32;
01948 e.xclient.data.l[3] = 0l;
01949 e.xclient.data.l[4] = 0l;
01950
01951 if ((mask & Modal) && ((p->state & Modal) != (state & Modal))) {
01952 e.xclient.data.l[0] = (state & Modal) ? 1 : 0;
01953 e.xclient.data.l[1] = net_wm_state_modal;
01954 e.xclient.data.l[2] = 0l;
01955
01956 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01957 }
01958
01959 if ((mask & Sticky) && ((p->state & Sticky) != (state & Sticky))) {
01960 e.xclient.data.l[0] = (state & Sticky) ? 1 : 0;
01961 e.xclient.data.l[1] = net_wm_state_sticky;
01962 e.xclient.data.l[2] = 0l;
01963
01964 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01965 }
01966
01967 if ((mask & Max) && (( (p->state&mask) & Max) != (state & Max))) {
01968
01969 unsigned long wishstate = (p->state & ~mask) | (state & mask);
01970 if ( ( (wishstate & MaxHoriz) != (p->state & MaxHoriz) )
01971 && ( (wishstate & MaxVert) != (p->state & MaxVert) ) ) {
01972 if ( (wishstate & Max) == Max ) {
01973 e.xclient.data.l[0] = 1;
01974 e.xclient.data.l[1] = net_wm_state_max_horiz;
01975 e.xclient.data.l[2] = net_wm_state_max_vert;
01976 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01977 } else if ( (wishstate & Max) == 0 ) {
01978 e.xclient.data.l[0] = 0;
01979 e.xclient.data.l[1] = net_wm_state_max_horiz;
01980 e.xclient.data.l[2] = net_wm_state_max_vert;
01981 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01982 } else {
01983 e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
01984 e.xclient.data.l[1] = net_wm_state_max_horiz;
01985 e.xclient.data.l[2] = 0;
01986 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01987 e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
01988 e.xclient.data.l[1] = net_wm_state_max_vert;
01989 e.xclient.data.l[2] = 0;
01990 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01991 }
01992 } else if ( (wishstate & MaxVert) != (p->state & MaxVert) ) {
01993 e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
01994 e.xclient.data.l[1] = net_wm_state_max_vert;
01995 e.xclient.data.l[2] = 0;
01996 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01997 } else if ( (wishstate & MaxHoriz) != (p->state & MaxHoriz) ) {
01998 e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
01999 e.xclient.data.l[1] = net_wm_state_max_horiz;
02000 e.xclient.data.l[2] = 0;
02001 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
02002 }
02003 }
02004
02005 if ((mask & Shaded) && ((p->state & Shaded) != (state & Shaded))) {
02006 e.xclient.data.l[0] = (state & Shaded) ? 1 : 0;
02007 e.xclient.data.l[1] = net_wm_state_shaded;
02008 e.xclient.data.l[2] = 0l;
02009
02010 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
02011 }
02012
02013 if ((mask & SkipTaskbar) &&
02014 ((p->state & SkipTaskbar) != (state & SkipTaskbar))) {
02015 e.xclient.data.l[0] = (state & SkipTaskbar) ? 1 : 0;
02016 e.xclient.data.l[1] = net_wm_state_skip_taskbar;
02017 e.xclient.data.l[2] = 0l;
02018
02019 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
02020 }
02021
02022 if ((mask & FullScreen) &&
02023 ((p->state & FullScreen) != (state & FullScreen))) {
02024 e.xclient.data.l[0] = (state & FullScreen) ? 1 : 0;
02025 e.xclient.data.l[1] = net_wm_state_fullscreen;
02026 e.xclient.data.l[2] = 0l;
02027
02028 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
02029 }
02030
02031 if ((mask & SkipPager) &&
02032 ((p->state & SkipPager) != (state & SkipPager))) {
02033 e.xclient.data.l[0] = (state & SkipPager) ? 1 : 0;
02034 e.xclient.data.l[1] = net_wm_state_skip_pager;
02035 e.xclient.data.l[2] = 0l;
02036
02037 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
02038 }
02039
02040 if ((mask & StaysOnTop) && ((p->state & StaysOnTop) != (state & StaysOnTop))) {
02041 e.xclient.data.l[0] = (state & StaysOnTop) ? 1 : 0;
02042 e.xclient.data.l[1] = net_wm_state_stays_on_top;
02043 e.xclient.data.l[2] = 0l;
02044
02045 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
02046 }
02047 } else {
02048 p->state &= ~mask;
02049 p->state |= state;
02050
02051 long data[8];
02052 int count = 0;
02053
02054
02055 if (p->state & Modal) data[count++] = net_wm_state_modal;
02056 if (p->state & MaxVert) data[count++] = net_wm_state_max_vert;
02057 if (p->state & MaxHoriz) data[count++] = net_wm_state_max_horiz;
02058 if (p->state & Shaded) data[count++] = net_wm_state_shaded;
02059 if (p->state & FullScreen) data[count++] = net_wm_state_fullscreen;
02060
02061
02062 if (p->state & StaysOnTop) data[count++] = net_wm_state_stays_on_top;
02063 if (p->state & Sticky) data[count++] = net_wm_state_sticky;
02064 if (p->state & SkipTaskbar) data[count++] = net_wm_state_skip_taskbar;
02065 if (p->state & SkipPager) data[count++] = net_wm_state_skip_pager;
02066
02067 #ifdef NETWMDEBUG
02068 fprintf(stderr, "NETWinInfo::setState: setting state property (%d)\n", count);
02069 for (int i = 0; i < count; i++)
02070 fprintf(stderr, "NETWinInfo::setState: state %ld '%s'\n",
02071 data[i], XGetAtomName(p->display, (Atom) data[i]));
02072 #endif
02073
02074 XChangeProperty(p->display, p->window, net_wm_state, XA_ATOM, 32,
02075 PropModeReplace, (unsigned char *) data, count);
02076 }
02077 }
02078
02079
02080 void NETWinInfo::setWindowType(WindowType type) {
02081 if (role != Client) return;
02082
02083 int len;
02084 long data[2];
02085
02086 switch (type) {
02087 case Override:
02088
02089
02090 data[0] = kde_net_wm_window_type_override;
02091 data[1] = net_wm_window_type_normal;
02092 len = 2;
02093 break;
02094
02095 case Dialog:
02096 data[0] = net_wm_window_type_dialog;
02097 data[1] = None;
02098 len = 1;
02099 break;
02100
02101 case Menu:
02102 data[0] = net_wm_window_type_menu;
02103 data[1] = None;
02104 len = 1;
02105 break;
02106
02107 case TopMenu:
02108
02109
02110 data[0] = kde_net_wm_window_type_topmenu;
02111 data[1] = net_wm_window_type_dock;
02112 len = 2;
02113 break;
02114
02115 case Tool:
02116 data[0] = net_wm_window_type_toolbar;
02117 data[1] = None;
02118 len = 1;
02119 break;
02120
02121 case Dock:
02122 data[0] = net_wm_window_type_dock;
02123 data[1] = None;
02124 len = 1;
02125 break;
02126
02127 case Desktop:
02128 data[0] = net_wm_window_type_desktop;
02129 data[1] = None;
02130 len = 1;
02131 break;
02132
02133 default:
02134 case Normal:
02135 data[0] = net_wm_window_type_normal;
02136 data[1] = None;
02137 len = 1;
02138 break;
02139 }
02140
02141 XChangeProperty(p->display, p->window, net_wm_window_type, XA_ATOM, 32,
02142 PropModeReplace, (unsigned char *) &data, len);
02143 }
02144
02145
02146 void NETWinInfo::setName(const char *name) {
02147 if (role != Client) return;
02148
02149 if (p->name) delete [] p->name;
02150 p->name = nstrdup(name);
02151 XChangeProperty(p->display, p->window, net_wm_name, UTF8_STRING, 8,
02152 PropModeReplace, (unsigned char *) p->name,
02153 strlen(p->name));
02154 }
02155
02156
02157 void NETWinInfo::setVisibleName(const char *visibleName) {
02158 if (role != WindowManager) return;
02159
02160 if (p->visible_name) delete [] p->visible_name;
02161 p->visible_name = nstrdup(visibleName);
02162 XChangeProperty(p->display, p->window, net_wm_visible_name, UTF8_STRING, 8,
02163 PropModeReplace, (unsigned char *) p->visible_name,
02164 strlen(p->visible_name));
02165 }
02166
02167
02168 void NETWinInfo::setIconName(const char *iconName) {
02169 if (role != Client) return;
02170
02171 if (p->icon_name) delete [] p->icon_name;
02172 p->icon_name = nstrdup(iconName);
02173 XChangeProperty(p->display, p->window, net_wm_icon_name, UTF8_STRING, 8,
02174 PropModeReplace, (unsigned char *) p->icon_name,
02175 strlen(p->icon_name));
02176 }
02177
02178
02179 void NETWinInfo::setVisibleIconName(const char *visibleIconName) {
02180 if (role != WindowManager) return;
02181
02182 if (p->visible_icon_name) delete [] p->visible_icon_name;
02183 p->visible_icon_name = nstrdup(visibleIconName);
02184 XChangeProperty(p->display, p->window, net_wm_visible_icon_name, UTF8_STRING, 8,
02185 PropModeReplace, (unsigned char *) p->visible_icon_name,
02186 strlen(p->visible_icon_name));
02187 }
02188
02189
02190 void NETWinInfo::setDesktop(int desktop) {
02191 if (p->mapping_state_dirty)
02192 update(XAWMState);
02193
02194 if (role == Client && p->mapping_state != Withdrawn) {
02195
02196
02197 if ( desktop == 0 )
02198 return;
02199
02200 XEvent e;
02201
02202 e.xclient.type = ClientMessage;
02203 e.xclient.message_type = net_wm_desktop;
02204 e.xclient.display = p->display;
02205 e.xclient.window = p->window;
02206 e.xclient.format = 32;
02207 e.xclient.data.l[0] = desktop == OnAllDesktops ? OnAllDesktops : desktop - 1;
02208 e.xclient.data.l[1] = 0l;
02209 e.xclient.data.l[2] = 0l;
02210 e.xclient.data.l[3] = 0l;
02211 e.xclient.data.l[4] = 0l;
02212
02213 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
02214 } else {
02215
02216 p->desktop = desktop;
02217 long d = desktop;
02218
02219 if ( d != OnAllDesktops ) {
02220 if ( d == 0 ) {
02221 XDeleteProperty( p->display, p->window, net_wm_desktop );
02222 return;
02223 }
02224
02225 d -= 1;
02226 }
02227
02228 XChangeProperty(p->display, p->window, net_wm_desktop, XA_CARDINAL, 32,
02229 PropModeReplace, (unsigned char *) &d, 1);
02230 }
02231 }
02232
02233
02234 void NETWinInfo::setPid(int pid) {
02235 if (role != Client) return;
02236
02237 p->pid = pid;
02238 long d = pid;
02239 XChangeProperty(p->display, p->window, net_wm_pid, XA_CARDINAL, 32,
02240 PropModeReplace, (unsigned char *) &d, 1);
02241 }
02242
02243
02244 void NETWinInfo::setHandledIcons(Bool handled) {
02245 if (role != Client) return;
02246
02247 p->handled_icons = handled;
02248 long d = handled;
02249 XChangeProperty(p->display, p->window, net_wm_handled_icons, XA_CARDINAL, 32,
02250 PropModeReplace, (unsigned char *) &d, 1);
02251 }
02252
02253
02254 void NETWinInfo::setKDESystemTrayWinFor(Window window) {
02255 if (role != Client) return;
02256
02257 p->kde_system_tray_win_for = window;
02258 XChangeProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
02259 XA_WINDOW, 32, PropModeReplace,
02260 (unsigned char *) &(p->kde_system_tray_win_for), 1);
02261 }
02262
02263
02264 void NETWinInfo::setKDEFrameStrut(NETStrut strut) {
02265 if (role != WindowManager) return;
02266
02267 p->frame_strut = strut;
02268
02269 long d[4];
02270 d[0] = strut.left;
02271 d[1] = strut.right;
02272 d[2] = strut.top;
02273 d[3] = strut.bottom;
02274
02275 XChangeProperty(p->display, p->window, kde_net_wm_frame_strut, XA_CARDINAL, 32,
02276 PropModeReplace, (unsigned char *) d, 4);
02277 }
02278
02279
02280 void NETWinInfo::kdeGeometry(NETRect& frame, NETRect& window) {
02281 if (p->win_geom.size.width == 0 || p->win_geom.size.height == 0) {
02282 Window unused;
02283 int x, y;
02284 unsigned int w, h, junk;
02285 XGetGeometry(p->display, p->window, &unused, &x, &y, &w, &h, &junk, &junk);
02286 XTranslateCoordinates(p->display, p->window, p->root, 0, 0, &x, &y, &unused
02287 );
02288
02289 p->win_geom.pos.x = x;
02290 p->win_geom.pos.y = y;
02291
02292 p->win_geom.size.width = w;
02293 p->win_geom.size.height = h;
02294 }
02295
02296 window = p->win_geom;
02297
02298 frame.pos.x = window.pos.x - p->frame_strut.left;
02299 frame.pos.y = window.pos.y - p->frame_strut.top;
02300 frame.size.width = window.size.width + p->frame_strut.left + p->frame_strut.right;
02301 frame.size.height = window.size.height + p->frame_strut.top + p->frame_strut.bottom;
02302 }
02303
02304
02305 NETIcon NETWinInfo::icon(int width, int height) const {
02306 NETIcon result;
02307
02308 if ( !p->icons.size() ) {
02309 result.size.width = 0;
02310 result.size.height = 0;
02311 result.data = 0;
02312 return result;
02313 }
02314
02315 result = p->icons[0];
02316
02317
02318
02319 if (width == height && height == -1) return result;
02320
02321 int i;
02322 for (i = 0; i < p->icons.size(); i++) {
02323 if ((p->icons[i].size.width >= width &&
02324 p->icons[i].size.width < result.size.width) &&
02325 (p->icons[i].size.height >= height &&
02326 p->icons[i].size.height < result.size.height))
02327 result = p->icons[i];
02328 }
02329
02330 return result;
02331 }
02332
02333
02334 unsigned long NETWinInfo::event(XEvent *event) {
02335 unsigned long dirty = 0;
02336
02337 if (role == WindowManager && event->type == ClientMessage &&
02338 event->xclient.format == 32) {
02339
02340 #ifdef NETWMDEBUG
02341 fprintf(stderr, "NETWinInfo::event: handling ClientMessage event\n");
02342 #endif // NETWMDEBUG
02343
02344 if (event->xclient.message_type == net_wm_state) {
02345 dirty = WMState;
02346
02347
02348
02349 #ifdef NETWMDEBUG
02350 fprintf(stderr,
02351 "NETWinInfo::event: state client message, getting new state/mask\n");
02352 #endif
02353
02354 int i;
02355 long state = 0, mask = 0;
02356
02357 for (i = 1; i < 3; i++) {
02358 #ifdef NETWMDEBUG
02359 fprintf(stderr, "NETWinInfo::event: message %ld '%s'\n",
02360 event->xclient.data.l[i],
02361 XGetAtomName(p->display, (Atom) event->xclient.data.l[i]));
02362 #endif
02363
02364 if ((Atom) event->xclient.data.l[i] == net_wm_state_modal)
02365 mask |= Modal;
02366 else if ((Atom) event->xclient.data.l[i] == net_wm_state_sticky)
02367 mask |= Sticky;
02368 else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_vert)
02369 mask |= MaxVert;
02370 else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_horiz)
02371 mask |= MaxHoriz;
02372 else if ((Atom) event->xclient.data.l[i] == net_wm_state_shaded)
02373 mask |= Shaded;
02374 else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_taskbar)
02375 mask |= SkipTaskbar;
02376 else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_pager)
02377 mask |= SkipPager;
02378 else if ((Atom) event->xclient.data.l[i] == net_wm_state_fullscreen)
02379 mask |= FullScreen;
02380 else if ((Atom) event->xclient.data.l[i] == net_wm_state_stays_on_top)
02381 mask |= StaysOnTop;
02382 }
02383
02384
02385 switch (event->xclient.data.l[0]) {
02386 case 1:
02387
02388 state = mask;
02389 break;
02390
02391 case 2:
02392
02393 state = (p->state & mask) ^ mask;
02394 break;
02395
02396 default:
02397
02398 ;
02399 }
02400
02401 #ifdef NETWMDEBUG
02402 fprintf(stderr, "NETWinInfo::event: calling changeState(%lx, %lx)\n",
02403 state, mask);
02404 #endif
02405
02406 changeState(state, mask);
02407 } else if (event->xclient.message_type == net_wm_desktop) {
02408 dirty = WMDesktop;
02409
02410 if( event->xclient.data.l[0] == OnAllDesktops )
02411 changeDesktop( OnAllDesktops );
02412 else
02413 changeDesktop(event->xclient.data.l[0] + 1);
02414 }
02415 }
02416
02417 if (event->type == PropertyNotify) {
02418
02419 #ifdef NETWMDEBUG
02420 fprintf(stderr, "NETWinInfo::event: handling PropertyNotify event\n");
02421 #endif
02422
02423 XEvent pe = *event;
02424
02425 Bool done = False;
02426 Bool compaction = False;
02427 while (! done) {
02428
02429 #ifdef NETWMDEBUG
02430 fprintf(stderr, "NETWinInfo::event: loop fire\n");
02431 #endif
02432
02433 if (pe.xproperty.atom == net_wm_name)
02434 dirty |= WMName;
02435 else if (pe.xproperty.atom == net_wm_visible_name)
02436 dirty |= WMVisibleName;
02437 else if (pe.xproperty.atom == net_wm_window_type)
02438 dirty |=WMWindowType;
02439 else if (pe.xproperty.atom == net_wm_strut)
02440 dirty |= WMStrut;
02441 else if (pe.xproperty.atom == net_wm_icon_geometry)
02442 dirty |= WMIconGeometry;
02443 else if (pe.xproperty.atom == net_wm_icon)
02444 dirty |= WMIcon;
02445 else if (pe.xproperty.atom == xa_wm_state)
02446 dirty |= XAWMState;
02447 else if (pe.xproperty.atom == net_wm_state)
02448 dirty |= WMState;
02449 else if (pe.xproperty.atom == net_wm_desktop)
02450 dirty |= WMDesktop;
02451 else if (pe.xproperty.atom == kde_net_wm_frame_strut)
02452 dirty |= WMKDEFrameStrut;
02453 else if (pe.xproperty.atom == kde_net_wm_system_tray_window_for)
02454 dirty |= WMKDESystemTrayWinFor;
02455 else {
02456
02457 #ifdef NETWMDEBUG
02458 fprintf(stderr, "NETWinInfo::event: putting back event and breaking\n");
02459 #endif
02460
02461 if ( compaction )
02462 XPutBackEvent(p->display, &pe);
02463 break;
02464 }
02465
02466 if (XCheckTypedWindowEvent(p->display, p->window, PropertyNotify, &pe) )
02467 compaction = True;
02468 else
02469 break;
02470 }
02471
02472 update(dirty);
02473 } else if (event->type == ConfigureNotify) {
02474
02475 #ifdef NETWMDEBUG
02476 fprintf(stderr, "NETWinInfo::event: handling ConfigureNotify event\n");
02477 #endif
02478
02479 dirty |= WMGeometry;
02480
02481
02482 p->win_geom.pos.x = event->xconfigure.x;
02483 p->win_geom.pos.y = event->xconfigure.y;
02484 p->win_geom.size.width = event->xconfigure.width;
02485 p->win_geom.size.height = event->xconfigure.height;
02486 }
02487
02488 return dirty;
02489 }
02490
02491
02492 void NETWinInfo::update(unsigned long dirty) {
02493 Atom type_ret;
02494 int format_ret;
02495 unsigned long nitems_ret, unused;
02496 unsigned char *data_ret;
02497
02498 if (dirty & XAWMState) {
02499 if (XGetWindowProperty(p->display, p->window, xa_wm_state, 0l, 1l,
02500 False, xa_wm_state, &type_ret, &format_ret,
02501 &nitems_ret, &unused, &data_ret)
02502 == Success) {
02503 if (type_ret == xa_wm_state && format_ret == 32 &&
02504 nitems_ret == 1) {
02505 long *state = (long *) data_ret;
02506
02507 switch(*state) {
02508 case IconicState:
02509 p->mapping_state = Iconic;
02510 break;
02511 case WithdrawnState:
02512 p->mapping_state = Withdrawn;
02513 break;
02514 case NormalState:
02515 default:
02516 p->mapping_state = Visible;
02517
02518 }
02519
02520 p->mapping_state_dirty = False;
02521 }
02522 if ( data_ret )
02523 XFree(data_ret);
02524 }
02525 }
02526
02527
02528 dirty &= p->properties;
02529
02530 if (dirty & WMState) {
02531 p->state = 0;
02532 if (XGetWindowProperty(p->display, p->window, net_wm_state, 0l, 2048l,
02533 False, XA_ATOM, &type_ret, &format_ret,
02534 &nitems_ret, &unused, &data_ret)
02535 == Success) {
02536 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
02537
02538 #ifdef NETWMDEBUG
02539 fprintf(stderr, "NETWinInfo::update: updating window state (%ld)\n",
02540 nitems_ret);
02541 #endif
02542
02543 long *states = (long *) data_ret;
02544 unsigned long count;
02545
02546 for (count = 0; count < nitems_ret; count++) {
02547 #ifdef NETWMDEBUG
02548 fprintf(stderr,
02549 "NETWinInfo::update: adding window state %ld '%s'\n",
02550 states[count],
02551 XGetAtomName(p->display, (Atom) states[count]));
02552 #endif
02553
02554 if ((Atom) states[count] == net_wm_state_modal)
02555 p->state |= Modal;
02556 else if ((Atom) states[count] == net_wm_state_sticky)
02557 p->state |= Sticky;
02558 else if ((Atom) states[count] == net_wm_state_max_vert)
02559 p->state |= MaxVert;
02560 else if ((Atom) states[count] == net_wm_state_max_horiz)
02561 p->state |= MaxHoriz;
02562 else if ((Atom) states[count] == net_wm_state_shaded)
02563 p->state |= Shaded;
02564 else if ((Atom) states[count] == net_wm_state_skip_taskbar)
02565 p->state |= SkipTaskbar;
02566 else if ((Atom) states[count] == net_wm_state_skip_pager)
02567 p->state |= SkipPager;
02568 else if ((Atom) states[count] == net_wm_state_fullscreen)
02569 p->state |= FullScreen;
02570 else if ((Atom) states[count] == net_wm_state_stays_on_top)
02571 p->state |= StaysOnTop;
02572 }
02573 }
02574 if ( data_ret )
02575 XFree(data_ret);
02576 }
02577 }
02578
02579 if (dirty & WMDesktop) {
02580 p->desktop = 0;
02581 if (XGetWindowProperty(p->display, p->window, net_wm_desktop, 0l, 1l,
02582 False, XA_CARDINAL, &type_ret,
02583 &format_ret, &nitems_ret,
02584 &unused, &data_ret)
02585 == Success) {
02586 if (type_ret == XA_CARDINAL && format_ret == 32 &&
02587 nitems_ret == 1) {
02588 p->desktop = *((long *) data_ret);
02589 if ((signed) p->desktop != OnAllDesktops)
02590 p->desktop++;
02591
02592 if ( p->desktop == 0 )
02593 p->desktop = OnAllDesktops;
02594 }
02595 if ( data_ret )
02596 XFree(data_ret);
02597 }
02598 }
02599
02600 if (dirty & WMName) {
02601 if (XGetWindowProperty(p->display, p->window, net_wm_name, 0l,
02602 (long) BUFSIZE, False, UTF8_STRING, &type_ret,
02603 &format_ret, &nitems_ret, &unused, &data_ret)
02604 == Success) {
02605 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
02606 if (p->name) delete [] p->name;
02607 p->name = nstrndup((const char *) data_ret, nitems_ret);
02608 }
02609
02610 if( data_ret )
02611 XFree(data_ret);
02612 }
02613 }
02614
02615 if (dirty & WMVisibleName) {
02616 if (XGetWindowProperty(p->display, p->window, net_wm_visible_name, 0l,
02617 (long) BUFSIZE, False, UTF8_STRING, &type_ret,
02618 &format_ret, &nitems_ret, &unused, &data_ret)
02619 == Success) {
02620 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
02621 if (p->visible_name) delete [] p->visible_name;
02622 p->visible_name = nstrndup((const char *) data_ret, nitems_ret);
02623 }
02624
02625 if( data_ret )
02626 XFree(data_ret);
02627 }
02628 }
02629
02630 if (dirty & WMIconName) {
02631
02632 char* text_ret = 0;
02633 if (XGetWindowProperty(p->display, p->window, net_wm_icon_name, 0l,
02634 (long) BUFSIZE, False, UTF8_STRING, &type_ret,
02635 &format_ret, &nitems_ret, &unused, &data_ret)
02636 == Success) {
02637 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
02638 if (p->icon_name) delete [] p->icon_name;
02639 p->icon_name = nstrndup((const char *) data_ret, nitems_ret);
02640 }
02641
02642 if( data_ret )
02643 XFree(data_ret);
02644 }
02645
02646 if ( !p->visible_icon_name && XGetIconName(p->display, p->window, &text_ret) ) {
02647 if (p->icon_name) delete [] p->icon_name;
02648 p->icon_name = strdup((const char *) text_ret);
02649
02650 if( text_ret )
02651 XFree(text_ret);
02652 }
02653 }
02654
02655 if (dirty & WMVisibleIconName)
02656 {
02657 char* text_ret = 0;
02658 if (XGetWindowProperty(p->display, p->window, net_wm_visible_icon_name, 0l,
02659 (long) BUFSIZE, False, UTF8_STRING, &type_ret,
02660 &format_ret, &nitems_ret, &unused, &data_ret)
02661 == Success) {
02662 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
02663 if (p->visible_icon_name) delete [] p->visible_icon_name;
02664 p->visible_icon_name = nstrndup((const char *) data_ret, nitems_ret);
02665 }
02666
02667 if( data_ret )
02668 XFree(data_ret);
02669 }
02670
02671
02672 if ( !p->visible_icon_name && XGetIconName(p->display, p->window, &text_ret) ) {
02673 if (p->visible_icon_name) delete [] p->visible_icon_name;
02674 p->visible_icon_name = strdup((const char *) text_ret);
02675
02676 if( text_ret )
02677 XFree(text_ret);
02678 }
02679 }
02680
02681 if (dirty & WMWindowType) {
02682 p->type = Unknown;
02683 if (XGetWindowProperty(p->display, p->window, net_wm_window_type, 0l, 2048l,
02684 False, XA_ATOM, &type_ret, &format_ret,
02685 &nitems_ret, &unused, &data_ret)
02686 == Success) {
02687 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
02688
02689 #ifdef NETWMDEBUG
02690 fprintf(stderr, "NETWinInfo::update: getting window type (%ld)\n",
02691 nitems_ret);
02692 #endif
02693
02694 unsigned long count = 0;
02695 long *types = (long *) data_ret;
02696
02697 while (p->type == Unknown && count < nitems_ret) {
02698
02699
02700
02701 #ifdef NETWMDEBUG
02702 fprintf(stderr,
02703 "NETWinInfo::update: examining window type %ld %s\n",
02704 types[count],
02705 XGetAtomName(p->display, (Atom) types[count]));
02706 #endif
02707
02708 if ((Atom) types[count] == net_wm_window_type_normal)
02709 p->type = Normal;
02710 else if ((Atom) types[count] == net_wm_window_type_desktop)
02711 p->type = Desktop;
02712 else if ((Atom) types[count] == net_wm_window_type_dock)
02713 p->type = Dock;
02714 else if ((Atom) types[count] == net_wm_window_type_toolbar)
02715 p->type = Tool;
02716 else if ((Atom) types[count] == net_wm_window_type_menu)
02717 p->type = Menu;
02718 else if ((Atom) types[count] == net_wm_window_type_dialog)
02719 p->type = Dialog;
02720 else if ((Atom) types[count] == kde_net_wm_window_type_override)
02721 p->type = Override;
02722 else if ((Atom) types[count] == kde_net_wm_window_type_topmenu)
02723 p->type = TopMenu;
02724
02725 count++;
02726 }
02727 }
02728
02729 if ( data_ret )
02730 XFree(data_ret);
02731 }
02732 }
02733
02734 if (dirty & WMStrut) {
02735 if (XGetWindowProperty(p->display, p->window, net_wm_strut, 0l, 4l,
02736 False, XA_CARDINAL, &type_ret, &format_ret,
02737 &nitems_ret, &unused, &data_ret)
02738 == Success) {
02739 if (type_ret == XA_CARDINAL && format_ret == 32 &&
02740 nitems_ret == 4) {
02741 long *d = (long *) data_ret;
02742 p->strut.left = d[0];
02743 p->strut.right = d[1];
02744 p->strut.top = d[2];
02745 p->strut.bottom = d[3];
02746 }
02747 if ( data_ret )
02748 XFree(data_ret);
02749 }
02750 }
02751
02752 if (dirty & WMIconGeometry) {
02753 if (XGetWindowProperty(p->display, p->window, net_wm_icon_geometry, 0l, 4l,
02754 False, XA_CARDINAL, &type_ret, &format_ret,
02755 &nitems_ret, &unused, &data_ret)
02756 == Success) {
02757 if (type_ret == XA_CARDINAL && format_ret == 32 &&
02758 nitems_ret == 4) {
02759 long *d = (long *) data_ret;
02760 p->icon_geom.pos.x = d[0];
02761 p->icon_geom.pos.y = d[1];
02762 p->icon_geom.size.width = d[2];
02763 p->icon_geom.size.height = d[3];
02764 }
02765 if ( data_ret )
02766 XFree(data_ret);
02767 }
02768 }
02769
02770 if (dirty & WMIcon) {
02771 readIcon(p);
02772 }
02773
02774 if (dirty & WMKDESystemTrayWinFor) {
02775 p->kde_system_tray_win_for = 0;
02776 if (XGetWindowProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
02777 0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
02778 &nitems_ret, &unused, &data_ret)
02779 == Success) {
02780 if (type_ret == XA_WINDOW && format_ret == 32 &&
02781 nitems_ret == 1) {
02782 p->kde_system_tray_win_for = *((Window *) data_ret);
02783 if ( p->kde_system_tray_win_for == 0 )
02784 p->kde_system_tray_win_for = p->root;
02785 }
02786 if ( data_ret )
02787 XFree(data_ret);
02788 }
02789 }
02790
02791 if (dirty & WMKDEFrameStrut) {
02792 if (XGetWindowProperty(p->display, p->window, kde_net_wm_frame_strut,
02793 0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
02794 &nitems_ret, &unused, &data_ret) == Success) {
02795 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
02796 long *d = (long *) data_ret;
02797
02798 p->frame_strut.left = d[0];
02799 p->frame_strut.right = d[1];
02800 p->frame_strut.top = d[2];
02801 p->frame_strut.bottom = d[3];
02802 }
02803 if ( data_ret )
02804 XFree(data_ret);
02805 }
02806 }
02807
02808 if (dirty & WMPid) {
02809 p->pid = 0;
02810 if (XGetWindowProperty(p->display, p->window, net_wm_pid, 0l, 1l,
02811 False, XA_CARDINAL, &type_ret, &format_ret,
02812 &nitems_ret, &unused, &data_ret) == Success) {
02813 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
02814 p->pid = *((long *) data_ret);
02815 }
02816 if ( data_ret )
02817 XFree(data_ret);
02818 }
02819 }
02820 }
02821
02822
02823 NETRect NETWinInfo::iconGeometry() const {
02824 return p->icon_geom;
02825 }
02826
02827
02828 unsigned long NETWinInfo::state() const {
02829 return p->state;
02830 }
02831
02832
02833 NETStrut NETWinInfo::strut() const {
02834 return p->strut;
02835 }
02836
02837
02838 NET::WindowType NETWinInfo::windowType() const {
02839 return p->type;
02840 }
02841
02842
02843 const char *NETWinInfo::name() const {
02844 return p->name;
02845 }
02846
02847
02848 const char *NETWinInfo::visibleName() const {
02849 return p->visible_name;
02850 }
02851
02852
02853 const char *NETWinInfo::iconName() const {
02854 return p->icon_name;
02855 }
02856
02857
02858 const char *NETWinInfo::visibleIconName() const {
02859 return p->visible_icon_name;
02860 }
02861
02862
02863 int NETWinInfo::desktop() const {
02864 return p->desktop;
02865 }
02866
02867 int NETWinInfo::pid() const {
02868 return p->pid;
02869 }
02870
02871
02872 Bool NETWinInfo::handledIcons() const {
02873 return p->handled_icons;
02874 }
02875
02876
02877 Window NETWinInfo::kdeSystemTrayWinFor() const {
02878 return p->kde_system_tray_win_for;
02879 }
02880
02881
02882 unsigned long NETWinInfo::properties() const {
02883 return p->properties;
02884 }
02885
02886
02887 NET::MappingState NETWinInfo::mappingState() const {
02888 return p->mapping_state;
02889 }
02890
02891 void NETRootInfo::virtual_hook( int, void* )
02892 { }
02893
02894 void NETWinInfo::virtual_hook( int, void* )
02895 { }
02896
02897 #endif