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