aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_netwm.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_x/xlib/ecore_x_netwm.c')
-rw-r--r--libraries/ecore/src/lib/ecore_x/xlib/ecore_x_netwm.c2003
1 files changed, 2003 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_netwm.c b/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_netwm.c
new file mode 100644
index 0000000..1a6fc9a
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_netwm.c
@@ -0,0 +1,2003 @@
1/*
2 * _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
3 */
4
5#ifdef HAVE_CONFIG_H
6# include <config.h>
7#endif /* ifdef HAVE_CONFIG_H */
8
9#include <stdio.h>
10#include <string.h>
11
12#include "Ecore.h"
13#include "ecore_x_private.h"
14#include "Ecore_X.h"
15
16typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info;
17
18struct _Ecore_X_Startup_Info
19{
20 Ecore_X_Window win;
21
22 int init;
23
24 int buffer_size;
25 char *buffer;
26
27 int length;
28
29 /* These are the sequence info fields */
30 char *id;
31 char *name;
32 int screen;
33 char *bin;
34 char *icon;
35 int desktop;
36 int timestamp;
37 char *description;
38 char *wmclass;
39 int silent;
40};
41
42static void _ecore_x_window_prop_string_utf8_set(Ecore_X_Window win,
43 Ecore_X_Atom atom,
44 const char *str);
45static char *_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win,
46 Ecore_X_Atom atom);
47#if 0 /* Unused */
48static int _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info);
49static int _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info,
50 char *data);
51#endif /* if 0 */
52static void _ecore_x_netwm_startup_info_free(void *data);
53
54/*
55 * Convenience macros
56 */
57#define _ATOM_SET_UTF8_STRING_LIST(win, atom, string, cnt) \
58 XChangeProperty(_ecore_x_disp, \
59 win, \
60 atom, \
61 ECORE_X_ATOM_UTF8_STRING, \
62 8, \
63 PropModeReplace, \
64 (unsigned char *)string, \
65 cnt)
66
67/*
68 * Local variables
69 */
70
71static Eina_Hash *startup_info = NULL;
72
73EAPI void
74ecore_x_netwm_init(void)
75{
76 LOGFN(__FILE__, __LINE__, __FUNCTION__);
77 startup_info = eina_hash_string_superfast_new(
78 _ecore_x_netwm_startup_info_free);
79} /* ecore_x_netwm_init */
80
81EAPI void
82ecore_x_netwm_shutdown(void)
83{
84 LOGFN(__FILE__, __LINE__, __FUNCTION__);
85 if (startup_info)
86 eina_hash_free(startup_info);
87
88 startup_info = NULL;
89} /* ecore_x_netwm_shutdown */
90
91/*
92 * WM identification
93 */
94EAPI void
95ecore_x_netwm_wm_identify(Ecore_X_Window root,
96 Ecore_X_Window check,
97 const char *wm_name)
98{
99 LOGFN(__FILE__, __LINE__, __FUNCTION__);
100 ecore_x_window_prop_window_set(root,
101 ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK,
102 &check,
103 1);
104 ecore_x_window_prop_window_set(check,
105 ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK,
106 &check,
107 1);
108 _ecore_x_window_prop_string_utf8_set(check,
109 ECORE_X_ATOM_NET_WM_NAME,
110 wm_name);
111 /* This one isn't mandatory */
112 _ecore_x_window_prop_string_utf8_set(root,
113 ECORE_X_ATOM_NET_WM_NAME,
114 wm_name);
115} /* ecore_x_netwm_wm_identify */
116
117/*
118 * Set supported atoms
119 */
120EAPI void
121ecore_x_netwm_supported_set(Ecore_X_Window root,
122 Ecore_X_Atom *supported,
123 int num)
124{
125 LOGFN(__FILE__, __LINE__, __FUNCTION__);
126 ecore_x_window_prop_atom_set(root,
127 ECORE_X_ATOM_NET_SUPPORTED,
128 supported,
129 num);
130} /* ecore_x_netwm_supported_set */
131
132EAPI Eina_Bool
133ecore_x_netwm_supported_get(Ecore_X_Window root,
134 Ecore_X_Atom **supported,
135 int *num)
136{
137 int num_ret;
138
139 if (num)
140 *num = 0;
141
142 if (supported)
143 *supported = NULL;
144
145 LOGFN(__FILE__, __LINE__, __FUNCTION__);
146 num_ret = ecore_x_window_prop_atom_list_get(root, ECORE_X_ATOM_NET_SUPPORTED,
147 supported);
148 if (num_ret <= 0)
149 return EINA_FALSE;
150
151 if (num)
152 *num = num_ret;
153
154 return EINA_TRUE;
155} /* ecore_x_netwm_supported_get */
156
157/*
158 * Desktop configuration and status
159 */
160EAPI void
161ecore_x_netwm_desk_count_set(Ecore_X_Window root,
162 unsigned int n_desks)
163{
164 LOGFN(__FILE__, __LINE__, __FUNCTION__);
165 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
166 &n_desks, 1);
167} /* ecore_x_netwm_desk_count_set */
168
169EAPI void
170ecore_x_netwm_desk_roots_set(Ecore_X_Window root,
171 Ecore_X_Window *vroots,
172 unsigned int n_desks)
173{
174 LOGFN(__FILE__, __LINE__, __FUNCTION__);
175 ecore_x_window_prop_window_set(root,
176 ECORE_X_ATOM_NET_VIRTUAL_ROOTS,
177 vroots,
178 n_desks);
179} /* ecore_x_netwm_desk_roots_set */
180
181EAPI void
182ecore_x_netwm_desk_names_set(Ecore_X_Window root,
183 const char **names,
184 unsigned int n_desks)
185{
186 char ss[32], *buf, *t;
187 const char *s;
188 unsigned int i;
189 int l, len;
190
191 LOGFN(__FILE__, __LINE__, __FUNCTION__);
192 buf = NULL;
193 len = 0;
194
195 for (i = 0; i < n_desks; i++)
196 {
197 s = (names) ? names[i] : NULL;
198 if (!s)
199 {
200 /* Default to "Desk-<number>" */
201 sprintf(ss, "Desk-%d", i);
202 s = ss;
203 }
204
205 l = strlen(s) + 1;
206 t = realloc(buf, len + l);
207 if (t)
208 {
209 buf = t;
210 memcpy(buf + len, s, l);
211 }
212 len += l;
213 }
214
215 _ATOM_SET_UTF8_STRING_LIST(root, ECORE_X_ATOM_NET_DESKTOP_NAMES, buf, len);
216
217 free(buf);
218} /* ecore_x_netwm_desk_names_set */
219
220EAPI void
221ecore_x_netwm_desk_size_set(Ecore_X_Window root,
222 unsigned int width,
223 unsigned int height)
224{
225 unsigned int size[2];
226
227 LOGFN(__FILE__, __LINE__, __FUNCTION__);
228 size[0] = width;
229 size[1] = height;
230 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_GEOMETRY, size,
231 2);
232} /* ecore_x_netwm_desk_size_set */
233
234EAPI void
235ecore_x_netwm_desk_viewports_set(Ecore_X_Window root,
236 unsigned int *origins,
237 unsigned int n_desks)
238{
239 LOGFN(__FILE__, __LINE__, __FUNCTION__);
240 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
241 origins, 2 * n_desks);
242} /* ecore_x_netwm_desk_viewports_set */
243
244EAPI void
245ecore_x_netwm_desk_layout_set(Ecore_X_Window root,
246 int orientation,
247 int columns,
248 int rows,
249 int starting_corner)
250{
251 unsigned int layout[4];
252
253 LOGFN(__FILE__, __LINE__, __FUNCTION__);
254 layout[0] = orientation;
255 layout[1] = columns;
256 layout[2] = rows;
257 layout[3] = starting_corner;
258 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT,
259 layout, 4);
260} /* ecore_x_netwm_desk_layout_set */
261
262EAPI void
263ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
264 unsigned int *areas,
265 unsigned int n_desks)
266{
267 LOGFN(__FILE__, __LINE__, __FUNCTION__);
268 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_WORKAREA, areas,
269 4 * n_desks);
270} /* ecore_x_netwm_desk_workareas_set */
271
272EAPI unsigned int *
273ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, unsigned int *n_desks)
274{
275 int ret;
276 unsigned int *areas = NULL;
277
278 if (!root) root = DefaultRootWindow(_ecore_x_disp);
279
280 ret = ecore_x_window_prop_card32_list_get(root, ECORE_X_ATOM_NET_WORKAREA,
281 &areas);
282 if (!areas)
283 {
284 if (n_desks) *n_desks = 0;
285 return 0;
286 }
287 if (n_desks) *n_desks = ret / 4;
288 return areas;
289}
290
291EAPI void
292ecore_x_netwm_desk_current_set(Ecore_X_Window root,
293 unsigned int desk)
294{
295 LOGFN(__FILE__, __LINE__, __FUNCTION__);
296 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_CURRENT_DESKTOP, &desk,
297 1);
298} /* ecore_x_netwm_desk_current_set */
299
300EAPI void
301ecore_x_netwm_showing_desktop_set(Ecore_X_Window root,
302 Eina_Bool on)
303{
304 unsigned int val;
305
306 LOGFN(__FILE__, __LINE__, __FUNCTION__);
307 val = (on) ? 1 : 0;
308 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, &val,
309 1);
310} /* ecore_x_netwm_showing_desktop_set */
311
312/*
313 * Client status
314 */
315
316/* Mapping order */
317EAPI void
318ecore_x_netwm_client_list_set(Ecore_X_Window root,
319 Ecore_X_Window *p_clients,
320 unsigned int n_clients)
321{
322 LOGFN(__FILE__, __LINE__, __FUNCTION__);
323 ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST,
324 p_clients, n_clients);
325} /* ecore_x_netwm_client_list_set */
326
327/* Stacking order */
328EAPI void
329ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root,
330 Ecore_X_Window *p_clients,
331 unsigned int n_clients)
332{
333 LOGFN(__FILE__, __LINE__, __FUNCTION__);
334 ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST_STACKING,
335 p_clients, n_clients);
336} /* ecore_x_netwm_client_list_stacking_set */
337
338EAPI void
339ecore_x_netwm_client_active_set(Ecore_X_Window root,
340 Ecore_X_Window win)
341{
342 LOGFN(__FILE__, __LINE__, __FUNCTION__);
343 ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_ACTIVE_WINDOW,
344 &win, 1);
345} /* ecore_x_netwm_client_active_set */
346
347EAPI void
348ecore_x_netwm_client_active_request(Ecore_X_Window root,
349 Ecore_X_Window win,
350 int type,
351 Ecore_X_Window current_win)
352{
353 XEvent xev;
354
355 LOGFN(__FILE__, __LINE__, __FUNCTION__);
356 if (!root)
357 root = DefaultRootWindow(_ecore_x_disp);
358
359 xev.xclient.type = ClientMessage;
360 xev.xclient.display = _ecore_x_disp;
361 xev.xclient.window = win;
362 xev.xclient.message_type = ECORE_X_ATOM_NET_ACTIVE_WINDOW;
363 xev.xclient.format = 32;
364 xev.xclient.data.l[0] = type;
365 xev.xclient.data.l[1] = CurrentTime;
366 xev.xclient.data.l[2] = current_win;
367 xev.xclient.data.l[3] = 0;
368 xev.xclient.data.l[4] = 0;
369
370 XSendEvent(_ecore_x_disp, root, False,
371 SubstructureRedirectMask | SubstructureNotifyMask, &xev);
372} /* ecore_x_netwm_client_active_request */
373
374EAPI void
375ecore_x_netwm_name_set(Ecore_X_Window win,
376 const char *name)
377{
378 LOGFN(__FILE__, __LINE__, __FUNCTION__);
379 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_NAME, name);
380} /* ecore_x_netwm_name_set */
381
382EAPI int
383ecore_x_netwm_name_get(Ecore_X_Window win,
384 char **name)
385{
386 LOGFN(__FILE__, __LINE__, __FUNCTION__);
387 if (name)
388 *name = _ecore_x_window_prop_string_utf8_get(win,
389 ECORE_X_ATOM_NET_WM_NAME);
390
391 return 1;
392} /* ecore_x_netwm_name_get */
393
394EAPI void
395ecore_x_netwm_startup_id_set(Ecore_X_Window win,
396 const char *id)
397{
398 LOGFN(__FILE__, __LINE__, __FUNCTION__);
399 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id);
400} /* ecore_x_netwm_startup_id_set */
401
402EAPI int
403ecore_x_netwm_startup_id_get(Ecore_X_Window win,
404 char **id)
405{
406 LOGFN(__FILE__, __LINE__, __FUNCTION__);
407 if (id)
408 *id = _ecore_x_window_prop_string_utf8_get(win,
409 ECORE_X_ATOM_NET_STARTUP_ID);
410
411 return 1;
412} /* ecore_x_netwm_startup_id_get */
413
414EAPI void
415ecore_x_netwm_visible_name_set(Ecore_X_Window win,
416 const char *name)
417{
418 LOGFN(__FILE__, __LINE__, __FUNCTION__);
419 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
420 name);
421} /* ecore_x_netwm_visible_name_set */
422
423EAPI int
424ecore_x_netwm_visible_name_get(Ecore_X_Window win,
425 char **name)
426{
427 LOGFN(__FILE__, __LINE__, __FUNCTION__);
428 if (name)
429 *name = _ecore_x_window_prop_string_utf8_get(
430 win,
431 ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
432
433 return 1;
434} /* ecore_x_netwm_visible_name_get */
435
436EAPI void
437ecore_x_netwm_icon_name_set(Ecore_X_Window win,
438 const char *name)
439{
440 LOGFN(__FILE__, __LINE__, __FUNCTION__);
441 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME,
442 name);
443} /* ecore_x_netwm_icon_name_set */
444
445EAPI int
446ecore_x_netwm_icon_name_get(Ecore_X_Window win,
447 char **name)
448{
449 LOGFN(__FILE__, __LINE__, __FUNCTION__);
450 if (name)
451 *name = _ecore_x_window_prop_string_utf8_get(
452 win,
453 ECORE_X_ATOM_NET_WM_ICON_NAME);
454
455 return 1;
456} /* ecore_x_netwm_icon_name_get */
457
458EAPI void
459ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win,
460 const char *name)
461{
462 LOGFN(__FILE__, __LINE__, __FUNCTION__);
463 _ecore_x_window_prop_string_utf8_set(win,
464 ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
465 name);
466} /* ecore_x_netwm_visible_icon_name_set */
467
468EAPI int
469ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win,
470 char **name)
471{
472 LOGFN(__FILE__, __LINE__, __FUNCTION__);
473 if (name)
474 *name = _ecore_x_window_prop_string_utf8_get(
475 win,
476 ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
477
478 return 1;
479} /* ecore_x_netwm_visible_icon_name_get */
480
481EAPI void
482ecore_x_netwm_desktop_set(Ecore_X_Window win,
483 unsigned int desk)
484{
485 LOGFN(__FILE__, __LINE__, __FUNCTION__);
486 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
487} /* ecore_x_netwm_desktop_set */
488
489EAPI Eina_Bool
490ecore_x_netwm_desktop_get(Ecore_X_Window win,
491 unsigned int *desk)
492{
493 int ret;
494 unsigned int tmp;
495
496 LOGFN(__FILE__, __LINE__, __FUNCTION__);
497 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP,
498 &tmp, 1);
499
500 if (desk)
501 *desk = tmp;
502
503 return ret == 1 ? EINA_TRUE : EINA_FALSE;
504} /* ecore_x_netwm_desktop_get */
505
506/*
507 * _NET_WM_STRUT is deprecated
508 */
509EAPI void
510ecore_x_netwm_strut_set(Ecore_X_Window win,
511 int left,
512 int right,
513 int top,
514 int bottom)
515{
516 unsigned int strut[4];
517
518 LOGFN(__FILE__, __LINE__, __FUNCTION__);
519 strut[0] = left;
520 strut[1] = right;
521 strut[2] = top;
522 strut[3] = bottom;
523 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
524} /* ecore_x_netwm_strut_set */
525
526/*
527 * _NET_WM_STRUT is deprecated
528 */
529EAPI Eina_Bool
530ecore_x_netwm_strut_get(Ecore_X_Window win,
531 int *left,
532 int *right,
533 int *top,
534 int *bottom)
535{
536 int ret = 0;
537 unsigned int strut[4];
538
539 LOGFN(__FILE__, __LINE__, __FUNCTION__);
540 ret = ecore_x_window_prop_card32_get(win,
541 ECORE_X_ATOM_NET_WM_STRUT,
542 strut,
543 4);
544 if (ret != 4)
545 return EINA_FALSE;
546
547 if (left)
548 *left = strut[0];
549
550 if (right)
551 *right = strut[1];
552
553 if (top)
554 *top = strut[2];
555
556 if (bottom)
557 *bottom = strut[3];
558
559 return EINA_TRUE;
560} /* ecore_x_netwm_strut_get */
561
562EAPI void
563ecore_x_netwm_strut_partial_set(Ecore_X_Window win,
564 int left,
565 int right,
566 int top,
567 int bottom,
568 int left_start_y,
569 int left_end_y,
570 int right_start_y,
571 int right_end_y,
572 int top_start_x,
573 int top_end_x,
574 int bottom_start_x,
575 int bottom_end_x)
576{
577 unsigned int strut[12];
578
579 LOGFN(__FILE__, __LINE__, __FUNCTION__);
580 strut[0] = left;
581 strut[1] = right;
582 strut[2] = top;
583 strut[3] = bottom;
584 strut[4] = left_start_y;
585 strut[5] = left_end_y;
586 strut[6] = right_start_y;
587 strut[7] = right_end_y;
588 strut[8] = top_start_x;
589 strut[9] = top_end_x;
590 strut[10] = bottom_start_x;
591 strut[11] = bottom_end_x;
592 ecore_x_window_prop_card32_set(win,
593 ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
594 strut,
595 12);
596} /* ecore_x_netwm_strut_partial_set */
597
598EAPI Eina_Bool
599ecore_x_netwm_strut_partial_get(Ecore_X_Window win,
600 int *left,
601 int *right,
602 int *top,
603 int *bottom,
604 int *left_start_y,
605 int *left_end_y,
606 int *right_start_y,
607 int *right_end_y,
608 int *top_start_x,
609 int *top_end_x,
610 int *bottom_start_x,
611 int *bottom_end_x)
612{
613 int ret = 0;
614 unsigned int strut[12];
615
616 LOGFN(__FILE__, __LINE__, __FUNCTION__);
617 ret = ecore_x_window_prop_card32_get(win,
618 ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
619 strut,
620 12);
621 if (ret != 12)
622 return EINA_FALSE;
623
624 if (left)
625 *left = strut[0];
626
627 if (right)
628 *right = strut[1];
629
630 if (top)
631 *top = strut[2];
632
633 if (bottom)
634 *bottom = strut[3];
635
636 if (left_start_y)
637 *left_start_y = strut[4];
638
639 if (left_end_y)
640 *left_end_y = strut[5];
641
642 if (right_start_y)
643 *right_start_y = strut[6];
644
645 if (right_end_y)
646 *right_end_y = strut[7];
647
648 if (top_start_x)
649 *top_start_x = strut[8];
650
651 if (top_end_x)
652 *top_end_x = strut[9];
653
654 if (bottom_start_x)
655 *bottom_start_x = strut[10];
656
657 if (bottom_end_x)
658 *bottom_end_x = strut[11];
659
660 return EINA_TRUE;
661} /* ecore_x_netwm_strut_partial_get */
662
663EAPI Eina_Bool
664ecore_x_netwm_icons_get(Ecore_X_Window win,
665 Ecore_X_Icon **icon,
666 int *num)
667{
668 unsigned int *data, *p;
669 unsigned int *src;
670 unsigned int len, icons, i;
671 int num_ret;
672
673 LOGFN(__FILE__, __LINE__, __FUNCTION__);
674 if (num)
675 *num = 0;
676
677 if (icon)
678 *icon = NULL;
679
680 num_ret = ecore_x_window_prop_card32_list_get(win, ECORE_X_ATOM_NET_WM_ICON,
681 &data);
682 if (num_ret <= 0)
683 return EINA_FALSE;
684
685 if (!data)
686 return EINA_FALSE;
687
688 if (num_ret < 2)
689 {
690 free(data);
691 return EINA_FALSE;
692 }
693
694 /* Check how many icons there are */
695 icons = 0;
696 p = data;
697 while (p)
698 {
699 len = p[0] * p[1];
700 p += (len + 2);
701 if ((p - data) > num_ret)
702 {
703 free(data);
704 return EINA_FALSE;
705 }
706
707 icons++;
708
709 if ((p - data) == num_ret)
710 p = NULL;
711 }
712 if (num)
713 *num = icons;
714
715 /* If the user doesn't want the icons, return */
716 if (!icon)
717 {
718 free(data);
719 return EINA_TRUE;
720 }
721
722 /* Allocate memory */
723 *icon = malloc(icons * sizeof(Ecore_X_Icon));
724 if (!(*icon))
725 {
726 free(data);
727 return EINA_FALSE;
728 }
729
730 /* Fetch the icons */
731 p = data;
732 for (i = 0; i < icons; i++)
733 {
734 unsigned int *ps, *pd, *pe;
735
736 len = p[0] * p[1];
737 ((*icon)[i]).width = p[0];
738 ((*icon)[i]).height = p[1];
739 src = &(p[2]);
740 ((*icon)[i]).data = malloc(len * sizeof(unsigned int));
741 if (!((*icon)[i]).data)
742 {
743 while (i)
744 free(((*icon)[--i]).data);
745 free(*icon);
746 free(data);
747 return EINA_FALSE;
748 }
749
750 pd = ((*icon)[i]).data;
751 ps = src;
752 pe = ps + len;
753 for (; ps < pe; ps++)
754 {
755 unsigned int r, g, b, a;
756
757 a = (*ps >> 24) & 0xff;
758 r = (((*ps >> 16) & 0xff) * a) / 255;
759 g = (((*ps >> 8) & 0xff) * a) / 255;
760 b = (((*ps) & 0xff) * a) / 255;
761 *pd = (a << 24) | (r << 16) | (g << 8) | (b);
762 pd++;
763 }
764 p += (len + 2);
765 }
766
767 free(data);
768
769 return EINA_TRUE;
770} /* ecore_x_netwm_icons_get */
771
772EAPI void
773ecore_x_netwm_icon_geometry_set(Ecore_X_Window win,
774 int x,
775 int y,
776 int width,
777 int height)
778{
779 unsigned int geometry[4];
780
781 LOGFN(__FILE__, __LINE__, __FUNCTION__);
782 geometry[0] = x;
783 geometry[1] = y;
784 geometry[2] = width;
785 geometry[3] = height;
786 ecore_x_window_prop_card32_set(win,
787 ECORE_X_ATOM_NET_WM_ICON_GEOMETRY,
788 geometry,
789 4);
790} /* ecore_x_netwm_icon_geometry_set */
791
792EAPI Eina_Bool
793ecore_x_netwm_icon_geometry_get(Ecore_X_Window win,
794 int *x,
795 int *y,
796 int *width,
797 int *height)
798{
799 int ret;
800 unsigned int geometry[4];
801
802 LOGFN(__FILE__, __LINE__, __FUNCTION__);
803 ret = ecore_x_window_prop_card32_get(win,
804 ECORE_X_ATOM_NET_WM_ICON_GEOMETRY,
805 geometry,
806 4);
807 if (ret != 4)
808 return EINA_FALSE;
809
810 if (x)
811 *x = geometry[0];
812
813 if (y)
814 *y = geometry[1];
815
816 if (width)
817 *width = geometry[2];
818
819 if (height)
820 *height = geometry[3];
821
822 return EINA_TRUE;
823} /* ecore_x_netwm_icon_geometry_get */
824
825EAPI void
826ecore_x_netwm_pid_set(Ecore_X_Window win,
827 int pid)
828{
829 unsigned int tmp;
830
831 LOGFN(__FILE__, __LINE__, __FUNCTION__);
832 tmp = pid;
833 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_PID,
834 &tmp, 1);
835} /* ecore_x_netwm_pid_set */
836
837EAPI Eina_Bool
838ecore_x_netwm_pid_get(Ecore_X_Window win,
839 int *pid)
840{
841 int ret;
842 unsigned int tmp;
843
844 LOGFN(__FILE__, __LINE__, __FUNCTION__);
845 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID,
846 &tmp, 1);
847 if (pid)
848 *pid = tmp;
849
850 return ret == 1 ? EINA_TRUE : EINA_FALSE;
851} /* ecore_x_netwm_pid_get */
852
853EAPI void
854ecore_x_netwm_handled_icons_set(Ecore_X_Window win)
855{
856 LOGFN(__FILE__, __LINE__, __FUNCTION__);
857 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
858 NULL, 0);
859} /* ecore_x_netwm_handled_icons_set */
860
861EAPI Eina_Bool
862ecore_x_netwm_handled_icons_get(Ecore_X_Window win)
863{
864 int ret = 0;
865 LOGFN(__FILE__, __LINE__, __FUNCTION__);
866 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
867 NULL, 0);
868 return ret == 0 ? EINA_TRUE : EINA_FALSE;
869} /* ecore_x_netwm_handled_icons_get */
870
871EAPI void
872ecore_x_netwm_user_time_set(Ecore_X_Window win,
873 unsigned int tim)
874{
875 LOGFN(__FILE__, __LINE__, __FUNCTION__);
876 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME,
877 &tim, 1);
878} /* ecore_x_netwm_user_time_set */
879
880EAPI Eina_Bool
881ecore_x_netwm_user_time_get(Ecore_X_Window win,
882 unsigned int *tim)
883{
884 int ret;
885 unsigned int tmp;
886
887 LOGFN(__FILE__, __LINE__, __FUNCTION__);
888 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME,
889 &tmp, 1);
890 if (tim)
891 *tim = tmp;
892
893 return ret == 1 ? EINA_TRUE : EINA_FALSE;
894} /* ecore_x_netwm_user_time_get */
895
896Ecore_X_Window_State
897_ecore_x_netwm_state_get(Ecore_X_Atom a)
898{
899 if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL)
900 return ECORE_X_WINDOW_STATE_MODAL;
901 else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY)
902 return ECORE_X_WINDOW_STATE_STICKY;
903 else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
904 return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
905 else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
906 return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
907 else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED)
908 return ECORE_X_WINDOW_STATE_SHADED;
909 else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
910 return ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
911 else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
912 return ECORE_X_WINDOW_STATE_SKIP_PAGER;
913 else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
914 return ECORE_X_WINDOW_STATE_HIDDEN;
915 else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
916 return ECORE_X_WINDOW_STATE_FULLSCREEN;
917 else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
918 return ECORE_X_WINDOW_STATE_ABOVE;
919 else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW)
920 return ECORE_X_WINDOW_STATE_BELOW;
921 else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
922 return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION;
923 else
924 return ECORE_X_WINDOW_STATE_UNKNOWN;
925} /* _ecore_x_netwm_state_get */
926
927static Ecore_X_Atom
928_ecore_x_netwm_state_atom_get(Ecore_X_Window_State s)
929{
930 switch(s)
931 {
932 case ECORE_X_WINDOW_STATE_MODAL:
933 return ECORE_X_ATOM_NET_WM_STATE_MODAL;
934
935 case ECORE_X_WINDOW_STATE_STICKY:
936 return ECORE_X_ATOM_NET_WM_STATE_STICKY;
937
938 case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
939 return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
940
941 case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
942 return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
943
944 case ECORE_X_WINDOW_STATE_SHADED:
945 return ECORE_X_ATOM_NET_WM_STATE_SHADED;
946
947 case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
948 return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
949
950 case ECORE_X_WINDOW_STATE_SKIP_PAGER:
951 return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
952
953 case ECORE_X_WINDOW_STATE_HIDDEN:
954 return ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
955
956 case ECORE_X_WINDOW_STATE_FULLSCREEN:
957 return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
958
959 case ECORE_X_WINDOW_STATE_ABOVE:
960 return ECORE_X_ATOM_NET_WM_STATE_ABOVE;
961
962 case ECORE_X_WINDOW_STATE_BELOW:
963 return ECORE_X_ATOM_NET_WM_STATE_BELOW;
964
965 case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
966 return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
967
968 default:
969 return 0;
970 } /* switch */
971} /* _ecore_x_netwm_state_atom_get */
972
973EAPI void
974ecore_x_netwm_window_state_set(Ecore_X_Window win,
975 Ecore_X_Window_State *state,
976 unsigned int num)
977{
978 Ecore_X_Atom *set;
979 unsigned int i;
980
981 LOGFN(__FILE__, __LINE__, __FUNCTION__);
982 if (!num)
983 {
984 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_NET_WM_STATE);
985 return;
986 }
987
988 set = malloc(num * sizeof(Ecore_X_Atom));
989 if (!set)
990 return;
991
992 for (i = 0; i < num; i++)
993 set[i] = _ecore_x_netwm_state_atom_get(state[i]);
994
995 ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_STATE, set, num);
996
997 free(set);
998} /* ecore_x_netwm_window_state_set */
999
1000EAPI Eina_Bool
1001ecore_x_netwm_window_state_get(Ecore_X_Window win,
1002 Ecore_X_Window_State **state,
1003 unsigned int *num)
1004{
1005 int num_ret, i;
1006 Ecore_X_Atom *atoms;
1007
1008 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1009 if (num)
1010 *num = 0;
1011
1012 if (state)
1013 *state = NULL;
1014
1015 num_ret = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_STATE,
1016 &atoms);
1017 if (num_ret <= 0)
1018 return EINA_FALSE;
1019
1020 if (state)
1021 {
1022 *state = malloc(num_ret * sizeof(Ecore_X_Window_State));
1023 if (*state)
1024 for (i = 0; i < num_ret; ++i)
1025 (*state)[i] = _ecore_x_netwm_state_get(atoms[i]);
1026
1027 if (num)
1028 *num = num_ret;
1029 }
1030
1031 free(atoms);
1032 return EINA_TRUE;
1033} /* ecore_x_netwm_window_state_get */
1034
1035static Ecore_X_Window_Type
1036_ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom)
1037{
1038 if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP)
1039 return ECORE_X_WINDOW_TYPE_DESKTOP;
1040 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK)
1041 return ECORE_X_WINDOW_TYPE_DOCK;
1042 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR)
1043 return ECORE_X_WINDOW_TYPE_TOOLBAR;
1044 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU)
1045 return ECORE_X_WINDOW_TYPE_MENU;
1046 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY)
1047 return ECORE_X_WINDOW_TYPE_UTILITY;
1048 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH)
1049 return ECORE_X_WINDOW_TYPE_SPLASH;
1050 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG)
1051 return ECORE_X_WINDOW_TYPE_DIALOG;
1052 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL)
1053 return ECORE_X_WINDOW_TYPE_NORMAL;
1054 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
1055 return ECORE_X_WINDOW_TYPE_DROPDOWN_MENU;
1056 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU)
1057 return ECORE_X_WINDOW_TYPE_POPUP_MENU;
1058 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP)
1059 return ECORE_X_WINDOW_TYPE_TOOLTIP;
1060 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION)
1061 return ECORE_X_WINDOW_TYPE_NOTIFICATION;
1062 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO)
1063 return ECORE_X_WINDOW_TYPE_COMBO;
1064 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND)
1065 return ECORE_X_WINDOW_TYPE_DND;
1066 else
1067 return ECORE_X_WINDOW_TYPE_UNKNOWN;
1068} /* _ecore_x_netwm_window_type_type_get */
1069
1070static Ecore_X_Atom
1071_ecore_x_netwm_window_type_atom_get(Ecore_X_Window_Type type)
1072{
1073 switch (type)
1074 {
1075 case ECORE_X_WINDOW_TYPE_DESKTOP:
1076 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
1077
1078 case ECORE_X_WINDOW_TYPE_DOCK:
1079 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
1080
1081 case ECORE_X_WINDOW_TYPE_TOOLBAR:
1082 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
1083
1084 case ECORE_X_WINDOW_TYPE_MENU:
1085 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
1086
1087 case ECORE_X_WINDOW_TYPE_UTILITY:
1088 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
1089
1090 case ECORE_X_WINDOW_TYPE_SPLASH:
1091 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
1092
1093 case ECORE_X_WINDOW_TYPE_DIALOG:
1094 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
1095
1096 case ECORE_X_WINDOW_TYPE_NORMAL:
1097 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
1098
1099 case ECORE_X_WINDOW_TYPE_DROPDOWN_MENU:
1100 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU;
1101
1102 case ECORE_X_WINDOW_TYPE_POPUP_MENU:
1103 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU;
1104
1105 case ECORE_X_WINDOW_TYPE_TOOLTIP:
1106 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP;
1107
1108 case ECORE_X_WINDOW_TYPE_NOTIFICATION:
1109 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION;
1110
1111 case ECORE_X_WINDOW_TYPE_COMBO:
1112 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO;
1113
1114 case ECORE_X_WINDOW_TYPE_DND:
1115 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND;
1116
1117 default:
1118 return 0;
1119 } /* switch */
1120} /* _ecore_x_netwm_window_type_atom_get */
1121
1122/*
1123 * FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR
1124 * , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG
1125 */
1126EAPI void
1127ecore_x_netwm_window_type_set(Ecore_X_Window win,
1128 Ecore_X_Window_Type type)
1129{
1130 Ecore_X_Atom atom;
1131
1132 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1133 atom = _ecore_x_netwm_window_type_atom_get(type);
1134 ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1135 &atom, 1);
1136} /* ecore_x_netwm_window_type_set */
1137
1138/* FIXME: Maybe return 0 on some conditions? */
1139EAPI Eina_Bool
1140ecore_x_netwm_window_type_get(Ecore_X_Window win,
1141 Ecore_X_Window_Type *type)
1142{
1143 int num;
1144 Ecore_X_Atom *atoms = NULL;
1145
1146 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1147 if (type)
1148 *type = ECORE_X_WINDOW_TYPE_NORMAL;
1149
1150 num = ecore_x_window_prop_atom_list_get(win,
1151 ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1152 &atoms);
1153 if ((type) && (num >= 1) && (atoms))
1154 *type = _ecore_x_netwm_window_type_type_get(atoms[0]);
1155
1156 free(atoms);
1157 if (num >= 1)
1158 return EINA_TRUE;
1159
1160 return EINA_FALSE;
1161} /* ecore_x_netwm_window_type_get */
1162
1163EAPI int
1164ecore_x_netwm_window_types_get(Ecore_X_Window win,
1165 Ecore_X_Window_Type **types)
1166{
1167 int num, i;
1168 Ecore_X_Atom *atoms = NULL;
1169 Ecore_X_Window_Type *atoms2 = NULL;
1170
1171 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1172 if (types)
1173 *types = NULL;
1174
1175 num = ecore_x_window_prop_atom_list_get(win,
1176 ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1177 &atoms);
1178 if ((num <= 0) || (!atoms))
1179 {
1180 if (atoms)
1181 free(atoms);
1182
1183 return 0;
1184 }
1185
1186 atoms2 = malloc(num * sizeof(Ecore_X_Window_Type));
1187 if (!atoms2)
1188 return 0;
1189
1190 for (i = 0; i < num; i++)
1191 atoms2[i] = _ecore_x_netwm_window_type_type_get(atoms[i]);
1192 free(atoms);
1193 if (types)
1194 *types = atoms2;
1195 else
1196 free(atoms2);
1197
1198 return num;
1199} /* ecore_x_netwm_window_types_get */
1200
1201static Ecore_X_Atom
1202_ecore_x_netwm_action_atom_get(Ecore_X_Action action)
1203{
1204 switch (action)
1205 {
1206 case ECORE_X_ACTION_MOVE:
1207 return ECORE_X_ATOM_NET_WM_ACTION_MOVE;
1208
1209 case ECORE_X_ACTION_RESIZE:
1210 return ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
1211
1212 case ECORE_X_ACTION_MINIMIZE:
1213 return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
1214
1215 case ECORE_X_ACTION_SHADE:
1216 return ECORE_X_ATOM_NET_WM_ACTION_SHADE;
1217
1218 case ECORE_X_ACTION_STICK:
1219 return ECORE_X_ATOM_NET_WM_ACTION_STICK;
1220
1221 case ECORE_X_ACTION_MAXIMIZE_HORZ:
1222 return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
1223
1224 case ECORE_X_ACTION_MAXIMIZE_VERT:
1225 return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
1226
1227 case ECORE_X_ACTION_FULLSCREEN:
1228 return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
1229
1230 case ECORE_X_ACTION_CHANGE_DESKTOP:
1231 return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
1232
1233 case ECORE_X_ACTION_CLOSE:
1234 return ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
1235
1236 case ECORE_X_ACTION_ABOVE:
1237 return ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
1238
1239 case ECORE_X_ACTION_BELOW:
1240 return ECORE_X_ATOM_NET_WM_ACTION_BELOW;
1241
1242 default:
1243 return 0;
1244 } /* switch */
1245} /* _ecore_x_netwm_action_atom_get */
1246
1247/* FIXME: Get complete list */
1248EAPI Eina_Bool
1249ecore_x_netwm_allowed_action_isset(Ecore_X_Window win,
1250 Ecore_X_Action action)
1251{
1252 int num, i;
1253 Ecore_X_Atom *atoms, atom;
1254 Eina_Bool ret = EINA_FALSE;
1255
1256 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1257 num = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1258 &atoms);
1259 if (num <= 0)
1260 return ret;
1261
1262 atom = _ecore_x_netwm_action_atom_get(action);
1263
1264 for (i = 0; i < num; ++i)
1265 {
1266 if (atom == atoms[i])
1267 {
1268 ret = 1;
1269 break;
1270 }
1271 }
1272
1273 free(atoms);
1274 return ret;
1275} /* ecore_x_netwm_allowed_action_isset */
1276
1277/* FIXME: Set complete list */
1278EAPI void
1279ecore_x_netwm_allowed_action_set(Ecore_X_Window win,
1280 Ecore_X_Action *action,
1281 unsigned int num)
1282{
1283 Ecore_X_Atom *set;
1284 unsigned int i;
1285
1286 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1287 if (!num)
1288 {
1289 ecore_x_window_prop_property_del(win,
1290 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
1291 return;
1292 }
1293
1294 set = malloc(num * sizeof(Ecore_X_Atom));
1295 if (!set)
1296 return;
1297
1298 for (i = 0; i < num; i++)
1299 set[i] = _ecore_x_netwm_action_atom_get(action[i]);
1300
1301 ecore_x_window_prop_atom_set(win,
1302 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
1303 set,
1304 num);
1305
1306 free(set);
1307} /* ecore_x_netwm_allowed_action_set */
1308
1309EAPI Eina_Bool
1310ecore_x_netwm_allowed_action_get(Ecore_X_Window win,
1311 Ecore_X_Action **action,
1312 unsigned int *num)
1313{
1314 int num_ret, i;
1315 Ecore_X_Atom *atoms;
1316
1317 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1318 if (num)
1319 *num = 0;
1320
1321 if (action)
1322 *action = NULL;
1323
1324 num_ret = ecore_x_window_prop_atom_list_get(
1325 win,
1326 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
1327 &atoms);
1328 if (num_ret <= 0)
1329 return EINA_FALSE;
1330
1331 if (action)
1332 {
1333 *action = malloc(num_ret * sizeof(Ecore_X_Action));
1334 if (*action)
1335 for (i = 0; i < num_ret; ++i)
1336 (*action)[i] = _ecore_x_netwm_action_atom_get(atoms[i]);
1337
1338 if (num)
1339 *num = num_ret;
1340 }
1341
1342 free(atoms);
1343 return EINA_TRUE;
1344} /* ecore_x_netwm_allowed_action_get */
1345
1346EAPI void
1347ecore_x_netwm_opacity_set(Ecore_X_Window win,
1348 unsigned int opacity)
1349{
1350 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1351 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
1352 &opacity, 1);
1353} /* ecore_x_netwm_opacity_set */
1354
1355EAPI Eina_Bool
1356ecore_x_netwm_opacity_get(Ecore_X_Window win,
1357 unsigned int *opacity)
1358{
1359 int ret;
1360 unsigned int tmp;
1361
1362 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1363 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
1364 &tmp, 1);
1365 if (opacity)
1366 *opacity = tmp;
1367
1368 return ret == 1 ? EINA_TRUE : EINA_FALSE;
1369} /* ecore_x_netwm_opacity_get */
1370
1371EAPI void
1372ecore_x_netwm_frame_size_set(Ecore_X_Window win,
1373 int fl,
1374 int fr,
1375 int ft,
1376 int fb)
1377{
1378 unsigned int frames[4];
1379
1380 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1381 frames[0] = fl;
1382 frames[1] = fr;
1383 frames[2] = ft;
1384 frames[3] = fb;
1385 ecore_x_window_prop_card32_set(win,
1386 ECORE_X_ATOM_NET_FRAME_EXTENTS,
1387 frames,
1388 4);
1389} /* ecore_x_netwm_frame_size_set */
1390
1391EAPI Eina_Bool
1392ecore_x_netwm_frame_size_get(Ecore_X_Window win,
1393 int *fl,
1394 int *fr,
1395 int *ft,
1396 int *fb)
1397{
1398 int ret = 0;
1399 unsigned int frames[4];
1400
1401 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1402 ret = ecore_x_window_prop_card32_get(win,
1403 ECORE_X_ATOM_NET_FRAME_EXTENTS,
1404 frames,
1405 4);
1406 if (ret != 4)
1407 return EINA_FALSE;
1408
1409 if (fl)
1410 *fl = frames[0];
1411
1412 if (fr)
1413 *fr = frames[1];
1414
1415 if (ft)
1416 *ft = frames[2];
1417
1418 if (fb)
1419 *fb = frames[3];
1420
1421 return EINA_TRUE;
1422} /* ecore_x_netwm_frame_size_get */
1423
1424EAPI Eina_Bool
1425ecore_x_netwm_sync_counter_get(Ecore_X_Window win,
1426 Ecore_X_Sync_Counter *counter)
1427{
1428 int ret;
1429 unsigned int tmp;
1430
1431 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1432 ret = ecore_x_window_prop_card32_get(
1433 win,
1434 ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
1435 &tmp,
1436 1);
1437
1438 if (counter)
1439 *counter = tmp;
1440
1441 return ret == 1 ? EINA_TRUE : EINA_FALSE;
1442} /* ecore_x_netwm_sync_counter_get */
1443
1444EAPI void
1445ecore_x_netwm_ping_send(Ecore_X_Window win)
1446{
1447 XEvent xev;
1448
1449 if (!win)
1450 return;
1451
1452 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1453 xev.xclient.type = ClientMessage;
1454 xev.xclient.display = _ecore_x_disp;
1455 xev.xclient.window = win;
1456 xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
1457 xev.xclient.format = 32;
1458 xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_PING;
1459 xev.xclient.data.l[1] = _ecore_x_event_last_time;
1460 xev.xclient.data.l[2] = win;
1461 xev.xclient.data.l[3] = 0;
1462 xev.xclient.data.l[4] = 0;
1463
1464 XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
1465} /* ecore_x_netwm_ping_send */
1466
1467EAPI void
1468ecore_x_netwm_sync_request_send(Ecore_X_Window win,
1469 unsigned int serial)
1470{
1471 XSyncValue value;
1472 XEvent xev;
1473
1474 if (!win)
1475 return;
1476
1477 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1478 XSyncIntToValue(&value, (int)serial);
1479
1480 xev.xclient.type = ClientMessage;
1481 xev.xclient.display = _ecore_x_disp;
1482 xev.xclient.window = win;
1483 xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
1484 xev.xclient.format = 32;
1485 xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
1486 xev.xclient.data.l[1] = _ecore_x_event_last_time;
1487 xev.xclient.data.l[2] = XSyncValueLow32(value);
1488 xev.xclient.data.l[3] = XSyncValueHigh32(value);
1489 xev.xclient.data.l[4] = 0;
1490
1491 XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
1492} /* ecore_x_netwm_sync_request_send */
1493
1494EAPI void
1495ecore_x_netwm_state_request_send(Ecore_X_Window win,
1496 Ecore_X_Window root,
1497 Ecore_X_Window_State s1,
1498 Ecore_X_Window_State s2,
1499 Eina_Bool set)
1500{
1501 XEvent xev;
1502
1503 if (!win)
1504 return;
1505
1506 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1507 if (!root)
1508 root = DefaultRootWindow(_ecore_x_disp);
1509
1510 xev.xclient.type = ClientMessage;
1511 xev.xclient.serial = 0;
1512 xev.xclient.send_event = True;
1513 xev.xclient.display = _ecore_x_disp;
1514 xev.xclient.window = win;
1515 xev.xclient.format = 32;
1516 xev.xclient.message_type = ECORE_X_ATOM_NET_WM_STATE;
1517 xev.xclient.data.l[0] = !!set;
1518 xev.xclient.data.l[1] = _ecore_x_netwm_state_atom_get(s1);
1519 xev.xclient.data.l[2] = _ecore_x_netwm_state_atom_get(s2);
1520 /* 1 == normal client, if someone wants to use this
1521 * function in a pager, this should be 2 */
1522 xev.xclient.data.l[3] = 1;
1523 xev.xclient.data.l[4] = 0;
1524
1525 XSendEvent(_ecore_x_disp, root, False,
1526 SubstructureNotifyMask | SubstructureRedirectMask, &xev);
1527} /* ecore_x_netwm_state_request_send */
1528
1529EAPI void
1530ecore_x_netwm_desktop_request_send(Ecore_X_Window win,
1531 Ecore_X_Window root,
1532 unsigned int desktop)
1533{
1534 XEvent xev;
1535
1536 if (!win)
1537 return;
1538
1539 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1540 if (!root)
1541 root = DefaultRootWindow(_ecore_x_disp);
1542
1543 xev.xclient.type = ClientMessage;
1544 xev.xclient.serial = 0;
1545 xev.xclient.send_event = True;
1546 xev.xclient.display = _ecore_x_disp;
1547 xev.xclient.window = win;
1548 xev.xclient.format = 32;
1549 xev.xclient.message_type = ECORE_X_ATOM_NET_WM_DESKTOP;
1550 xev.xclient.data.l[0] = desktop;
1551
1552 XSendEvent(_ecore_x_disp, root, False,
1553 SubstructureNotifyMask | SubstructureRedirectMask, &xev);
1554} /* ecore_x_netwm_desktop_request_send */
1555
1556int
1557_ecore_x_netwm_startup_info_begin(Ecore_X_Window win __UNUSED__,
1558 char *data __UNUSED__)
1559{
1560#if 0
1561 Ecore_X_Startup_Info *info;
1562 unsigned char *exists = 0;
1563
1564 if (!startup_info)
1565 return 0;
1566
1567 info = eina_hash_find(startup_info, (void *)win);
1568 if (info)
1569 {
1570 exists = 1;
1571 WRN("Already got info for win: 0x%x", win);
1572 _ecore_x_netwm_startup_info_free(info);
1573 }
1574
1575 info = calloc(1, sizeof(Ecore_X_Startup_Info));
1576 if (!info)
1577 return 0;
1578
1579 info->win = win;
1580 info->length = 0;
1581 info->buffer_size = 161;
1582 info->buffer = calloc(info->buffer_size, sizeof(char));
1583 if (!info->buffer)
1584 {
1585 _ecore_x_netwm_startup_info_free(info);
1586 return 0;
1587 }
1588
1589 memcpy(info->buffer, data, 20);
1590 info->length += 20;
1591 info->buffer[info->length] = 0;
1592 if (exists)
1593 eina_hash_modify(startup_info, (void *)info->win, info);
1594 else
1595 eina_hash_add(startup_info, (void *)info->win, info);
1596
1597 if (strlen(info->buffer) != 20)
1598 /* We have a '\0' in there, the message is done */
1599 _ecore_x_netwm_startup_info_process(info);
1600
1601#endif /* if 0 */
1602 return 1;
1603} /* _ecore_x_netwm_startup_info_begin */
1604
1605int
1606_ecore_x_netwm_startup_info(Ecore_X_Window win __UNUSED__,
1607 char *data __UNUSED__)
1608{
1609#if 0
1610 Ecore_X_Startup_Info *info;
1611 char *p;
1612
1613 if (!startup_info)
1614 return 0;
1615
1616 info = eina_hash_find(startup_info, (void *)win);
1617 if (!info)
1618 return 0;
1619
1620 if ((info->length + 20) > info->buffer_size)
1621 {
1622 info->buffer_size += 160;
1623 info->buffer = realloc(info->buffer, info->buffer_size * sizeof(char));
1624 if (!info->buffer)
1625 {
1626 eina_hash_del(startup_info, (void *)info->win);
1627 _ecore_x_netwm_startup_info_free(info);
1628 return 0;
1629 }
1630 }
1631
1632 memcpy(info->buffer + info->length, data, 20);
1633 p = info->buffer + info->length;
1634 info->length += 20;
1635 info->buffer[info->length] = 0;
1636 if (strlen(p) != 20)
1637 /* We have a '\0' in there, the message is done */
1638 _ecore_x_netwm_startup_info_process(info);
1639
1640#endif /* if 0 */
1641 return 1;
1642} /* _ecore_x_netwm_startup_info */
1643
1644/*
1645 * Set UTF-8 string property
1646 */
1647static void
1648_ecore_x_window_prop_string_utf8_set(Ecore_X_Window win,
1649 Ecore_X_Atom atom,
1650 const char *str)
1651{
1652 XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8,
1653 PropModeReplace, (unsigned char *)str, strlen(str));
1654} /* _ecore_x_window_prop_string_utf8_set */
1655
1656/*
1657 * Get UTF-8 string property
1658 */
1659static char *
1660_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win,
1661 Ecore_X_Atom atom)
1662{
1663 char *str;
1664 unsigned char *prop_ret;
1665 Atom type_ret;
1666 unsigned long bytes_after, num_ret;
1667 int format_ret;
1668
1669 str = NULL;
1670 prop_ret = NULL;
1671 XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
1672 ECORE_X_ATOM_UTF8_STRING, &type_ret,
1673 &format_ret, &num_ret, &bytes_after, &prop_ret);
1674 if (prop_ret && num_ret > 0 && format_ret == 8)
1675 {
1676 str = malloc(num_ret + 1);
1677 if (str)
1678 {
1679 memcpy(str, prop_ret, num_ret);
1680 str[num_ret] = '\0';
1681 }
1682 }
1683
1684 if (prop_ret)
1685 XFree(prop_ret);
1686
1687 return str;
1688} /* _ecore_x_window_prop_string_utf8_get */
1689
1690#if 0 /* Unused */
1691/*
1692 * Process startup info
1693 */
1694static int
1695_ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info)
1696{
1697 Ecore_X_Event_Startup_Sequence *e;
1698 int event;
1699 char *p;
1700
1701 p = strchr(info->buffer, ':');
1702 if (!p)
1703 {
1704 eina_hash_del(startup_info, (void *)info->win);
1705 _ecore_x_netwm_startup_info_free(info);
1706 return 0;
1707 }
1708
1709 *p = 0;
1710 if (!strcmp(info->buffer, "new"))
1711 {
1712 if (info->init)
1713 event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
1714 else
1715 event = ECORE_X_EVENT_STARTUP_SEQUENCE_NEW;
1716
1717 info->init = 1;
1718 }
1719 else if (!strcmp(info->buffer, "change"))
1720 event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
1721 else if (!strcmp(info->buffer, "remove"))
1722 event = ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE;
1723 else
1724 {
1725 eina_hash_del(startup_info, (void *)info->win);
1726 _ecore_x_netwm_startup_info_free(info);
1727 return 0;
1728 }
1729
1730 p++;
1731
1732 if (!_ecore_x_netwm_startup_info_parse(info, p))
1733 {
1734 eina_hash_del(startup_info, (void *)info->win);
1735 _ecore_x_netwm_startup_info_free(info);
1736 return 0;
1737 }
1738
1739 if (info->init)
1740 {
1741 e = calloc(1, sizeof(Ecore_X_Event_Startup_Sequence));
1742 if (!e)
1743 {
1744 eina_hash_del(startup_info, (void *)info->win);
1745 _ecore_x_netwm_startup_info_free(info);
1746 return 0;
1747 }
1748
1749 e->win = info->win;
1750 ecore_event_add(event, e, NULL, NULL);
1751 }
1752
1753 if (event == ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE)
1754 {
1755 eina_hash_del(startup_info, (void *)info->win);
1756 _ecore_x_netwm_startup_info_free(info);
1757 }
1758 else
1759 {
1760 /* Discard buffer */
1761 info->length = 0;
1762 info->buffer[0] = 0;
1763 }
1764
1765 return 1;
1766} /* _ecore_x_netwm_startup_info_process */
1767
1768/*
1769 * Parse startup info
1770 */
1771static int
1772_ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info,
1773 char *data)
1774{
1775 while (*data)
1776 {
1777 int in_quot_sing, in_quot_dbl, escaped;
1778 char *p, *pp;
1779 char *key;
1780 char value[1024];
1781
1782 /* Skip space */
1783 while (*data == ' ') data++;
1784 /* Get key */
1785 key = data;
1786 data = strchr(key, '=');
1787 if (!data)
1788 return 0;
1789
1790 *data = 0;
1791 data++;
1792
1793 /* Get value */
1794 p = data;
1795 pp = value;
1796 in_quot_dbl = 0;
1797 in_quot_sing = 0;
1798 escaped = 0;
1799 while (*p)
1800 {
1801 if ((pp - value) >= 1024)
1802 return 0;
1803
1804 if (escaped)
1805 {
1806 *pp = *p;
1807 pp++;
1808 escaped = 0;
1809 }
1810 else if (in_quot_sing)
1811 {
1812 if (*p == '\\')
1813 escaped = 1;
1814 else if (*p == '\'')
1815 in_quot_sing = 0;
1816 else
1817 {
1818 *pp = *p;
1819 pp++;
1820 }
1821 }
1822 else if (in_quot_dbl)
1823 {
1824 if (*p == '\\')
1825 escaped = 1;
1826 else if (*p == '\"')
1827 in_quot_dbl = 0;
1828 else
1829 {
1830 *pp = *p;
1831 pp++;
1832 }
1833 }
1834 else
1835 {
1836 if (*p == '\\')
1837 escaped = 1;
1838 else if (*p == '\'')
1839 in_quot_sing = 1;
1840 else if (*p == '\"')
1841 in_quot_dbl = 1;
1842 else if (*p == ' ')
1843 break;
1844 else
1845 {
1846 *pp = *p;
1847 pp++;
1848 }
1849 }
1850
1851 p++;
1852 }
1853 if ((in_quot_dbl) || (in_quot_sing))
1854 return 0;
1855
1856 data = p;
1857 *pp = 0;
1858
1859 /* Parse info */
1860 if (!strcmp(key, "ID"))
1861 {
1862 if ((info->id) && (strcmp(info->id, value)))
1863 return 0;
1864
1865 info->id = strdup(value);
1866 p = strstr(value, "_TIME");
1867 if (p)
1868 info->timestamp = atoi(p + 5);
1869 }
1870 else if (!strcmp(key, "NAME"))
1871 {
1872 if (info->name)
1873 free(info->name);
1874
1875 info->name = strdup(value);
1876 }
1877 else if (!strcmp(key, "SCREEN"))
1878 info->screen = atoi(value);
1879 else if (!strcmp(key, "BIN"))
1880 {
1881 if (info->bin)
1882 free(info->bin);
1883
1884 info->bin = strdup(value);
1885 }
1886 else if (!strcmp(key, "ICON"))
1887 {
1888 if (info->icon)
1889 free(info->icon);
1890
1891 info->icon = strdup(value);
1892 }
1893 else if (!strcmp(key, "DESKTOP"))
1894 info->desktop = atoi(value);
1895 else if (!strcmp(key, "TIMESTAMP"))
1896 {
1897 if (!info->timestamp)
1898 info->timestamp = atoi(value);
1899 }
1900 else if (!strcmp(key, "DESCRIPTION"))
1901 {
1902 if (info->description)
1903 free(info->description);
1904
1905 info->description = strdup(value);
1906 }
1907 else if (!strcmp(key, "WMCLASS"))
1908 {
1909 if (info->wmclass)
1910 free(info->wmclass);
1911
1912 info->wmclass = strdup(value);
1913 }
1914 else if (!strcmp(key, "SILENT"))
1915 info->silent = atoi(value);
1916 else
1917 ERR("Ecore X Sequence, Unknown: %s=%s", key, value);
1918 }
1919 if (!info->id)
1920 return 0;
1921
1922 return 1;
1923} /* _ecore_x_netwm_startup_info_parse */
1924
1925#endif /* if 0 */
1926
1927/*
1928 * Free startup info struct
1929 */
1930static void
1931_ecore_x_netwm_startup_info_free(void *data)
1932{
1933 Ecore_X_Startup_Info *info;
1934
1935 info = data;
1936 if (!info)
1937 return;
1938
1939 if (info->buffer)
1940 free(info->buffer);
1941
1942 if (info->id)
1943 free(info->id);
1944
1945 if (info->name)
1946 free(info->name);
1947
1948 if (info->bin)
1949 free(info->bin);
1950
1951 if (info->icon)
1952 free(info->icon);
1953
1954 if (info->description)
1955 free(info->description);
1956
1957 if (info->wmclass)
1958 free(info->wmclass);
1959
1960 free(info);
1961} /* _ecore_x_netwm_startup_info_free */
1962
1963/*
1964 * Is screen composited?
1965 */
1966EAPI Eina_Bool
1967ecore_x_screen_is_composited(int screen)
1968{
1969 Ecore_X_Window win;
1970 static Ecore_X_Atom atom = None;
1971 char buf[32];
1972
1973 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1974 snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
1975 if (atom == None)
1976 atom = XInternAtom(_ecore_x_disp, buf, False);
1977
1978 if (atom == None)
1979 return EINA_FALSE;
1980
1981 win = XGetSelectionOwner(_ecore_x_disp, atom);
1982
1983 return (win != None) ? EINA_TRUE : EINA_FALSE;
1984} /* ecore_x_screen_is_composited */
1985
1986EAPI void
1987ecore_x_screen_is_composited_set(int screen,
1988 Ecore_X_Window win)
1989{
1990 static Ecore_X_Atom atom = None;
1991 char buf[32];
1992
1993 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1994 snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
1995 if (atom == None)
1996 atom = XInternAtom(_ecore_x_disp, buf, False);
1997
1998 if (atom == None)
1999 return;
2000
2001 XSetSelectionOwner(_ecore_x_disp, atom, win, _ecore_x_event_last_time);
2002} /* ecore_x_screen_is_composited_set */
2003