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