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