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