chiark / gitweb /
Imported Upstream version 1.0.0
[e16] / src / gnome.c
1 /*
2  * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3  * Copyright (C) 2004-2008 Kim Woelders
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to
7  * deal in the Software without restriction, including without limitation the
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9  * sell copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies of the Software, its documentation and marketing & publicity
14  * materials, and acknowledgment shall be given in the documentation, materials
15  * and software packages that this Software was used.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #include "E.h"
25 #include "desktops.h"
26 #include "e16-ecore_hints.h"
27 #include "ewins.h"
28 #include "hints.h"
29 #include "xwin.h"
30
31 /* WIN_WM_NAME STRING - contains a string identifier for the WM's name */
32 #define XA_WIN_WM_NAME                     "_WIN_WM_NAME"
33
34 /* WIN_WM_NAME VERSION - contains a string identifier for the WM's version */
35 #define XA_WIN_WM_VERSION                  "_WIN_WM_VERSION"
36
37 /* WIN_AREA CARD32[2] contains the current desktop area X,Y */
38 #define XA_WIN_AREA                        "_WIN_AREA"
39
40 /* WIN_AREA CARD32[2] contains the current desktop area size WxH */
41 #define XA_WIN_AREA_COUNT                  "_WIN_AREA_COUNT"
42
43 /* array of atoms - atom being one of the following atoms */
44 #define XA_WIN_PROTOCOLS                   "_WIN_PROTOCOLS"
45
46 /* array of iocn in various sizes */
47 /* Type: array of CARD32 */
48 /*       first item is icon count (n) */
49 /*       second item is icon record length (in CARD32s) */
50 /*       this is followed by (n) icon records as follows */
51 /*           pixmap (XID) */
52 /*           mask (XID) */
53 /*           width (CARD32) */
54 /*           height (CARD32) */
55 /*           depth (of pixmap, mask is assumed to be of depth 1) (CARD32) */
56 /*           drawable (screen root drawable of pixmap) (XID) */
57 /*           ... additional fields can be added at the end of this list */
58 #define XA_WIN_ICONS                    "_WIN_ICONS"
59
60 /* WIN_WORKSPACE CARD32 contains the current desktop number */
61 #define XA_WIN_WORKSPACE                   "_WIN_WORKSPACE"
62 /* WIN_WORKSPACE_COUNT CARD32 contains the number of desktops */
63 #define XA_WIN_WORKSPACE_COUNT             "_WIN_WORKSPACE_COUNT"
64
65 /* WIN_WORKSPACE_NAMES StringList (Text Property) of workspace names */
66 /* unused by enlightenment */
67 #define XA_WIN_WORKSPACE_NAMES             "_WIN_WORKSPACE_NAMES"
68
69 /* ********** Don't use this.. iffy at best. *********** */
70 /* The available work area for client windows. The WM can set this and the WM */
71 /* and/or clients may change it at any time. If it is changed the WM and/or  */
72 /* clients should honor the changes. If this property does not exist a client */
73 /* or WM can create it. */
74 /*
75  * CARD32              min_x;
76  * CARD32              min_y;
77  * CARD32              max_x;
78  * CARD32              max_y;
79  */
80 #define XA_WIN_WORKAREA                    "_WIN_WORKAREA"
81 /* array of 4 CARD32's */
82
83 /* This is a list of window id's the WM is currently managing - primarily */
84 /* for being able to have external "tasklist" apps */
85 #define XA_WIN_CLIENT_LIST                 "_WIN_CLIENT_LIST"
86 /* array of N XID's */
87
88 /*********************************************************/
89 /* Properties on client windows                          */
90 /*********************************************************/
91
92 /* The layer the window exists in */
93 /*      0 = Desktop */
94 /*      1 = Below */
95 /*      2 = Normal (default app layer) */
96 /*      4 = OnTop */
97 /*      6 = Dock (always on top - for panel) */
98 /* The app sets this alone, not the WM. If this property changes the WM */
99 /* should comply and change the appearance/behavior of the Client window */
100 /* if this hint does nto exist the WM Will create it ont he Client window */
101 #define WIN_LAYER_DESKTOP                0
102 #define WIN_LAYER_BELOW                  2
103 #define WIN_LAYER_NORMAL                 4
104 #define WIN_LAYER_ONTOP                  6
105 #define WIN_LAYER_DOCK                   8
106 #define WIN_LAYER_ABOVE_DOCK             10
107 #define WIN_LAYER_MENU                   12
108 #define XA_WIN_LAYER                     "_WIN_LAYER"
109 /* WIN_LAYER = CARD32 */
110
111 /* flags for the window's state. The WM will change these as needed when */
112 /* state changes. If the property contains info on client map, E will modify */
113 /* the windows state accordingly. if the Hint does not exist the WM will */
114 /* create it on the client window. 0 for the bit means off, 1 means on. */
115 /* unused (default) values are 0 */
116
117 /* removed Minimized - no explanation of what it really means - ambiguity */
118 /* should not be here if not clear */
119 #define WIN_STATE_STICKY          (1<<0)        /* everyone knows sticky */
120 #define WIN_STATE_RESERVED_BIT1   (1<<1)        /* removed minimize here */
121 #define WIN_STATE_MAXIMIZED_VERT  (1<<2)        /* window in maximized V state */
122 #define WIN_STATE_MAXIMIZED_HORIZ (1<<3)        /* window in maximized H state */
123 #define WIN_STATE_HIDDEN          (1<<4)        /* not on taskbar but window visible */
124 #define WIN_STATE_SHADED          (1<<5)        /* shaded (NeXT style) */
125 #define WIN_STATE_HID_WORKSPACE   (1<<6)        /* not on current desktop */
126 #define WIN_STATE_HID_TRANSIENT   (1<<7)        /* owner of transient is hidden */
127 #define WIN_STATE_FIXED_POSITION  (1<<8)        /* window is fixed in position even */
128 #define WIN_STATE_ARRANGE_IGNORE  (1<<9)        /* ignore for auto arranging */
129                                          /* when scrolling about large */
130                                          /* virtual desktops ala fvwm */
131 #define XA_WIN_STATE              "_WIN_STATE"
132 /* WIN_STATE = CARD32 */
133
134 /* Preferences for behavior for app */
135 /* ONLY the client sets this */
136 #define WIN_HINTS_SKIP_FOCUS             (1<<0) /* "alt-tab" skips this win */
137 #define WIN_HINTS_SKIP_WINLIST           (1<<1) /* not in win list */
138 #define WIN_HINTS_SKIP_TASKBAR           (1<<2) /* not on taskbar */
139 #define WIN_HINTS_GROUP_TRANSIENT        (1<<3) /* ??????? */
140 #define WIN_HINTS_FOCUS_ON_CLICK         (1<<4) /* app only accepts focus when clicked */
141 #define WIN_HINTS_DO_NOT_COVER           (1<<5) /* attempt to not cover this window */
142 #define XA_WIN_HINTS                     "_WIN_HINTS"
143 /* WIN_HINTS = CARD32 */
144
145 /* Application state - also "color reactiveness" - the app can keep changing */
146 /* this property when it changes its state and the WM or monitoring program */
147 /* will pick this up and display somehting accordingly. ONLY the client sets */
148 /* this. */
149 #define WIN_APP_STATE_NONE                 0
150 #define WIN_APP_STATE_ACTIVE1              1
151 #define WIN_APP_STATE_ACTIVE2              2
152 #define WIN_APP_STATE_ERROR1               3
153 #define WIN_APP_STATE_ERROR2               4
154 #define WIN_APP_STATE_FATAL_ERROR1         5
155 #define WIN_APP_STATE_FATAL_ERROR2         6
156 #define WIN_APP_STATE_IDLE1                7
157 #define WIN_APP_STATE_IDLE2                8
158 #define WIN_APP_STATE_WAITING1             9
159 #define WIN_APP_STATE_WAITING2             10
160 #define WIN_APP_STATE_WORKING1             11
161 #define WIN_APP_STATE_WORKING2             12
162 #define WIN_APP_STATE_NEED_USER_INPUT1     13
163 #define WIN_APP_STATE_NEED_USER_INPUT2     14
164 #define WIN_APP_STATE_STRUGGLING1          15
165 #define WIN_APP_STATE_STRUGGLING2          16
166 #define WIN_APP_STATE_DISK_TRAFFIC1        17
167 #define WIN_APP_STATE_DISK_TRAFFIC2        18
168 #define WIN_APP_STATE_NETWORK_TRAFFIC1     19
169 #define WIN_APP_STATE_NETWORK_TRAFFIC2     20
170 #define WIN_APP_STATE_OVERLOADED1          21
171 #define WIN_APP_STATE_OVERLOADED2          22
172 #define WIN_APP_STATE_PERCENT000_1         23
173 #define WIN_APP_STATE_PERCENT000_2         24
174 #define WIN_APP_STATE_PERCENT010_1         25
175 #define WIN_APP_STATE_PERCENT010_2         26
176 #define WIN_APP_STATE_PERCENT020_1         27
177 #define WIN_APP_STATE_PERCENT020_2         28
178 #define WIN_APP_STATE_PERCENT030_1         29
179 #define WIN_APP_STATE_PERCENT030_2         30
180 #define WIN_APP_STATE_PERCENT040_1         31
181 #define WIN_APP_STATE_PERCENT040_2         32
182 #define WIN_APP_STATE_PERCENT050_1         33
183 #define WIN_APP_STATE_PERCENT050_2         34
184 #define WIN_APP_STATE_PERCENT060_1         35
185 #define WIN_APP_STATE_PERCENT060_2         36
186 #define WIN_APP_STATE_PERCENT070_1         37
187 #define WIN_APP_STATE_PERCENT070_2         38
188 #define WIN_APP_STATE_PERCENT080_1         39
189 #define WIN_APP_STATE_PERCENT080_2         40
190 #define WIN_APP_STATE_PERCENT090_1         41
191 #define WIN_APP_STATE_PERCENT090_2         42
192 #define WIN_APP_STATE_PERCENT100_1         43
193 #define WIN_APP_STATE_PERCENT100_2         44
194 #define XA_WIN_APP_STATE                   "_WIN_APP_STATE"
195 /* WIN_APP_STATE = CARD32 */
196
197 /* Expanded space occupied - this is the area on screen the app's window */
198 /* will occupy when "expanded" - ie if you have a button on an app that */
199 /* "hides" it by reducing its size, this is the geometry of the expanded */
200 /* window - so the window manager can allow for this when doign auto */
201 /* positioing of client windows assuming the app can at any point use this */
202 /* this area and thus try and keep it clear. ONLY the client sets this */
203 /*
204  * CARD32              x;
205  * CARD32              y;
206  * CARD32              width;
207  * CARD32              height;
208  */
209 #define XA_WIN_EXPANDED_SIZE               "_WIN_EXPANDED_SIZE"
210 /* array of 4 CARD32's */
211
212 /* CARD32 that contians the desktop number the application is on If the */
213 /* application's state is "sticky" it is irrelevant. Only the WM should */
214 /* change this. */
215 #define XA_WIN_WORKSPACE                   "_WIN_WORKSPACE"
216
217 /* This atom is a 32-bit integer that is either 0 or 1 (currently). */
218 /* 0 denotes everything is as per usual but 1 denotes that ALL configure */
219 /* requests by the client on the client window with this property are */
220 /* not just a simple "moving" of the window, but the result of a user */
221 /* moving the window BUT the client handling that interaction by moving */
222 /* its own window. The window manager should respond accordingly by assuming */
223 /* any configure requests for this window whilst this atom is "active" in */
224 /* the "1" state are a client move and should handle flipping desktops if */
225 /* the window is being dragged "off screem" or across desktop boundaries */
226 /* etc. This atom is ONLY ever set by the client */
227 #define XA_WIN_CLIENT_MOVING               "_WIN_CLIENT_MOVING"
228 /* WIN_CLIENT_MOVING = CARD32 */
229
230 /* Designed for checking if the WIN_ supporting WM is still there  */
231 /* and kicking about - basically check this property - check the window */
232 /* ID it points to - then check that window Id has this property too */
233 /* if that is the case the WIN_ supporting WM is there and alive and the */
234 /* list of WIN_PROTOCOLS is valid */
235 #define XA_WIN_SUPPORTING_WM_CHECK         "_WIN_SUPPORTING_WM_CHECK"
236 /* CARD32 */
237
238 /*********************************************************/
239 /* How an app can modify things after mapping            */
240 /*********************************************************/
241
242 /* For a client to change layer or state it should send a client message */
243 /* to the root window as follows: */
244 /*
245  * Display             *disp;
246  * Window               root, client_window;
247  * XClientMessageEvent  xev;
248  * CARD32                new_layer;
249  * 
250  *     xev.type = ClientMessage;
251  *     xev.window = client_window;
252  *     xev.message_type = EInternAtom(XA_WIN_LAYER);
253  *     xev.format = 32;
254  *     xev.data.l[0] = new_layer;
255  *     xev.data.l[1] = CurrentTime;
256  *     XSendEvent(disp, root, False, SubstructureNotifyMask, (XEvent *) &xev);
257  */
258 /*
259  * Display             *disp;
260  * Window               root, client_window;
261  * XClientMessageEvent  xev;
262  * CARD32               mask_of_members_to_change, new_members;
263  * 
264  *     xev.type = ClientMessage;
265  *     xev.window = client_window;
266  *     xev.message_type = EInternAtom(XA_WIN_STATE);
267  *     xev.format = 32;
268  *     xev.data.l[0] = mask_of_members_to_change;
269  *     xev.data.l[1] = new_members;
270  *     xev.data.l[2] = CurrentTimep;
271  *     XSendEvent(disp, root, False, SubstructureNotifyMask, (XEvent *) &xev);
272  */
273 /*
274  * Display             *disp;
275  * Window               root, client_window;
276  * XClientMessageEvent  xev;
277  * CARD32               new_desktop_number;
278  * 
279  *     xev.type = ClientMessage;
280  *     xev.window = client_window;
281  *     xev.message_type = EInternAtom(XA_WIN_WORKSPACE);
282  *     xev.format = 32;
283  *     xev.data.l[0] = new_desktop_number;
284  *     xev.data.l[2] = CurrentTimep;
285  *     XSendEvent(disp, root, False, SubstructureNotifyMask, (XEvent *) &xev);
286  */
287
288 #if 0                           /* Does nothing useful */
289 static void
290 GNOME_GetHintIcons(EWin * ewin, Atom atom_change)
291 {
292    static Atom         atom_get = 0;
293    int                 num, i;
294    Ecore_X_ID         *plst;
295    Pixmap              pmap;
296    Pixmap              mask;
297
298    if (EwinIsInternal(ewin))
299       return;
300
301    if (!atom_get)
302       atom_get = EInternAtom(XA_WIN_ICONS);
303    if ((atom_change) && (atom_change != atom_get))
304       return;
305
306    num = ecore_x_window_prop_xid_list_get(EwinGetClientXwin(ewin), atom_get,
307                                           XA_PIXMAP, &plst);
308    if (num < 2)
309       return;
310
311    for (i = 0; i < num / 2; i++)
312      {
313         pmap = plst[2 * i];
314         mask = plst[2 * i + 1];
315      }
316    free(plst);
317 }
318 #endif
319
320 static void
321 GNOME_GetHintLayer(EWin * ewin, Atom atom_change)
322 {
323    static Atom         atom_get = 0;
324    int                 num;
325    unsigned int        layer;
326
327    if (EwinIsInternal(ewin))
328       return;
329
330    if (!atom_get)
331       atom_get = EInternAtom(XA_WIN_LAYER);
332    if ((atom_change) && (atom_change != atom_get))
333       return;
334
335    num = ecore_x_window_prop_card32_get(EwinGetClientXwin(ewin), atom_get,
336                                         &layer, 1);
337    if (num <= 0)
338       return;
339
340    EoSetLayer(ewin, layer);
341    EwinChange(ewin, EWIN_CHANGE_LAYER);
342 }
343
344 static void
345 GNOME_GetHintState(EWin * ewin, Atom atom_change)
346 {
347    static Atom         atom_get = 0;
348    int                 num;
349    unsigned int        flags;
350
351    if (EwinIsInternal(ewin))
352       return;
353
354    if (!atom_get)
355       atom_get = EInternAtom(XA_WIN_STATE);
356    if ((atom_change) && (atom_change != atom_get))
357       return;
358
359    num = ecore_x_window_prop_card32_get(EwinGetClientXwin(ewin), atom_get,
360                                         &flags, 1);
361    if (num <= 0)
362       return;
363
364    if (flags & WIN_STATE_SHADED)
365       ewin->state.shaded = 1;
366    if (flags & WIN_STATE_STICKY)
367       EoSetSticky(ewin, 1);
368    if (flags & WIN_STATE_FIXED_POSITION)
369       EwinInhSetUser(ewin, move, 1);
370    if (flags & WIN_STATE_ARRANGE_IGNORE)
371       ewin->props.ignorearrange = 1;
372 }
373
374 #if 0                           /* Does nothing */
375 static void
376 GNOME_GetHintAppState(EWin * ewin, Atom atom_change)
377 {
378    static Atom         atom_get = 0;
379    int                 num;
380    unsigned int        flags;
381
382    /* have nothing interesting to do with an app state (lamp) right now */
383
384    if (EwinIsInternal(ewin))
385       return;
386
387    if (!atom_get)
388       atom_get = EInternAtom(XA_WIN_APP_STATE);
389    if ((atom_change) && (atom_change != atom_get))
390       return;
391
392    num = ecore_x_window_prop_card32_get(EwinGetClientXwin(ewin), atom_get,
393                                         &flags, 1);
394    if (num <= 0)
395       return;
396 }
397 #endif
398
399 static void
400 GNOME_GetHintDesktop(EWin * ewin, Atom atom_change)
401 {
402    static Atom         atom_get = 0;
403    int                 num;
404    unsigned int        desk;
405
406    if (EwinIsInternal(ewin))
407       return;
408
409    if (!atom_get)
410       atom_get = EInternAtom(XA_WIN_WORKSPACE);
411    if ((atom_change) && (atom_change != atom_get))
412       return;
413
414    num = ecore_x_window_prop_card32_get(EwinGetClientXwin(ewin), atom_get,
415                                         &desk, 1);
416    if (num <= 0)
417       return;
418
419    EoSetDesk(ewin, DeskGet(desk));
420    EwinChange(ewin, EWIN_CHANGE_DESKTOP);
421 }
422
423 static void
424 GNOME_GetHint(EWin * ewin, Atom atom_change)
425 {
426    static Atom         atom_get = 0;
427    int                 num;
428    unsigned int        flags;
429
430    if (EwinIsInternal(ewin))
431       return;
432
433    if (!atom_get)
434       atom_get = EInternAtom(XA_WIN_HINTS);
435    if ((atom_change) && (atom_change != atom_get))
436       return;
437
438    num = ecore_x_window_prop_card32_get(EwinGetClientXwin(ewin), atom_get,
439                                         &flags, 1);
440    if (num <= 0)
441       return;
442
443    if (flags & WIN_HINTS_SKIP_TASKBAR)
444       ewin->props.skip_ext_task = 1;
445    if (flags & WIN_HINTS_SKIP_FOCUS)
446       ewin->props.skip_focuslist = 1;
447    if (flags & WIN_HINTS_SKIP_WINLIST)
448       ewin->props.skip_winlist = 1;
449    if (flags & WIN_HINTS_FOCUS_ON_CLICK)
450       ewin->props.focusclick = 1;
451    if (flags & WIN_HINTS_DO_NOT_COVER)
452       ewin->props.never_use_area = 1;
453 }
454
455 void
456 GNOME_SetHint(const EWin * ewin)
457 {
458    static Atom         atom_set = 0;
459    unsigned int        val;
460
461    if ((ewin->type == EWIN_TYPE_MENU) || (ewin->type == EWIN_TYPE_PAGER))
462       return;
463    if (!atom_set)
464       atom_set = EInternAtom(XA_WIN_STATE);
465    val = 0;
466    if (EoIsSticky(ewin))
467       val |= WIN_STATE_STICKY;
468    if (ewin->state.shaded)
469       val |= WIN_STATE_SHADED;
470    if (EwinInhGetUser(ewin, move))
471       val |= WIN_STATE_FIXED_POSITION;
472    ecore_x_window_prop_card32_set(EwinGetClientXwin(ewin), atom_set, &val, 1);
473 }
474
475 void
476 GNOME_SetEwinArea(const EWin * ewin)
477 {
478    static Atom         atom_set = 0;
479    unsigned int        val[2];
480
481    if ((ewin->type == EWIN_TYPE_MENU) || (ewin->type == EWIN_TYPE_PAGER))
482       return;
483    if (!atom_set)
484       atom_set = EInternAtom(XA_WIN_AREA);
485    val[0] = ewin->area_x;
486    val[1] = ewin->area_y;
487    ecore_x_window_prop_card32_set(EwinGetClientXwin(ewin), atom_set, val, 2);
488 }
489
490 void
491 GNOME_SetEwinDesk(const EWin * ewin)
492 {
493    static Atom         atom_set = 0;
494    unsigned int        val;
495
496    if ((ewin->type == EWIN_TYPE_MENU) || (ewin->type == EWIN_TYPE_PAGER))
497       return;
498    if (!atom_set)
499       atom_set = EInternAtom(XA_WIN_WORKSPACE);
500    val = EoGetDeskNum(ewin);
501    ecore_x_window_prop_card32_set(EwinGetClientXwin(ewin), atom_set, &val, 1);
502 }
503
504 #if 0                           /* Does nothing */
505 static void
506 GNOME_GetExpandedSize(EWin * ewin, Atom atom_change)
507 {
508    static Atom         atom_get = 0;
509    int                 num;
510    unsigned int        exp[4];
511
512    if (EwinIsInternal(ewin))
513       return;
514
515    if (!atom_get)
516       atom_get = EInternAtom(XA_WIN_EXPANDED_SIZE);
517    if ((atom_change) && (atom_change != atom_get))
518       return;
519
520    num = ecore_x_window_prop_card32_get(EwinGetClientXwin(ewin), atom_get,
521                                         exp, 4);
522    if (num >= 4)
523      {
524 #if 0                           /* Not actually used */
525         ewin->expanded_x = retval[0];
526         ewin->expanded_y = retval[1];
527         ewin->expanded_width = retval[2];
528         ewin->expanded_height = retval[3];
529 #endif
530      }
531 }
532 #endif
533
534 static void
535 GNOME_SetUsedHints(void)
536 {
537    static Atom         atom_set = 0;
538    Ecore_X_Atom        list[10];
539
540    if (!atom_set)
541       atom_set = EInternAtom(XA_WIN_PROTOCOLS);
542    list[0] = EInternAtom(XA_WIN_LAYER);
543    list[1] = EInternAtom(XA_WIN_STATE);
544    list[2] = EInternAtom(XA_WIN_HINTS);
545    list[3] = EInternAtom(XA_WIN_APP_STATE);
546    list[4] = EInternAtom(XA_WIN_EXPANDED_SIZE);
547    list[5] = EInternAtom(XA_WIN_ICONS);
548    list[6] = EInternAtom(XA_WIN_WORKSPACE);
549    list[7] = EInternAtom(XA_WIN_WORKSPACE_COUNT);
550    list[8] = EInternAtom(XA_WIN_WORKSPACE_NAMES);
551    list[9] = EInternAtom(XA_WIN_CLIENT_LIST);
552    ecore_x_window_prop_atom_set(WinGetXwin(VROOT), atom_set, list, 10);
553 }
554
555 void
556 GNOME_SetCurrentArea(void)
557 {
558    static Atom         atom_set = 0;
559    unsigned int        val[2];
560    int                 ax, ay;
561
562    if (!atom_set)
563       atom_set = EInternAtom(XA_WIN_AREA);
564    DeskCurrentGetArea(&ax, &ay);
565    val[0] = ax;
566    val[1] = ay;
567    ecore_x_window_prop_card32_set(WinGetXwin(VROOT), atom_set, val, 2);
568 }
569
570 void
571 GNOME_SetCurrentDesk(void)
572 {
573    static Atom         atom_set = 0;
574    unsigned int        val;
575
576    if (!atom_set)
577       atom_set = EInternAtom(XA_WIN_WORKSPACE);
578    val = DesksGetCurrentNum();
579    ecore_x_window_prop_card32_set(WinGetXwin(VROOT), atom_set, &val, 1);
580 }
581
582 static void
583 GNOME_SetWMCheck(Window win_wm_check)
584 {
585    static Atom         atom_set = 0;
586    unsigned int        val;
587
588    if (!atom_set)
589       atom_set = EInternAtom(XA_WIN_SUPPORTING_WM_CHECK);
590    val = win_wm_check;
591    ecore_x_window_prop_card32_set(WinGetXwin(VROOT), atom_set, &val, 1);
592    ecore_x_window_prop_card32_set(win_wm_check, atom_set, &val, 1);
593 }
594
595 void
596 GNOME_SetDeskCount(void)
597 {
598    static Atom         atom_set = 0;
599    unsigned int        val;
600
601    if (!atom_set)
602       atom_set = EInternAtom(XA_WIN_WORKSPACE_COUNT);
603    val = DesksGetNumber();
604    ecore_x_window_prop_card32_set(WinGetXwin(VROOT), atom_set, &val, 1);
605 }
606
607 void
608 GNOME_SetAreaCount(void)
609 {
610    static Atom         atom_set = 0;
611    int                 ax, ay;
612    unsigned int        val[2];
613
614    if (!atom_set)
615       atom_set = EInternAtom(XA_WIN_AREA_COUNT);
616    DesksGetAreaSize(&ax, &ay);
617    val[0] = ax;
618    val[1] = ay;
619    ecore_x_window_prop_card32_set(WinGetXwin(VROOT), atom_set, val, 2);
620 }
621
622 void
623 GNOME_SetDeskNames(void)
624 {
625    static Atom         atom_set = 0;
626    char                s[1024], **names;
627    int                 i, n_desks;
628
629    if (!atom_set)
630       atom_set = EInternAtom(XA_WIN_WORKSPACE_NAMES);
631
632    n_desks = DesksGetNumber();
633    names = EMALLOC(char *, n_desks);
634
635    if (!names)
636       return;
637
638    for (i = 0; i < n_desks; i++)
639      {
640         Esnprintf(s, sizeof(s), "%i", i);
641         names[i] = Estrdup(s);
642      }
643
644    ecore_x_window_prop_string_list_set(WinGetXwin(VROOT), atom_set, names,
645                                        n_desks);
646
647    for (i = 0; i < n_desks; i++)
648       Efree(names[i]);
649    Efree(names);
650 }
651
652 void
653 GNOME_SetClientList(void)
654 {
655    static Atom         atom_set = 0;
656    unsigned int       *wl;
657    int                 j, i, num;
658    EWin               *const *lst;
659
660    if (!atom_set)
661       atom_set = EInternAtom(XA_WIN_CLIENT_LIST);
662
663    lst = EwinListOrderGet(&num);
664    wl = NULL;
665    j = 0;
666    if (lst)
667      {
668         wl = EMALLOC(unsigned int, num);
669
670         for (i = 0; i < num; i++)
671           {
672              if (!lst[i]->props.skip_ext_task && !EwinIsTransientChild(lst[i]))
673                 wl[j++] = EwinGetClientXwin(lst[i]);
674           }
675      }
676    ecore_x_window_prop_card32_set(WinGetXwin(VROOT), atom_set, wl, j);
677    Efree(wl);
678 }
679
680 static void
681 GNOME_SetWMNameVer(void)
682 {
683    static Atom         atom_set = 0, atom_set2 = 0;
684
685    if (!atom_set)
686       atom_set = EInternAtom(XA_WIN_WM_NAME);
687    ecore_x_window_prop_string_set(WinGetXwin(VROOT), atom_set, e_wm_name);
688
689    if (!atom_set2)
690       atom_set2 = EInternAtom(XA_WIN_WM_VERSION);
691    ecore_x_window_prop_string_set(WinGetXwin(VROOT), atom_set2, e_wm_version);
692 }
693
694 void
695 GNOME_DelHints(const EWin * ewin)
696 {
697    static Atom         atom_get[6] = { 0, 0, 0, 0, 0, 0 };
698    Window              win;
699
700    if (!atom_get[0])
701      {
702         atom_get[0] = EInternAtom(XA_WIN_WORKSPACE);
703         atom_get[1] = EInternAtom(XA_WIN_LAYER);
704         atom_get[2] = EInternAtom(XA_WIN_STATE);
705         atom_get[3] = EInternAtom(XA_WIN_HINTS);
706         atom_get[4] = EInternAtom(XA_WIN_APP_STATE);
707         atom_get[5] = EInternAtom(XA_WIN_AREA);
708      }
709
710    win = EwinGetClientXwin(ewin);
711    XDeleteProperty(disp, win, atom_get[0]);
712    XDeleteProperty(disp, win, atom_get[1]);
713    XDeleteProperty(disp, win, atom_get[2]);
714    XDeleteProperty(disp, win, atom_get[3]);
715    XDeleteProperty(disp, win, atom_get[4]);
716    XDeleteProperty(disp, win, atom_get[5]);
717 }
718
719 void
720 GNOME_GetHints(EWin * ewin, Atom atom_change)
721 {
722    GNOME_GetHintDesktop(ewin, atom_change);
723    GNOME_GetHintLayer(ewin, atom_change);
724    GNOME_GetHintState(ewin, atom_change);
725    GNOME_GetHint(ewin, atom_change);
726 #if 0                           /* Do nothing */
727    GNOME_GetHintIcons(ewin, atom_change);
728    GNOME_GetHintAppState(ewin, atom_change);
729    GNOME_GetExpandedSize(ewin, atom_change);
730 #endif
731 }
732
733 void
734 GNOME_SetHints(Window win_wm_check)
735 {
736    GNOME_SetWMNameVer();
737    GNOME_SetUsedHints();
738    GNOME_SetWMCheck(win_wm_check);
739    {
740       Atom                atom_set;
741       unsigned int        val;
742
743       atom_set = EInternAtom("_WIN_DESKTOP_BUTTON_PROXY");
744       Mode.button_proxy_win =
745          XCreateSimpleWindow(disp, WinGetXwin(VROOT), -80, -80, 24, 24, 0,
746                              0, 0);
747       val = Mode.button_proxy_win;
748       ecore_x_window_prop_card32_set(WinGetXwin(VROOT), atom_set, &val, 1);
749       ecore_x_window_prop_card32_set(Mode.button_proxy_win, atom_set, &val, 1);
750    }
751 }
752
753 int
754 GNOME_ProcessClientClientMessage(EWin * ewin, XClientMessageEvent * event)
755 {
756    static Atom         a4 = 0, a5 = 0;
757
758    if (!a4)
759       a4 = EInternAtom("_WIN_LAYER");
760    if (!a5)
761       a5 = EInternAtom("_WIN_STATE");
762
763    if (event->message_type == a4)
764      {
765         unsigned int        val;
766
767         val = event->data.l[0];
768         EoSetLayer(ewin, val);
769         ecore_x_window_prop_card32_set(EwinGetClientXwin(ewin), a4, &val, 1);
770         EwinRaise(ewin);
771         return 1;
772      }
773    if (event->message_type == a5)
774      {
775         if (event->data.l[0] & WIN_STATE_FIXED_POSITION)
776           {
777              if (event->data.l[1] & WIN_STATE_FIXED_POSITION)
778                 EwinInhSetUser(ewin, move, 1);
779              else
780                 EwinInhSetUser(ewin, move, 0);
781           }
782         if (event->data.l[0] & WIN_STATE_ARRANGE_IGNORE)
783           {
784              if (event->data.l[1] & WIN_STATE_ARRANGE_IGNORE)
785                 ewin->props.ignorearrange = 1;
786              else
787                 ewin->props.ignorearrange = 0;
788           }
789         if ((event->data.l[0] & WIN_STATE_STICKY)
790             && (!ewin->props.ignorearrange))
791           {
792              EwinOpStick(ewin, OPSRC_USER,
793                          (event->data.l[1] & WIN_STATE_STICKY) != 0);
794           }
795         if (event->data.l[0] & WIN_STATE_SHADED)
796           {
797              EwinOpShade(ewin, OPSRC_USER,
798                          (event->data.l[1] & WIN_STATE_SHADED) != 0);
799           }
800         HintsSetWindowState(ewin);
801         return 1;
802      }
803
804    return 0;
805 }
806
807 int
808 GNOME_ProcessRootClientMessage(XClientMessageEvent * event)
809 {
810    static Atom         a2 = 0, a3 = 0;
811
812    if (!a2)
813       a2 = EInternAtom("_WIN_AREA");
814    if (!a3)
815       a3 = EInternAtom("_WIN_WORKSPACE");
816
817    if (event->message_type == a2)
818      {
819         DeskCurrentGotoArea(event->data.l[0], event->data.l[1]);
820         return 1;
821      }
822    if (event->message_type == a3)
823      {
824         DeskGotoNum(event->data.l[0]);
825         return 1;
826      }
827
828    return 0;
829 }