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