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