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