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