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