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