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