diff options
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.c | 2003 |
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 | |||
16 | typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info; | ||
17 | |||
18 | struct _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 | |||
42 | static void _ecore_x_window_prop_string_utf8_set(Ecore_X_Window win, | ||
43 | Ecore_X_Atom atom, | ||
44 | const char *str); | ||
45 | static char *_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win, | ||
46 | Ecore_X_Atom atom); | ||
47 | #if 0 /* Unused */ | ||
48 | static int _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info); | ||
49 | static int _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info, | ||
50 | char *data); | ||
51 | #endif /* if 0 */ | ||
52 | static 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 | |||
71 | static Eina_Hash *startup_info = NULL; | ||
72 | |||
73 | EAPI void | ||
74 | ecore_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 | |||
81 | EAPI void | ||
82 | ecore_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 | */ | ||
94 | EAPI void | ||
95 | ecore_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 | */ | ||
120 | EAPI void | ||
121 | ecore_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 | |||
132 | EAPI Eina_Bool | ||
133 | ecore_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 | */ | ||
160 | EAPI void | ||
161 | ecore_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 | |||
169 | EAPI void | ||
170 | ecore_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 | |||
181 | EAPI void | ||
182 | ecore_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 | |||
220 | EAPI void | ||
221 | ecore_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 | |||
234 | EAPI void | ||
235 | ecore_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 | |||
244 | EAPI void | ||
245 | ecore_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 | |||
262 | EAPI void | ||
263 | ecore_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 | |||
272 | EAPI unsigned int * | ||
273 | ecore_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 | |||
291 | EAPI void | ||
292 | ecore_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 | |||
300 | EAPI void | ||
301 | ecore_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 */ | ||
317 | EAPI void | ||
318 | ecore_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 */ | ||
328 | EAPI void | ||
329 | ecore_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 | |||
338 | EAPI void | ||
339 | ecore_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 | |||
347 | EAPI void | ||
348 | ecore_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 | |||
374 | EAPI void | ||
375 | ecore_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 | |||
382 | EAPI int | ||
383 | ecore_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 | |||
394 | EAPI void | ||
395 | ecore_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 | |||
402 | EAPI int | ||
403 | ecore_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 | |||
414 | EAPI void | ||
415 | ecore_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 | |||
423 | EAPI int | ||
424 | ecore_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 | |||
436 | EAPI void | ||
437 | ecore_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 | |||
445 | EAPI int | ||
446 | ecore_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 | |||
458 | EAPI void | ||
459 | ecore_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 | |||
468 | EAPI int | ||
469 | ecore_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 | |||
481 | EAPI void | ||
482 | ecore_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 | |||
489 | EAPI Eina_Bool | ||
490 | ecore_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 | */ | ||
509 | EAPI void | ||
510 | ecore_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 | */ | ||
529 | EAPI Eina_Bool | ||
530 | ecore_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 | |||
562 | EAPI void | ||
563 | ecore_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 | |||
598 | EAPI Eina_Bool | ||
599 | ecore_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 | |||
663 | EAPI Eina_Bool | ||
664 | ecore_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 | |||
772 | EAPI void | ||
773 | ecore_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 | |||
792 | EAPI Eina_Bool | ||
793 | ecore_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 | |||
825 | EAPI void | ||
826 | ecore_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 | |||
837 | EAPI Eina_Bool | ||
838 | ecore_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 | |||
853 | EAPI void | ||
854 | ecore_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 | |||
861 | EAPI Eina_Bool | ||
862 | ecore_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 | |||
871 | EAPI void | ||
872 | ecore_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 | |||
880 | EAPI Eina_Bool | ||
881 | ecore_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 | |||
896 | Ecore_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 | |||
927 | static 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 | |||
973 | EAPI void | ||
974 | ecore_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 | |||
1000 | EAPI Eina_Bool | ||
1001 | ecore_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 | |||
1035 | static 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 | |||
1070 | static 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 | */ | ||
1126 | EAPI void | ||
1127 | ecore_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? */ | ||
1139 | EAPI Eina_Bool | ||
1140 | ecore_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 | |||
1163 | EAPI int | ||
1164 | ecore_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 | |||
1201 | static 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 */ | ||
1248 | EAPI Eina_Bool | ||
1249 | ecore_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 */ | ||
1278 | EAPI void | ||
1279 | ecore_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 | |||
1309 | EAPI Eina_Bool | ||
1310 | ecore_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 | |||
1346 | EAPI void | ||
1347 | ecore_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 | |||
1355 | EAPI Eina_Bool | ||
1356 | ecore_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 | |||
1371 | EAPI void | ||
1372 | ecore_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 | |||
1391 | EAPI Eina_Bool | ||
1392 | ecore_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 | |||
1424 | EAPI Eina_Bool | ||
1425 | ecore_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 | |||
1444 | EAPI void | ||
1445 | ecore_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 | |||
1467 | EAPI void | ||
1468 | ecore_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 | |||
1494 | EAPI void | ||
1495 | ecore_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 | |||
1529 | EAPI void | ||
1530 | ecore_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 | |||
1556 | int | ||
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 | |||
1605 | int | ||
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 | */ | ||
1647 | static 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 | */ | ||
1659 | static 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 | */ | ||
1694 | static 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 | */ | ||
1771 | static 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 | */ | ||
1930 | static 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 | */ | ||
1966 | EAPI Eina_Bool | ||
1967 | ecore_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 | |||
1986 | EAPI void | ||
1987 | ecore_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 | |||