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
00028 #include <qwidget.h>
00029 #ifdef Q_WS_X11 //FIXME
00030
00031 #include "netwm.h"
00032
00033 #include <string.h>
00034 #include <stdio.h>
00035 #include <assert.h>
00036 #include <stdlib.h>
00037
00038 #include <X11/Xmd.h>
00039
00040 #include "netwm_p.h"
00041
00042 #include <kasyncprop.h>
00043
00044
00045 static Atom UTF8_STRING = 0;
00046
00047
00048 static Atom net_supported = 0;
00049 static Atom net_client_list = 0;
00050 static Atom net_client_list_stacking = 0;
00051 static Atom net_desktop_geometry = 0;
00052 static Atom net_desktop_viewport = 0;
00053 static Atom net_current_desktop = 0;
00054 static Atom net_desktop_names = 0;
00055 static Atom net_number_of_desktops = 0;
00056 static Atom net_active_window = 0;
00057 static Atom net_workarea = 0;
00058 static Atom net_supporting_wm_check = 0;
00059 static Atom net_virtual_roots = 0;
00060 static Atom net_showing_desktop = 0;
00061
00062
00063 static Atom net_close_window = 0;
00064 static Atom net_restack_window = 0;
00065 static Atom net_wm_moveresize = 0;
00066 static Atom net_moveresize_window = 0;
00067
00068
00069 static Atom net_wm_name = 0;
00070 static Atom net_wm_visible_name = 0;
00071 static Atom net_wm_icon_name = 0;
00072 static Atom net_wm_visible_icon_name = 0;
00073 static Atom net_wm_desktop = 0;
00074 static Atom net_wm_window_type = 0;
00075 static Atom net_wm_state = 0;
00076 static Atom net_wm_strut = 0;
00077 static Atom net_wm_extended_strut = 0;
00078 static Atom net_wm_icon_geometry = 0;
00079 static Atom net_wm_icon = 0;
00080 static Atom net_wm_pid = 0;
00081 static Atom net_wm_user_time = 0;
00082 static Atom net_wm_handled_icons = 0;
00083 static Atom net_startup_id = 0;
00084 static Atom net_wm_allowed_actions = 0;
00085 static Atom wm_window_role = 0;
00086 static Atom net_frame_extents = 0;
00087
00088
00089 static Atom kde_net_system_tray_windows = 0;
00090 static Atom kde_net_wm_system_tray_window_for = 0;
00091 static Atom kde_net_wm_frame_strut = 0;
00092 static Atom kde_net_wm_window_type_override = 0;
00093 static Atom kde_net_wm_window_type_topmenu = 0;
00094 static Atom kde_net_wm_temporary_rules = 0;
00095
00096
00097 static Atom wm_protocols = 0;
00098 static Atom net_wm_ping = 0;
00099 static Atom net_wm_take_activity = 0;
00100
00101
00102 static Atom net_wm_window_type_normal = 0;
00103 static Atom net_wm_window_type_desktop = 0;
00104 static Atom net_wm_window_type_dock = 0;
00105 static Atom net_wm_window_type_toolbar = 0;
00106 static Atom net_wm_window_type_menu = 0;
00107 static Atom net_wm_window_type_dialog = 0;
00108 static Atom net_wm_window_type_utility = 0;
00109 static Atom net_wm_window_type_splash = 0;
00110
00111
00112 static Atom net_wm_state_modal = 0;
00113 static Atom net_wm_state_sticky = 0;
00114 static Atom net_wm_state_max_vert = 0;
00115 static Atom net_wm_state_max_horiz = 0;
00116 static Atom net_wm_state_shaded = 0;
00117 static Atom net_wm_state_skip_taskbar = 0;
00118 static Atom net_wm_state_skip_pager = 0;
00119 static Atom net_wm_state_hidden = 0;
00120 static Atom net_wm_state_fullscreen = 0;
00121 static Atom net_wm_state_above = 0;
00122 static Atom net_wm_state_below = 0;
00123 static Atom net_wm_state_demands_attention = 0;
00124
00125
00126 static Atom net_wm_action_move = 0;
00127 static Atom net_wm_action_resize = 0;
00128 static Atom net_wm_action_minimize = 0;
00129 static Atom net_wm_action_shade = 0;
00130 static Atom net_wm_action_stick = 0;
00131 static Atom net_wm_action_max_vert = 0;
00132 static Atom net_wm_action_max_horiz = 0;
00133 static Atom net_wm_action_fullscreen = 0;
00134 static Atom net_wm_action_change_desk = 0;
00135 static Atom net_wm_action_close = 0;
00136
00137
00138 static Atom net_wm_state_stays_on_top = 0;
00139
00140
00141 static Atom xa_wm_state = 0;
00142
00143
00144 static Atom net_wm_full_placement = 0;
00145
00146 static Bool netwm_atoms_created = False;
00147 const unsigned long netwm_sendevent_mask = (SubstructureRedirectMask|
00148 SubstructureNotifyMask);
00149
00150
00151 const long MAX_PROP_SIZE = 100000;
00152
00153 static char *nstrdup(const char *s1) {
00154 if (! s1) return (char *) 0;
00155
00156 int l = strlen(s1) + 1;
00157 char *s2 = new char[l];
00158 strncpy(s2, s1, l);
00159 return s2;
00160 }
00161
00162
00163 static char *nstrndup(const char *s1, int l) {
00164 if (! s1 || l == 0) return (char *) 0;
00165
00166 char *s2 = new char[l+1];
00167 strncpy(s2, s1, l);
00168 s2[l] = '\0';
00169 return s2;
00170 }
00171
00172
00173 static Window *nwindup(Window *w1, int n) {
00174 if (! w1 || n == 0) return (Window *) 0;
00175
00176 Window *w2 = new Window[n];
00177 while (n--) w2[n] = w1[n];
00178 return w2;
00179 }
00180
00181
00182 static void refdec_nri(NETRootInfoPrivate *p) {
00183
00184 #ifdef NETWMDEBUG
00185 fprintf(stderr, "NET: decrementing NETRootInfoPrivate::ref (%d)\n", p->ref - 1);
00186 #endif
00187
00188 if (! --p->ref) {
00189
00190 #ifdef NETWMDEBUG
00191 fprintf(stderr, "NET: \tno more references, deleting\n");
00192 #endif
00193
00194 delete [] p->name;
00195 delete [] p->stacking;
00196 delete [] p->clients;
00197 delete [] p->virtual_roots;
00198 delete [] p->kde_system_tray_windows;
00199
00200 int i;
00201 for (i = 0; i < p->desktop_names.size(); i++)
00202 delete [] p->desktop_names[i];
00203 }
00204 }
00205
00206
00207 static void refdec_nwi(NETWinInfoPrivate *p) {
00208
00209 #ifdef NETWMDEBUG
00210 fprintf(stderr, "NET: decrementing NETWinInfoPrivate::ref (%d)\n", p->ref - 1);
00211 #endif
00212
00213 if (! --p->ref) {
00214
00215 #ifdef NETWMDEBUG
00216 fprintf(stderr, "NET: \tno more references, deleting\n");
00217 #endif
00218
00219 delete [] p->name;
00220 delete [] p->visible_name;
00221 delete [] p->icon_name;
00222 delete [] p->visible_icon_name;
00223 delete [] p->startup_id;
00224
00225 int i;
00226 for (i = 0; i < p->icons.size(); i++)
00227 delete [] p->icons[i].data;
00228 }
00229 }
00230
00231
00232 static int wcmp(const void *a, const void *b) {
00233 return *((Window *) a) - *((Window *) b);
00234 }
00235
00236
00237 static const int netAtomCount = 78;
00238 static void create_atoms(Display *d) {
00239 static const char * const names[netAtomCount] =
00240 {
00241 "UTF8_STRING",
00242 "_NET_SUPPORTED",
00243 "_NET_SUPPORTING_WM_CHECK",
00244 "_NET_CLIENT_LIST",
00245 "_NET_CLIENT_LIST_STACKING",
00246 "_NET_NUMBER_OF_DESKTOPS",
00247 "_NET_DESKTOP_GEOMETRY",
00248 "_NET_DESKTOP_VIEWPORT",
00249 "_NET_CURRENT_DESKTOP",
00250 "_NET_DESKTOP_NAMES",
00251 "_NET_ACTIVE_WINDOW",
00252 "_NET_WORKAREA",
00253 "_NET_VIRTUAL_ROOTS",
00254 "_NET_SHOWING_DESKTOP",
00255 "_NET_CLOSE_WINDOW",
00256 "_NET_RESTACK_WINDOW",
00257
00258 "_NET_WM_MOVERESIZE",
00259 "_NET_MOVERESIZE_WINDOW",
00260 "_NET_WM_NAME",
00261 "_NET_WM_VISIBLE_NAME",
00262 "_NET_WM_ICON_NAME",
00263 "_NET_WM_VISIBLE_ICON_NAME",
00264 "_NET_WM_DESKTOP",
00265 "_NET_WM_WINDOW_TYPE",
00266 "_NET_WM_STATE",
00267 "_NET_WM_STRUT",
00268 "_NET_WM_STRUT_PARTIAL",
00269 "_NET_WM_ICON_GEOMETRY",
00270 "_NET_WM_ICON",
00271 "_NET_WM_PID",
00272 "_NET_WM_USER_TIME",
00273 "_NET_WM_HANDLED_ICONS",
00274 "_NET_STARTUP_ID",
00275 "_NET_WM_ALLOWED_ACTIONS",
00276 "_NET_WM_PING",
00277 "_NET_WM_TAKE_ACTIVITY",
00278 "WM_WINDOW_ROLE",
00279 "_NET_FRAME_EXTENTS",
00280
00281 "_NET_WM_WINDOW_TYPE_NORMAL",
00282 "_NET_WM_WINDOW_TYPE_DESKTOP",
00283 "_NET_WM_WINDOW_TYPE_DOCK",
00284 "_NET_WM_WINDOW_TYPE_TOOLBAR",
00285 "_NET_WM_WINDOW_TYPE_MENU",
00286 "_NET_WM_WINDOW_TYPE_DIALOG",
00287 "_NET_WM_WINDOW_TYPE_UTILITY",
00288 "_NET_WM_WINDOW_TYPE_SPLASH",
00289
00290 "_NET_WM_STATE_MODAL",
00291 "_NET_WM_STATE_STICKY",
00292 "_NET_WM_STATE_MAXIMIZED_VERT",
00293 "_NET_WM_STATE_MAXIMIZED_HORZ",
00294 "_NET_WM_STATE_SHADED",
00295 "_NET_WM_STATE_SKIP_TASKBAR",
00296 "_NET_WM_STATE_SKIP_PAGER",
00297 "_NET_WM_STATE_HIDDEN",
00298 "_NET_WM_STATE_FULLSCREEN",
00299 "_NET_WM_STATE_ABOVE",
00300 "_NET_WM_STATE_BELOW",
00301 "_NET_WM_STATE_DEMANDS_ATTENTION",
00302
00303 "_NET_WM_ACTION_MOVE",
00304 "_NET_WM_ACTION_RESIZE",
00305 "_NET_WM_ACTION_MINIMIZE",
00306 "_NET_WM_ACTION_SHADE",
00307 "_NET_WM_ACTION_STICK",
00308 "_NET_WM_ACTION_MAXIMIZE_VERT",
00309 "_NET_WM_ACTION_MAXIMIZE_HORZ",
00310 "_NET_WM_ACTION_FULLSCREEN",
00311 "_NET_WM_ACTION_CHANGE_DESKTOP",
00312 "_NET_WM_ACTION_CLOSE",
00313
00314 "_NET_WM_STATE_STAYS_ON_TOP",
00315
00316 "_KDE_NET_SYSTEM_TRAY_WINDOWS",
00317 "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
00318 "_KDE_NET_WM_FRAME_STRUT",
00319 "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE",
00320 "_KDE_NET_WM_WINDOW_TYPE_TOPMENU",
00321 "_KDE_NET_WM_TEMPORARY_RULES",
00322
00323 "WM_STATE",
00324 "WM_PROTOCOLS",
00325
00326 "_NET_WM_FULL_PLACEMENT"
00327 };
00328
00329 Atom atoms[netAtomCount], *atomsp[netAtomCount] =
00330 {
00331 &UTF8_STRING,
00332 &net_supported,
00333 &net_supporting_wm_check,
00334 &net_client_list,
00335 &net_client_list_stacking,
00336 &net_number_of_desktops,
00337 &net_desktop_geometry,
00338 &net_desktop_viewport,
00339 &net_current_desktop,
00340 &net_desktop_names,
00341 &net_active_window,
00342 &net_workarea,
00343 &net_virtual_roots,
00344 &net_showing_desktop,
00345 &net_close_window,
00346 &net_restack_window,
00347
00348 &net_wm_moveresize,
00349 &net_moveresize_window,
00350 &net_wm_name,
00351 &net_wm_visible_name,
00352 &net_wm_icon_name,
00353 &net_wm_visible_icon_name,
00354 &net_wm_desktop,
00355 &net_wm_window_type,
00356 &net_wm_state,
00357 &net_wm_strut,
00358 &net_wm_extended_strut,
00359 &net_wm_icon_geometry,
00360 &net_wm_icon,
00361 &net_wm_pid,
00362 &net_wm_user_time,
00363 &net_wm_handled_icons,
00364 &net_startup_id,
00365 &net_wm_allowed_actions,
00366 &net_wm_ping,
00367 &net_wm_take_activity,
00368 &wm_window_role,
00369 &net_frame_extents,
00370
00371 &net_wm_window_type_normal,
00372 &net_wm_window_type_desktop,
00373 &net_wm_window_type_dock,
00374 &net_wm_window_type_toolbar,
00375 &net_wm_window_type_menu,
00376 &net_wm_window_type_dialog,
00377 &net_wm_window_type_utility,
00378 &net_wm_window_type_splash,
00379
00380 &net_wm_state_modal,
00381 &net_wm_state_sticky,
00382 &net_wm_state_max_vert,
00383 &net_wm_state_max_horiz,
00384 &net_wm_state_shaded,
00385 &net_wm_state_skip_taskbar,
00386 &net_wm_state_skip_pager,
00387 &net_wm_state_hidden,
00388 &net_wm_state_fullscreen,
00389 &net_wm_state_above,
00390 &net_wm_state_below,
00391 &net_wm_state_demands_attention,
00392
00393 &net_wm_action_move,
00394 &net_wm_action_resize,
00395 &net_wm_action_minimize,
00396 &net_wm_action_shade,
00397 &net_wm_action_stick,
00398 &net_wm_action_max_vert,
00399 &net_wm_action_max_horiz,
00400 &net_wm_action_fullscreen,
00401 &net_wm_action_change_desk,
00402 &net_wm_action_close,
00403
00404 &net_wm_state_stays_on_top,
00405
00406 &kde_net_system_tray_windows,
00407 &kde_net_wm_system_tray_window_for,
00408 &kde_net_wm_frame_strut,
00409 &kde_net_wm_window_type_override,
00410 &kde_net_wm_window_type_topmenu,
00411 &kde_net_wm_temporary_rules,
00412
00413 &xa_wm_state,
00414 &wm_protocols,
00415
00416 &net_wm_full_placement
00417 };
00418
00419 assert( !netwm_atoms_created );
00420
00421 int i = netAtomCount;
00422 while (i--)
00423 atoms[i] = 0;
00424
00425 XInternAtoms(d, (char **) names, netAtomCount, False, atoms);
00426
00427 i = netAtomCount;
00428 while (i--)
00429 *atomsp[i] = atoms[i];
00430
00431 netwm_atoms_created = True;
00432 }
00433
00434
00435 static void readIcon(Display* display, Window window, Atom property,
00436 NETRArray<NETIcon>& icons, int& icon_count, bool has_prefetch) {
00437
00438 #ifdef NETWMDEBUG
00439 fprintf(stderr, "NET: readIcon\n");
00440 #endif
00441
00442 Atom type_ret;
00443 int format_ret;
00444 unsigned long nitems_ret = 0, after_ret = 0;
00445 unsigned char *data_ret = 0;
00446
00447
00448 for (int i = 0; i < icons.size(); i++)
00449 delete [] icons[i].data;
00450 icons.reset();
00451 icon_count = 0;
00452
00453
00454 unsigned char *buffer = 0;
00455 unsigned long offset = 0;
00456 unsigned long buffer_offset = 0;
00457 unsigned long bufsize = 0;
00458
00459
00460 do {
00461 int status;
00462 if( has_prefetch )
00463 status = KXReceiveWindowProperty(display, window, property, offset,
00464 MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
00465 &format_ret, &nitems_ret, &after_ret, &data_ret);
00466 else
00467 status = XGetWindowProperty(display, window, property, offset,
00468 MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
00469 &format_ret, &nitems_ret, &after_ret, &data_ret);
00470 has_prefetch = false;
00471 if( status == Success) {
00472 if (!bufsize)
00473 {
00474 if (nitems_ret < 3 || type_ret != XA_CARDINAL ||
00475 format_ret != 32) {
00476
00477
00478
00479
00480 if ( data_ret )
00481 XFree(data_ret);
00482 return;
00483 }
00484
00485 bufsize = nitems_ret * sizeof(long) + after_ret;
00486 buffer = (unsigned char *) malloc(bufsize);
00487 }
00488 else if (buffer_offset + nitems_ret*sizeof(long) > bufsize)
00489 {
00490 fprintf(stderr, "NETWM: Warning readIcon() needs buffer adjustment!\n");
00491 bufsize = buffer_offset + nitems_ret * sizeof(long) + after_ret;
00492 buffer = (unsigned char *) realloc(buffer, bufsize);
00493 }
00494 memcpy((buffer + buffer_offset), data_ret, nitems_ret * sizeof(long));
00495 buffer_offset += nitems_ret * sizeof(long);
00496 offset += nitems_ret;
00497
00498 if ( data_ret )
00499 XFree(data_ret);
00500 } else {
00501 if (buffer)
00502 free(buffer);
00503 return;
00504 }
00505 }
00506 while (after_ret > 0);
00507
00508 CARD32 *data32;
00509 unsigned long i, j, k, sz, s;
00510 unsigned long *d = (unsigned long *) buffer;
00511 for (i = 0, j = 0; i < bufsize; i++) {
00512 icons[j].size.width = *d++;
00513 i += sizeof(long);
00514 icons[j].size.height = *d++;
00515 i += sizeof(long);
00516
00517 sz = icons[j].size.width * icons[j].size.height;
00518 s = sz * sizeof(long);
00519
00520 if ( i + s - 1 > bufsize || sz == 0 || sz > 1024 * 1024 ) {
00521 break;
00522 }
00523
00524 delete [] icons[j].data;
00525 data32 = new CARD32[sz];
00526 icons[j].data = (unsigned char *) data32;
00527 for (k = 0; k < sz; k++, i += sizeof(long)) {
00528 *data32++ = (CARD32) *d++;
00529 }
00530 j++;
00531 icon_count++;
00532 }
00533
00534 #ifdef NETWMDEBUG
00535 fprintf(stderr, "NET: readIcon got %d icons\n", icon_count);
00536 #endif
00537
00538 free(buffer);
00539 }
00540
00541
00542 template <class Z>
00543 NETRArray<Z>::NETRArray()
00544 : sz(0), capacity(2)
00545 {
00546 d = (Z*) calloc(capacity, sizeof(Z));
00547 }
00548
00549
00550 template <class Z>
00551 NETRArray<Z>::~NETRArray() {
00552 free(d);
00553 }
00554
00555
00556 template <class Z>
00557 void NETRArray<Z>::reset() {
00558 sz = 0;
00559 capacity = 2;
00560 d = (Z*) realloc(d, sizeof(Z)*capacity);
00561 memset( (void*) d, 0, sizeof(Z)*capacity );
00562 }
00563
00564 template <class Z>
00565 Z &NETRArray<Z>::operator[](int index) {
00566 if (index >= capacity) {
00567
00568
00569
00570 int newcapacity = 2*capacity > index+1 ? 2*capacity : index+1;
00571
00572 d = (Z*) realloc(d, sizeof(Z)*newcapacity);
00573 memset( (void*) &d[capacity], 0, sizeof(Z)*(newcapacity-capacity) );
00574 capacity = newcapacity;
00575 }
00576 if (index >= sz)
00577 sz = index + 1;
00578
00579 return d[index];
00580 }
00581
00582
00583
00584
00585 NETRootInfo::NETRootInfo(Display *display, Window supportWindow, const char *wmName,
00586 const unsigned long properties[], int properties_size,
00587 int screen, bool doActivate)
00588 {
00589
00590 #ifdef NETWMDEBUG
00591 fprintf(stderr, "NETRootInfo::NETRootInfo: using window manager constructor\n");
00592 #endif
00593
00594 p = new NETRootInfoPrivate;
00595 p->ref = 1;
00596
00597 p->display = display;
00598 p->name = nstrdup(wmName);
00599
00600 if (screen != -1) {
00601 p->screen = screen;
00602 } else {
00603 p->screen = DefaultScreen(p->display);
00604 }
00605
00606 p->root = RootWindow(p->display, p->screen);
00607 p->supportwindow = supportWindow;
00608 p->number_of_desktops = p->current_desktop = 0;
00609 p->active = None;
00610 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00611 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00612 p->kde_system_tray_windows = 0;
00613 p->kde_system_tray_windows_count = 0;
00614 p->showing_desktop = false;
00615 setDefaultProperties();
00616 if( properties_size > PROPERTIES_SIZE ) {
00617 fprintf( stderr, "NETRootInfo::NETRootInfo(): properties array too large\n");
00618 properties_size = PROPERTIES_SIZE;
00619 }
00620 for( int i = 0; i < properties_size; ++i )
00621 p->properties[ i ] = properties[ i ];
00622
00623 p->properties[ PROTOCOLS ] |= ( Supported | SupportingWMCheck );
00624 p->client_properties[ PROTOCOLS ] = DesktopNames
00625 | WMPing;
00626 p->client_properties[ PROTOCOLS2 ] = WM2TakeActivity;
00627
00628 role = WindowManager;
00629
00630 if (! netwm_atoms_created) create_atoms(p->display);
00631
00632 if (doActivate) activate();
00633 }
00634
00635 NETRootInfo::NETRootInfo(Display *display, Window supportWindow, const char *wmName,
00636 unsigned long properties, int screen, bool doActivate)
00637 {
00638
00639 #ifdef NETWMDEBUG
00640 fprintf(stderr, "NETRootInfo::NETRootInfo: using window manager constructor\n");
00641 #endif
00642
00643 p = new NETRootInfoPrivate;
00644 p->ref = 1;
00645
00646 p->display = display;
00647 p->name = nstrdup(wmName);
00648
00649 if (screen != -1) {
00650 p->screen = screen;
00651 } else {
00652 p->screen = DefaultScreen(p->display);
00653 }
00654
00655 p->root = RootWindow(p->display, p->screen);
00656 p->supportwindow = supportWindow;
00657 p->number_of_desktops = p->current_desktop = 0;
00658 p->active = None;
00659 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00660 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00661 p->kde_system_tray_windows = 0;
00662 p->kde_system_tray_windows_count = 0;
00663 p->showing_desktop = false;
00664 setDefaultProperties();
00665 p->properties[ PROTOCOLS ] = properties;
00666
00667 p->properties[ PROTOCOLS ] |= ( Supported | SupportingWMCheck );
00668 p->client_properties[ PROTOCOLS ] = DesktopNames
00669 | WMPing;
00670 p->client_properties[ PROTOCOLS2 ] = WM2TakeActivity;
00671
00672 role = WindowManager;
00673
00674 if (! netwm_atoms_created) create_atoms(p->display);
00675
00676 if (doActivate) activate();
00677 }
00678
00679
00680 NETRootInfo::NETRootInfo(Display *display, const unsigned long properties[], int properties_size,
00681 int screen, bool doActivate)
00682 {
00683
00684 #ifdef NETWMDEBUG
00685 fprintf(stderr, "NETRootInfo::NETRootInfo: using Client constructor\n");
00686 #endif
00687
00688 p = new NETRootInfoPrivate;
00689 p->ref = 1;
00690
00691 p->name = 0;
00692
00693 p->display = display;
00694
00695 if (screen != -1) {
00696 p->screen = screen;
00697 } else {
00698 p->screen = DefaultScreen(p->display);
00699 }
00700
00701 p->root = RootWindow(p->display, p->screen);
00702 p->rootSize.width = WidthOfScreen(ScreenOfDisplay(p->display, p->screen));
00703 p->rootSize.height = HeightOfScreen(ScreenOfDisplay(p->display, p->screen));
00704
00705 p->supportwindow = None;
00706 p->number_of_desktops = p->current_desktop = 0;
00707 p->active = None;
00708 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00709 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00710 p->kde_system_tray_windows = 0;
00711 p->kde_system_tray_windows_count = 0;
00712 p->showing_desktop = false;
00713 setDefaultProperties();
00714 if( properties_size > 2 ) {
00715 fprintf( stderr, "NETWinInfo::NETWinInfo(): properties array too large\n");
00716 properties_size = 2;
00717 }
00718 for( int i = 0; i < properties_size; ++i )
00719
00720 switch( i ) {
00721 case 0:
00722 p->client_properties[ PROTOCOLS ] = properties[ i ];
00723 break;
00724 case 1:
00725 p->client_properties[ PROTOCOLS2 ] = properties[ i ];
00726 break;
00727 }
00728 for( int i = 0; i < PROPERTIES_SIZE; ++i )
00729 p->properties[ i ] = 0;
00730
00731 role = Client;
00732
00733 if (! netwm_atoms_created) create_atoms(p->display);
00734
00735 if (doActivate) activate();
00736 }
00737
00738 NETRootInfo::NETRootInfo(Display *display, unsigned long properties, int screen,
00739 bool doActivate)
00740 {
00741
00742 #ifdef NETWMDEBUG
00743 fprintf(stderr, "NETRootInfo::NETRootInfo: using Client constructor\n");
00744 #endif
00745
00746 p = new NETRootInfoPrivate;
00747 p->ref = 1;
00748
00749 p->name = 0;
00750
00751 p->display = display;
00752
00753 if (screen != -1) {
00754 p->screen = screen;
00755 } else {
00756 p->screen = DefaultScreen(p->display);
00757 }
00758
00759 p->root = RootWindow(p->display, p->screen);
00760 p->rootSize.width = WidthOfScreen(ScreenOfDisplay(p->display, p->screen));
00761 p->rootSize.height = HeightOfScreen(ScreenOfDisplay(p->display, p->screen));
00762
00763 p->supportwindow = None;
00764 p->number_of_desktops = p->current_desktop = 0;
00765 p->active = None;
00766 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00767 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00768 p->kde_system_tray_windows = 0;
00769 p->kde_system_tray_windows_count = 0;
00770 p->showing_desktop = false;
00771 setDefaultProperties();
00772 p->client_properties[ PROTOCOLS ] = properties;
00773 for( int i = 0; i < PROPERTIES_SIZE; ++i )
00774 p->properties[ i ] = 0;
00775
00776 role = Client;
00777
00778 if (! netwm_atoms_created) create_atoms(p->display);
00779
00780 if (doActivate) activate();
00781 }
00782
00783
00784 NETRootInfo2::NETRootInfo2(Display *display, Window supportWindow, const char *wmName,
00785 unsigned long properties[], int properties_size,
00786 int screen, bool doActivate)
00787 : NETRootInfo( display, supportWindow, wmName, properties, properties_size,
00788 screen, doActivate )
00789 {
00790 }
00791
00792 NETRootInfo2::NETRootInfo2(Display *display, const unsigned long properties[], int properties_size,
00793 int screen, bool doActivate)
00794 : NETRootInfo( display, properties, properties_size, screen, doActivate )
00795 {
00796 }
00797
00798 NETRootInfo3::NETRootInfo3(Display *display, Window supportWindow, const char *wmName,
00799 unsigned long properties[], int properties_size,
00800 int screen, bool doActivate)
00801 : NETRootInfo2( display, supportWindow, wmName, properties, properties_size,
00802 screen, doActivate )
00803 {
00804 }
00805
00806 NETRootInfo3::NETRootInfo3(Display *display, const unsigned long properties[], int properties_size,
00807 int screen, bool doActivate)
00808 : NETRootInfo2( display, properties, properties_size, screen, doActivate )
00809 {
00810 }
00811
00812 NETRootInfo4::NETRootInfo4(Display *display, Window supportWindow, const char *wmName,
00813 unsigned long properties[], int properties_size,
00814 int screen, bool doActivate)
00815 : NETRootInfo3( display, supportWindow, wmName, properties, properties_size,
00816 screen, doActivate )
00817 {
00818 }
00819
00820 NETRootInfo4::NETRootInfo4(Display *display, const unsigned long properties[], int properties_size,
00821 int screen, bool doActivate)
00822 : NETRootInfo3( display, properties, properties_size, screen, doActivate )
00823 {
00824 }
00825
00826
00827
00828 NETRootInfo::NETRootInfo(const NETRootInfo &rootinfo) {
00829
00830 #ifdef NETWMDEBUG
00831 fprintf(stderr, "NETRootInfo::NETRootInfo: using copy constructor\n");
00832 #endif
00833
00834 p = rootinfo.p;
00835 role = rootinfo.role;
00836
00837 p->ref++;
00838 }
00839
00840
00841
00842
00843 NETRootInfo::~NETRootInfo() {
00844 refdec_nri(p);
00845
00846 if (! p->ref) delete p;
00847 }
00848
00849
00850 void NETRootInfo::setDefaultProperties()
00851 {
00852 p->properties[ PROTOCOLS ] = Supported | SupportingWMCheck;
00853 p->properties[ WINDOW_TYPES ] = NormalMask | DesktopMask | DockMask
00854 | ToolbarMask | MenuMask | DialogMask;
00855 p->properties[ STATES ] = Modal | Sticky | MaxVert | MaxHoriz | Shaded
00856 | SkipTaskbar | StaysOnTop;
00857 p->properties[ PROTOCOLS2 ] = 0;
00858 p->properties[ ACTIONS ] = 0;
00859 p->client_properties[ PROTOCOLS ] = 0;
00860 p->client_properties[ WINDOW_TYPES ] = 0;
00861 p->client_properties[ STATES ] = 0;
00862 p->client_properties[ PROTOCOLS2 ] = 0;
00863 p->client_properties[ ACTIONS ] = 0;
00864 }
00865
00866 void NETRootInfo::activate() {
00867 if (role == WindowManager) {
00868
00869 #ifdef NETWMDEBUG
00870 fprintf(stderr,
00871 "NETRootInfo::activate: setting supported properties on root\n");
00872 #endif
00873
00874 setSupported();
00875 } else {
00876
00877 #ifdef NETWMDEBUG
00878 fprintf(stderr, "NETRootInfo::activate: updating client information\n");
00879 #endif
00880
00881 update(p->client_properties);
00882 }
00883 }
00884
00885
00886 void NETRootInfo::setClientList(Window *windows, unsigned int count) {
00887 if (role != WindowManager) return;
00888
00889 p->clients_count = count;
00890
00891 delete [] p->clients;
00892 p->clients = nwindup(windows, count);
00893
00894 #ifdef NETWMDEBUG
00895 fprintf(stderr, "NETRootInfo::setClientList: setting list with %ld windows\n",
00896 p->clients_count);
00897 #endif
00898
00899 XChangeProperty(p->display, p->root, net_client_list, XA_WINDOW, 32,
00900 PropModeReplace, (unsigned char *)p->clients,
00901 p->clients_count);
00902 }
00903
00904
00905 void NETRootInfo::setClientListStacking(Window *windows, unsigned int count) {
00906 if (role != WindowManager) return;
00907
00908 p->stacking_count = count;
00909 delete [] p->stacking;
00910 p->stacking = nwindup(windows, count);
00911
00912 #ifdef NETWMDEBUG
00913 fprintf(stderr,
00914 "NETRootInfo::setClientListStacking: setting list with %ld windows\n",
00915 p->clients_count);
00916 #endif
00917
00918 XChangeProperty(p->display, p->root, net_client_list_stacking, XA_WINDOW, 32,
00919 PropModeReplace, (unsigned char *) p->stacking,
00920 p->stacking_count);
00921 }
00922
00923
00924 void NETRootInfo::setKDESystemTrayWindows(Window *windows, unsigned int count) {
00925 if (role != WindowManager) return;
00926
00927 p->kde_system_tray_windows_count = count;
00928 delete [] p->kde_system_tray_windows;
00929 p->kde_system_tray_windows = nwindup(windows, count);
00930
00931 #ifdef NETWMDEBUG
00932 fprintf(stderr,
00933 "NETRootInfo::setKDESystemTrayWindows: setting list with %ld windows\n",
00934 p->kde_system_tray_windows_count);
00935 #endif
00936
00937 XChangeProperty(p->display, p->root, kde_net_system_tray_windows, XA_WINDOW, 32,
00938 PropModeReplace,
00939 (unsigned char *) p->kde_system_tray_windows,
00940 p->kde_system_tray_windows_count);
00941 }
00942
00943
00944 void NETRootInfo::setNumberOfDesktops(int numberOfDesktops) {
00945
00946 #ifdef NETWMDEBUG
00947 fprintf(stderr,
00948 "NETRootInfo::setNumberOfDesktops: setting desktop count to %d (%s)\n",
00949 numberOfDesktops, (role == WindowManager) ? "WM" : "Client");
00950 #endif
00951
00952 if (role == WindowManager) {
00953 p->number_of_desktops = numberOfDesktops;
00954 long d = numberOfDesktops;
00955 XChangeProperty(p->display, p->root, net_number_of_desktops, XA_CARDINAL, 32,
00956 PropModeReplace, (unsigned char *) &d, 1);
00957 } else {
00958 XEvent e;
00959
00960 e.xclient.type = ClientMessage;
00961 e.xclient.message_type = net_number_of_desktops;
00962 e.xclient.display = p->display;
00963 e.xclient.window = p->root;
00964 e.xclient.format = 32;
00965 e.xclient.data.l[0] = numberOfDesktops;
00966 e.xclient.data.l[1] = 0l;
00967 e.xclient.data.l[2] = 0l;
00968 e.xclient.data.l[3] = 0l;
00969 e.xclient.data.l[4] = 0l;
00970
00971 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
00972 }
00973 }
00974
00975
00976 void NETRootInfo::setCurrentDesktop(int desktop) {
00977
00978 #ifdef NETWMDEBUG
00979 fprintf(stderr,
00980 "NETRootInfo::setCurrentDesktop: setting current desktop = %d (%s)\n",
00981 desktop, (role == WindowManager) ? "WM" : "Client");
00982 #endif
00983
00984 if (role == WindowManager) {
00985 p->current_desktop = desktop;
00986 long d = p->current_desktop - 1;
00987 XChangeProperty(p->display, p->root, net_current_desktop, XA_CARDINAL, 32,
00988 PropModeReplace, (unsigned char *) &d, 1);
00989 } else {
00990 XEvent e;
00991
00992 e.xclient.type = ClientMessage;
00993 e.xclient.message_type = net_current_desktop;
00994 e.xclient.display = p->display;
00995 e.xclient.window = p->root;
00996 e.xclient.format = 32;
00997 e.xclient.data.l[0] = desktop - 1;
00998 e.xclient.data.l[1] = 0l;
00999 e.xclient.data.l[2] = 0l;
01000 e.xclient.data.l[3] = 0l;
01001 e.xclient.data.l[4] = 0l;
01002
01003 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01004 }
01005 }
01006
01007
01008 void NETRootInfo::setDesktopName(int desktop, const char *desktopName) {
01009
01010 if (desktop < 1) return;
01011
01012 delete [] p->desktop_names[desktop - 1];
01013 p->desktop_names[desktop - 1] = nstrdup(desktopName);
01014
01015 unsigned int i, proplen,
01016 num = ((p->number_of_desktops > p->desktop_names.size()) ?
01017 p->number_of_desktops : p->desktop_names.size());
01018 for (i = 0, proplen = 0; i < num; i++)
01019 proplen += (p->desktop_names[i] != 0 ? strlen(p->desktop_names[i])+1 : 1 );
01020
01021 char *prop = new char[proplen], *propp = prop;
01022
01023 for (i = 0; i < num; i++)
01024 if (p->desktop_names[i]) {
01025 strcpy(propp, p->desktop_names[i]);
01026 propp += strlen(p->desktop_names[i]) + 1;
01027 } else
01028 *propp++ = '\0';
01029
01030 #ifdef NETWMDEBUG
01031 fprintf(stderr,
01032 "NETRootInfo::setDesktopName(%d, '%s')\n"
01033 "NETRootInfo::setDesktopName: total property length = %d",
01034 desktop, desktopName, proplen);
01035 #endif
01036
01037 XChangeProperty(p->display, p->root, net_desktop_names, UTF8_STRING, 8,
01038 PropModeReplace, (unsigned char *) prop, proplen);
01039
01040 delete [] prop;
01041 }
01042
01043
01044 void NETRootInfo::setDesktopGeometry(int , const NETSize &geometry) {
01045
01046 #ifdef NETWMDEBUG
01047 fprintf(stderr, "NETRootInfo::setDesktopGeometry( -- , { %d, %d }) (%s)\n",
01048 geometry.width, geometry.height, (role == WindowManager) ? "WM" : "Client");
01049 #endif
01050
01051 if (role == WindowManager) {
01052 p->geometry = geometry;
01053
01054 long data[2];
01055 data[0] = p->geometry.width;
01056 data[1] = p->geometry.height;
01057
01058 XChangeProperty(p->display, p->root, net_desktop_geometry, XA_CARDINAL, 32,
01059 PropModeReplace, (unsigned char *) data, 2);
01060 } else {
01061 XEvent e;
01062
01063 e.xclient.type = ClientMessage;
01064 e.xclient.message_type = net_desktop_geometry;
01065 e.xclient.display = p->display;
01066 e.xclient.window = p->root;
01067 e.xclient.format = 32;
01068 e.xclient.data.l[0] = geometry.width;
01069 e.xclient.data.l[1] = geometry.height;
01070 e.xclient.data.l[2] = 0l;
01071 e.xclient.data.l[3] = 0l;
01072 e.xclient.data.l[4] = 0l;
01073
01074 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01075 }
01076 }
01077
01078
01079 void NETRootInfo::setDesktopViewport(int desktop, const NETPoint &viewport) {
01080
01081 #ifdef NETWMDEBUG
01082 fprintf(stderr, "NETRootInfo::setDesktopViewport(%d, { %d, %d }) (%s)\n",
01083 desktop, viewport.x, viewport.y, (role == WindowManager) ? "WM" : "Client");
01084 #endif
01085
01086 if (desktop < 1) return;
01087
01088 if (role == WindowManager) {
01089 p->viewport[desktop - 1] = viewport;
01090
01091 int d, i, l;
01092 l = p->number_of_desktops * 2;
01093 long *data = new long[l];
01094 for (d = 0, i = 0; d < p->number_of_desktops; d++) {
01095 data[i++] = p->viewport[d].x;
01096 data[i++] = p->viewport[d].y;
01097 }
01098
01099 XChangeProperty(p->display, p->root, net_desktop_viewport, XA_CARDINAL, 32,
01100 PropModeReplace, (unsigned char *) data, l);
01101
01102 delete [] data;
01103 } else {
01104 XEvent e;
01105
01106 e.xclient.type = ClientMessage;
01107 e.xclient.message_type = net_desktop_viewport;
01108 e.xclient.display = p->display;
01109 e.xclient.window = p->root;
01110 e.xclient.format = 32;
01111 e.xclient.data.l[0] = viewport.x;
01112 e.xclient.data.l[1] = viewport.y;
01113 e.xclient.data.l[2] = 0l;
01114 e.xclient.data.l[3] = 0l;
01115 e.xclient.data.l[4] = 0l;
01116
01117 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01118 }
01119 }
01120
01121
01122 void NETRootInfo::setSupported() {
01123 if (role != WindowManager) {
01124 #ifdef NETWMDEBUG
01125 fprintf(stderr, "NETRootInfo::setSupported - role != WindowManager\n");
01126 #endif
01127
01128 return;
01129 }
01130
01131 Atom atoms[netAtomCount];
01132 int pnum = 2;
01133
01134
01135 atoms[0] = net_supported;
01136 atoms[1] = net_supporting_wm_check;
01137
01138 if (p->properties[ PROTOCOLS ] & ClientList)
01139 atoms[pnum++] = net_client_list;
01140
01141 if (p->properties[ PROTOCOLS ] & ClientListStacking)
01142 atoms[pnum++] = net_client_list_stacking;
01143
01144 if (p->properties[ PROTOCOLS ] & NumberOfDesktops)
01145 atoms[pnum++] = net_number_of_desktops;
01146
01147 if (p->properties[ PROTOCOLS ] & DesktopGeometry)
01148 atoms[pnum++] = net_desktop_geometry;
01149
01150 if (p->properties[ PROTOCOLS ] & DesktopViewport)
01151 atoms[pnum++] = net_desktop_viewport;
01152
01153 if (p->properties[ PROTOCOLS ] & CurrentDesktop)
01154 atoms[pnum++] = net_current_desktop;
01155
01156 if (p->properties[ PROTOCOLS ] & DesktopNames)
01157 atoms[pnum++] = net_desktop_names;
01158
01159 if (p->properties[ PROTOCOLS ] & ActiveWindow)
01160 atoms[pnum++] = net_active_window;
01161
01162 if (p->properties[ PROTOCOLS ] & WorkArea)
01163 atoms[pnum++] = net_workarea;
01164
01165 if (p->properties[ PROTOCOLS ] & VirtualRoots)
01166 atoms[pnum++] = net_virtual_roots;
01167
01168 if (p->properties[ PROTOCOLS ] & CloseWindow)
01169 atoms[pnum++] = net_close_window;
01170
01171 if (p->properties[ PROTOCOLS2 ] & WM2RestackWindow)
01172 atoms[pnum++] = net_restack_window;
01173
01174 if (p->properties[ PROTOCOLS2 ] & WM2ShowingDesktop)
01175 atoms[pnum++] = net_showing_desktop;
01176
01177
01178 if (p->properties[ PROTOCOLS ] & WMMoveResize)
01179 atoms[pnum++] = net_wm_moveresize;
01180
01181 if (p->properties[ PROTOCOLS2 ] & WM2MoveResizeWindow)
01182 atoms[pnum++] = net_moveresize_window;
01183
01184 if (p->properties[ PROTOCOLS ] & WMName)
01185 atoms[pnum++] = net_wm_name;
01186
01187 if (p->properties[ PROTOCOLS ] & WMVisibleName)
01188 atoms[pnum++] = net_wm_visible_name;
01189
01190 if (p->properties[ PROTOCOLS ] & WMIconName)
01191 atoms[pnum++] = net_wm_icon_name;
01192
01193 if (p->properties[ PROTOCOLS ] & WMVisibleIconName)
01194 atoms[pnum++] = net_wm_visible_icon_name;
01195
01196 if (p->properties[ PROTOCOLS ] & WMDesktop)
01197 atoms[pnum++] = net_wm_desktop;
01198
01199 if (p->properties[ PROTOCOLS ] & WMWindowType) {
01200 atoms[pnum++] = net_wm_window_type;
01201
01202
01203 if (p->properties[ WINDOW_TYPES ] & NormalMask)
01204 atoms[pnum++] = net_wm_window_type_normal;
01205 if (p->properties[ WINDOW_TYPES ] & DesktopMask)
01206 atoms[pnum++] = net_wm_window_type_desktop;
01207 if (p->properties[ WINDOW_TYPES ] & DockMask)
01208 atoms[pnum++] = net_wm_window_type_dock;
01209 if (p->properties[ WINDOW_TYPES ] & ToolbarMask)
01210 atoms[pnum++] = net_wm_window_type_toolbar;
01211 if (p->properties[ WINDOW_TYPES ] & MenuMask)
01212 atoms[pnum++] = net_wm_window_type_menu;
01213 if (p->properties[ WINDOW_TYPES ] & DialogMask)
01214 atoms[pnum++] = net_wm_window_type_dialog;
01215 if (p->properties[ WINDOW_TYPES ] & UtilityMask)
01216 atoms[pnum++] = net_wm_window_type_utility;
01217 if (p->properties[ WINDOW_TYPES ] & SplashMask)
01218 atoms[pnum++] = net_wm_window_type_splash;
01219
01220 if (p->properties[ WINDOW_TYPES ] & OverrideMask)
01221 atoms[pnum++] = kde_net_wm_window_type_override;
01222 if (p->properties[ WINDOW_TYPES ] & TopMenuMask)
01223 atoms[pnum++] = kde_net_wm_window_type_topmenu;
01224 }
01225
01226 if (p->properties[ PROTOCOLS ] & WMState) {
01227 atoms[pnum++] = net_wm_state;
01228
01229
01230 if (p->properties[ STATES ] & Modal)
01231 atoms[pnum++] = net_wm_state_modal;
01232 if (p->properties[ STATES ] & Sticky)
01233 atoms[pnum++] = net_wm_state_sticky;
01234 if (p->properties[ STATES ] & MaxVert)
01235 atoms[pnum++] = net_wm_state_max_vert;
01236 if (p->properties[ STATES ] & MaxHoriz)
01237 atoms[pnum++] = net_wm_state_max_horiz;
01238 if (p->properties[ STATES ] & Shaded)
01239 atoms[pnum++] = net_wm_state_shaded;
01240 if (p->properties[ STATES ] & SkipTaskbar)
01241 atoms[pnum++] = net_wm_state_skip_taskbar;
01242 if (p->properties[ STATES ] & SkipPager)
01243 atoms[pnum++] = net_wm_state_skip_pager;
01244 if (p->properties[ STATES ] & Hidden)
01245 atoms[pnum++] = net_wm_state_hidden;
01246 if (p->properties[ STATES ] & FullScreen)
01247 atoms[pnum++] = net_wm_state_fullscreen;
01248 if (p->properties[ STATES ] & KeepAbove)
01249 atoms[pnum++] = net_wm_state_above;
01250 if (p->properties[ STATES ] & KeepBelow)
01251 atoms[pnum++] = net_wm_state_below;
01252 if (p->properties[ STATES ] & DemandsAttention)
01253 atoms[pnum++] = net_wm_state_demands_attention;
01254
01255 if (p->properties[ STATES ] & StaysOnTop)
01256 atoms[pnum++] = net_wm_state_stays_on_top;
01257 }
01258
01259 if (p->properties[ PROTOCOLS ] & WMStrut)
01260 atoms[pnum++] = net_wm_strut;
01261
01262 if (p->properties[ PROTOCOLS2 ] & WM2ExtendedStrut)
01263 atoms[pnum++] = net_wm_extended_strut;
01264
01265 if (p->properties[ PROTOCOLS ] & WMIconGeometry)
01266 atoms[pnum++] = net_wm_icon_geometry;
01267
01268 if (p->properties[ PROTOCOLS ] & WMIcon)
01269 atoms[pnum++] = net_wm_icon;
01270
01271 if (p->properties[ PROTOCOLS ] & WMPid)
01272 atoms[pnum++] = net_wm_pid;
01273
01274 if (p->properties[ PROTOCOLS ] & WMHandledIcons)
01275 atoms[pnum++] = net_wm_handled_icons;
01276
01277 if (p->properties[ PROTOCOLS ] & WMPing)
01278 atoms[pnum++] = net_wm_ping;
01279
01280 if (p->properties[ PROTOCOLS2 ] & WM2TakeActivity)
01281 atoms[pnum++] = net_wm_take_activity;
01282
01283 if (p->properties[ PROTOCOLS2 ] & WM2UserTime)
01284 atoms[pnum++] = net_wm_user_time;
01285
01286 if (p->properties[ PROTOCOLS2 ] & WM2StartupId)
01287 atoms[pnum++] = net_startup_id;
01288
01289 if (p->properties[ PROTOCOLS2 ] & WM2AllowedActions) {
01290 atoms[pnum++] = net_wm_allowed_actions;
01291
01292
01293 if (p->properties[ ACTIONS ] & ActionMove)
01294 atoms[pnum++] = net_wm_action_move;
01295 if (p->properties[ ACTIONS ] & ActionResize)
01296 atoms[pnum++] = net_wm_action_resize;
01297 if (p->properties[ ACTIONS ] & ActionMinimize)
01298 atoms[pnum++] = net_wm_action_minimize;
01299 if (p->properties[ ACTIONS ] & ActionShade)
01300 atoms[pnum++] = net_wm_action_shade;
01301 if (p->properties[ ACTIONS ] & ActionStick)
01302 atoms[pnum++] = net_wm_action_stick;
01303 if (p->properties[ ACTIONS ] & ActionMaxVert)
01304 atoms[pnum++] = net_wm_action_max_vert;
01305 if (p->properties[ ACTIONS ] & ActionMaxHoriz)
01306 atoms[pnum++] = net_wm_action_max_horiz;
01307 if (p->properties[ ACTIONS ] & ActionFullScreen)
01308 atoms[pnum++] = net_wm_action_fullscreen;
01309 if (p->properties[ ACTIONS ] & ActionChangeDesktop)
01310 atoms[pnum++] = net_wm_action_change_desk;
01311 if (p->properties[ ACTIONS ] & ActionClose)
01312 atoms[pnum++] = net_wm_action_close;
01313 }
01314
01315
01316 if (p->properties[ PROTOCOLS ] & KDESystemTrayWindows)
01317 atoms[pnum++] = kde_net_system_tray_windows;
01318
01319 if (p->properties[ PROTOCOLS ] & WMKDESystemTrayWinFor)
01320 atoms[pnum++] = kde_net_wm_system_tray_window_for;
01321
01322 if (p->properties[ PROTOCOLS ] & WMFrameExtents) {
01323 atoms[pnum++] = net_frame_extents;
01324 atoms[pnum++] = kde_net_wm_frame_strut;
01325 }
01326
01327 if (p->properties[ PROTOCOLS2 ] & WM2KDETemporaryRules)
01328 atoms[pnum++] = kde_net_wm_temporary_rules;
01329 if (p->properties[ PROTOCOLS2 ] & WM2FullPlacement)
01330 atoms[pnum++] = net_wm_full_placement;
01331
01332 XChangeProperty(p->display, p->root, net_supported, XA_ATOM, 32,
01333 PropModeReplace, (unsigned char *) atoms, pnum);
01334 XChangeProperty(p->display, p->root, net_supporting_wm_check, XA_WINDOW, 32,
01335 PropModeReplace, (unsigned char *) &(p->supportwindow), 1);
01336
01337 #ifdef NETWMDEBUG
01338 fprintf(stderr,
01339 "NETRootInfo::setSupported: _NET_SUPPORTING_WM_CHECK = 0x%lx on 0x%lx\n"
01340 " : _NET_WM_NAME = '%s' on 0x%lx\n",
01341 p->supportwindow, p->supportwindow, p->name, p->supportwindow);
01342 #endif
01343
01344 XChangeProperty(p->display, p->supportwindow, net_supporting_wm_check,
01345 XA_WINDOW, 32, PropModeReplace,
01346 (unsigned char *) &(p->supportwindow), 1);
01347 XChangeProperty(p->display, p->supportwindow, net_wm_name, UTF8_STRING, 8,
01348 PropModeReplace, (unsigned char *) p->name,
01349 strlen(p->name));
01350 }
01351
01352 void NETRootInfo::updateSupportedProperties( Atom atom )
01353 {
01354 if( atom == net_supported )
01355 p->properties[ PROTOCOLS ] |= Supported;
01356
01357 else if( atom == net_supporting_wm_check )
01358 p->properties[ PROTOCOLS ] |= SupportingWMCheck;
01359
01360 else if( atom == net_client_list )
01361 p->properties[ PROTOCOLS ] |= ClientList;
01362
01363 else if( atom == net_client_list_stacking )
01364 p->properties[ PROTOCOLS ] |= ClientListStacking;
01365
01366 else if( atom == net_number_of_desktops )
01367 p->properties[ PROTOCOLS ] |= NumberOfDesktops;
01368
01369 else if( atom == net_desktop_geometry )
01370 p->properties[ PROTOCOLS ] |= DesktopGeometry;
01371
01372 else if( atom == net_desktop_viewport )
01373 p->properties[ PROTOCOLS ] |= DesktopViewport;
01374
01375 else if( atom == net_current_desktop )
01376 p->properties[ PROTOCOLS ] |= CurrentDesktop;
01377
01378 else if( atom == net_desktop_names )
01379 p->properties[ PROTOCOLS ] |= DesktopNames;
01380
01381 else if( atom == net_active_window )
01382 p->properties[ PROTOCOLS ] |= ActiveWindow;
01383
01384 else if( atom == net_workarea )
01385 p->properties[ PROTOCOLS ] |= WorkArea;
01386
01387 else if( atom == net_virtual_roots )
01388 p->properties[ PROTOCOLS ] |= VirtualRoots;
01389
01390 else if( atom == net_close_window )
01391 p->properties[ PROTOCOLS ] |= CloseWindow;
01392
01393 else if( atom == net_restack_window )
01394 p->properties[ PROTOCOLS2 ] |= WM2RestackWindow;
01395
01396 else if( atom == net_showing_desktop )
01397 p->properties[ PROTOCOLS2 ] |= WM2ShowingDesktop;
01398
01399
01400 else if( atom == net_wm_moveresize )
01401 p->properties[ PROTOCOLS ] |= WMMoveResize;
01402
01403 else if( atom == net_moveresize_window )
01404 p->properties[ PROTOCOLS2 ] |= WM2MoveResizeWindow;
01405
01406 else if( atom == net_wm_name )
01407 p->properties[ PROTOCOLS ] |= WMName;
01408
01409 else if( atom == net_wm_visible_name )
01410 p->properties[ PROTOCOLS ] |= WMVisibleName;
01411
01412 else if( atom == net_wm_icon_name )
01413 p->properties[ PROTOCOLS ] |= WMIconName;
01414
01415 else if( atom == net_wm_visible_icon_name )
01416 p->properties[ PROTOCOLS ] |= WMVisibleIconName;
01417
01418 else if( atom == net_wm_desktop )
01419 p->properties[ PROTOCOLS ] |= WMDesktop;
01420
01421 else if( atom == net_wm_window_type )
01422 p->properties[ PROTOCOLS ] |= WMWindowType;
01423
01424
01425 else if( atom == net_wm_window_type_normal )
01426 p->properties[ WINDOW_TYPES ] |= NormalMask;
01427 else if( atom == net_wm_window_type_desktop )
01428 p->properties[ WINDOW_TYPES ] |= DesktopMask;
01429 else if( atom == net_wm_window_type_dock )
01430 p->properties[ WINDOW_TYPES ] |= DockMask;
01431 else if( atom == net_wm_window_type_toolbar )
01432 p->properties[ WINDOW_TYPES ] |= ToolbarMask;
01433 else if( atom == net_wm_window_type_menu )
01434 p->properties[ WINDOW_TYPES ] |= MenuMask;
01435 else if( atom == net_wm_window_type_dialog )
01436 p->properties[ WINDOW_TYPES ] |= DialogMask;
01437 else if( atom == net_wm_window_type_utility )
01438 p->properties[ WINDOW_TYPES ] |= UtilityMask;
01439 else if( atom == net_wm_window_type_splash )
01440 p->properties[ WINDOW_TYPES ] |= SplashMask;
01441
01442 else if( atom == kde_net_wm_window_type_override )
01443 p->properties[ WINDOW_TYPES ] |= OverrideMask;
01444 else if( atom == kde_net_wm_window_type_topmenu )
01445 p->properties[ WINDOW_TYPES ] |= TopMenuMask;
01446
01447 else if( atom == net_wm_state )
01448 p->properties[ PROTOCOLS ] |= WMState;
01449
01450
01451 else if( atom == net_wm_state_modal )
01452 p->properties[ STATES ] |= Modal;
01453 else if( atom == net_wm_state_sticky )
01454 p->properties[ STATES ] |= Sticky;
01455 else if( atom == net_wm_state_max_vert )
01456 p->properties[ STATES ] |= MaxVert;
01457 else if( atom == net_wm_state_max_horiz )
01458 p->properties[ STATES ] |= MaxHoriz;
01459 else if( atom == net_wm_state_shaded )
01460 p->properties[ STATES ] |= Shaded;
01461 else if( atom == net_wm_state_skip_taskbar )
01462 p->properties[ STATES ] |= SkipTaskbar;
01463 else if( atom == net_wm_state_skip_pager )
01464 p->properties[ STATES ] |= SkipPager;
01465 else if( atom == net_wm_state_hidden )
01466 p->properties[ STATES ] |= Hidden;
01467 else if( atom == net_wm_state_fullscreen )
01468 p->properties[ STATES ] |= FullScreen;
01469 else if( atom == net_wm_state_above )
01470 p->properties[ STATES ] |= KeepAbove;
01471 else if( atom == net_wm_state_below )
01472 p->properties[ STATES ] |= KeepBelow;
01473 else if( atom == net_wm_state_demands_attention )
01474 p->properties[ STATES ] |= DemandsAttention;
01475
01476 else if( atom == net_wm_state_stays_on_top )
01477 p->properties[ STATES ] |= StaysOnTop;
01478
01479 else if( atom == net_wm_strut )
01480 p->properties[ PROTOCOLS ] |= WMStrut;
01481
01482 else if( atom == net_wm_extended_strut )
01483 p->properties[ PROTOCOLS2 ] |= WM2ExtendedStrut;
01484
01485 else if( atom == net_wm_icon_geometry )
01486 p->properties[ PROTOCOLS ] |= WMIconGeometry;
01487
01488 else if( atom == net_wm_icon )
01489 p->properties[ PROTOCOLS ] |= WMIcon;
01490
01491 else if( atom == net_wm_pid )
01492 p->properties[ PROTOCOLS ] |= WMPid;
01493
01494 else if( atom == net_wm_handled_icons )
01495 p->properties[ PROTOCOLS ] |= WMHandledIcons;
01496
01497 else if( atom == net_wm_ping )
01498 p->properties[ PROTOCOLS ] |= WMPing;
01499
01500 else if( atom == net_wm_take_activity )
01501 p->properties[ PROTOCOLS2 ] |= WM2TakeActivity;
01502
01503 else if( atom == net_wm_user_time )
01504 p->properties[ PROTOCOLS2 ] |= WM2UserTime;
01505
01506 else if( atom == net_startup_id )
01507 p->properties[ PROTOCOLS2 ] |= WM2StartupId;
01508
01509 else if( atom == net_wm_allowed_actions )
01510 p->properties[ PROTOCOLS2 ] |= WM2AllowedActions;
01511
01512
01513 else if( atom == net_wm_action_move )
01514 p->properties[ ACTIONS ] |= ActionMove;
01515 else if( atom == net_wm_action_resize )
01516 p->properties[ ACTIONS ] |= ActionResize;
01517 else if( atom == net_wm_action_minimize )
01518 p->properties[ ACTIONS ] |= ActionMinimize;
01519 else if( atom == net_wm_action_shade )
01520 p->properties[ ACTIONS ] |= ActionShade;
01521 else if( atom == net_wm_action_stick )
01522 p->properties[ ACTIONS ] |= ActionStick;
01523 else if( atom == net_wm_action_max_vert )
01524 p->properties[ ACTIONS ] |= ActionMaxVert;
01525 else if( atom == net_wm_action_max_horiz )
01526 p->properties[ ACTIONS ] |= ActionMaxHoriz;
01527 else if( atom == net_wm_action_fullscreen )
01528 p->properties[ ACTIONS ] |= ActionFullScreen;
01529 else if( atom == net_wm_action_change_desk )
01530 p->properties[ ACTIONS ] |= ActionChangeDesktop;
01531 else if( atom == net_wm_action_close )
01532 p->properties[ ACTIONS ] |= ActionClose;
01533
01534
01535 else if( atom == kde_net_system_tray_windows )
01536 p->properties[ PROTOCOLS ] |= KDESystemTrayWindows;
01537
01538 else if( atom == kde_net_wm_system_tray_window_for )
01539 p->properties[ PROTOCOLS ] |= WMKDESystemTrayWinFor;
01540
01541 else if( atom == net_frame_extents )
01542 p->properties[ PROTOCOLS ] |= WMFrameExtents;
01543 else if( atom == kde_net_wm_frame_strut )
01544 p->properties[ PROTOCOLS ] |= WMKDEFrameStrut;
01545
01546 else if( atom == kde_net_wm_temporary_rules )
01547 p->properties[ PROTOCOLS2 ] |= WM2KDETemporaryRules;
01548 else if( atom == net_wm_full_placement )
01549 p->properties[ PROTOCOLS2 ] |= WM2FullPlacement;
01550 }
01551
01552 extern Time qt_x_user_time;
01553 void NETRootInfo::setActiveWindow(Window window) {
01554 setActiveWindow( window, FromUnknown, qt_x_user_time, None );
01555 }
01556
01557 void NETRootInfo::setActiveWindow(Window window, NET::RequestSource src,
01558 Time timestamp, Window active_window ) {
01559
01560 #ifdef NETWMDEBUG
01561 fprintf(stderr, "NETRootInfo::setActiveWindow(0x%lx) (%s)\n",
01562 window, (role == WindowManager) ? "WM" : "Client");
01563 #endif
01564
01565 if (role == WindowManager) {
01566 p->active = window;
01567 XChangeProperty(p->display, p->root, net_active_window, XA_WINDOW, 32,
01568 PropModeReplace, (unsigned char *) &(p->active), 1);
01569 } else {
01570 XEvent e;
01571
01572 e.xclient.type = ClientMessage;
01573 e.xclient.message_type = net_active_window;
01574 e.xclient.display = p->display;
01575 e.xclient.window = window;
01576 e.xclient.format = 32;
01577 e.xclient.data.l[0] = src;
01578 e.xclient.data.l[1] = timestamp;
01579 e.xclient.data.l[2] = active_window;
01580 e.xclient.data.l[3] = 0l;
01581 e.xclient.data.l[4] = 0l;
01582
01583 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01584 }
01585 }
01586
01587
01588 void NETRootInfo::setWorkArea(int desktop, const NETRect &workarea) {
01589
01590 #ifdef NETWMDEBUG
01591 fprintf(stderr, "NETRootInfo::setWorkArea(%d, { %d, %d, %d, %d }) (%s)\n",
01592 desktop, workarea.pos.x, workarea.pos.y, workarea.size.width, workarea.size.height,
01593 (role == WindowManager) ? "WM" : "Client");
01594 #endif
01595
01596 if (role != WindowManager || desktop < 1) return;
01597
01598 p->workarea[desktop - 1] = workarea;
01599
01600 long *wa = new long[p->number_of_desktops * 4];
01601 int i, o;
01602 for (i = 0, o = 0; i < p->number_of_desktops; i++) {
01603 wa[o++] = p->workarea[i].pos.x;
01604 wa[o++] = p->workarea[i].pos.y;
01605 wa[o++] = p->workarea[i].size.width;
01606 wa[o++] = p->workarea[i].size.height;
01607 }
01608
01609 XChangeProperty(p->display, p->root, net_workarea, XA_CARDINAL, 32,
01610 PropModeReplace, (unsigned char *) wa,
01611 p->number_of_desktops * 4);
01612
01613 delete [] wa;
01614 }
01615
01616
01617 void NETRootInfo::setVirtualRoots(Window *windows, unsigned int count) {
01618 if (role != WindowManager) return;
01619
01620 p->virtual_roots_count = count;
01621 p->virtual_roots = windows;
01622
01623 #ifdef NETWMDEBUG
01624 fprintf(stderr, "NETRootInfo::setVirtualRoots: setting list with %ld windows\n",
01625 p->virtual_roots_count);
01626 #endif
01627
01628 XChangeProperty(p->display, p->root, net_virtual_roots, XA_WINDOW, 32,
01629 PropModeReplace, (unsigned char *) p->virtual_roots,
01630 p->virtual_roots_count);
01631 }
01632
01633
01634 void NETRootInfo::setShowingDesktop( bool showing ) {
01635 if (role == WindowManager) {
01636 long d = p->showing_desktop = showing;
01637 XChangeProperty(p->display, p->root, net_showing_desktop, XA_CARDINAL, 32,
01638 PropModeReplace, (unsigned char *) &d, 1);
01639 } else {
01640 XEvent e;
01641
01642 e.xclient.type = ClientMessage;
01643 e.xclient.message_type = net_showing_desktop;
01644 e.xclient.display = p->display;
01645 e.xclient.window = 0;
01646 e.xclient.format = 32;
01647 e.xclient.data.l[0] = showing ? 1 : 0;
01648 e.xclient.data.l[1] = 0;
01649 e.xclient.data.l[2] = 0;
01650 e.xclient.data.l[3] = 0;
01651 e.xclient.data.l[4] = 0;
01652
01653 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01654 }
01655 }
01656
01657
01658 bool NETRootInfo::showingDesktop() const {
01659 return p->showing_desktop;
01660 }
01661
01662
01663 void NETRootInfo::closeWindowRequest(Window window) {
01664
01665 #ifdef NETWMDEBUG
01666 fprintf(stderr, "NETRootInfo::closeWindowRequest: requesting close for 0x%lx\n",
01667 window);
01668 #endif
01669
01670 XEvent e;
01671
01672 e.xclient.type = ClientMessage;
01673 e.xclient.message_type = net_close_window;
01674 e.xclient.display = p->display;
01675 e.xclient.window = window;
01676 e.xclient.format = 32;
01677 e.xclient.data.l[0] = 0l;
01678 e.xclient.data.l[1] = 0l;
01679 e.xclient.data.l[2] = 0l;
01680 e.xclient.data.l[3] = 0l;
01681 e.xclient.data.l[4] = 0l;
01682
01683 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01684 }
01685
01686
01687 void NETRootInfo::moveResizeRequest(Window window, int x_root, int y_root,
01688 Direction direction)
01689 {
01690
01691 #ifdef NETWMDEBUG
01692 fprintf(stderr,
01693 "NETRootInfo::moveResizeRequest: requesting resize/move for 0x%lx (%d, %d, %d)\n",
01694 window, x_root, y_root, direction);
01695 #endif
01696
01697 XEvent e;
01698
01699 e.xclient.type = ClientMessage;
01700 e.xclient.message_type = net_wm_moveresize;
01701 e.xclient.display = p->display;
01702 e.xclient.window = window,
01703 e.xclient.format = 32;
01704 e.xclient.data.l[0] = x_root;
01705 e.xclient.data.l[1] = y_root;
01706 e.xclient.data.l[2] = direction;
01707 e.xclient.data.l[3] = 0l;
01708 e.xclient.data.l[4] = 0l;
01709
01710 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01711 }
01712
01713 void NETRootInfo::moveResizeWindowRequest(Window window, int flags, int x, int y, int width, int height )
01714 {
01715
01716 #ifdef NETWMDEBUG
01717 fprintf(stderr,
01718 "NETRootInfo::moveResizeWindowRequest: resizing/moving 0x%lx (%d, %d, %d, %d, %d)\n",
01719 window, flags, x, y, width, height);
01720 #endif
01721
01722 XEvent e;
01723
01724 e.xclient.type = ClientMessage;
01725 e.xclient.message_type = net_moveresize_window;
01726 e.xclient.display = p->display;
01727 e.xclient.window = window,
01728 e.xclient.format = 32;
01729 e.xclient.data.l[0] = flags;
01730 e.xclient.data.l[1] = x;
01731 e.xclient.data.l[2] = y;
01732 e.xclient.data.l[3] = width;
01733 e.xclient.data.l[4] = height;
01734
01735 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01736 }
01737
01738 void NETRootInfo::restackRequest(Window window, Window above, int detail)
01739 {
01740 restackRequest( window, FromTool, above, detail, qt_x_user_time );
01741 }
01742
01743 void NETRootInfo::restackRequest(Window window, RequestSource src, Window above, int detail, Time timestamp )
01744 {
01745 #ifdef NETWMDEBUG
01746 fprintf(stderr,
01747 "NETRootInfo::restackRequest: requesting restack for 0x%lx (%lx, %d)\n",
01748 window, above, detail);
01749 #endif
01750
01751 XEvent e;
01752
01753 e.xclient.type = ClientMessage;
01754 e.xclient.message_type = net_restack_window;
01755 e.xclient.display = p->display;
01756 e.xclient.window = window,
01757 e.xclient.format = 32;
01758 e.xclient.data.l[0] = src;
01759 e.xclient.data.l[1] = above;
01760 e.xclient.data.l[2] = detail;
01761 e.xclient.data.l[3] = timestamp;
01762 e.xclient.data.l[4] = 0l;
01763
01764 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
01765 }
01766
01767 void NETRootInfo2::sendPing( Window window, Time timestamp )
01768 {
01769 if (role != WindowManager) return;
01770 #ifdef NETWMDEBUG
01771 fprintf(stderr, "NETRootInfo2::setPing: window 0x%lx, timestamp %lu\n",
01772 window, timestamp );
01773 #endif
01774 XEvent e;
01775 e.xclient.type = ClientMessage;
01776 e.xclient.message_type = wm_protocols;
01777 e.xclient.display = p->display;
01778 e.xclient.window = window,
01779 e.xclient.format = 32;
01780 e.xclient.data.l[0] = net_wm_ping;
01781 e.xclient.data.l[1] = timestamp;
01782 e.xclient.data.l[2] = window;
01783 e.xclient.data.l[3] = 0;
01784 e.xclient.data.l[4] = 0;
01785
01786 XSendEvent(p->display, window, False, 0, &e);
01787 }
01788
01789 void NETRootInfo3::takeActivity( Window window, Time timestamp, long flags )
01790 {
01791 if (role != WindowManager) return;
01792 #ifdef NETWMDEBUG
01793 fprintf(stderr, "NETRootInfo2::takeActivity: window 0x%lx, timestamp %lu, flags 0x%lx\n",
01794 window, timestamp, flags );
01795 #endif
01796 XEvent e;
01797 e.xclient.type = ClientMessage;
01798 e.xclient.message_type = wm_protocols;
01799 e.xclient.display = p->display;
01800 e.xclient.window = window,
01801 e.xclient.format = 32;
01802 e.xclient.data.l[0] = net_wm_take_activity;
01803 e.xclient.data.l[1] = timestamp;
01804 e.xclient.data.l[2] = window;
01805 e.xclient.data.l[3] = flags;
01806 e.xclient.data.l[4] = 0;
01807
01808 XSendEvent(p->display, window, False, 0, &e);
01809 }
01810
01811
01812
01813
01814
01815 const NETRootInfo &NETRootInfo::operator=(const NETRootInfo &rootinfo) {
01816
01817 #ifdef NETWMDEBUG
01818 fprintf(stderr, "NETRootInfo::operator=()\n");
01819 #endif
01820
01821 if (p != rootinfo.p) {
01822 refdec_nri(p);
01823
01824 if (! p->ref) delete p;
01825 }
01826
01827 p = rootinfo.p;
01828 role = rootinfo.role;
01829 p->ref++;
01830
01831 return *this;
01832 }
01833
01834 unsigned long NETRootInfo::event(XEvent *ev )
01835 {
01836 unsigned long props[ 1 ];
01837 event( ev, props, 1 );
01838 return props[ 0 ];
01839 }
01840
01841 void NETRootInfo::event(XEvent *event, unsigned long* properties, int properties_size )
01842 {
01843 unsigned long props[ PROPERTIES_SIZE ] = { 0, 0, 0, 0, 0 };
01844 assert( PROPERTIES_SIZE == 5 );
01845 unsigned long& dirty = props[ PROTOCOLS ];
01846 unsigned long& dirty2 = props[ PROTOCOLS2 ];
01847 bool do_update = false;
01848
01849
01850
01851 if (role == WindowManager && event->type == ClientMessage &&
01852 event->xclient.format == 32) {
01853 #ifdef NETWMDEBUG
01854 fprintf(stderr, "NETRootInfo::event: handling ClientMessage event\n");
01855 #endif
01856
01857 if (event->xclient.message_type == net_number_of_desktops) {
01858 dirty = NumberOfDesktops;
01859
01860 #ifdef NETWMDEBUG
01861 fprintf(stderr, "NETRootInfo::event: changeNumberOfDesktops(%ld)\n",
01862 event->xclient.data.l[0]);
01863 #endif
01864
01865 changeNumberOfDesktops(event->xclient.data.l[0]);
01866 } else if (event->xclient.message_type == net_desktop_geometry) {
01867 dirty = DesktopGeometry;
01868
01869 NETSize sz;
01870 sz.width = event->xclient.data.l[0];
01871 sz.height = event->xclient.data.l[1];
01872
01873 #ifdef NETWMDEBUG
01874 fprintf(stderr, "NETRootInfo::event: changeDesktopGeometry( -- , { %d, %d })\n",
01875 sz.width, sz.height);
01876 #endif
01877
01878 changeDesktopGeometry(~0, sz);
01879 } else if (event->xclient.message_type == net_desktop_viewport) {
01880 dirty = DesktopViewport;
01881
01882 NETPoint pt;
01883 pt.x = event->xclient.data.l[0];
01884 pt.y = event->xclient.data.l[1];
01885
01886 #ifdef NETWMDEBUG
01887 fprintf(stderr, "NETRootInfo::event: changeDesktopViewport(%d, { %d, %d })\n",
01888 p->current_desktop, pt.x, pt.y);
01889 #endif
01890
01891 changeDesktopViewport(p->current_desktop, pt);
01892 } else if (event->xclient.message_type == net_current_desktop) {
01893 dirty = CurrentDesktop;
01894
01895 #ifdef NETWMDEBUG
01896 fprintf(stderr, "NETRootInfo::event: changeCurrentDesktop(%ld)\n",
01897 event->xclient.data.l[0] + 1);
01898 #endif
01899
01900 changeCurrentDesktop(event->xclient.data.l[0] + 1);
01901 } else if (event->xclient.message_type == net_active_window) {
01902 dirty = ActiveWindow;
01903
01904 #ifdef NETWMDEBUG
01905 fprintf(stderr, "NETRootInfo::event: changeActiveWindow(0x%lx)\n",
01906 event->xclient.window);
01907 #endif
01908
01909 changeActiveWindow(event->xclient.window);
01910 if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
01911 {
01912 RequestSource src = FromUnknown;
01913 Time timestamp = CurrentTime;
01914 Window active_window = None;
01915
01916 if( event->xclient.data.l[0] >= FromUnknown
01917 && event->xclient.data.l[0] <= FromTool )
01918 {
01919 src = static_cast< RequestSource >( event->xclient.data.l[0] );
01920 timestamp = event->xclient.data.l[1];
01921 active_window = event->xclient.data.l[2];
01922 }
01923 this2->changeActiveWindow( event->xclient.window, src, timestamp, active_window );
01924 }
01925 } else if (event->xclient.message_type == net_wm_moveresize) {
01926
01927 #ifdef NETWMDEBUG
01928 fprintf(stderr, "NETRootInfo::event: moveResize(%ld, %ld, %ld, %ld)\n",
01929 event->xclient.window,
01930 event->xclient.data.l[0],
01931 event->xclient.data.l[1],
01932 event->xclient.data.l[2]
01933 );
01934 #endif
01935
01936 moveResize(event->xclient.window,
01937 event->xclient.data.l[0],
01938 event->xclient.data.l[1],
01939 event->xclient.data.l[2]);
01940 } else if (event->xclient.message_type == net_moveresize_window) {
01941
01942 #ifdef NETWMDEBUG
01943 fprintf(stderr, "NETRootInfo::event: moveResizeWindow(%ld, %ld, %ld, %ld, %ld, %ld)\n",
01944 event->xclient.window,
01945 event->xclient.data.l[0],
01946 event->xclient.data.l[1],
01947 event->xclient.data.l[2],
01948 event->xclient.data.l[3],
01949 event->xclient.data.l[4]
01950 );
01951 #endif
01952
01953 if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
01954 this2->moveResizeWindow(event->xclient.window,
01955 event->xclient.data.l[0],
01956 event->xclient.data.l[1],
01957 event->xclient.data.l[2],
01958 event->xclient.data.l[3],
01959 event->xclient.data.l[4]);
01960 } else if (event->xclient.message_type == net_close_window) {
01961
01962 #ifdef NETWMDEBUG
01963 fprintf(stderr, "NETRootInfo::event: closeWindow(0x%lx)\n",
01964 event->xclient.window);
01965 #endif
01966
01967 closeWindow(event->xclient.window);
01968 } else if (event->xclient.message_type == net_restack_window) {
01969
01970 #ifdef NETWMDEBUG
01971 fprintf(stderr, "NETRootInfo::event: restackWindow(0x%lx)\n",
01972 event->xclient.window);
01973 #endif
01974
01975 if( NETRootInfo3* this3 = dynamic_cast< NETRootInfo3* >( this ))
01976 {
01977 RequestSource src = FromUnknown;
01978 Time timestamp = CurrentTime;
01979
01980 if( event->xclient.data.l[0] >= FromUnknown
01981 && event->xclient.data.l[0] <= FromTool )
01982 {
01983 src = static_cast< RequestSource >( event->xclient.data.l[0] );
01984 timestamp = event->xclient.data.l[3];
01985 }
01986 this3->restackWindow(event->xclient.window, src,
01987 event->xclient.data.l[1], event->xclient.data.l[2], timestamp);
01988 }
01989 else if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
01990 this2->restackWindow(event->xclient.window,
01991 event->xclient.data.l[1], event->xclient.data.l[2]);
01992 } else if (event->xclient.message_type == wm_protocols
01993 && (Atom)event->xclient.data.l[ 0 ] == net_wm_ping) {
01994 dirty = WMPing;
01995
01996 #ifdef NETWMDEBUG
01997 fprintf(stderr, "NETRootInfo2::event: gotPing(0x%lx,%lu)\n",
01998 event->xclient.window, event->xclient.data.l[1]);
01999 #endif
02000 if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
02001 this2->gotPing( event->xclient.data.l[2], event->xclient.data.l[1]);
02002 } else if (event->xclient.message_type == wm_protocols
02003 && (Atom)event->xclient.data.l[ 0 ] == net_wm_take_activity) {
02004 dirty2 = WM2TakeActivity;
02005
02006 #ifdef NETWMDEBUG
02007 fprintf(stderr, "NETRootInfo2::event: gotTakeActivity(0x%lx,%lu,0x%lx)\n",
02008 event->xclient.window, event->xclient.data.l[1], event->xclient.data.l[3]);
02009 #endif
02010 if( NETRootInfo3* this3 = dynamic_cast< NETRootInfo3* >( this ))
02011 this3->gotTakeActivity( event->xclient.data.l[2], event->xclient.data.l[1],
02012 event->xclient.data.l[3]);
02013 } else if (event->xclient.message_type == net_showing_desktop) {
02014 dirty2 = WM2ShowingDesktop;
02015
02016 #ifdef NETWMDEBUG
02017 fprintf(stderr, "NETRootInfo::event: changeShowingDesktop(%ld)\n",
02018 event->xclient.data.l[0]);
02019 #endif
02020
02021 if( NETRootInfo4* this4 = dynamic_cast< NETRootInfo4* >( this ))
02022 this4->changeShowingDesktop(event->xclient.data.l[0]);
02023 }
02024 }
02025
02026 if (event->type == PropertyNotify) {
02027
02028 #ifdef NETWMDEBUG
02029 fprintf(stderr, "NETRootInfo::event: handling PropertyNotify event\n");
02030 #endif
02031
02032 XEvent pe = *event;
02033
02034 Bool done = False;
02035 Bool compaction = False;
02036 while (! done) {
02037
02038 #ifdef NETWMDEBUG
02039 fprintf(stderr, "NETRootInfo::event: loop fire\n");
02040 #endif
02041
02042 if (pe.xproperty.atom == net_client_list)
02043 dirty |= ClientList;
02044 else if (pe.xproperty.atom == net_client_list_stacking)
02045 dirty |= ClientListStacking;
02046 else if (pe.xproperty.atom == kde_net_system_tray_windows)
02047 dirty |= KDESystemTrayWindows;
02048 else if (pe.xproperty.atom == net_desktop_names)
02049 dirty |= DesktopNames;
02050 else if (pe.xproperty.atom == net_workarea)
02051 dirty |= WorkArea;
02052 else if (pe.xproperty.atom == net_number_of_desktops)
02053 dirty |= NumberOfDesktops;
02054 else if (pe.xproperty.atom == net_desktop_geometry)
02055 dirty |= DesktopGeometry;
02056 else if (pe.xproperty.atom == net_desktop_viewport)
02057 dirty |= DesktopViewport;
02058 else if (pe.xproperty.atom == net_current_desktop)
02059 dirty |= CurrentDesktop;
02060 else if (pe.xproperty.atom == net_active_window)
02061 dirty |= ActiveWindow;
02062 else if (pe.xproperty.atom == net_showing_desktop)
02063 dirty2 |= WM2ShowingDesktop;
02064 else {
02065
02066 #ifdef NETWMDEBUG
02067 fprintf(stderr, "NETRootInfo::event: putting back event and breaking\n");
02068 #endif
02069
02070 if ( compaction )
02071 XPutBackEvent(p->display, &pe);
02072 break;
02073 }
02074
02075 if (XCheckTypedWindowEvent(p->display, p->root, PropertyNotify, &pe) )
02076 compaction = True;
02077 else
02078 break;
02079 }
02080
02081 do_update = true;
02082 }
02083
02084 if( do_update )
02085 update( props );
02086
02087 #ifdef NETWMDEBUG
02088 fprintf(stderr, "NETRootInfo::event: handled events, returning dirty = 0x%lx, 0x%lx\n",
02089 dirty, dirty2);
02090 #endif
02091
02092 if( properties_size > PROPERTIES_SIZE )
02093 properties_size = PROPERTIES_SIZE;
02094 for( int i = 0;
02095 i < properties_size;
02096 ++i )
02097 properties[ i ] = props[ i ];
02098 }
02099
02100
02101
02102
02103 void NETRootInfo::update( const unsigned long dirty_props[] )
02104 {
02105 Atom type_ret;
02106 int format_ret;
02107 unsigned char *data_ret;
02108 unsigned long nitems_ret, unused;
02109 unsigned long props[ PROPERTIES_SIZE ];
02110 for( int i = 0;
02111 i < PROPERTIES_SIZE;
02112 ++i )
02113 props[ i ] = dirty_props[ i ] & p->client_properties[ i ];
02114 const unsigned long& dirty = props[ PROTOCOLS ];
02115 const unsigned long& dirty2 = props[ PROTOCOLS2 ];
02116
02117
02118
02119 if (dirty & Supported )
02120 KXAskWindowProperty(p->display, p->root, net_supported,
02121 0l, MAX_PROP_SIZE, False, XA_ATOM);
02122 if (dirty & ClientList)
02123 KXAskWindowProperty(p->display, p->root, net_client_list,
02124 0l, MAX_PROP_SIZE, False, XA_WINDOW);
02125 if (dirty & KDESystemTrayWindows)
02126 KXAskWindowProperty(p->display, p->root, kde_net_system_tray_windows,
02127 0l, MAX_PROP_SIZE, False, XA_WINDOW);
02128 if (dirty & ClientListStacking)
02129 KXAskWindowProperty(p->display, p->root, net_client_list_stacking,
02130 0, MAX_PROP_SIZE, False, XA_WINDOW);
02131 if (dirty & NumberOfDesktops)
02132 KXAskWindowProperty(p->display, p->root, net_number_of_desktops,
02133 0l, 1l, False, XA_CARDINAL);
02134 if (dirty & DesktopGeometry)
02135 KXAskWindowProperty(p->display, p->root, net_desktop_geometry,
02136 0l, 2l, False, XA_CARDINAL);
02137 if (dirty & DesktopViewport)
02138 KXAskWindowProperty(p->display, p->root, net_desktop_viewport,
02139 0l, 2l, False, XA_CARDINAL);
02140 if (dirty & CurrentDesktop)
02141 KXAskWindowProperty(p->display, p->root, net_current_desktop,
02142 0l, 1l, False, XA_CARDINAL);
02143 if (dirty & DesktopNames)
02144 KXAskWindowProperty(p->display, p->root, net_desktop_names,
02145 0l, MAX_PROP_SIZE, False, UTF8_STRING);
02146 if (dirty & ActiveWindow)
02147 KXAskWindowProperty(p->display, p->root, net_active_window, 0l, 1l,
02148 False, XA_WINDOW);
02149 if (dirty & WorkArea)
02150 KXAskWindowProperty(p->display, p->root, net_workarea, 0l,
02151 MAX_PROP_SIZE, False, XA_CARDINAL);
02152 if (dirty & SupportingWMCheck) {
02153 KXAskWindowProperty(p->display, p->root, net_supporting_wm_check,
02154 0l, 1l, False, XA_WINDOW);
02155
02156
02157 KXAskWindowProperty(p->display, p->supportwindow,
02158 net_wm_name, 0l, MAX_PROP_SIZE, False,
02159 UTF8_STRING);
02160 }
02161 if (dirty & VirtualRoots)
02162 KXAskWindowProperty(p->display, p->root, net_virtual_roots,
02163 0, MAX_PROP_SIZE, False, XA_WINDOW);
02164 if (dirty2 & WM2ShowingDesktop)
02165 KXAskWindowProperty(p->display, p->root, net_showing_desktop,
02166 0, MAX_PROP_SIZE, False, XA_CARDINAL);
02167
02168
02169
02170 if (dirty & Supported ) {
02171
02172 for( int i = 0; i < PROPERTIES_SIZE; ++i )
02173 p->properties[ i ] = 0;
02174 if( KXReceiveWindowProperty(p->display, p->root, net_supported,
02175 0l, MAX_PROP_SIZE, False, XA_ATOM, &type_ret,
02176 &format_ret, &nitems_ret, &unused, &data_ret)
02177 == Success ) {
02178 if( type_ret == XA_ATOM && format_ret == 32 ) {
02179 Atom* atoms = (Atom*) data_ret;
02180 for( unsigned int i = 0;
02181 i < nitems_ret;
02182 ++i )
02183 updateSupportedProperties( atoms[ i ] );
02184 }
02185 if ( data_ret )
02186 XFree(data_ret);
02187 }
02188 }
02189
02190 if (dirty & ClientList) {
02191 bool read_ok = false;
02192 if (KXReceiveWindowProperty(p->display, p->root, net_client_list,
02193 0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
02194 &format_ret, &nitems_ret, &unused, &data_ret)
02195 == Success) {
02196 if (type_ret == XA_WINDOW && format_ret == 32) {
02197 Window *wins = (Window *) data_ret;
02198
02199 qsort(wins, nitems_ret, sizeof(Window), wcmp);
02200
02201 if (p->clients) {
02202 if (role == Client) {
02203 unsigned long new_index = 0, old_index = 0;
02204 unsigned long new_count = nitems_ret,
02205 old_count = p->clients_count;
02206
02207 while (old_index < old_count || new_index < new_count) {
02208 if (old_index == old_count) {
02209 addClient(wins[new_index++]);
02210 } else if (new_index == new_count) {
02211 removeClient(p->clients[old_index++]);
02212 } else {
02213 if (p->clients[old_index] <
02214 wins[new_index]) {
02215 removeClient(p->clients[old_index++]);
02216 } else if (wins[new_index] <
02217 p->clients[old_index]) {
02218 addClient(wins[new_index++]);
02219 } else {
02220 new_index++;
02221 old_index++;
02222 }
02223 }
02224 }
02225 }
02226
02227 delete [] p->clients;
02228 } else {
02229 #ifdef NETWMDEBUG
02230 fprintf(stderr, "NETRootInfo::update: client list null, creating\n");
02231 #endif
02232
02233 unsigned long n;
02234 for (n = 0; n < nitems_ret; n++) {
02235 addClient(wins[n]);
02236 }
02237 }
02238
02239 p->clients_count = nitems_ret;
02240 p->clients = nwindup(wins, p->clients_count);
02241 read_ok = true;
02242 }
02243
02244 if ( data_ret )
02245 XFree(data_ret);
02246 }
02247 if( !read_ok ) {
02248 for( unsigned int i = 0; i < p->clients_count; ++ i )
02249 removeClient(p->clients[i]);
02250 p->clients_count = 0;
02251 delete[] p->clients;
02252 p->clients = NULL;
02253 }
02254
02255 #ifdef NETWMDEBUG
02256 fprintf(stderr, "NETRootInfo::update: client list updated (%ld clients)\n",
02257 p->clients_count);
02258 #endif
02259 }
02260
02261 if (dirty & KDESystemTrayWindows) {
02262 bool read_ok = false;
02263 if (KXReceiveWindowProperty(p->display, p->root, kde_net_system_tray_windows,
02264 0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
02265 &format_ret, &nitems_ret, &unused, &data_ret)
02266 == Success) {
02267 if (type_ret == XA_WINDOW && format_ret == 32) {
02268 Window *wins = (Window *) data_ret;
02269
02270 qsort(wins, nitems_ret, sizeof(Window), wcmp);
02271
02272 if (p->kde_system_tray_windows) {
02273 if (role == Client) {
02274 unsigned long new_index = 0, new_count = nitems_ret;
02275 unsigned long old_index = 0,
02276 old_count = p->kde_system_tray_windows_count;
02277
02278 while(old_index < old_count || new_index < new_count) {
02279 if (old_index == old_count) {
02280 addSystemTrayWin(wins[new_index++]);
02281 } else if (new_index == new_count) {
02282 removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
02283 } else {
02284 if (p->kde_system_tray_windows[old_index] <
02285 wins[new_index]) {
02286 removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
02287 } else if (wins[new_index] <
02288 p->kde_system_tray_windows[old_index]) {
02289 addSystemTrayWin(wins[new_index++]);
02290 } else {
02291 new_index++;
02292 old_index++;
02293 }
02294 }
02295 }
02296 }
02297
02298 } else {
02299 unsigned long n;
02300 for (n = 0; n < nitems_ret; n++) {
02301 addSystemTrayWin(wins[n]);
02302 }
02303 }
02304
02305 p->kde_system_tray_windows_count = nitems_ret;
02306 delete [] p->kde_system_tray_windows;
02307 p->kde_system_tray_windows =
02308 nwindup(wins, p->kde_system_tray_windows_count);
02309 read_ok = true;
02310 }
02311
02312 if ( data_ret )
02313 XFree(data_ret);
02314 }
02315 if( !read_ok ) {
02316 for( unsigned int i = 0; i < p->kde_system_tray_windows_count; ++i )
02317 removeSystemTrayWin(p->kde_system_tray_windows[i]);
02318 p->kde_system_tray_windows_count = 0;
02319 delete [] p->kde_system_tray_windows;
02320 p->kde_system_tray_windows = NULL;
02321 }
02322 }
02323
02324 if (dirty & ClientListStacking) {
02325 p->stacking_count = 0;
02326 delete[] p->stacking;
02327 p->stacking = NULL;
02328 if (KXReceiveWindowProperty(p->display, p->root, net_client_list_stacking,
02329 0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
02330 &format_ret, &nitems_ret, &unused, &data_ret)
02331 == Success) {
02332 if (type_ret == XA_WINDOW && format_ret == 32) {
02333 Window *wins = (Window *) data_ret;
02334
02335 p->stacking_count = nitems_ret;
02336 p->stacking = nwindup(wins, p->stacking_count);
02337 }
02338
02339 #ifdef NETWMDEBUG
02340 fprintf(stderr,"NETRootInfo::update: client stacking updated (%ld clients)\n",
02341 p->stacking_count);
02342 #endif
02343
02344 if ( data_ret )
02345 XFree(data_ret);
02346 }
02347 }
02348
02349 if (dirty & NumberOfDesktops) {
02350 p->number_of_desktops = 0;
02351
02352 if (KXReceiveWindowProperty(p->display, p->root, net_number_of_desktops,
02353 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
02354 &nitems_ret, &unused, &data_ret)
02355 == Success) {
02356 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
02357 p->number_of_desktops = *((long *) data_ret);
02358 }
02359
02360 #ifdef NETWMDEBUG
02361 fprintf(stderr, "NETRootInfo::update: number of desktops = %d\n",
02362 p->number_of_desktops);
02363 #endif
02364 if ( data_ret )
02365 XFree(data_ret);
02366 }
02367 }
02368
02369 if (dirty & DesktopGeometry) {
02370 p->geometry = p->rootSize;
02371 if (KXReceiveWindowProperty(p->display, p->root, net_desktop_geometry,
02372 0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
02373 &nitems_ret, &unused, &data_ret)
02374 == Success) {
02375 if (type_ret == XA_CARDINAL && format_ret == 32 &&
02376 nitems_ret == 2) {
02377 long *data = (long *) data_ret;
02378
02379 p->geometry.width = data[0];
02380 p->geometry.height = data[1];
02381
02382 #ifdef NETWMDEBUG
02383 fprintf(stderr, "NETRootInfo::update: desktop geometry updated\n");
02384 #endif
02385 }
02386 if ( data_ret )
02387 XFree(data_ret);
02388 }
02389 }
02390
02391 if (dirty & DesktopViewport) {
02392 for (int i = 0; i < p->viewport.size(); i++)
02393 p->viewport[i].x = p->viewport[i].y = 0;
02394 if (KXReceiveWindowProperty(p->display, p->root, net_desktop_viewport,
02395 0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
02396 &nitems_ret, &unused, &data_ret)
02397 == Success) {
02398 if (type_ret == XA_CARDINAL && format_ret == 32 &&
02399 nitems_ret == 2) {
02400 long *data = (long *) data_ret;
02401
02402 int d, i, n;
02403 n = nitems_ret / 2;
02404 for (d = 0, i = 0; d < n; d++) {
02405 p->viewport[d].x = data[i++];
02406 p->viewport[d].y = data[i++];
02407 }
02408
02409 #ifdef NETWMDEBUG
02410 fprintf(stderr,
02411 "NETRootInfo::update: desktop viewport array updated (%d entries)\n",
02412 p->viewport.size());
02413
02414 if (nitems_ret % 2 != 0) {
02415 fprintf(stderr,
02416 "NETRootInfo::update(): desktop viewport array "
02417 "size not a multiple of 2\n");
02418 }
02419 #endif
02420 }
02421 if ( data_ret )
02422 XFree(data_ret);
02423 }
02424 }
02425
02426 if (dirty & CurrentDesktop) {
02427 p->current_desktop = 0;
02428 if (KXReceiveWindowProperty(p->display, p->root, net_current_desktop,
02429 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
02430 &nitems_ret, &unused, &data_ret)
02431 == Success) {
02432 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
02433 p->current_desktop = *((long *) data_ret) + 1;
02434 }
02435
02436 #ifdef NETWMDEBUG
02437 fprintf(stderr, "NETRootInfo::update: current desktop = %d\n",
02438 p->current_desktop);
02439 #endif
02440 if ( data_ret )
02441 XFree(data_ret);
02442 }
02443 }
02444
02445 if (dirty & DesktopNames) {
02446 for( int i = 0; i < p->desktop_names.size(); ++i )
02447 delete[] p->desktop_names[ i ];
02448 p->desktop_names.reset();
02449 if (KXReceiveWindowProperty(p->display, p->root, net_desktop_names,
02450 0l, MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
02451 &format_ret, &nitems_ret, &unused, &data_ret)
02452 == Success) {
02453 if (type_ret == UTF8_STRING && format_ret == 8) {
02454 const char *d = (const char *) data_ret;
02455 unsigned int s, n, index;
02456
02457 for (s = 0, n = 0, index = 0; n < nitems_ret; n++) {
02458 if (d[n] == '\0') {
02459 delete [] p->desktop_names[index];
02460 p->desktop_names[index++] = nstrndup((d + s), n - s + 1);
02461 s = n + 1;
02462 }
02463 }
02464 }
02465
02466 #ifdef NETWMDEBUG
02467 fprintf(stderr, "NETRootInfo::update: desktop names array updated (%d entries)\n",
02468 p->desktop_names.size());
02469 #endif
02470 if ( data_ret )
02471 XFree(data_ret);
02472 }
02473 }
02474
02475 if (dirty & ActiveWindow) {
02476 p->active = None;
02477 if (KXReceiveWindowProperty(p->display, p->root, net_active_window, 0l, 1l,
02478 False, XA_WINDOW, &type_ret, &format_ret,
02479 &nitems_ret, &unused, &data_ret)
02480 == Success) {
02481 if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
02482 p->active = *((Window *) data_ret);
02483 }
02484
02485 #ifdef NETWMDEBUG
02486 fprintf(stderr, "NETRootInfo::update: active window = 0x%lx\n",
02487 p->active);
02488 #endif
02489 if ( data_ret )
02490 XFree(data_ret);
02491 }
02492 }
02493
02494 if (dirty & WorkArea) {
02495 p->workarea.reset();
02496 if (KXReceiveWindowProperty(p->display, p->root, net_workarea, 0l,
02497 MAX_PROP_SIZE, False, XA_CARDINAL,
02498 &type_ret, &format_ret, &nitems_ret, &unused,
02499 &data_ret)
02500 == Success) {
02501 if (type_ret == XA_CARDINAL && format_ret == 32 &&
02502 nitems_ret == (unsigned) (p->number_of_desktops * 4)) {
02503 long *d = (long *) data_ret;
02504 int i, j;
02505 for (i = 0, j = 0; i < p->number_of_desktops; i++) {
02506 p->workarea[i].pos.x = d[j++];
02507 p->workarea[i].pos.y = d[j++];
02508 p->workarea[i].size.width = d[j++];
02509 p->workarea[i].size.height = d[j++];
02510 }
02511 }
02512
02513 #ifdef NETWMDEBUG
02514 fprintf(stderr, "NETRootInfo::update: work area array updated (%d entries)\n",
02515 p->workarea.size());
02516 #endif
02517 if ( data_ret )
02518 XFree(data_ret);
02519 }
02520 }
02521
02522
02523 if (dirty & SupportingWMCheck) {
02524 p->supportwindow = None;
02525 delete[] p->name;
02526 p->name = NULL;
02527 bool was_2nd_read = false;
02528 if (KXReceiveWindowProperty(p->display, p->root, net_supporting_wm_check,
02529 0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
02530 &nitems_ret, &unused, &data_ret)
02531 == Success) {
02532 if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
02533 p->supportwindow = *((Window *) data_ret);
02534
02535 unsigned char *name_ret;
02536 was_2nd_read = true;
02537 if (KXReceiveWindowProperty(p->display, p->supportwindow,
02538 net_wm_name, 0l, MAX_PROP_SIZE, False,
02539 UTF8_STRING, &type_ret, &format_ret,
02540 &nitems_ret, &unused, &name_ret)
02541 == Success) {
02542 if (type_ret == UTF8_STRING && format_ret == 8)
02543 p->name = nstrndup((const char *) name_ret, nitems_ret);
02544
02545 if ( name_ret )
02546 XFree(name_ret);
02547 }
02548 }
02549
02550 #ifdef NETWMDEBUG
02551 fprintf(stderr,
02552 "NETRootInfo::update: supporting window manager = '%s'\n",
02553 p->name);
02554 #endif
02555 if ( data_ret )
02556 XFree(data_ret);
02557 }
02558 if( !was_2nd_read ) {
02559 unsigned char *name_ret;
02560 if( KXReceiveWindowProperty(p->display, p->supportwindow,
02561 net_wm_name, 0l, MAX_PROP_SIZE, False,
02562 UTF8_STRING, &type_ret, &format_ret,
02563 &nitems_ret, &unused, &name_ret) == Success
02564 && name_ret )
02565 XFree( name_ret );
02566 }
02567 }
02568
02569 if (dirty & VirtualRoots) {
02570 p->virtual_roots_count = 0;
02571 delete[] p->virtual_roots;
02572 p->virtual_roots = NULL;
02573 if (KXReceiveWindowProperty(p->display, p->root, net_virtual_roots,
02574 0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
02575 &format_ret, &nitems_ret, &unused, &data_ret)
02576 == Success) {
02577 if (type_ret == XA_WINDOW && format_ret == 32) {
02578 Window *wins = (Window *) data_ret;
02579
02580 p->virtual_roots_count = nitems_ret;
02581 p->virtual_roots = nwindup(wins, p->virtual_roots_count);
02582 }
02583
02584 #ifdef NETWMDEBUG
02585 fprintf(stderr, "NETRootInfo::updated: virtual roots updated (%ld windows)\n",
02586 p->virtual_roots_count);
02587 #endif
02588 if ( data_ret )
02589 XFree(data_ret);
02590 }
02591 }
02592
02593 if (dirty2 & WM2ShowingDesktop) {
02594 p->showing_desktop = false;
02595 if (KXReceiveWindowProperty(p->display, p->root, net_showing_desktop,
02596 0, MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
02597 &format_ret, &nitems_ret, &unused, &data_ret)
02598 == Success) {
02599 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
02600 p->showing_desktop = *((long *) data_ret);
02601 }
02602
02603 #ifdef NETWMDEBUG
02604 fprintf(stderr, "NETRootInfo::update: showing desktop = %d\n",
02605 p->showing_desktop);
02606 #endif
02607 if ( data_ret )
02608 XFree(data_ret);
02609 }
02610 }
02611 }
02612
02613
02614 Display *NETRootInfo::x11Display() const {
02615 return p->display;
02616 }
02617
02618
02619 Window NETRootInfo::rootWindow() const {
02620 return p->root;
02621 }
02622
02623
02624 Window NETRootInfo::supportWindow() const {
02625 return p->supportwindow;
02626 }
02627
02628
02629 const char *NETRootInfo::wmName() const {
02630 return p->name; }
02631
02632
02633 int NETRootInfo::screenNumber() const {
02634 return p->screen;
02635 }
02636
02637
02638 unsigned long NETRootInfo::supported() const {
02639 return role == WindowManager
02640 ? p->properties[ PROTOCOLS ]
02641 : p->client_properties[ PROTOCOLS ];
02642 }
02643
02644 const unsigned long* NETRootInfo::supportedProperties() const {
02645 return p->properties;
02646 }
02647
02648 const unsigned long* NETRootInfo::passedProperties() const {
02649 return role == WindowManager
02650 ? p->properties
02651 : p->client_properties;
02652 }
02653
02654 bool NETRootInfo::isSupported( NET::Property property ) const {
02655 return p->properties[ PROTOCOLS ] & property;
02656 }
02657
02658 bool NETRootInfo::isSupported( NET::Property2 property ) const {
02659 return p->properties[ PROTOCOLS2 ] & property;
02660 }
02661
02662 bool NETRootInfo::isSupported( NET::WindowType type ) const {
02663 return p->properties[ WINDOW_TYPES ] & type;
02664 }
02665
02666 bool NETRootInfo::isSupported( NET::State state ) const {
02667 return p->properties[ STATES ] & state;
02668 }
02669
02670 bool NETRootInfo::isSupported( NET::Action action ) const {
02671 return p->properties[ ACTIONS ] & action;
02672 }
02673
02674 const Window *NETRootInfo::clientList() const {
02675 return p->clients;
02676 }
02677
02678
02679 int NETRootInfo::clientListCount() const {
02680 return p->clients_count;
02681 }
02682
02683
02684 const Window *NETRootInfo::clientListStacking() const {
02685 return p->stacking;
02686 }
02687
02688
02689 int NETRootInfo::clientListStackingCount() const {
02690 return p->stacking_count;
02691 }
02692
02693
02694 const Window *NETRootInfo::kdeSystemTrayWindows() const {
02695 return p->kde_system_tray_windows;
02696 }
02697
02698
02699 int NETRootInfo::kdeSystemTrayWindowsCount() const {
02700 return p->kde_system_tray_windows_count;
02701 }
02702
02703
02704 NETSize NETRootInfo::desktopGeometry(int) const {
02705 return p->geometry.width != 0 ? p->geometry : p->rootSize;
02706 }
02707
02708
02709 NETPoint NETRootInfo::desktopViewport(int desktop) const {
02710 if (desktop < 1) {
02711 NETPoint pt;
02712 return pt;
02713 }
02714
02715 return p->viewport[desktop - 1];
02716 }
02717
02718
02719 NETRect NETRootInfo::workArea(int desktop) const {
02720 if (desktop < 1) {
02721 NETRect rt;
02722 return rt;
02723 }
02724
02725 return p->workarea[desktop - 1];
02726 }
02727
02728
02729 const char *NETRootInfo::desktopName(int desktop) const {
02730 if (desktop < 1) {
02731 return 0;
02732 }
02733
02734 return p->desktop_names[desktop - 1];
02735 }
02736
02737
02738 const Window *NETRootInfo::virtualRoots( ) const {
02739 return p->virtual_roots;
02740 }
02741
02742
02743 int NETRootInfo::virtualRootsCount() const {
02744 return p->virtual_roots_count;
02745 }
02746
02747
02748 int NETRootInfo::numberOfDesktops() const {
02749 return p->number_of_desktops == 0 ? 1 : p->number_of_desktops;
02750 }
02751
02752
02753 int NETRootInfo::currentDesktop() const {
02754 return p->current_desktop == 0 ? 1 : p->current_desktop;
02755 }
02756
02757
02758 Window NETRootInfo::activeWindow() const {
02759 return p->active;
02760 }
02761
02762
02763
02764
02765 const int NETWinInfo::OnAllDesktops = NET::OnAllDesktops;
02766
02767 NETWinInfo::NETWinInfo(Display *display, Window window, Window rootWindow,
02768 const unsigned long properties[], int properties_size,
02769 Role role)
02770 {
02771
02772 #ifdef NETWMDEBUG
02773 fprintf(stderr, "NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
02774 (role == WindowManager) ? "WindowManager" : "Client");
02775 #endif
02776
02777 p = new NETWinInfoPrivate;
02778 p->ref = 1;
02779
02780 p->display = display;
02781 p->window = window;
02782 p->root = rootWindow;
02783 p->mapping_state = Withdrawn;
02784 p->mapping_state_dirty = True;
02785 p->state = 0;
02786 p->types[ 0 ] = Unknown;
02787 p->name = (char *) 0;
02788 p->visible_name = (char *) 0;
02789 p->icon_name = (char *) 0;
02790 p->visible_icon_name = (char *) 0;
02791 p->desktop = p->pid = p->handled_icons = 0;
02792 p->user_time = -1U;
02793 p->startup_id = NULL;
02794 p->transient_for = None;
02795 p->window_group = None;
02796 p->allowed_actions = 0;
02797 p->has_net_support = false;
02798 p->class_class = (char*) 0;
02799 p->class_name = (char*) 0;
02800 p->role = (char*) 0;
02801 p->client_machine = (char*) 0;
02802
02803
02804
02805
02806
02807 p->kde_system_tray_win_for = 0;
02808
02809 for( int i = 0;
02810 i < PROPERTIES_SIZE;
02811 ++i )
02812 p->properties[ i ] = 0;
02813 if( properties_size > PROPERTIES_SIZE )
02814 properties_size = PROPERTIES_SIZE;
02815 for( int i = 0;
02816 i < properties_size;
02817 ++i )
02818 p->properties[ i ] = properties[ i ];
02819
02820 p->icon_count = 0;
02821
02822 this->role = role;
02823
02824 if (! netwm_atoms_created) create_atoms(p->display);
02825
02826 update(p->properties);
02827 }
02828
02829
02830 NETWinInfo::NETWinInfo(Display *display, Window window, Window rootWindow,
02831 unsigned long properties, Role role)
02832 {
02833
02834 #ifdef NETWMDEBUG
02835 fprintf(stderr, "NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
02836 (role == WindowManager) ? "WindowManager" : "Client");
02837 #endif
02838
02839 p = new NETWinInfoPrivate;
02840 p->ref = 1;
02841
02842 p->display = display;
02843 p->window = window;
02844 p->root = rootWindow;
02845 p->mapping_state = Withdrawn;
02846 p->mapping_state_dirty = True;
02847 p->state = 0;
02848 p->types[ 0 ] = Unknown;
02849 p->name = (char *) 0;
02850 p->visible_name = (char *) 0;
02851 p->icon_name = (char *) 0;
02852 p->visible_icon_name = (char *) 0;
02853 p->desktop = p->pid = p->handled_icons = 0;
02854 p->user_time = -1U;
02855 p->startup_id = NULL;
02856 p->transient_for = None;
02857 p->window_group = None;
02858 p->allowed_actions = 0;
02859 p->has_net_support = false;
02860 p->class_class = (char*) 0;
02861 p->class_name = (char*) 0;
02862 p->role = (char*) 0;
02863 p->client_machine = (char*) 0;
02864
02865
02866
02867
02868
02869 p->kde_system_tray_win_for = 0;
02870
02871 for( int i = 0;
02872 i < PROPERTIES_SIZE;
02873 ++i )
02874 p->properties[ i ] = 0;
02875 p->properties[ PROTOCOLS ] = properties;
02876
02877 p->icon_count = 0;
02878
02879 this->role = role;
02880
02881 if (! netwm_atoms_created) create_atoms(p->display);
02882
02883 update(p->properties);
02884 }
02885
02886
02887 NETWinInfo::NETWinInfo(const NETWinInfo &wininfo) {
02888 p = wininfo.p;
02889 p->ref++;
02890 }
02891
02892
02893 NETWinInfo::~NETWinInfo() {
02894 refdec_nwi(p);
02895
02896 if (! p->ref) delete p;
02897 }
02898
02899
02900
02901
02902 const NETWinInfo &NETWinInfo::operator=(const NETWinInfo &wininfo) {
02903
02904 #ifdef NETWMDEBUG
02905 fprintf(stderr, "NETWinInfo::operator=()\n");
02906 #endif
02907
02908 if (p != wininfo.p) {
02909 refdec_nwi(p);
02910
02911 if (! p->ref) delete p;
02912 }
02913
02914 p = wininfo.p;
02915 role = wininfo.role;
02916 p->ref++;
02917
02918 return *this;
02919 }
02920
02921
02922 void NETWinInfo::setIcon(NETIcon icon, Bool replace) {
02923 setIconInternal( p->icons, p->icon_count, net_wm_icon, icon, replace );
02924 }
02925
02926 void NETWinInfo::setIconInternal(NETRArray<NETIcon>& icons, int& icon_count, Atom property, NETIcon icon, Bool replace) {
02927 if (role != Client) return;
02928
02929 int proplen, i, sz, j;
02930
02931 if (replace) {
02932
02933 for (i = 0; i < icons.size(); i++) {
02934 delete [] icons[i].data;
02935 icons[i].data = 0;
02936 icons[i].size.width = 0;
02937 icons[i].size.height = 0;
02938 }
02939
02940 icon_count = 0;
02941 }
02942
02943
02944 icons[icon_count] = icon;
02945 icon_count++;
02946
02947
02948 NETIcon &ni = icons[icon_count - 1];
02949 sz = ni.size.width * ni.size.height;
02950 CARD32 *d = new CARD32[sz];
02951 ni.data = (unsigned char *) d;
02952 memcpy(d, icon.data, sz * sizeof(CARD32));
02953
02954
02955 for (i = 0, proplen = 0; i < icon_count; i++) {
02956 proplen += 2 + (icons[i].size.width *
02957 icons[i].size.height);
02958 }
02959
02960 CARD32 *d32;
02961 long *prop = new long[proplen], *pprop = prop;
02962 for (i = 0; i < icon_count; i++) {
02963
02964 *pprop++ = icons[i].size.width;
02965 *pprop++ = icons[i].size.height;
02966
02967
02968 sz = (icons[i].size.width * icons[i].size.height);
02969 d32 = (CARD32 *) icons[i].data;
02970 for (j = 0; j < sz; j++) *pprop++ = *d32++;
02971 }
02972
02973 XChangeProperty(p->display, p->window, property, XA_CARDINAL, 32,
02974 PropModeReplace, (unsigned char *) prop, proplen);
02975
02976 delete [] prop;
02977 }
02978
02979
02980 void NETWinInfo::setIconGeometry(NETRect geometry) {
02981 if (role != Client) return;
02982
02983 p->icon_geom = geometry;
02984
02985 if( geometry.size.width == 0 )
02986 XDeleteProperty(p->display, p->window, net_wm_icon_geometry);
02987 else {
02988 long data[4];
02989 data[0] = geometry.pos.x;
02990 data[1] = geometry.pos.y;
02991 data[2] = geometry.size.width;
02992 data[3] = geometry.size.height;
02993
02994 XChangeProperty(p->display, p->window, net_wm_icon_geometry, XA_CARDINAL,
02995 32, PropModeReplace, (unsigned char *) data, 4);
02996 }
02997 }
02998
02999
03000 void NETWinInfo::setExtendedStrut(const NETExtendedStrut& extended_strut ) {
03001 if (role != Client) return;
03002
03003 p->extended_strut = extended_strut;
03004
03005 long data[12];
03006 data[0] = extended_strut.left_width;
03007 data[1] = extended_strut.right_width;
03008 data[2] = extended_strut.top_width;
03009 data[3] = extended_strut.bottom_width;
03010 data[4] = extended_strut.left_start;
03011 data[5] = extended_strut.left_end;
03012 data[6] = extended_strut.right_start;
03013 data[7] = extended_strut.right_end;
03014 data[8] = extended_strut.top_start;
03015 data[9] = extended_strut.top_end;
03016 data[10] = extended_strut.bottom_start;
03017 data[11] = extended_strut.bottom_end;
03018
03019 XChangeProperty(p->display, p->window, net_wm_extended_strut, XA_CARDINAL, 32,
03020 PropModeReplace, (unsigned char *) data, 12);
03021 }
03022
03023
03024 void NETWinInfo::setStrut(NETStrut strut) {
03025 if (role != Client) return;
03026
03027 p->strut = strut;
03028
03029 long data[4];
03030 data[0] = strut.left;
03031 data[1] = strut.right;
03032 data[2] = strut.top;
03033 data[3] = strut.bottom;
03034
03035 XChangeProperty(p->display, p->window, net_wm_strut, XA_CARDINAL, 32,
03036 PropModeReplace, (unsigned char *) data, 4);
03037 }
03038
03039
03040 void NETWinInfo::setState(unsigned long state, unsigned long mask) {
03041 if (p->mapping_state_dirty)
03042 updateWMState();
03043
03044
03045 if( ( p->properties[ PROTOCOLS ] & WMState ) == 0 ) {
03046 p->properties[ PROTOCOLS ] |= WMState;
03047 unsigned long props[ PROPERTIES_SIZE ] = { WMState, 0 };
03048 assert( PROPERTIES_SIZE == 2 );
03049 update( props );
03050 p->properties[ PROTOCOLS ] &= ~WMState;
03051 }
03052
03053 if (role == Client && p->mapping_state != Withdrawn) {
03054
03055 #ifdef NETWMDEBUG
03056 fprintf(stderr, "NETWinInfo::setState (0x%lx, 0x%lx) (Client)\n",
03057 state, mask);
03058 #endif // NETWMDEBUG
03059
03060 XEvent e;
03061 e.xclient.type = ClientMessage;
03062 e.xclient.message_type = net_wm_state;
03063 e.xclient.display = p->display;
03064 e.xclient.window = p->window;
03065 e.xclient.format = 32;
03066 e.xclient.data.l[3] = 0l;
03067 e.xclient.data.l[4] = 0l;
03068
03069 if ((mask & Modal) && ((p->state & Modal) != (state & Modal))) {
03070 e.xclient.data.l[0] = (state & Modal) ? 1 : 0;
03071 e.xclient.data.l[1] = net_wm_state_modal;
03072 e.xclient.data.l[2] = 0l;
03073
03074 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03075 }
03076
03077 if ((mask & Sticky) && ((p->state & Sticky) != (state & Sticky))) {
03078 e.xclient.data.l[0] = (state & Sticky) ? 1 : 0;
03079 e.xclient.data.l[1] = net_wm_state_sticky;
03080 e.xclient.data.l[2] = 0l;
03081
03082 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03083 }
03084
03085 if ((mask & Max) && (( (p->state&mask) & Max) != (state & Max))) {
03086
03087 unsigned long wishstate = (p->state & ~mask) | (state & mask);
03088 if ( ( (wishstate & MaxHoriz) != (p->state & MaxHoriz) )
03089 && ( (wishstate & MaxVert) != (p->state & MaxVert) ) ) {
03090 if ( (wishstate & Max) == Max ) {
03091 e.xclient.data.l[0] = 1;
03092 e.xclient.data.l[1] = net_wm_state_max_horiz;
03093 e.xclient.data.l[2] = net_wm_state_max_vert;
03094 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03095 } else if ( (wishstate & Max) == 0 ) {
03096 e.xclient.data.l[0] = 0;
03097 e.xclient.data.l[1] = net_wm_state_max_horiz;
03098 e.xclient.data.l[2] = net_wm_state_max_vert;
03099 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03100 } else {
03101 e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
03102 e.xclient.data.l[1] = net_wm_state_max_horiz;
03103 e.xclient.data.l[2] = 0;
03104 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03105 e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
03106 e.xclient.data.l[1] = net_wm_state_max_vert;
03107 e.xclient.data.l[2] = 0;
03108 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03109 }
03110 } else if ( (wishstate & MaxVert) != (p->state & MaxVert) ) {
03111 e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
03112 e.xclient.data.l[1] = net_wm_state_max_vert;
03113 e.xclient.data.l[2] = 0;
03114 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03115 } else if ( (wishstate & MaxHoriz) != (p->state & MaxHoriz) ) {
03116 e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
03117 e.xclient.data.l[1] = net_wm_state_max_horiz;
03118 e.xclient.data.l[2] = 0;
03119 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03120 }
03121 }
03122
03123 if ((mask & Shaded) && ((p->state & Shaded) != (state & Shaded))) {
03124 e.xclient.data.l[0] = (state & Shaded) ? 1 : 0;
03125 e.xclient.data.l[1] = net_wm_state_shaded;
03126 e.xclient.data.l[2] = 0l;
03127
03128 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03129 }
03130
03131 if ((mask & SkipTaskbar) &&
03132 ((p->state & SkipTaskbar) != (state & SkipTaskbar))) {
03133 e.xclient.data.l[0] = (state & SkipTaskbar) ? 1 : 0;
03134 e.xclient.data.l[1] = net_wm_state_skip_taskbar;
03135 e.xclient.data.l[2] = 0l;
03136
03137 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03138 }
03139
03140 if ((mask & SkipPager) &&
03141 ((p->state & SkipPager) != (state & SkipPager))) {
03142 e.xclient.data.l[0] = (state & SkipPager) ? 1 : 0;
03143 e.xclient.data.l[1] = net_wm_state_skip_pager;
03144 e.xclient.data.l[2] = 0l;
03145
03146 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03147 }
03148
03149 if ((mask & Hidden) &&
03150 ((p->state & Hidden) != (state & Hidden))) {
03151 e.xclient.data.l[0] = (state & Hidden) ? 1 : 0;
03152 e.xclient.data.l[1] = net_wm_state_hidden;
03153 e.xclient.data.l[2] = 0l;
03154
03155 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03156 }
03157
03158 if ((mask & FullScreen) &&
03159 ((p->state & FullScreen) != (state & FullScreen))) {
03160 e.xclient.data.l[0] = (state & FullScreen) ? 1 : 0;
03161 e.xclient.data.l[1] = net_wm_state_fullscreen;
03162 e.xclient.data.l[2] = 0l;
03163
03164 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03165 }
03166
03167 if ((mask & KeepAbove) &&
03168 ((p->state & KeepAbove) != (state & KeepAbove))) {
03169 e.xclient.data.l[0] = (state & KeepAbove) ? 1 : 0;
03170 e.xclient.data.l[1] = net_wm_state_above;
03171 e.xclient.data.l[2] = 0l;
03172
03173 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03174 }
03175
03176 if ((mask & KeepBelow) &&
03177 ((p->state & KeepBelow) != (state & KeepBelow))) {
03178 e.xclient.data.l[0] = (state & KeepBelow) ? 1 : 0;
03179 e.xclient.data.l[1] = net_wm_state_below;
03180 e.xclient.data.l[2] = 0l;
03181
03182 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03183 }
03184
03185 if ((mask & StaysOnTop) && ((p->state & StaysOnTop) != (state & StaysOnTop))) {
03186 e.xclient.data.l[0] = (state & StaysOnTop) ? 1 : 0;
03187 e.xclient.data.l[1] = net_wm_state_stays_on_top;
03188 e.xclient.data.l[2] = 0l;
03189
03190 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03191 }
03192
03193 if ((mask & DemandsAttention) &&
03194 ((p->state & DemandsAttention) != (state & DemandsAttention))) {
03195 e.xclient.data.l[0] = (state & DemandsAttention) ? 1 : 0;
03196 e.xclient.data.l[1] = net_wm_state_demands_attention;
03197 e.xclient.data.l[2] = 0l;
03198
03199 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03200 }
03201
03202 } else {
03203 p->state &= ~mask;
03204 p->state |= state;
03205
03206 long data[50];
03207 int count = 0;
03208
03209
03210 if (p->state & Modal) data[count++] = net_wm_state_modal;
03211 if (p->state & MaxVert) data[count++] = net_wm_state_max_vert;
03212 if (p->state & MaxHoriz) data[count++] = net_wm_state_max_horiz;
03213 if (p->state & Shaded) data[count++] = net_wm_state_shaded;
03214 if (p->state & Hidden) data[count++] = net_wm_state_hidden;
03215 if (p->state & FullScreen) data[count++] = net_wm_state_fullscreen;
03216 if (p->state & DemandsAttention) data[count++] = net_wm_state_demands_attention;
03217
03218
03219 if (p->state & KeepAbove) data[count++] = net_wm_state_above;
03220 if (p->state & KeepBelow) data[count++] = net_wm_state_below;
03221 if (p->state & StaysOnTop) data[count++] = net_wm_state_stays_on_top;
03222 if (p->state & Sticky) data[count++] = net_wm_state_sticky;
03223 if (p->state & SkipTaskbar) data[count++] = net_wm_state_skip_taskbar;
03224 if (p->state & SkipPager) data[count++] = net_wm_state_skip_pager;
03225
03226 #ifdef NETWMDEBUG
03227 fprintf(stderr, "NETWinInfo::setState: setting state property (%d)\n", count);
03228 for (int i = 0; i < count; i++) {
03229 char* data_ret = XGetAtomName(p->display, (Atom) data[i]);
03230 fprintf(stderr, "NETWinInfo::setState: state %ld '%s'\n",
03231 data[i], data_ret);
03232 if ( data_ret )
03233 XFree( data_ret );
03234 }
03235
03236 #endif
03237
03238 XChangeProperty(p->display, p->window, net_wm_state, XA_ATOM, 32,
03239 PropModeReplace, (unsigned char *) data, count);
03240 }
03241 }
03242
03243
03244 void NETWinInfo::setWindowType(WindowType type) {
03245 if (role != Client) return;
03246
03247 int len;
03248 long data[2];
03249
03250 switch (type) {
03251 case Override:
03252
03253
03254 data[0] = kde_net_wm_window_type_override;
03255 data[1] = net_wm_window_type_normal;
03256 len = 2;
03257 break;
03258
03259 case Dialog:
03260 data[0] = net_wm_window_type_dialog;
03261 data[1] = None;
03262 len = 1;
03263 break;
03264
03265 case Menu:
03266 data[0] = net_wm_window_type_menu;
03267 data[1] = None;
03268 len = 1;
03269 break;
03270
03271 case TopMenu:
03272
03273
03274 data[0] = kde_net_wm_window_type_topmenu;
03275 data[1] = net_wm_window_type_dock;
03276 len = 2;
03277 break;
03278
03279 case Tool:
03280 data[0] = net_wm_window_type_toolbar;
03281 data[1] = None;
03282 len = 1;
03283 break;
03284
03285 case Dock:
03286 data[0] = net_wm_window_type_dock;
03287 data[1] = None;
03288 len = 1;
03289 break;
03290
03291 case Desktop:
03292 data[0] = net_wm_window_type_desktop;
03293 data[1] = None;
03294 len = 1;
03295 break;
03296
03297 case Utility:
03298 data[0] = net_wm_window_type_utility;
03299 data[1] = net_wm_window_type_dialog;
03300 len = 2;
03301 break;
03302
03303 case Splash:
03304 data[0] = net_wm_window_type_splash;
03305 data[1] = net_wm_window_type_dock;
03306 len = 2;
03307 break;
03308
03309 default:
03310 case Normal:
03311 data[0] = net_wm_window_type_normal;
03312 data[1] = None;
03313 len = 1;
03314 break;
03315 }
03316
03317 XChangeProperty(p->display, p->window, net_wm_window_type, XA_ATOM, 32,
03318 PropModeReplace, (unsigned char *) &data, len);
03319 }
03320
03321
03322 void NETWinInfo::setName(const char *name) {
03323 if (role != Client) return;
03324
03325 delete [] p->name;
03326 p->name = nstrdup(name);
03327 if( p->name[ 0 ] != '\0' )
03328 XChangeProperty(p->display, p->window, net_wm_name, UTF8_STRING, 8,
03329 PropModeReplace, (unsigned char *) p->name,
03330 strlen(p->name));
03331 else
03332 XDeleteProperty(p->display, p->window, net_wm_name);
03333 }
03334
03335
03336 void NETWinInfo::setVisibleName(const char *visibleName) {
03337 if (role != WindowManager) return;
03338
03339 delete [] p->visible_name;
03340 p->visible_name = nstrdup(visibleName);
03341 if( p->visible_name[ 0 ] != '\0' )
03342 XChangeProperty(p->display, p->window, net_wm_visible_name, UTF8_STRING, 8,
03343 PropModeReplace, (unsigned char *) p->visible_name,
03344 strlen(p->visible_name));
03345 else
03346 XDeleteProperty(p->display, p->window, net_wm_visible_name);
03347 }
03348
03349
03350 void NETWinInfo::setIconName(const char *iconName) {
03351 if (role != Client) return;
03352
03353 delete [] p->icon_name;
03354 p->icon_name = nstrdup(iconName);
03355 if( p->icon_name[ 0 ] != '\0' )
03356 XChangeProperty(p->display, p->window, net_wm_icon_name, UTF8_STRING, 8,
03357 PropModeReplace, (unsigned char *) p->icon_name,
03358 strlen(p->icon_name));
03359 else
03360 XDeleteProperty(p->display, p->window, net_wm_icon_name);
03361 }
03362
03363
03364 void NETWinInfo::setVisibleIconName(const char *visibleIconName) {
03365 if (role != WindowManager) return;
03366
03367 delete [] p->visible_icon_name;
03368 p->visible_icon_name = nstrdup(visibleIconName);
03369 if( p->visible_icon_name[ 0 ] != '\0' )
03370 XChangeProperty(p->display, p->window, net_wm_visible_icon_name, UTF8_STRING, 8,
03371 PropModeReplace, (unsigned char *) p->visible_icon_name,
03372 strlen(p->visible_icon_name));
03373 else
03374 XDeleteProperty(p->display, p->window, net_wm_visible_icon_name);
03375 }
03376
03377
03378 void NETWinInfo::setDesktop(int desktop) {
03379 if (p->mapping_state_dirty)
03380 updateWMState();
03381
03382 if (role == Client && p->mapping_state != Withdrawn) {
03383
03384
03385 if ( desktop == 0 )
03386 return;
03387
03388 XEvent e;
03389
03390 e.xclient.type = ClientMessage;
03391 e.xclient.message_type = net_wm_desktop;
03392 e.xclient.display = p->display;
03393 e.xclient.window = p->window;
03394 e.xclient.format = 32;
03395 e.xclient.data.l[0] = desktop == OnAllDesktops ? OnAllDesktops : desktop - 1;
03396 e.xclient.data.l[1] = 0l;
03397 e.xclient.data.l[2] = 0l;
03398 e.xclient.data.l[3] = 0l;
03399 e.xclient.data.l[4] = 0l;
03400
03401 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
03402 } else {
03403
03404 p->desktop = desktop;
03405 long d = desktop;
03406
03407 if ( d != OnAllDesktops ) {
03408 if ( d == 0 ) {
03409 XDeleteProperty( p->display, p->window, net_wm_desktop );
03410 return;
03411 }
03412
03413 d -= 1;
03414 }
03415
03416 XChangeProperty(p->display, p->window, net_wm_desktop, XA_CARDINAL, 32,
03417 PropModeReplace, (unsigned char *) &d, 1);
03418 }
03419 }
03420
03421
03422 void NETWinInfo::setPid(int pid) {
03423 if (role != Client) return;
03424
03425 p->pid = pid;
03426 long d = pid;
03427 XChangeProperty(p->display, p->window, net_wm_pid, XA_CARDINAL, 32,
03428 PropModeReplace, (unsigned char *) &d, 1);
03429 }
03430
03431
03432 void NETWinInfo::setHandledIcons(Bool handled) {
03433 if (role != Client) return;
03434
03435 p->handled_icons = handled;
03436 long d = handled;
03437 XChangeProperty(p->display, p->window, net_wm_handled_icons, XA_CARDINAL, 32,
03438 PropModeReplace, (unsigned char *) &d, 1);
03439 }
03440
03441 void NETWinInfo::setStartupId(const char* id) {
03442 if (role != Client) return;
03443
03444 delete[] p->startup_id;
03445 p->startup_id = nstrdup(id);
03446 XChangeProperty(p->display, p->window, net_startup_id, UTF8_STRING, 8,
03447 PropModeReplace, reinterpret_cast< unsigned char* >( p->startup_id ),
03448 strlen( p->startup_id ));
03449 }
03450
03451 void NETWinInfo::setAllowedActions( unsigned long actions ) {
03452 if( role != WindowManager )
03453 return;
03454 long data[50];
03455 int count = 0;
03456
03457 p->allowed_actions = actions;
03458 if (p->allowed_actions & ActionMove) data[count++] = net_wm_action_move;
03459 if (p->allowed_actions & ActionResize) data[count++] = net_wm_action_resize;
03460 if (p->allowed_actions & ActionMinimize) data[count++] = net_wm_action_minimize;
03461 if (p->allowed_actions & ActionShade) data[count++] = net_wm_action_shade;
03462 if (p->allowed_actions & ActionStick) data[count++] = net_wm_action_stick;
03463 if (p->allowed_actions & ActionMaxVert) data[count++] = net_wm_action_max_vert;
03464 if (p->allowed_actions & ActionMaxHoriz) data[count++] = net_wm_action_max_horiz;
03465 if (p->allowed_actions & ActionFullScreen) data[count++] = net_wm_action_fullscreen;
03466 if (p->allowed_actions & ActionChangeDesktop) data[count++] = net_wm_action_change_desk;
03467 if (p->allowed_actions & ActionClose) data[count++] = net_wm_action_close;
03468
03469 #ifdef NETWMDEBUG
03470 fprintf(stderr, "NETWinInfo::setAllowedActions: setting property (%d)\n", count);
03471 for (int i = 0; i < count; i++) {
03472 char* data_ret = XGetAtomName(p->display, (Atom) data[i]);
03473 fprintf(stderr, "NETWinInfo::setAllowedActions: action %ld '%s'\n",
03474 data[i], data_ret);
03475 if ( data_ret )
03476 XFree(data_ret);
03477 }
03478 #endif
03479
03480 XChangeProperty(p->display, p->window, net_wm_allowed_actions, XA_ATOM, 32,
03481 PropModeReplace, (unsigned char *) data, count);
03482 }
03483
03484 void NETWinInfo::setKDESystemTrayWinFor(Window window) {
03485 if (role != Client) return;
03486
03487 p->kde_system_tray_win_for = window;
03488 XChangeProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
03489 XA_WINDOW, 32, PropModeReplace,
03490 (unsigned char *) &(p->kde_system_tray_win_for), 1);
03491 }
03492
03493
03494 void NETWinInfo::setKDEFrameStrut(NETStrut strut) {
03495 setFrameExtents( strut );
03496 }
03497
03498 void NETWinInfo::setFrameExtents(NETStrut strut) {
03499 if (role != WindowManager) return;
03500
03501 p->frame_strut = strut;
03502
03503 long d[4];
03504 d[0] = strut.left;
03505 d[1] = strut.right;
03506 d[2] = strut.top;
03507 d[3] = strut.bottom;
03508
03509 XChangeProperty(p->display, p->window, net_frame_extents, XA_CARDINAL, 32,
03510 PropModeReplace, (unsigned char *) d, 4);
03511 XChangeProperty(p->display, p->window, kde_net_wm_frame_strut, XA_CARDINAL, 32,
03512 PropModeReplace, (unsigned char *) d, 4);
03513 }
03514
03515
03516 void NETWinInfo::kdeGeometry(NETRect& frame, NETRect& window) {
03517 if (p->win_geom.size.width == 0 || p->win_geom.size.height == 0) {
03518 Window unused;
03519 int x, y;
03520 unsigned int w, h, junk;
03521 XGetGeometry(p->display, p->window, &unused, &x, &y, &w, &h, &junk, &junk);
03522 XTranslateCoordinates(p->display, p->window, p->root, 0, 0, &x, &y, &unused
03523 );
03524
03525 p->win_geom.pos.x = x;
03526 p->win_geom.pos.y = y;
03527
03528 p->win_geom.size.width = w;
03529 p->win_geom.size.height = h;
03530 }
03531
03532 window = p->win_geom;
03533
03534 frame.pos.x = window.pos.x - p->frame_strut.left;
03535 frame.pos.y = window.pos.y - p->frame_strut.top;
03536 frame.size.width = window.size.width + p->frame_strut.left + p->frame_strut.right;
03537 frame.size.height = window.size.height + p->frame_strut.top + p->frame_strut.bottom;
03538 }
03539
03540
03541 NETIcon NETWinInfo::icon(int width, int height) const {
03542 return iconInternal( p->icons, p->icon_count, width, height );
03543 }
03544
03545 NETIcon NETWinInfo::iconInternal(NETRArray<NETIcon>& icons, int icon_count, int width, int height) const {
03546 NETIcon result;
03547
03548 if ( !icon_count ) {
03549 result.size.width = 0;
03550 result.size.height = 0;
03551 result.data = 0;
03552 return result;
03553 }
03554
03555 result = icons[0];
03556
03557
03558
03559 if (width == height && height == -1) return result;
03560
03561 int i;
03562 for (i = 0; i < icons.size(); i++) {
03563 if ((icons[i].size.width >= width &&
03564 icons[i].size.width < result.size.width) &&
03565 (icons[i].size.height >= height &&
03566 icons[i].size.height < result.size.height))
03567 result = icons[i];
03568 }
03569
03570 return result;
03571 }
03572
03573 void NETWinInfo::setUserTime( Time time ) {
03574 if (role != Client) return;
03575
03576 p->user_time = time;
03577 long d = time;
03578 XChangeProperty(p->display, p->window, net_wm_user_time, XA_CARDINAL, 32,
03579 PropModeReplace, (unsigned char *) &d, 1);
03580 }
03581
03582
03583 unsigned long NETWinInfo::event(XEvent *ev )
03584 {
03585 unsigned long props[ 1 ];
03586 event( ev, props, 1 );
03587 return props[ 0 ];
03588 }
03589
03590 void NETWinInfo::event(XEvent *event, unsigned long* properties, int properties_size ) {
03591 unsigned long props[ PROPERTIES_SIZE ] = { 0, 0 };
03592 assert( PROPERTIES_SIZE == 2 );
03593 unsigned long& dirty = props[ PROTOCOLS ];
03594 unsigned long& dirty2 = props[ PROTOCOLS2 ];
03595 bool do_update = false;
03596
03597 if (role == WindowManager && event->type == ClientMessage &&
03598 event->xclient.format == 32) {
03599
03600 #ifdef NETWMDEBUG
03601 fprintf(stderr, "NETWinInfo::event: handling ClientMessage event\n");
03602 #endif // NETWMDEBUG
03603
03604 if (event->xclient.message_type == net_wm_state) {
03605 dirty = WMState;
03606
03607
03608
03609 #ifdef NETWMDEBUG
03610 fprintf(stderr,
03611 "NETWinInfo::event: state client message, getting new state/mask\n");
03612 #endif
03613
03614 int i;
03615 long state = 0, mask = 0;
03616
03617 for (i = 1; i < 3; i++) {
03618 #ifdef NETWMDEBUG
03619 char* debug_txt = XGetAtomName(p->display, (Atom) event->xclient.data.l[i]);
03620 fprintf(stderr, "NETWinInfo::event: message %ld '%s'\n",
03621 event->xclient.data.l[i], debug_txt );
03622 if ( debug_txt )
03623 XFree( debug_txt );
03624 #endif
03625
03626 if ((Atom) event->xclient.data.l[i] == net_wm_state_modal)
03627 mask |= Modal;
03628 else if ((Atom) event->xclient.data.l[i] == net_wm_state_sticky)
03629 mask |= Sticky;
03630 else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_vert)
03631 mask |= MaxVert;
03632 else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_horiz)
03633 mask |= MaxHoriz;
03634 else if ((Atom) event->xclient.data.l[i] == net_wm_state_shaded)
03635 mask |= Shaded;
03636 else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_taskbar)
03637 mask |= SkipTaskbar;
03638 else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_pager)
03639 mask |= SkipPager;
03640 else if ((Atom) event->xclient.data.l[i] == net_wm_state_hidden)
03641 mask |= Hidden;
03642 else if ((Atom) event->xclient.data.l[i] == net_wm_state_fullscreen)
03643 mask |= FullScreen;
03644 else if ((Atom) event->xclient.data.l[i] == net_wm_state_above)
03645 mask |= KeepAbove;
03646 else if ((Atom) event->xclient.data.l[i] == net_wm_state_below)
03647 mask |= KeepBelow;
03648 else if ((Atom) event->xclient.data.l[i] == net_wm_state_demands_attention)
03649 mask |= DemandsAttention;
03650 else if ((Atom) event->xclient.data.l[i] == net_wm_state_stays_on_top)
03651 mask |= StaysOnTop;
03652 }
03653
03654
03655 switch (event->xclient.data.l[0]) {
03656 case 1:
03657
03658 state = mask;
03659 break;
03660
03661 case 2:
03662
03663 state = (p->state & mask) ^ mask;
03664 break;
03665
03666 default:
03667
03668 ;
03669 }
03670
03671 #ifdef NETWMDEBUG
03672 fprintf(stderr, "NETWinInfo::event: calling changeState(%lx, %lx)\n",
03673 state, mask);
03674 #endif
03675
03676 changeState(state, mask);
03677 } else if (event->xclient.message_type == net_wm_desktop) {
03678 dirty = WMDesktop;
03679
03680 if( event->xclient.data.l[0] == OnAllDesktops )
03681 changeDesktop( OnAllDesktops );
03682 else
03683 changeDesktop(event->xclient.data.l[0] + 1);
03684 }
03685 }
03686
03687 if (event->type == PropertyNotify) {
03688
03689 #ifdef NETWMDEBUG
03690 fprintf(stderr, "NETWinInfo::event: handling PropertyNotify event\n");
03691 #endif
03692
03693 XEvent pe = *event;
03694
03695 Bool done = False;
03696 Bool compaction = False;
03697 while (! done) {
03698
03699 #ifdef NETWMDEBUG
03700 fprintf(stderr, "NETWinInfo::event: loop fire\n");
03701 #endif
03702
03703 if (pe.xproperty.atom == net_wm_name)
03704 dirty |= WMName;
03705 else if (pe.xproperty.atom == net_wm_visible_name)
03706 dirty |= WMVisibleName;
03707 else if (pe.xproperty.atom == net_wm_desktop)
03708 dirty |= WMDesktop;
03709 else if (pe.xproperty.atom == net_wm_window_type)
03710 dirty |=WMWindowType;
03711 else if (pe.xproperty.atom == net_wm_state)
03712 dirty |= WMState;
03713 else if (pe.xproperty.atom == net_wm_strut)
03714 dirty |= WMStrut;
03715 else if (pe.xproperty.atom == net_wm_extended_strut)
03716 dirty2 |= WM2ExtendedStrut;
03717 else if (pe.xproperty.atom == net_wm_icon_geometry)
03718 dirty |= WMIconGeometry;
03719 else if (pe.xproperty.atom == net_wm_icon)
03720 dirty |= WMIcon;
03721 else if (pe.xproperty.atom == net_wm_pid)
03722 dirty |= WMPid;
03723 else if (pe.xproperty.atom == net_wm_handled_icons)
03724 dirty |= WMHandledIcons;
03725 else if (pe.xproperty.atom == net_startup_id)
03726 dirty2 |= WM2StartupId;
03727 else if (pe.xproperty.atom == net_wm_allowed_actions)
03728 dirty2 |= WM2AllowedActions;
03729 else if (pe.xproperty.atom == kde_net_wm_system_tray_window_for)
03730 dirty |= WMKDESystemTrayWinFor;
03731 else if (pe.xproperty.atom == xa_wm_state)
03732 dirty |= XAWMState;
03733 else if (pe.xproperty.atom == net_frame_extents)
03734 dirty |= WMFrameExtents;
03735 else if (pe.xproperty.atom == kde_net_wm_frame_strut)
03736 dirty |= WMKDEFrameStrut;
03737 else if (pe.xproperty.atom == net_wm_icon_name)
03738 dirty |= WMIconName;
03739 else if (pe.xproperty.atom == net_wm_visible_icon_name)
03740 dirty |= WMVisibleIconName;
03741 else if (pe.xproperty.atom == net_wm_user_time)
03742 dirty2 |= WM2UserTime;
03743 else if (pe.xproperty.atom == XA_WM_HINTS)
03744 dirty2 |= WM2GroupLeader;
03745 else if (pe.xproperty.atom == XA_WM_TRANSIENT_FOR)
03746 dirty2 |= WM2TransientFor;
03747 else if (pe.xproperty.atom == XA_WM_CLASS)
03748 dirty2 |= WM2WindowClass;
03749 else if (pe.xproperty.atom == wm_window_role)
03750 dirty2 |= WM2WindowRole;
03751 else if (pe.xproperty.atom == XA_WM_CLIENT_MACHINE)
03752 dirty2 |= WM2ClientMachine;
03753 else {
03754
03755 #ifdef NETWMDEBUG
03756 fprintf(stderr, "NETWinInfo::event: putting back event and breaking\n");
03757 #endif
03758
03759 if ( compaction )
03760 XPutBackEvent(p->display, &pe);
03761 break;
03762 }
03763
03764 if (XCheckTypedWindowEvent(p->display, p->window, PropertyNotify, &pe) )
03765 compaction = True;
03766 else
03767 break;
03768 }
03769
03770 do_update = true;
03771 } else if (event->type == ConfigureNotify) {
03772
03773 #ifdef NETWMDEBUG
03774 fprintf(stderr, "NETWinInfo::event: handling ConfigureNotify event\n");
03775 #endif
03776
03777 dirty |= WMGeometry;
03778
03779
03780 p->win_geom.pos.x = event->xconfigure.x;
03781 p->win_geom.pos.y = event->xconfigure.y;
03782 p->win_geom.size.width = event->xconfigure.width;
03783 p->win_geom.size.height = event->xconfigure.height;
03784 }
03785
03786 if( do_update )
03787 update( props );
03788
03789 if( properties_size > PROPERTIES_SIZE )
03790 properties_size = PROPERTIES_SIZE;
03791 for( int i = 0;
03792 i < properties_size;
03793 ++i )
03794 properties[ i ] = props[ i ];
03795 }
03796
03797 void NETWinInfo::updateWMState() {
03798 unsigned long props[ PROPERTIES_SIZE ] = { XAWMState, 0 };
03799 assert( PROPERTIES_SIZE == 2 );
03800 update( props );
03801 }
03802
03803 void NETWinInfo::update(const unsigned long dirty_props[]) {
03804 Atom type_ret;
03805 int format_ret;
03806 unsigned long nitems_ret, unused;
03807 unsigned char *data_ret;
03808 unsigned long props[ PROPERTIES_SIZE ];
03809 for( int i = 0;
03810 i < PROPERTIES_SIZE;
03811 ++i )
03812 props[ i ] = dirty_props[ i ] & p->properties[ i ];
03813 const unsigned long& dirty = props[ PROTOCOLS ];
03814 const unsigned long& dirty2 = props[ PROTOCOLS2 ];
03815
03816
03817 if( dirty_props[ PROTOCOLS ] & XAWMState )
03818 props[ PROTOCOLS ] |= XAWMState;
03819
03820
03821
03822 if (dirty & XAWMState)
03823 KXAskWindowProperty(p->display, p->window, xa_wm_state, 0l, 1l,
03824 False, xa_wm_state);
03825 if (dirty & WMState)
03826 KXAskWindowProperty(p->display, p->window, net_wm_state, 0l, 2048l,
03827 False, XA_ATOM);
03828 if (dirty & WMDesktop)
03829 KXAskWindowProperty(p->display, p->window, net_wm_desktop, 0l, 1l,
03830 False, XA_CARDINAL);
03831 if (dirty & WMName)
03832 KXAskWindowProperty(p->display, p->window, net_wm_name, 0l,
03833 MAX_PROP_SIZE, False, UTF8_STRING);
03834 if (dirty & WMVisibleName)
03835 KXAskWindowProperty(p->display, p->window, net_wm_visible_name, 0l,
03836 MAX_PROP_SIZE, False, UTF8_STRING);
03837 if (dirty & WMIconName)
03838 KXAskWindowProperty(p->display, p->window, net_wm_icon_name, 0l,
03839 MAX_PROP_SIZE, False, UTF8_STRING);
03840 if (dirty & WMVisibleIconName)
03841 KXAskWindowProperty(p->display, p->window, net_wm_visible_icon_name, 0l,
03842 MAX_PROP_SIZE, False, UTF8_STRING);
03843 if (dirty & WMWindowType)
03844 KXAskWindowProperty(p->display, p->window, net_wm_window_type, 0l, 2048l,
03845 False, XA_ATOM);
03846 if (dirty & WMStrut)
03847 KXAskWindowProperty(p->display, p->window, net_wm_strut, 0l, 4l,
03848 False, XA_CARDINAL);
03849 if (dirty2 & WM2ExtendedStrut)
03850 KXAskWindowProperty(p->display, p->window, net_wm_extended_strut, 0l, 12l,
03851 False, XA_CARDINAL);
03852 if (dirty & WMIconGeometry)
03853 KXAskWindowProperty(p->display, p->window, net_wm_icon_geometry, 0l, 4l,
03854 False, XA_CARDINAL);
03855 if (dirty & WMIcon)
03856 KXAskWindowProperty(p->display, p->window, net_wm_icon, 0l,
03857 MAX_PROP_SIZE, False, XA_CARDINAL);
03858 if (dirty & WMKDESystemTrayWinFor)
03859 KXAskWindowProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
03860 0l, 1l, False, XA_WINDOW);
03861 if (dirty & WMFrameExtents) {
03862 KXAskWindowProperty(p->display, p->window, net_frame_extents,
03863 0l, 4l, False, XA_CARDINAL);
03864 KXAskWindowProperty(p->display, p->window, kde_net_wm_frame_strut,
03865 0l, 4l, False, XA_CARDINAL);
03866 }
03867 if (dirty & WMPid)
03868 KXAskWindowProperty(p->display, p->window, net_wm_pid, 0l, 1l,
03869 False, XA_CARDINAL);
03870 if (dirty2 & WM2StartupId)
03871 KXAskWindowProperty(p->display, p->window, net_startup_id, 0l,
03872 MAX_PROP_SIZE, False, UTF8_STRING);
03873 if( dirty2 & WM2AllowedActions )
03874 KXAskWindowProperty(p->display, p->window, net_wm_allowed_actions, 0l, 2048l,
03875 False, XA_ATOM);
03876 if (dirty2 & WM2UserTime)
03877 KXAskWindowProperty(p->display, p->window, net_wm_user_time, 0l, 1l,
03878 False, XA_CARDINAL);
03879 #if 0
03880 if (dirty2 & WM2TransientFor)
03881 todo
03882 XGetTransientForHint(p->display, p->window, &p->transient_for);
03883 if (dirty2 & WM2GroupLeader)
03884 todo
03885 XWMHints *hints = XGetWMHints(p->display, p->window);
03886 if( dirty2 & WM2WindowClass )
03887 todo
03888 if( XGetClassHint( p->display, p->window, &hint ))
03889 #endif
03890 if( dirty2 & WM2WindowRole )
03891 KXAskWindowProperty(p->display, p->window, wm_window_role, 0l,
03892 MAX_PROP_SIZE, False, XA_STRING);
03893 if( dirty2 & WM2ClientMachine )
03894 KXAskWindowProperty(p->display, p->window, XA_WM_CLIENT_MACHINE, 0l,
03895 MAX_PROP_SIZE, False, XA_STRING);
03896
03897
03898
03899 if (dirty & XAWMState) {
03900 p->mapping_state = Withdrawn;
03901 if (KXReceiveWindowProperty(p->display, p->window, xa_wm_state, 0l, 1l,
03902 False, xa_wm_state, &type_ret, &format_ret,
03903 &nitems_ret, &unused, &data_ret)
03904 == Success) {
03905 if (type_ret == xa_wm_state && format_ret == 32 &&
03906 nitems_ret == 1) {
03907 long *state = (long *) data_ret;
03908
03909 switch(*state) {
03910 case IconicState:
03911 p->mapping_state = Iconic;
03912 break;
03913 case NormalState:
03914 p->mapping_state = Visible;
03915 break;
03916 case WithdrawnState:
03917 default:
03918 p->mapping_state = Withdrawn;
03919 break;
03920 }
03921
03922 p->mapping_state_dirty = False;
03923 }
03924 if ( data_ret )
03925 XFree(data_ret);
03926 }
03927 }
03928
03929 if (dirty & WMState) {
03930 p->state = 0;
03931 if (KXReceiveWindowProperty(p->display, p->window, net_wm_state, 0l, 2048l,
03932 False, XA_ATOM, &type_ret, &format_ret,
03933 &nitems_ret, &unused, &data_ret)
03934 == Success) {
03935 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
03936
03937 #ifdef NETWMDEBUG
03938 fprintf(stderr, "NETWinInfo::update: updating window state (%ld)\n",
03939 nitems_ret);
03940 #endif
03941
03942 long *states = (long *) data_ret;
03943 unsigned long count;
03944
03945 for (count = 0; count < nitems_ret; count++) {
03946 #ifdef NETWMDEBUG
03947 char* data_ret = XGetAtomName(p->display, (Atom) states[count]);
03948 fprintf(stderr,
03949 "NETWinInfo::update: adding window state %ld '%s'\n",
03950 states[count], data_ret );
03951 if ( data_ret )
03952 XFree( data_ret );
03953 #endif
03954
03955 if ((Atom) states[count] == net_wm_state_modal)
03956 p->state |= Modal;
03957 else if ((Atom) states[count] == net_wm_state_sticky)
03958 p->state |= Sticky;
03959 else if ((Atom) states[count] == net_wm_state_max_vert)
03960 p->state |= MaxVert;
03961 else if ((Atom) states[count] == net_wm_state_max_horiz)
03962 p->state |= MaxHoriz;
03963 else if ((Atom) states[count] == net_wm_state_shaded)
03964 p->state |= Shaded;
03965 else if ((Atom) states[count] == net_wm_state_skip_taskbar)
03966 p->state |= SkipTaskbar;
03967 else if ((Atom) states[count] == net_wm_state_skip_pager)
03968 p->state |= SkipPager;
03969 else if ((Atom) states[count] == net_wm_state_hidden)
03970 p->state |= Hidden;
03971 else if ((Atom) states[count] == net_wm_state_fullscreen)
03972 p->state |= FullScreen;
03973 else if ((Atom) states[count] == net_wm_state_above)
03974 p->state |= KeepAbove;
03975 else if ((Atom) states[count] == net_wm_state_below)
03976 p->state |= KeepBelow;
03977 else if ((Atom) states[count] == net_wm_state_demands_attention)
03978 p->state |= DemandsAttention;
03979 else if ((Atom) states[count] == net_wm_state_stays_on_top)
03980 p->state |= StaysOnTop;
03981 }
03982 }
03983 if ( data_ret )
03984 XFree(data_ret);
03985 }
03986 }
03987
03988 if (dirty & WMDesktop) {
03989 p->desktop = 0;
03990 if (KXReceiveWindowProperty(p->display, p->window, net_wm_desktop, 0l, 1l,
03991 False, XA_CARDINAL, &type_ret,
03992 &format_ret, &nitems_ret,
03993 &unused, &data_ret)
03994 == Success) {
03995 if (type_ret == XA_CARDINAL && format_ret == 32 &&
03996 nitems_ret == 1) {
03997 p->desktop = *((long *) data_ret);
03998 if ((signed) p->desktop != OnAllDesktops)
03999 p->desktop++;
04000
04001 if ( p->desktop == 0 )
04002 p->desktop = OnAllDesktops;
04003 }
04004 if ( data_ret )
04005 XFree(data_ret);
04006 }
04007 }
04008
04009 if (dirty & WMName) {
04010 delete[] p->name;
04011 p->name = NULL;
04012 if (KXReceiveWindowProperty(p->display, p->window, net_wm_name, 0l,
04013 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
04014 &format_ret, &nitems_ret, &unused, &data_ret)
04015 == Success) {
04016 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
04017 p->name = nstrndup((const char *) data_ret, nitems_ret);
04018 }
04019
04020 if( data_ret )
04021 XFree(data_ret);
04022 }
04023 }
04024
04025 if (dirty & WMVisibleName) {
04026 delete[] p->visible_name;
04027 p->visible_name = NULL;
04028 if (KXReceiveWindowProperty(p->display, p->window, net_wm_visible_name, 0l,
04029 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
04030 &format_ret, &nitems_ret, &unused, &data_ret)
04031 == Success) {
04032 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
04033 p->visible_name = nstrndup((const char *) data_ret, nitems_ret);
04034 }
04035
04036 if( data_ret )
04037 XFree(data_ret);
04038 }
04039 }
04040
04041 if (dirty & WMIconName) {
04042 delete[] p->icon_name;
04043 p->icon_name = NULL;
04044 if (KXReceiveWindowProperty(p->display, p->window, net_wm_icon_name, 0l,
04045 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
04046 &format_ret, &nitems_ret, &unused, &data_ret)
04047 == Success) {
04048 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
04049 p->icon_name = nstrndup((const char *) data_ret, nitems_ret);
04050 }
04051
04052 if( data_ret )
04053 XFree(data_ret);
04054 }
04055 }
04056
04057 if (dirty & WMVisibleIconName)
04058 {
04059 delete[] p->visible_icon_name;
04060 p->visible_icon_name = NULL;
04061 if (KXReceiveWindowProperty(p->display, p->window, net_wm_visible_icon_name, 0l,
04062 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
04063 &format_ret, &nitems_ret, &unused, &data_ret)
04064 == Success) {
04065 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
04066 p->visible_icon_name = nstrndup((const char *) data_ret, nitems_ret);
04067 }
04068
04069 if( data_ret )
04070 XFree(data_ret);
04071 }
04072 }
04073
04074 if (dirty & WMWindowType) {
04075 p->types.reset();
04076 p->types[ 0 ] = Unknown;
04077 p->has_net_support = false;
04078 if (KXReceiveWindowProperty(p->display, p->window, net_wm_window_type, 0l, 2048l,
04079 False, XA_ATOM, &type_ret, &format_ret,
04080 &nitems_ret, &unused, &data_ret)
04081 == Success) {
04082 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
04083
04084 #ifdef NETWMDEBUG
04085 fprintf(stderr, "NETWinInfo::update: getting window type (%ld)\n",
04086 nitems_ret);
04087 #endif
04088
04089 p->has_net_support = true;
04090
04091 unsigned long count = 0;
04092 long *types = (long *) data_ret;
04093 int pos = 0;
04094
04095 while (count < nitems_ret) {
04096
04097 #ifdef NETWMDEBUG
04098 char* debug_type = XGetAtomName(p->display, (Atom) types[count]);
04099 fprintf(stderr,
04100 "NETWinInfo::update: examining window type %ld %s\n",
04101 types[count], debug_type );
04102 if ( debug_type )
04103 XFree( debug_type );
04104 #endif
04105
04106 if ((Atom) types[count] == net_wm_window_type_normal)
04107 p->types[ pos++ ] = Normal;
04108 else if ((Atom) types[count] == net_wm_window_type_desktop)
04109 p->types[ pos++ ] = Desktop;
04110 else if ((Atom) types[count] == net_wm_window_type_dock)
04111 p->types[ pos++ ] = Dock;
04112 else if ((Atom) types[count] == net_wm_window_type_toolbar)
04113 p->types[ pos++ ] = Tool;
04114 else if ((Atom) types[count] == net_wm_window_type_menu)
04115 p->types[ pos++ ] = Menu;
04116 else if ((Atom) types[count] == net_wm_window_type_dialog)
04117 p->types[ pos++ ] = Dialog;
04118 else if ((Atom) types[count] == net_wm_window_type_utility)
04119 p->types[ pos++ ] = Utility;
04120 else if ((Atom) types[count] == net_wm_window_type_splash)
04121 p->types[ pos++ ] = Splash;
04122 else if ((Atom) types[count] == kde_net_wm_window_type_override)
04123 p->types[ pos++ ] = Override;
04124 else if ((Atom) types[count] == kde_net_wm_window_type_topmenu)
04125 p->types[ pos++ ] = TopMenu;
04126
04127 count++;
04128 }
04129 }
04130
04131 if ( data_ret )
04132 XFree(data_ret);
04133 }
04134 }
04135
04136 if (dirty & WMStrut) {
04137 p->strut = NETStrut();
04138 if (KXReceiveWindowProperty(p->display, p->window, net_wm_strut, 0l, 4l,
04139 False, XA_CARDINAL, &type_ret, &format_ret,
04140 &nitems_ret, &unused, &data_ret)
04141 == Success) {
04142 if (type_ret == XA_CARDINAL && format_ret == 32 &&
04143 nitems_ret == 4) {
04144 long *d = (long *) data_ret;
04145 p->strut.left = d[0];
04146 p->strut.right = d[1];
04147 p->strut.top = d[2];
04148 p->strut.bottom = d[3];
04149 }
04150 if ( data_ret )
04151 XFree(data_ret);
04152 }
04153 }
04154
04155 if (dirty2 & WM2ExtendedStrut) {
04156 p->extended_strut = NETExtendedStrut();
04157 if (KXReceiveWindowProperty(p->display, p->window, net_wm_extended_strut, 0l, 12l,
04158 False, XA_CARDINAL, &type_ret, &format_ret,
04159 &nitems_ret, &unused, &data_ret)
04160 == Success) {
04161 if (type_ret == XA_CARDINAL && format_ret == 32 &&
04162 nitems_ret == 12) {
04163 long *d = (long *) data_ret;
04164 p->extended_strut.left_width = d[0];
04165 p->extended_strut.right_width = d[1];
04166 p->extended_strut.top_width = d[2];
04167 p->extended_strut.bottom_width = d[3];
04168 p->extended_strut.left_start = d[4];
04169 p->extended_strut.left_end = d[5];
04170 p->extended_strut.right_start = d[6];
04171 p->extended_strut.right_end = d[7];
04172 p->extended_strut.top_start = d[8];
04173 p->extended_strut.top_end = d[9];
04174 p->extended_strut.bottom_start = d[10];
04175 p->extended_strut.bottom_end = d[11];
04176 }
04177 if ( data_ret )
04178 XFree(data_ret);
04179 }
04180 }
04181
04182 if (dirty & WMIconGeometry) {
04183 p->icon_geom = NETRect();
04184 if (KXReceiveWindowProperty(p->display, p->window, net_wm_icon_geometry, 0l, 4l,
04185 False, XA_CARDINAL, &type_ret, &format_ret,
04186 &nitems_ret, &unused, &data_ret)
04187 == Success) {
04188 if (type_ret == XA_CARDINAL && format_ret == 32 &&
04189 nitems_ret == 4) {
04190 long *d = (long *) data_ret;
04191 p->icon_geom.pos.x = d[0];
04192 p->icon_geom.pos.y = d[1];
04193 p->icon_geom.size.width = d[2];
04194 p->icon_geom.size.height = d[3];
04195 }
04196 if ( data_ret )
04197 XFree(data_ret);
04198 }
04199 }
04200
04201 if (dirty & WMIcon) {
04202 readIcon(p->display,p->window,net_wm_icon,p->icons,p->icon_count, true);
04203 }
04204
04205 if (dirty & WMKDESystemTrayWinFor) {
04206 p->kde_system_tray_win_for = 0;
04207 if (KXReceiveWindowProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
04208 0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
04209 &nitems_ret, &unused, &data_ret)
04210 == Success) {
04211 if (type_ret == XA_WINDOW && format_ret == 32 &&
04212 nitems_ret == 1) {
04213 p->kde_system_tray_win_for = *((Window *) data_ret);
04214 if ( p->kde_system_tray_win_for == 0 )
04215 p->kde_system_tray_win_for = p->root;
04216 }
04217 if ( data_ret )
04218 XFree(data_ret);
04219 }
04220 }
04221
04222 if (dirty & WMFrameExtents) {
04223 p->frame_strut = NETStrut();
04224 bool ok = false;
04225 if (KXReceiveWindowProperty(p->display, p->window, net_frame_extents,
04226 0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
04227 &nitems_ret, &unused, &data_ret) == Success) {
04228 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
04229 ok = true;
04230 long *d = (long *) data_ret;
04231
04232 p->frame_strut.left = d[0];
04233 p->frame_strut.right = d[1];
04234 p->frame_strut.top = d[2];
04235 p->frame_strut.bottom = d[3];
04236 }
04237 if ( data_ret )
04238 XFree(data_ret);
04239 }
04240
04241
04242 if (KXReceiveWindowProperty(p->display, p->window, kde_net_wm_frame_strut,
04243 0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
04244 &nitems_ret, &unused, &data_ret) == Success ) {
04245 if (!ok && type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
04246 ok = true;
04247 long *d = (long *) data_ret;
04248
04249 p->frame_strut.left = d[0];
04250 p->frame_strut.right = d[1];
04251 p->frame_strut.top = d[2];
04252 p->frame_strut.bottom = d[3];
04253 }
04254 if ( data_ret )
04255 XFree(data_ret);
04256 }
04257 }
04258
04259 if (dirty & WMPid) {
04260 p->pid = 0;
04261 if (KXReceiveWindowProperty(p->display, p->window, net_wm_pid, 0l, 1l,
04262 False, XA_CARDINAL, &type_ret, &format_ret,
04263 &nitems_ret, &unused, &data_ret) == Success) {
04264 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
04265 p->pid = *((long *) data_ret);
04266 }
04267 if ( data_ret )
04268 XFree(data_ret);
04269 }
04270 }
04271
04272 if (dirty2 & WM2StartupId)
04273 {
04274 delete[] p->startup_id;
04275 p->startup_id = NULL;
04276 if (KXReceiveWindowProperty(p->display, p->window, net_startup_id, 0l,
04277 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
04278 &format_ret, &nitems_ret, &unused, &data_ret)
04279 == Success) {
04280 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
04281 p->startup_id = nstrndup((const char *) data_ret, nitems_ret);
04282 }
04283
04284 if( data_ret )
04285 XFree(data_ret);
04286 }
04287 }
04288
04289 if( dirty2 & WM2AllowedActions ) {
04290 p->allowed_actions = 0;
04291 if (KXReceiveWindowProperty(p->display, p->window, net_wm_allowed_actions, 0l, 2048l,
04292 False, XA_ATOM, &type_ret, &format_ret,
04293 &nitems_ret, &unused, &data_ret)
04294 == Success) {
04295 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
04296
04297 #ifdef NETWMDEBUG
04298 fprintf(stderr, "NETWinInfo::update: updating allowed actions (%ld)\n",
04299 nitems_ret);
04300 #endif
04301
04302 long *actions = (long *) data_ret;
04303 unsigned long count;
04304
04305 for (count = 0; count < nitems_ret; count++) {
04306 #ifdef NETWMDEBUG
04307 fprintf(stderr,
04308 "NETWinInfo::update: adding allowed action %ld '%s'\n",
04309 actions[count],
04310 XGetAtomName(p->display, (Atom) actions[count]));
04311 #endif
04312
04313 if ((Atom) actions[count] == net_wm_action_move)
04314 p->allowed_actions |= ActionMove;
04315 if ((Atom) actions[count] == net_wm_action_resize)
04316 p->allowed_actions |= ActionResize;
04317 if ((Atom) actions[count] == net_wm_action_minimize)
04318 p->allowed_actions |= ActionMinimize;
04319 if ((Atom) actions[count] == net_wm_action_shade)
04320 p->allowed_actions |= ActionShade;
04321 if ((Atom) actions[count] == net_wm_action_stick)
04322 p->allowed_actions |= ActionStick;
04323 if ((Atom) actions[count] == net_wm_action_max_vert)
04324 p->allowed_actions |= ActionMaxVert;
04325 if ((Atom) actions[count] == net_wm_action_max_horiz)
04326 p->allowed_actions |= ActionMaxHoriz;
04327 if ((Atom) actions[count] == net_wm_action_fullscreen)
04328 p->allowed_actions |= ActionFullScreen;
04329 if ((Atom) actions[count] == net_wm_action_change_desk)
04330 p->allowed_actions |= ActionChangeDesktop;
04331 if ((Atom) actions[count] == net_wm_action_close)
04332 p->allowed_actions |= ActionClose;
04333 }
04334 }
04335 if ( data_ret )
04336 XFree(data_ret);
04337 }
04338 }
04339
04340 if (dirty2 & WM2UserTime) {
04341 p->user_time = -1U;
04342 if (KXReceiveWindowProperty(p->display, p->window, net_wm_user_time, 0l, 1l,
04343 False, XA_CARDINAL, &type_ret, &format_ret,
04344 &nitems_ret, &unused, &data_ret) == Success) {
04345
04346 if (type_ret == XA_CARDINAL && format_ret == 32 ) {
04347 p->user_time = *((long *) data_ret);
04348 }
04349 if ( data_ret )
04350 XFree(data_ret);
04351 }
04352 }
04353
04354 if (dirty2 & WM2TransientFor) {
04355 p->transient_for = None;
04356 XGetTransientForHint(p->display, p->window, &p->transient_for);
04357 }
04358
04359 if (dirty2 & WM2GroupLeader) {
04360 XWMHints *hints = XGetWMHints(p->display, p->window);
04361 p->window_group = None;
04362 if ( hints )
04363 {
04364 if( hints->flags & WindowGroupHint )
04365 p->window_group = hints->window_group;
04366 XFree( reinterpret_cast< char* >( hints ));
04367 }
04368 }
04369
04370 if( dirty2 & WM2WindowClass ) {
04371 delete[] p->class_class;
04372 delete[] p->class_name;
04373 p->class_class = NULL;
04374 p->class_name = NULL;
04375 XClassHint hint;
04376 if( XGetClassHint( p->display, p->window, &hint )) {
04377 p->class_class = strdup( hint.res_class );
04378 p->class_name = strdup( hint.res_name );
04379 XFree( hint.res_class );
04380 XFree( hint.res_name );
04381 }
04382 }
04383
04384 if( dirty2 & WM2WindowRole ) {
04385 delete[] p->role;
04386 p->role = NULL;
04387 if (KXReceiveWindowProperty(p->display, p->window, wm_window_role, 0l,
04388 MAX_PROP_SIZE, False, XA_STRING, &type_ret,
04389 &format_ret, &nitems_ret, &unused, &data_ret)
04390 == Success) {
04391 if (type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0) {
04392 p->role = nstrndup((const char *) data_ret, nitems_ret);
04393 }
04394 if( data_ret )
04395 XFree(data_ret);
04396 }
04397 }
04398
04399 if( dirty2 & WM2ClientMachine ) {
04400 delete[] p->client_machine;
04401 p->client_machine = NULL;
04402 if (KXReceiveWindowProperty(p->display, p->window, XA_WM_CLIENT_MACHINE, 0l,
04403 MAX_PROP_SIZE, False, XA_STRING, &type_ret,
04404 &format_ret, &nitems_ret, &unused, &data_ret)
04405 == Success) {
04406 if (type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0) {
04407 p->client_machine = nstrndup((const char *) data_ret, nitems_ret);
04408 }
04409 if( data_ret )
04410 XFree(data_ret);
04411 }
04412 }
04413 }
04414
04415
04416 NETRect NETWinInfo::iconGeometry() const {
04417 return p->icon_geom;
04418 }
04419
04420
04421 unsigned long NETWinInfo::state() const {
04422 return p->state;
04423 }
04424
04425
04426 NETStrut NETWinInfo::strut() const {
04427 return p->strut;
04428 }
04429
04430 NETExtendedStrut NETWinInfo::extendedStrut() const {
04431 return p->extended_strut;
04432 }
04433
04434 bool NET::typeMatchesMask( WindowType type, unsigned long mask ) {
04435 switch( type ) {
04436 #define CHECK_TYPE_MASK( type ) \
04437 case type: \
04438 if( mask & type##Mask ) \
04439 return true; \
04440 break;
04441 CHECK_TYPE_MASK( Normal )
04442 CHECK_TYPE_MASK( Desktop )
04443 CHECK_TYPE_MASK( Dock )
04444 CHECK_TYPE_MASK( Toolbar )
04445 CHECK_TYPE_MASK( Menu )
04446 CHECK_TYPE_MASK( Dialog )
04447 CHECK_TYPE_MASK( Override )
04448 CHECK_TYPE_MASK( TopMenu )
04449 CHECK_TYPE_MASK( Utility )
04450 CHECK_TYPE_MASK( Splash )
04451 #undef CHECK_TYPE_MASK
04452 default:
04453 break;
04454 }
04455 return false;
04456 }
04457
04458 NET::WindowType NETWinInfo::windowType( unsigned long supported_types ) const {
04459 for( int i = 0;
04460 i < p->types.size();
04461 ++i ) {
04462
04463 if( typeMatchesMask( p->types[ i ], supported_types ))
04464 return p->types[ i ];
04465 }
04466 return Unknown;
04467 }
04468
04469 NET::WindowType NETWinInfo::windowType() const {
04470 return p->types[ 0 ];
04471 }
04472
04473
04474 const char *NETWinInfo::name() const {
04475 return p->name;
04476 }
04477
04478
04479 const char *NETWinInfo::visibleName() const {
04480 return p->visible_name;
04481 }
04482
04483
04484 const char *NETWinInfo::iconName() const {
04485 return p->icon_name;
04486 }
04487
04488
04489 const char *NETWinInfo::visibleIconName() const {
04490 return p->visible_icon_name;
04491 }
04492
04493
04494 int NETWinInfo::desktop() const {
04495 return p->desktop;
04496 }
04497
04498 int NETWinInfo::pid() const {
04499 return p->pid;
04500 }
04501
04502 Time NETWinInfo::userTime() const {
04503 return p->user_time;
04504 }
04505
04506 const char* NETWinInfo::startupId() const {
04507 return p->startup_id;
04508 }
04509
04510 unsigned long NETWinInfo::allowedActions() const {
04511 return p->allowed_actions;
04512 }
04513
04514 bool NETWinInfo::hasNETSupport() const {
04515 return p->has_net_support;
04516 }
04517
04518 Window NETWinInfo::transientFor() const {
04519 return p->transient_for;
04520 }
04521
04522 Window NETWinInfo::groupLeader() const {
04523 return p->window_group;
04524 }
04525
04526 const char* NETWinInfo::windowClassClass() const {
04527 return p->class_class;
04528 }
04529
04530 const char* NETWinInfo::windowClassName() const {
04531 return p->class_name;
04532 }
04533
04534 const char* NETWinInfo::windowRole() const {
04535 return p->role;
04536 }
04537
04538 const char* NETWinInfo::clientMachine() const {
04539 return p->client_machine;
04540 }
04541
04542 Bool NETWinInfo::handledIcons() const {
04543 return p->handled_icons;
04544 }
04545
04546
04547 Window NETWinInfo::kdeSystemTrayWinFor() const {
04548 return p->kde_system_tray_win_for;
04549 }
04550
04551 const unsigned long* NETWinInfo::passedProperties() const {
04552 return p->properties;
04553 }
04554
04555 unsigned long NETWinInfo::properties() const {
04556 return p->properties[ PROTOCOLS ];
04557 }
04558
04559
04560 NET::MappingState NETWinInfo::mappingState() const {
04561 return p->mapping_state;
04562 }
04563
04564 void NETRootInfo::virtual_hook( int, void* )
04565 { }
04566
04567 void NETWinInfo::virtual_hook( int, void* )
04568 { }
04569
04570
04571
04572
04573 #if 0
04574 int NET::timestampCompare( Time time1, Time time2 )
04575 {
04576 if( time1 == time2 )
04577 return 0;
04578 return ( time1 - time2 ) < 0x7fffffffU ? 1 : -1;
04579 }
04580
04581 Time NET::timestampDiff( Time time1, Time time2 )
04582 {
04583 return time2 - time1;
04584 }
04585 #else
04586 int NET::timestampCompare( unsigned long time1_, unsigned long time2_ )
04587 {
04588 Q_UINT32 time1 = time1_;
04589 Q_UINT32 time2 = time2_;
04590 if( time1 == time2 )
04591 return 0;
04592 return Q_UINT32( time1 - time2 ) < 0x7fffffffU ? 1 : -1;
04593 }
04594
04595 int NET::timestampDiff( unsigned long time1_, unsigned long time2_ )
04596 {
04597 Q_UINT32 time1 = time1_;
04598 Q_UINT32 time2 = time2_;
04599 return Q_UINT32( time2 - time1 );
04600 }
04601 #endif
04602
04603
04604 #endif