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