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 result = icons[0];
03471
03472
03473
03474 if (width == height && height == -1) return result;
03475
03476 int i;
03477 for (i = 0; i < icons.size(); i++) {
03478 if ((icons[i].size.width >= width &&
03479 icons[i].size.width < result.size.width) &&
03480 (icons[i].size.height >= height &&
03481 icons[i].size.height < result.size.height))
03482 result = icons[i];
03483 }
03484
03485 return result;
03486 }
03487
03488 void NETWinInfo::setUserTime( Time time ) {
03489 if (role != Client) return;
03490
03491 p->user_time = time;
03492 long d = time;
03493 XChangeProperty(p->display, p->window, net_wm_user_time, XA_CARDINAL, 32,
03494 PropModeReplace, (unsigned char *) &d, 1);
03495 }
03496
03497
03498 unsigned long NETWinInfo::event(XEvent *ev )
03499 {
03500 unsigned long props[ 1 ];
03501 event( ev, props, 1 );
03502 return props[ 0 ];
03503 }
03504
03505 void NETWinInfo::event(XEvent *event, unsigned long* properties, int properties_size ) {
03506 unsigned long props[ PROPERTIES_SIZE ] = { 0, 0 };
03507 assert( PROPERTIES_SIZE == 2 );
03508 unsigned long& dirty = props[ PROTOCOLS ];
03509 unsigned long& dirty2 = props[ PROTOCOLS2 ];
03510 bool do_update = false;
03511
03512 if (role == WindowManager && event->type == ClientMessage &&
03513 event->xclient.format == 32) {
03514
03515 #ifdef NETWMDEBUG
03516 fprintf(stderr, "NETWinInfo::event: handling ClientMessage event\n");
03517 #endif // NETWMDEBUG
03518
03519 if (event->xclient.message_type == net_wm_state) {
03520 dirty = WMState;
03521
03522
03523
03524 #ifdef NETWMDEBUG
03525 fprintf(stderr,
03526 "NETWinInfo::event: state client message, getting new state/mask\n");
03527 #endif
03528
03529 int i;
03530 long state = 0, mask = 0;
03531
03532 for (i = 1; i < 3; i++) {
03533 #ifdef NETWMDEBUG
03534 char* debug_txt = XGetAtomName(p->display, (Atom) event->xclient.data.l[i]);
03535 fprintf(stderr, "NETWinInfo::event: message %ld '%s'\n",
03536 event->xclient.data.l[i], debug_txt );
03537 if ( debug_txt )
03538 XFree( debug_txt );
03539 #endif
03540
03541 if ((Atom) event->xclient.data.l[i] == net_wm_state_modal)
03542 mask |= Modal;
03543 else if ((Atom) event->xclient.data.l[i] == net_wm_state_sticky)
03544 mask |= Sticky;
03545 else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_vert)
03546 mask |= MaxVert;
03547 else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_horiz)
03548 mask |= MaxHoriz;
03549 else if ((Atom) event->xclient.data.l[i] == net_wm_state_shaded)
03550 mask |= Shaded;
03551 else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_taskbar)
03552 mask |= SkipTaskbar;
03553 else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_pager)
03554 mask |= SkipPager;
03555 else if ((Atom) event->xclient.data.l[i] == net_wm_state_hidden)
03556 mask |= Hidden;
03557 else if ((Atom) event->xclient.data.l[i] == net_wm_state_fullscreen)
03558 mask |= FullScreen;
03559 else if ((Atom) event->xclient.data.l[i] == net_wm_state_above)
03560 mask |= KeepAbove;
03561 else if ((Atom) event->xclient.data.l[i] == net_wm_state_below)
03562 mask |= KeepBelow;
03563 else if ((Atom) event->xclient.data.l[i] == net_wm_state_demands_attention)
03564 mask |= DemandsAttention;
03565 else if ((Atom) event->xclient.data.l[i] == net_wm_state_stays_on_top)
03566 mask |= StaysOnTop;
03567 }
03568
03569
03570 switch (event->xclient.data.l[0]) {
03571 case 1:
03572
03573 state = mask;
03574 break;
03575
03576 case 2:
03577
03578 state = (p->state & mask) ^ mask;
03579 break;
03580
03581 default:
03582
03583 ;
03584 }
03585
03586 #ifdef NETWMDEBUG
03587 fprintf(stderr, "NETWinInfo::event: calling changeState(%lx, %lx)\n",
03588 state, mask);
03589 #endif
03590
03591 changeState(state, mask);
03592 } else if (event->xclient.message_type == net_wm_desktop) {
03593 dirty = WMDesktop;
03594
03595 if( event->xclient.data.l[0] == OnAllDesktops )
03596 changeDesktop( OnAllDesktops );
03597 else
03598 changeDesktop(event->xclient.data.l[0] + 1);
03599 }
03600 }
03601
03602 if (event->type == PropertyNotify) {
03603
03604 #ifdef NETWMDEBUG
03605 fprintf(stderr, "NETWinInfo::event: handling PropertyNotify event\n");
03606 #endif
03607
03608 XEvent pe = *event;
03609
03610 Bool done = False;
03611 Bool compaction = False;
03612 while (! done) {
03613
03614 #ifdef NETWMDEBUG
03615 fprintf(stderr, "NETWinInfo::event: loop fire\n");
03616 #endif
03617
03618 if (pe.xproperty.atom == net_wm_name)
03619 dirty |= WMName;
03620 else if (pe.xproperty.atom == net_wm_visible_name)
03621 dirty |= WMVisibleName;
03622 else if (pe.xproperty.atom == net_wm_desktop)
03623 dirty |= WMDesktop;
03624 else if (pe.xproperty.atom == net_wm_window_type)
03625 dirty |=WMWindowType;
03626 else if (pe.xproperty.atom == net_wm_state)
03627 dirty |= WMState;
03628 else if (pe.xproperty.atom == net_wm_strut)
03629 dirty |= WMStrut;
03630 else if (pe.xproperty.atom == net_wm_extended_strut)
03631 dirty2 |= WM2ExtendedStrut;
03632 else if (pe.xproperty.atom == net_wm_icon_geometry)
03633 dirty |= WMIconGeometry;
03634 else if (pe.xproperty.atom == net_wm_icon)
03635 dirty |= WMIcon;
03636 else if (pe.xproperty.atom == net_wm_pid)
03637 dirty |= WMPid;
03638 else if (pe.xproperty.atom == net_wm_handled_icons)
03639 dirty |= WMHandledIcons;
03640 else if (pe.xproperty.atom == net_startup_id)
03641 dirty2 |= WM2StartupId;
03642 else if (pe.xproperty.atom == net_wm_allowed_actions)
03643 dirty2 |= WM2AllowedActions;
03644 else if (pe.xproperty.atom == kde_net_wm_system_tray_window_for)
03645 dirty |= WMKDESystemTrayWinFor;
03646 else if (pe.xproperty.atom == xa_wm_state)
03647 dirty |= XAWMState;
03648 else if (pe.xproperty.atom == net_frame_extents)
03649 dirty |= WMFrameExtents;
03650 else if (pe.xproperty.atom == kde_net_wm_frame_strut)
03651 dirty |= WMKDEFrameStrut;
03652 else if (pe.xproperty.atom == net_wm_icon_name)
03653 dirty |= WMIconName;
03654 else if (pe.xproperty.atom == net_wm_visible_icon_name)
03655 dirty |= WMVisibleIconName;
03656 else if (pe.xproperty.atom == net_wm_user_time)
03657 dirty2 |= WM2UserTime;
03658 else if (pe.xproperty.atom == XA_WM_HINTS)
03659 dirty2 |= WM2GroupLeader;
03660 else if (pe.xproperty.atom == XA_WM_TRANSIENT_FOR)
03661 dirty2 |= WM2TransientFor;
03662 else if (pe.xproperty.atom == XA_WM_CLASS)
03663 dirty2 |= WM2WindowClass;
03664 else if (pe.xproperty.atom == wm_window_role)
03665 dirty2 |= WM2WindowRole;
03666 else if (pe.xproperty.atom == XA_WM_CLIENT_MACHINE)
03667 dirty2 |= WM2ClientMachine;
03668 else {
03669
03670 #ifdef NETWMDEBUG
03671 fprintf(stderr, "NETWinInfo::event: putting back event and breaking\n");
03672 #endif
03673
03674 if ( compaction )
03675 XPutBackEvent(p->display, &pe);
03676 break;
03677 }
03678
03679 if (XCheckTypedWindowEvent(p->display, p->window, PropertyNotify, &pe) )
03680 compaction = True;
03681 else
03682 break;
03683 }
03684
03685 do_update = true;
03686 } else if (event->type == ConfigureNotify) {
03687
03688 #ifdef NETWMDEBUG
03689 fprintf(stderr, "NETWinInfo::event: handling ConfigureNotify event\n");
03690 #endif
03691
03692 dirty |= WMGeometry;
03693
03694
03695 p->win_geom.pos.x = event->xconfigure.x;
03696 p->win_geom.pos.y = event->xconfigure.y;
03697 p->win_geom.size.width = event->xconfigure.width;
03698 p->win_geom.size.height = event->xconfigure.height;
03699 }
03700
03701 if( do_update )
03702 update( props );
03703
03704 if( properties_size > PROPERTIES_SIZE )
03705 properties_size = PROPERTIES_SIZE;
03706 for( int i = 0;
03707 i < properties_size;
03708 ++i )
03709 properties[ i ] = props[ i ];
03710 }
03711
03712 void NETWinInfo::updateWMState() {
03713 unsigned long props[ PROPERTIES_SIZE ] = { XAWMState, 0 };
03714 assert( PROPERTIES_SIZE == 2 );
03715 update( props );
03716 }
03717
03718 void NETWinInfo::update(const unsigned long dirty_props[]) {
03719 Atom type_ret;
03720 int format_ret;
03721 unsigned long nitems_ret, unused;
03722 unsigned char *data_ret;
03723 unsigned long props[ PROPERTIES_SIZE ];
03724 for( int i = 0;
03725 i < PROPERTIES_SIZE;
03726 ++i )
03727 props[ i ] = dirty_props[ i ] & p->properties[ i ];
03728 const unsigned long& dirty = props[ PROTOCOLS ];
03729 const unsigned long& dirty2 = props[ PROTOCOLS2 ];
03730
03731
03732 if( dirty_props[ PROTOCOLS ] & XAWMState )
03733 props[ PROTOCOLS ] |= XAWMState;
03734
03735 if (dirty & XAWMState) {
03736 p->mapping_state = Withdrawn;
03737 if (XGetWindowProperty(p->display, p->window, xa_wm_state, 0l, 1l,
03738 False, xa_wm_state, &type_ret, &format_ret,
03739 &nitems_ret, &unused, &data_ret)
03740 == Success) {
03741 if (type_ret == xa_wm_state && format_ret == 32 &&
03742 nitems_ret == 1) {
03743 long *state = (long *) data_ret;
03744
03745 switch(*state) {
03746 case IconicState:
03747 p->mapping_state = Iconic;
03748 break;
03749 case NormalState:
03750 p->mapping_state = Visible;
03751 break;
03752 case WithdrawnState:
03753 default:
03754 p->mapping_state = Withdrawn;
03755 break;
03756 }
03757
03758 p->mapping_state_dirty = False;
03759 }
03760 if ( data_ret )
03761 XFree(data_ret);
03762 }
03763 }
03764
03765 if (dirty & WMState) {
03766 p->state = 0;
03767 if (XGetWindowProperty(p->display, p->window, net_wm_state, 0l, 2048l,
03768 False, XA_ATOM, &type_ret, &format_ret,
03769 &nitems_ret, &unused, &data_ret)
03770 == Success) {
03771 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
03772
03773 #ifdef NETWMDEBUG
03774 fprintf(stderr, "NETWinInfo::update: updating window state (%ld)\n",
03775 nitems_ret);
03776 #endif
03777
03778 long *states = (long *) data_ret;
03779 unsigned long count;
03780
03781 for (count = 0; count < nitems_ret; count++) {
03782 #ifdef NETWMDEBUG
03783 char* data_ret = XGetAtomName(p->display, (Atom) states[count]);
03784 fprintf(stderr,
03785 "NETWinInfo::update: adding window state %ld '%s'\n",
03786 states[count], data_ret );
03787 if ( data_ret )
03788 XFree( data_ret );
03789 #endif
03790
03791 if ((Atom) states[count] == net_wm_state_modal)
03792 p->state |= Modal;
03793 else if ((Atom) states[count] == net_wm_state_sticky)
03794 p->state |= Sticky;
03795 else if ((Atom) states[count] == net_wm_state_max_vert)
03796 p->state |= MaxVert;
03797 else if ((Atom) states[count] == net_wm_state_max_horiz)
03798 p->state |= MaxHoriz;
03799 else if ((Atom) states[count] == net_wm_state_shaded)
03800 p->state |= Shaded;
03801 else if ((Atom) states[count] == net_wm_state_skip_taskbar)
03802 p->state |= SkipTaskbar;
03803 else if ((Atom) states[count] == net_wm_state_skip_pager)
03804 p->state |= SkipPager;
03805 else if ((Atom) states[count] == net_wm_state_hidden)
03806 p->state |= Hidden;
03807 else if ((Atom) states[count] == net_wm_state_fullscreen)
03808 p->state |= FullScreen;
03809 else if ((Atom) states[count] == net_wm_state_above)
03810 p->state |= KeepAbove;
03811 else if ((Atom) states[count] == net_wm_state_below)
03812 p->state |= KeepBelow;
03813 else if ((Atom) states[count] == net_wm_state_demands_attention)
03814 p->state |= DemandsAttention;
03815 else if ((Atom) states[count] == net_wm_state_stays_on_top)
03816 p->state |= StaysOnTop;
03817 }
03818 }
03819 if ( data_ret )
03820 XFree(data_ret);
03821 }
03822 }
03823
03824 if (dirty & WMDesktop) {
03825 p->desktop = 0;
03826 if (XGetWindowProperty(p->display, p->window, net_wm_desktop, 0l, 1l,
03827 False, XA_CARDINAL, &type_ret,
03828 &format_ret, &nitems_ret,
03829 &unused, &data_ret)
03830 == Success) {
03831 if (type_ret == XA_CARDINAL && format_ret == 32 &&
03832 nitems_ret == 1) {
03833 p->desktop = *((long *) data_ret);
03834 if ((signed) p->desktop != OnAllDesktops)
03835 p->desktop++;
03836
03837 if ( p->desktop == 0 )
03838 p->desktop = OnAllDesktops;
03839 }
03840 if ( data_ret )
03841 XFree(data_ret);
03842 }
03843 }
03844
03845 if (dirty & WMName) {
03846 delete[] p->name;
03847 p->name = NULL;
03848 if (XGetWindowProperty(p->display, p->window, net_wm_name, 0l,
03849 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
03850 &format_ret, &nitems_ret, &unused, &data_ret)
03851 == Success) {
03852 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
03853 p->name = nstrndup((const char *) data_ret, nitems_ret);
03854 }
03855
03856 if( data_ret )
03857 XFree(data_ret);
03858 }
03859 }
03860
03861 if (dirty & WMVisibleName) {
03862 delete[] p->visible_name;
03863 p->visible_name = NULL;
03864 if (XGetWindowProperty(p->display, p->window, net_wm_visible_name, 0l,
03865 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
03866 &format_ret, &nitems_ret, &unused, &data_ret)
03867 == Success) {
03868 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
03869 p->visible_name = nstrndup((const char *) data_ret, nitems_ret);
03870 }
03871
03872 if( data_ret )
03873 XFree(data_ret);
03874 }
03875 }
03876
03877 if (dirty & WMIconName) {
03878 delete[] p->icon_name;
03879 p->icon_name = NULL;
03880 if (XGetWindowProperty(p->display, p->window, net_wm_icon_name, 0l,
03881 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
03882 &format_ret, &nitems_ret, &unused, &data_ret)
03883 == Success) {
03884 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
03885 p->icon_name = nstrndup((const char *) data_ret, nitems_ret);
03886 }
03887
03888 if( data_ret )
03889 XFree(data_ret);
03890 }
03891 }
03892
03893 if (dirty & WMVisibleIconName)
03894 {
03895 delete[] p->visible_icon_name;
03896 p->visible_icon_name = NULL;
03897 if (XGetWindowProperty(p->display, p->window, net_wm_visible_icon_name, 0l,
03898 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
03899 &format_ret, &nitems_ret, &unused, &data_ret)
03900 == Success) {
03901 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
03902 p->visible_icon_name = nstrndup((const char *) data_ret, nitems_ret);
03903 }
03904
03905 if( data_ret )
03906 XFree(data_ret);
03907 }
03908 }
03909
03910 if (dirty & WMWindowType) {
03911 p->types.reset();
03912 p->types[ 0 ] = Unknown;
03913 p->has_net_support = false;
03914 if (XGetWindowProperty(p->display, p->window, net_wm_window_type, 0l, 2048l,
03915 False, XA_ATOM, &type_ret, &format_ret,
03916 &nitems_ret, &unused, &data_ret)
03917 == Success) {
03918 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
03919
03920 #ifdef NETWMDEBUG
03921 fprintf(stderr, "NETWinInfo::update: getting window type (%ld)\n",
03922 nitems_ret);
03923 #endif
03924
03925 p->has_net_support = true;
03926
03927 unsigned long count = 0;
03928 long *types = (long *) data_ret;
03929 int pos = 0;
03930
03931 while (count < nitems_ret) {
03932
03933 #ifdef NETWMDEBUG
03934 char* debug_type = XGetAtomName(p->display, (Atom) types[count]);
03935 fprintf(stderr,
03936 "NETWinInfo::update: examining window type %ld %s\n",
03937 types[count], debug_type );
03938 if ( debug_type )
03939 XFree( debug_type );
03940 #endif
03941
03942 if ((Atom) types[count] == net_wm_window_type_normal)
03943 p->types[ pos++ ] = Normal;
03944 else if ((Atom) types[count] == net_wm_window_type_desktop)
03945 p->types[ pos++ ] = Desktop;
03946 else if ((Atom) types[count] == net_wm_window_type_dock)
03947 p->types[ pos++ ] = Dock;
03948 else if ((Atom) types[count] == net_wm_window_type_toolbar)
03949 p->types[ pos++ ] = Tool;
03950 else if ((Atom) types[count] == net_wm_window_type_menu)
03951 p->types[ pos++ ] = Menu;
03952 else if ((Atom) types[count] == net_wm_window_type_dialog)
03953 p->types[ pos++ ] = Dialog;
03954 else if ((Atom) types[count] == net_wm_window_type_utility)
03955 p->types[ pos++ ] = Utility;
03956 else if ((Atom) types[count] == net_wm_window_type_splash)
03957 p->types[ pos++ ] = Splash;
03958 else if ((Atom) types[count] == kde_net_wm_window_type_override)
03959 p->types[ pos++ ] = Override;
03960 else if ((Atom) types[count] == kde_net_wm_window_type_topmenu)
03961 p->types[ pos++ ] = TopMenu;
03962
03963 count++;
03964 }
03965 }
03966
03967 if ( data_ret )
03968 XFree(data_ret);
03969 }
03970 }
03971
03972 if (dirty & WMStrut) {
03973 p->strut = NETStrut();
03974 if (XGetWindowProperty(p->display, p->window, net_wm_strut, 0l, 4l,
03975 False, XA_CARDINAL, &type_ret, &format_ret,
03976 &nitems_ret, &unused, &data_ret)
03977 == Success) {
03978 if (type_ret == XA_CARDINAL && format_ret == 32 &&
03979 nitems_ret == 4) {
03980 long *d = (long *) data_ret;
03981 p->strut.left = d[0];
03982 p->strut.right = d[1];
03983 p->strut.top = d[2];
03984 p->strut.bottom = d[3];
03985 }
03986 if ( data_ret )
03987 XFree(data_ret);
03988 }
03989 }
03990
03991 if (dirty2 & WM2ExtendedStrut) {
03992 p->extended_strut = NETExtendedStrut();
03993 if (XGetWindowProperty(p->display, p->window, net_wm_extended_strut, 0l, 12l,
03994 False, XA_CARDINAL, &type_ret, &format_ret,
03995 &nitems_ret, &unused, &data_ret)
03996 == Success) {
03997 if (type_ret == XA_CARDINAL && format_ret == 32 &&
03998 nitems_ret == 12) {
03999 long *d = (long *) data_ret;
04000 p->extended_strut.left_width = d[0];
04001 p->extended_strut.right_width = d[1];
04002 p->extended_strut.top_width = d[2];
04003 p->extended_strut.bottom_width = d[3];
04004 p->extended_strut.left_start = d[4];
04005 p->extended_strut.left_end = d[5];
04006 p->extended_strut.right_start = d[6];
04007 p->extended_strut.right_end = d[7];
04008 p->extended_strut.top_start = d[8];
04009 p->extended_strut.top_end = d[9];
04010 p->extended_strut.bottom_start = d[10];
04011 p->extended_strut.bottom_end = d[11];
04012 }
04013 if ( data_ret )
04014 XFree(data_ret);
04015 }
04016 }
04017
04018 if (dirty & WMIconGeometry) {
04019 p->icon_geom = NETRect();
04020 if (XGetWindowProperty(p->display, p->window, net_wm_icon_geometry, 0l, 4l,
04021 False, XA_CARDINAL, &type_ret, &format_ret,
04022 &nitems_ret, &unused, &data_ret)
04023 == Success) {
04024 if (type_ret == XA_CARDINAL && format_ret == 32 &&
04025 nitems_ret == 4) {
04026 long *d = (long *) data_ret;
04027 p->icon_geom.pos.x = d[0];
04028 p->icon_geom.pos.y = d[1];
04029 p->icon_geom.size.width = d[2];
04030 p->icon_geom.size.height = d[3];
04031 }
04032 if ( data_ret )
04033 XFree(data_ret);
04034 }
04035 }
04036
04037 if (dirty & WMIcon) {
04038 readIcon(p->display,p->window,net_wm_icon,p->icons,p->icon_count);
04039 }
04040
04041 if (dirty & WMKDESystemTrayWinFor) {
04042 p->kde_system_tray_win_for = 0;
04043 if (XGetWindowProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
04044 0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
04045 &nitems_ret, &unused, &data_ret)
04046 == Success) {
04047 if (type_ret == XA_WINDOW && format_ret == 32 &&
04048 nitems_ret == 1) {
04049 p->kde_system_tray_win_for = *((Window *) data_ret);
04050 if ( p->kde_system_tray_win_for == 0 )
04051 p->kde_system_tray_win_for = p->root;
04052 }
04053 if ( data_ret )
04054 XFree(data_ret);
04055 }
04056 }
04057
04058 if (dirty & WMFrameExtents) {
04059 p->frame_strut = NETStrut();
04060 bool ok = false;
04061 if (XGetWindowProperty(p->display, p->window, net_frame_extents,
04062 0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
04063 &nitems_ret, &unused, &data_ret) == Success) {
04064 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
04065 ok = true;
04066 long *d = (long *) data_ret;
04067
04068 p->frame_strut.left = d[0];
04069 p->frame_strut.right = d[1];
04070 p->frame_strut.top = d[2];
04071 p->frame_strut.bottom = d[3];
04072 }
04073 if ( data_ret )
04074 XFree(data_ret);
04075 }
04076 if (!ok && XGetWindowProperty(p->display, p->window, kde_net_wm_frame_strut,
04077 0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
04078 &nitems_ret, &unused, &data_ret) == Success) {
04079 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
04080 ok = true;
04081 long *d = (long *) data_ret;
04082
04083 p->frame_strut.left = d[0];
04084 p->frame_strut.right = d[1];
04085 p->frame_strut.top = d[2];
04086 p->frame_strut.bottom = d[3];
04087 }
04088 if ( data_ret )
04089 XFree(data_ret);
04090 }
04091 }
04092
04093 if (dirty & WMPid) {
04094 p->pid = 0;
04095 if (XGetWindowProperty(p->display, p->window, net_wm_pid, 0l, 1l,
04096 False, XA_CARDINAL, &type_ret, &format_ret,
04097 &nitems_ret, &unused, &data_ret) == Success) {
04098 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
04099 p->pid = *((long *) data_ret);
04100 }
04101 if ( data_ret )
04102 XFree(data_ret);
04103 }
04104 }
04105
04106 if (dirty2 & WM2StartupId)
04107 {
04108 delete[] p->startup_id;
04109 p->startup_id = NULL;
04110 if (XGetWindowProperty(p->display, p->window, net_startup_id, 0l,
04111 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
04112 &format_ret, &nitems_ret, &unused, &data_ret)
04113 == Success) {
04114 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
04115 p->startup_id = nstrndup((const char *) data_ret, nitems_ret);
04116 }
04117
04118 if( data_ret )
04119 XFree(data_ret);
04120 }
04121 }
04122
04123 if( dirty2 & WM2AllowedActions ) {
04124 p->allowed_actions = 0;
04125 if (XGetWindowProperty(p->display, p->window, net_wm_allowed_actions, 0l, 2048l,
04126 False, XA_ATOM, &type_ret, &format_ret,
04127 &nitems_ret, &unused, &data_ret)
04128 == Success) {
04129 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
04130
04131 #ifdef NETWMDEBUG
04132 fprintf(stderr, "NETWinInfo::update: updating allowed actions (%ld)\n",
04133 nitems_ret);
04134 #endif
04135
04136 long *actions = (long *) data_ret;
04137 unsigned long count;
04138
04139 for (count = 0; count < nitems_ret; count++) {
04140 #ifdef NETWMDEBUG
04141 fprintf(stderr,
04142 "NETWinInfo::update: adding allowed action %ld '%s'\n",
04143 actions[count],
04144 XGetAtomName(p->display, (Atom) actions[count]));
04145 #endif
04146
04147 if ((Atom) actions[count] == net_wm_action_move)
04148 p->allowed_actions |= ActionMove;
04149 if ((Atom) actions[count] == net_wm_action_resize)
04150 p->allowed_actions |= ActionResize;
04151 if ((Atom) actions[count] == net_wm_action_minimize)
04152 p->allowed_actions |= ActionMinimize;
04153 if ((Atom) actions[count] == net_wm_action_shade)
04154 p->allowed_actions |= ActionShade;
04155 if ((Atom) actions[count] == net_wm_action_stick)
04156 p->allowed_actions |= ActionStick;
04157 if ((Atom) actions[count] == net_wm_action_max_vert)
04158 p->allowed_actions |= ActionMaxVert;
04159 if ((Atom) actions[count] == net_wm_action_max_horiz)
04160 p->allowed_actions |= ActionMaxHoriz;
04161 if ((Atom) actions[count] == net_wm_action_fullscreen)
04162 p->allowed_actions |= ActionFullScreen;
04163 if ((Atom) actions[count] == net_wm_action_change_desk)
04164 p->allowed_actions |= ActionChangeDesktop;
04165 if ((Atom) actions[count] == net_wm_action_close)
04166 p->allowed_actions |= ActionClose;
04167 }
04168 }
04169 if ( data_ret )
04170 XFree(data_ret);
04171 }
04172 }
04173
04174 if (dirty2 & WM2UserTime) {
04175 p->user_time = -1U;
04176 if (XGetWindowProperty(p->display, p->window, net_wm_user_time, 0l, 1l,
04177 False, XA_CARDINAL, &type_ret, &format_ret,
04178 &nitems_ret, &unused, &data_ret) == Success) {
04179
04180 if (type_ret == XA_CARDINAL && format_ret == 32 ) {
04181 p->user_time = *((long *) data_ret);
04182 }
04183 if ( data_ret )
04184 XFree(data_ret);
04185 }
04186 }
04187
04188 if (dirty2 & WM2TransientFor) {
04189 p->transient_for = None;
04190 XGetTransientForHint(p->display, p->window, &p->transient_for);
04191 }
04192
04193 if (dirty2 & WM2GroupLeader) {
04194 XWMHints *hints = XGetWMHints(p->display, p->window);
04195 p->window_group = None;
04196 if ( hints )
04197 {
04198 if( hints->flags & WindowGroupHint )
04199 p->window_group = hints->window_group;
04200 XFree( reinterpret_cast< char* >( hints ));
04201 }
04202 }
04203
04204 if( dirty2 & WM2WindowClass ) {
04205 delete[] p->class_class;
04206 delete[] p->class_name;
04207 p->class_class = NULL;
04208 p->class_name = NULL;
04209 XClassHint hint;
04210 if( XGetClassHint( p->display, p->window, &hint )) {
04211 p->class_class = strdup( hint.res_class );
04212 p->class_name = strdup( hint.res_name );
04213 XFree( hint.res_class );
04214 XFree( hint.res_name );
04215 }
04216 }
04217
04218 if( dirty2 & WM2WindowRole ) {
04219 delete[] p->role;
04220 p->role = NULL;
04221 if (XGetWindowProperty(p->display, p->window, wm_window_role, 0l,
04222 MAX_PROP_SIZE, False, XA_STRING, &type_ret,
04223 &format_ret, &nitems_ret, &unused, &data_ret)
04224 == Success) {
04225 if (type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0) {
04226 p->role = nstrndup((const char *) data_ret, nitems_ret);
04227 }
04228 if( data_ret )
04229 XFree(data_ret);
04230 }
04231 }
04232
04233 if( dirty2 & WM2ClientMachine ) {
04234 delete[] p->client_machine;
04235 p->client_machine = NULL;
04236 if (XGetWindowProperty(p->display, p->window, XA_WM_CLIENT_MACHINE, 0l,
04237 MAX_PROP_SIZE, False, XA_STRING, &type_ret,
04238 &format_ret, &nitems_ret, &unused, &data_ret)
04239 == Success) {
04240 if (type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0) {
04241 p->client_machine = nstrndup((const char *) data_ret, nitems_ret);
04242 }
04243 if( data_ret )
04244 XFree(data_ret);
04245 }
04246 }
04247 }
04248
04249
04250 NETRect NETWinInfo::iconGeometry() const {
04251 return p->icon_geom;
04252 }
04253
04254
04255 unsigned long NETWinInfo::state() const {
04256 return p->state;
04257 }
04258
04259
04260 NETStrut NETWinInfo::strut() const {
04261 return p->strut;
04262 }
04263
04264 NETExtendedStrut NETWinInfo::extendedStrut() const {
04265 return p->extended_strut;
04266 }
04267
04268 bool NET::typeMatchesMask( WindowType type, unsigned long mask ) {
04269 switch( type ) {
04270 #define CHECK_TYPE_MASK( type ) \
04271 case type: \
04272 if( mask & type##Mask ) \
04273 return true; \
04274 break;
04275 CHECK_TYPE_MASK( Normal )
04276 CHECK_TYPE_MASK( Desktop )
04277 CHECK_TYPE_MASK( Dock )
04278 CHECK_TYPE_MASK( Toolbar )
04279 CHECK_TYPE_MASK( Menu )
04280 CHECK_TYPE_MASK( Dialog )
04281 CHECK_TYPE_MASK( Override )
04282 CHECK_TYPE_MASK( TopMenu )
04283 CHECK_TYPE_MASK( Utility )
04284 CHECK_TYPE_MASK( Splash )
04285 #undef CHECK_TYPE_MASK
04286 default:
04287 break;
04288 }
04289 return false;
04290 }
04291
04292 NET::WindowType NETWinInfo::windowType( unsigned long supported_types ) const {
04293 for( int i = 0;
04294 i < p->types.size();
04295 ++i ) {
04296
04297 if( typeMatchesMask( p->types[ i ], supported_types ))
04298 return p->types[ i ];
04299 }
04300 return Unknown;
04301 }
04302
04303 NET::WindowType NETWinInfo::windowType() const {
04304 return p->types[ 0 ];
04305 }
04306
04307
04308 const char *NETWinInfo::name() const {
04309 return p->name;
04310 }
04311
04312
04313 const char *NETWinInfo::visibleName() const {
04314 return p->visible_name;
04315 }
04316
04317
04318 const char *NETWinInfo::iconName() const {
04319 return p->icon_name;
04320 }
04321
04322
04323 const char *NETWinInfo::visibleIconName() const {
04324 return p->visible_icon_name;
04325 }
04326
04327
04328 int NETWinInfo::desktop() const {
04329 return p->desktop;
04330 }
04331
04332 int NETWinInfo::pid() const {
04333 return p->pid;
04334 }
04335
04336 Time NETWinInfo::userTime() const {
04337 return p->user_time;
04338 }
04339
04340 const char* NETWinInfo::startupId() const {
04341 return p->startup_id;
04342 }
04343
04344 unsigned long NETWinInfo::allowedActions() const {
04345 return p->allowed_actions;
04346 }
04347
04348 bool NETWinInfo::hasNETSupport() const {
04349 return p->has_net_support;
04350 }
04351
04352 Window NETWinInfo::transientFor() const {
04353 return p->transient_for;
04354 }
04355
04356 Window NETWinInfo::groupLeader() const {
04357 return p->window_group;
04358 }
04359
04360 const char* NETWinInfo::windowClassClass() const {
04361 return p->class_class;
04362 }
04363
04364 const char* NETWinInfo::windowClassName() const {
04365 return p->class_name;
04366 }
04367
04368 const char* NETWinInfo::windowRole() const {
04369 return p->role;
04370 }
04371
04372 const char* NETWinInfo::clientMachine() const {
04373 return p->client_machine;
04374 }
04375
04376 Bool NETWinInfo::handledIcons() const {
04377 return p->handled_icons;
04378 }
04379
04380
04381 Window NETWinInfo::kdeSystemTrayWinFor() const {
04382 return p->kde_system_tray_win_for;
04383 }
04384
04385 const unsigned long* NETWinInfo::passedProperties() const {
04386 return p->properties;
04387 }
04388
04389 unsigned long NETWinInfo::properties() const {
04390 return p->properties[ PROTOCOLS ];
04391 }
04392
04393
04394 NET::MappingState NETWinInfo::mappingState() const {
04395 return p->mapping_state;
04396 }
04397
04398 void NETRootInfo::virtual_hook( int, void* )
04399 { }
04400
04401 void NETWinInfo::virtual_hook( int, void* )
04402 { }
04403
04404
04405
04406
04407 #if 0
04408 int NET::timestampCompare( Time time1, Time time2 )
04409 {
04410 if( time1 == time2 )
04411 return 0;
04412 return ( time1 - time2 ) < 0x7fffffffU ? 1 : -1;
04413 }
04414
04415 Time NET::timestampDiff( Time time1, Time time2 )
04416 {
04417 return time2 - time1;
04418 }
04419 #else
04420 int NET::timestampCompare( unsigned long time1_, unsigned long time2_ )
04421 {
04422 Q_UINT32 time1 = time1_;
04423 Q_UINT32 time2 = time2_;
04424 if( time1 == time2 )
04425 return 0;
04426 return Q_UINT32( time1 - time2 ) < 0x7fffffffU ? 1 : -1;
04427 }
04428
04429 int NET::timestampDiff( unsigned long time1_, unsigned long time2_ )
04430 {
04431 Q_UINT32 time1 = time1_;
04432 Q_UINT32 time2 = time2_;
04433 return Q_UINT32( time2 - time1 );
04434 }
04435 #endif
04436
04437
04438 #endif