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