diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_icccm.c | 1568 |
1 files changed, 1568 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_icccm.c b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_icccm.c new file mode 100644 index 0000000..6459db7 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_icccm.c | |||
@@ -0,0 +1,1568 @@ | |||
1 | #include "ecore_xcb_private.h" | ||
2 | #include <xcb/xcb_icccm.h> | ||
3 | |||
4 | EAPI void | ||
5 | ecore_x_icccm_init(void) | ||
6 | { | ||
7 | } | ||
8 | |||
9 | /** | ||
10 | * Sets the WM_COMMAND property for @a win. | ||
11 | * | ||
12 | * @param win The window. | ||
13 | * @param argc Number of arguments. | ||
14 | * @param argv Arguments. | ||
15 | */ | ||
16 | EAPI void | ||
17 | ecore_x_icccm_command_set(Ecore_X_Window win, | ||
18 | int argc, | ||
19 | char **argv) | ||
20 | { | ||
21 | void *buf; | ||
22 | char *b; | ||
23 | int nbytes, i; | ||
24 | |||
25 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
26 | CHECK_XCB_CONN; | ||
27 | |||
28 | for (i = 0, nbytes = 0; i < argc; i++) | ||
29 | if (argv[i]) nbytes += strlen(argv[i]) + 1; | ||
30 | |||
31 | buf = malloc(sizeof(char) * nbytes); | ||
32 | if (!buf) return; | ||
33 | |||
34 | b = (char *)buf; | ||
35 | for (i = 0; i < argc; i++) | ||
36 | { | ||
37 | if (argv[i]) | ||
38 | { | ||
39 | strcpy(b, argv[i]); | ||
40 | b += strlen(argv[i]) + 1; | ||
41 | } | ||
42 | else | ||
43 | *b++ = '\0'; | ||
44 | } | ||
45 | xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, | ||
46 | ECORE_X_ATOM_WM_COMMAND, ECORE_X_ATOM_STRING, 8, | ||
47 | nbytes, buf); | ||
48 | free(buf); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * Get the WM_COMMAND property for @a win. | ||
53 | * | ||
54 | * Return the command of a window. String must be free'd when done with. | ||
55 | * | ||
56 | * @param win The window. | ||
57 | * @param argc Number of arguments. | ||
58 | * @param argv Arguments. | ||
59 | */ | ||
60 | EAPI void | ||
61 | ecore_x_icccm_command_get(Ecore_X_Window win, | ||
62 | int *argc, | ||
63 | char ***argv) | ||
64 | { | ||
65 | xcb_get_property_cookie_t cookie; | ||
66 | xcb_get_property_reply_t *reply; | ||
67 | int len = 0; | ||
68 | char **v, *data, *cp, *start; | ||
69 | int c = 0, i = 0, j = 0; | ||
70 | |||
71 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
72 | CHECK_XCB_CONN; | ||
73 | |||
74 | if (argc) *argc = 0; | ||
75 | if (argv) *argv = NULL; | ||
76 | |||
77 | cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, | ||
78 | ECORE_X_ATOM_WM_COMMAND, | ||
79 | XCB_GET_PROPERTY_TYPE_ANY, | ||
80 | 0, 1000000L); | ||
81 | reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); | ||
82 | if (!reply) return; | ||
83 | |||
84 | if ((reply->type != ECORE_X_ATOM_STRING) || (reply->format != 8)) | ||
85 | { | ||
86 | free(reply); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | len = reply->value_len; | ||
91 | if (len < 1) | ||
92 | { | ||
93 | free(reply); | ||
94 | return; | ||
95 | } | ||
96 | |||
97 | data = (char *)xcb_get_property_value(reply); | ||
98 | if (len && (data[len - 1] == '\0')) | ||
99 | len--; | ||
100 | |||
101 | c = 1; | ||
102 | for (cp = (char *)data, i = len; i > 0; cp++, i--) | ||
103 | if (*cp == '\0') c++; | ||
104 | |||
105 | v = (char **)malloc((c + 1) * sizeof(char *)); | ||
106 | if (!v) | ||
107 | { | ||
108 | free(reply); | ||
109 | return; | ||
110 | } | ||
111 | |||
112 | start = (char *)malloc((len + 1) * sizeof(char)); | ||
113 | if (!start) | ||
114 | { | ||
115 | free(reply); | ||
116 | free(v); | ||
117 | return; | ||
118 | } | ||
119 | |||
120 | memcpy(start, (char *)data, len); | ||
121 | start[len] = '\0'; | ||
122 | for (cp = start, i = len + 1, j = 0; i > 0; cp++, i--) | ||
123 | { | ||
124 | if (*cp == '\0') | ||
125 | { | ||
126 | v[j] = start; | ||
127 | start = (cp + 1); | ||
128 | j++; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | if (c < 1) | ||
133 | { | ||
134 | free(reply); | ||
135 | free(v); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | if (argc) *argc = c; | ||
140 | |||
141 | if (argv) | ||
142 | { | ||
143 | (*argv) = malloc(c * sizeof(char *)); | ||
144 | if (!*argv) | ||
145 | { | ||
146 | free(reply); | ||
147 | free(v); | ||
148 | if (argc) *argc = 0; | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | for (i = 0; i < c; i++) | ||
153 | { | ||
154 | if (v[i]) | ||
155 | (*argv)[i] = strdup(v[i]); | ||
156 | else | ||
157 | (*argv)[i] = strdup(""); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | free(reply); | ||
162 | free(v); | ||
163 | } | ||
164 | |||
165 | EAPI char * | ||
166 | ecore_x_icccm_title_get(Ecore_X_Window win) | ||
167 | { | ||
168 | xcb_get_property_cookie_t cookie; | ||
169 | #ifdef OLD_XCB_VERSION | ||
170 | xcb_get_text_property_reply_t prop; | ||
171 | #else | ||
172 | xcb_icccm_get_text_property_reply_t prop; | ||
173 | #endif | ||
174 | uint8_t ret = 0; | ||
175 | char *title = NULL; | ||
176 | |||
177 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
178 | CHECK_XCB_CONN; | ||
179 | |||
180 | if (!win) return NULL; | ||
181 | #ifdef OLD_XCB_VERSION | ||
182 | cookie = xcb_get_wm_name_unchecked(_ecore_xcb_conn, win); | ||
183 | ret = xcb_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); | ||
184 | #else | ||
185 | cookie = xcb_icccm_get_wm_name_unchecked(_ecore_xcb_conn, win); | ||
186 | ret = xcb_icccm_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); | ||
187 | #endif | ||
188 | if (ret == 0) return NULL; | ||
189 | if (prop.name_len < 1) | ||
190 | { | ||
191 | #ifdef OLD_XCB_VERSION | ||
192 | xcb_get_text_property_reply_wipe(&prop); | ||
193 | #else | ||
194 | xcb_icccm_get_text_property_reply_wipe(&prop); | ||
195 | #endif | ||
196 | return NULL; | ||
197 | } | ||
198 | |||
199 | if (!(title = malloc((prop.name_len + 1) * sizeof(char *)))) | ||
200 | { | ||
201 | #ifdef OLD_XCB_VERSION | ||
202 | xcb_get_text_property_reply_wipe(&prop); | ||
203 | #else | ||
204 | xcb_icccm_get_text_property_reply_wipe(&prop); | ||
205 | #endif | ||
206 | return NULL; | ||
207 | } | ||
208 | memcpy(title, prop.name, sizeof(char *) * prop.name_len); | ||
209 | title[prop.name_len] = '\0'; | ||
210 | |||
211 | if (prop.encoding != ECORE_X_ATOM_UTF8_STRING) | ||
212 | { | ||
213 | Ecore_Xcb_Textproperty tp; | ||
214 | int count = 0; | ||
215 | char **list = NULL; | ||
216 | Eina_Bool ret = EINA_FALSE; | ||
217 | |||
218 | tp.value = strdup(title); | ||
219 | tp.nitems = prop.name_len; | ||
220 | tp.encoding = prop.encoding; | ||
221 | #ifdef HAVE_ICONV | ||
222 | ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count); | ||
223 | #else | ||
224 | ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count); | ||
225 | #endif | ||
226 | if (ret) | ||
227 | { | ||
228 | if (count > 0) | ||
229 | title = strdup(list[0]); | ||
230 | |||
231 | if (list) free(list); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | #ifdef OLD_XCB_VERSION | ||
236 | xcb_get_text_property_reply_wipe(&prop); | ||
237 | #else | ||
238 | xcb_icccm_get_text_property_reply_wipe(&prop); | ||
239 | #endif | ||
240 | return title; | ||
241 | } | ||
242 | |||
243 | EAPI void | ||
244 | ecore_x_icccm_title_set(Ecore_X_Window win, | ||
245 | const char *title) | ||
246 | { | ||
247 | Ecore_Xcb_Textproperty prop; | ||
248 | char *list[1]; | ||
249 | Eina_Bool ret = EINA_FALSE; | ||
250 | |||
251 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
252 | CHECK_XCB_CONN; | ||
253 | |||
254 | if (!title) return; | ||
255 | |||
256 | prop.value = NULL; | ||
257 | list[0] = strdup(title); | ||
258 | |||
259 | #ifdef HAVE_ICONV | ||
260 | ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle, | ||
261 | &prop); | ||
262 | #else | ||
263 | ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle, | ||
264 | &prop); | ||
265 | #endif | ||
266 | |||
267 | if (ret) | ||
268 | { | ||
269 | #ifdef OLD_XCB_VERSION | ||
270 | xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, | ||
271 | strlen(prop.value), prop.value); | ||
272 | #else | ||
273 | xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8, | ||
274 | strlen(prop.value), prop.value); | ||
275 | #endif | ||
276 | if (prop.value) free(prop.value); | ||
277 | } | ||
278 | else | ||
279 | #ifdef OLD_XCB_VERSION | ||
280 | xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, | ||
281 | strlen(title), title); | ||
282 | #else | ||
283 | xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8, | ||
284 | strlen(title), title); | ||
285 | #endif | ||
286 | free(list[0]); | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * Get a window name & class. | ||
291 | * @param win The window | ||
292 | * @param n The name string | ||
293 | * @param c The class string | ||
294 | * | ||
295 | * Get a window name * class | ||
296 | */ | ||
297 | EAPI void | ||
298 | ecore_x_icccm_name_class_get(Ecore_X_Window win, | ||
299 | char **name, | ||
300 | char **class) | ||
301 | { | ||
302 | xcb_get_property_cookie_t cookie; | ||
303 | #ifdef OLD_XCB_VERSION | ||
304 | xcb_get_wm_class_reply_t prop; | ||
305 | #else | ||
306 | xcb_icccm_get_wm_class_reply_t prop; | ||
307 | #endif | ||
308 | uint8_t ret = 0; | ||
309 | |||
310 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
311 | CHECK_XCB_CONN; | ||
312 | |||
313 | if (name) *name = NULL; | ||
314 | if (class) *class = NULL; | ||
315 | |||
316 | #ifdef OLD_XCB_VERSION | ||
317 | cookie = xcb_get_wm_class_unchecked(_ecore_xcb_conn, win); | ||
318 | ret = xcb_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL); | ||
319 | #else | ||
320 | cookie = xcb_icccm_get_wm_class_unchecked(_ecore_xcb_conn, win); | ||
321 | ret = xcb_icccm_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL); | ||
322 | #endif | ||
323 | if (ret == 0) return; | ||
324 | |||
325 | if (name) *name = strdup(prop.instance_name); | ||
326 | if (class) *class = strdup(prop.class_name); | ||
327 | |||
328 | #ifdef OLD_XCB_VERSION | ||
329 | xcb_get_wm_class_reply_wipe(&prop); | ||
330 | #else | ||
331 | xcb_icccm_get_wm_class_reply_wipe(&prop); | ||
332 | #endif | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * Set a window name & class. | ||
337 | * @param win The window | ||
338 | * @param n The name string | ||
339 | * @param c The class string | ||
340 | * | ||
341 | * Set a window name * class | ||
342 | */ | ||
343 | EAPI void | ||
344 | ecore_x_icccm_name_class_set(Ecore_X_Window win, | ||
345 | const char *name, | ||
346 | const char *class) | ||
347 | { | ||
348 | char *class_string, *s; | ||
349 | int length_name, length_class; | ||
350 | |||
351 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
352 | CHECK_XCB_CONN; | ||
353 | |||
354 | length_name = strlen(name); | ||
355 | length_class = strlen(class); | ||
356 | class_string = | ||
357 | (char *)malloc(sizeof(char) * (length_name + length_class + 2)); | ||
358 | if (!class_string) return; | ||
359 | |||
360 | s = class_string; | ||
361 | if (length_name) | ||
362 | { | ||
363 | strcpy(s, name); | ||
364 | s += length_name + 1; | ||
365 | } | ||
366 | else | ||
367 | *s++ = '\0'; | ||
368 | |||
369 | if (length_class) | ||
370 | strcpy(s, class); | ||
371 | else | ||
372 | *s = '\0'; | ||
373 | |||
374 | xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, | ||
375 | ECORE_X_ATOM_WM_CLASS, ECORE_X_ATOM_STRING, 8, | ||
376 | length_name + length_class + 2, (void *)class_string); | ||
377 | free(class_string); | ||
378 | } | ||
379 | |||
380 | /** | ||
381 | * Specify that a window is transient for another top-level window and should be handled accordingly. | ||
382 | * @param win the transient window | ||
383 | * @param forwin the toplevel window | ||
384 | */ | ||
385 | EAPI void | ||
386 | ecore_x_icccm_transient_for_set(Ecore_X_Window win, | ||
387 | Ecore_X_Window forwindow) | ||
388 | { | ||
389 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
390 | CHECK_XCB_CONN; | ||
391 | |||
392 | xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, | ||
393 | ECORE_X_ATOM_WM_TRANSIENT_FOR, ECORE_X_ATOM_WINDOW, 32, | ||
394 | 1, (void *)&forwindow); | ||
395 | } | ||
396 | |||
397 | /** | ||
398 | * Remove the transient_for setting from a window. | ||
399 | * @param The window | ||
400 | */ | ||
401 | EAPI void | ||
402 | ecore_x_icccm_transient_for_unset(Ecore_X_Window win) | ||
403 | { | ||
404 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
405 | |||
406 | ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_TRANSIENT_FOR); | ||
407 | } | ||
408 | |||
409 | /** | ||
410 | * Get the window this window is transient for, if any. | ||
411 | * @param win The window to check | ||
412 | * @return The window ID of the top-level window, or 0 if the property does not exist. | ||
413 | */ | ||
414 | EAPI Ecore_X_Window | ||
415 | ecore_x_icccm_transient_for_get(Ecore_X_Window win) | ||
416 | { | ||
417 | Ecore_X_Window forwin = 0; | ||
418 | xcb_get_property_cookie_t cookie; | ||
419 | |||
420 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
421 | CHECK_XCB_CONN; | ||
422 | |||
423 | #ifdef OLD_XCB_VERSION | ||
424 | cookie = xcb_get_wm_transient_for_unchecked(_ecore_xcb_conn, win); | ||
425 | xcb_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL); | ||
426 | #else | ||
427 | cookie = xcb_icccm_get_wm_transient_for_unchecked(_ecore_xcb_conn, win); | ||
428 | xcb_icccm_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL); | ||
429 | #endif | ||
430 | |||
431 | return forwin; | ||
432 | } | ||
433 | |||
434 | /** | ||
435 | * Get the window role. | ||
436 | * @param win The window | ||
437 | * @return The window's role string. | ||
438 | */ | ||
439 | EAPI char * | ||
440 | ecore_x_icccm_window_role_get(Ecore_X_Window win) | ||
441 | { | ||
442 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
443 | |||
444 | return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE); | ||
445 | } | ||
446 | |||
447 | /** | ||
448 | * Set the window role hint. | ||
449 | * @param win The window | ||
450 | * @param role The role string | ||
451 | */ | ||
452 | EAPI void | ||
453 | ecore_x_icccm_window_role_set(Ecore_X_Window win, | ||
454 | const char *role) | ||
455 | { | ||
456 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
457 | |||
458 | ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE, role); | ||
459 | } | ||
460 | |||
461 | /** | ||
462 | * Get the window's client leader. | ||
463 | * @param win The window | ||
464 | * @return The window's client leader window, or 0 if unset | ||
465 | */ | ||
466 | EAPI Ecore_X_Window | ||
467 | ecore_x_icccm_client_leader_get(Ecore_X_Window win) | ||
468 | { | ||
469 | Ecore_X_Window leader; | ||
470 | |||
471 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
472 | |||
473 | if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER, | ||
474 | &leader, 1) > 0) | ||
475 | return leader; | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | /** | ||
481 | * Set the window's client leader. | ||
482 | * @param win The window | ||
483 | * @param l The client leader window | ||
484 | * | ||
485 | * All non-transient top-level windows created by an app other than | ||
486 | * the main window must have this property set to the app's main window. | ||
487 | */ | ||
488 | EAPI void | ||
489 | ecore_x_icccm_client_leader_set(Ecore_X_Window win, | ||
490 | Ecore_X_Window leader) | ||
491 | { | ||
492 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
493 | |||
494 | ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER, | ||
495 | &leader, 1); | ||
496 | } | ||
497 | |||
498 | EAPI Ecore_X_Window_State_Hint | ||
499 | ecore_x_icccm_state_get(Ecore_X_Window win) | ||
500 | { | ||
501 | xcb_get_property_cookie_t cookie; | ||
502 | xcb_get_property_reply_t *reply; | ||
503 | Ecore_X_Window_State_Hint hint = ECORE_X_WINDOW_STATE_HINT_NONE; | ||
504 | uint8_t *prop; | ||
505 | |||
506 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
507 | CHECK_XCB_CONN; | ||
508 | |||
509 | cookie = | ||
510 | xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, | ||
511 | ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE, | ||
512 | 0L, 0x7fffffff); | ||
513 | reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); | ||
514 | if (!reply) return hint; | ||
515 | if ((reply->type == 0) || (reply->format != 8) || (reply->value_len != 2)) | ||
516 | { | ||
517 | free(reply); | ||
518 | return hint; | ||
519 | } | ||
520 | |||
521 | prop = (uint8_t *)xcb_get_property_value(reply); | ||
522 | #ifdef OLD_XCB_VERSION | ||
523 | switch (prop[0]) | ||
524 | { | ||
525 | case XCB_WM_STATE_WITHDRAWN: | ||
526 | hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; | ||
527 | break; | ||
528 | |||
529 | case XCB_WM_STATE_NORMAL: | ||
530 | hint = ECORE_X_WINDOW_STATE_HINT_NORMAL; | ||
531 | break; | ||
532 | |||
533 | case XCB_WM_STATE_ICONIC: | ||
534 | hint = ECORE_X_WINDOW_STATE_HINT_ICONIC; | ||
535 | break; | ||
536 | |||
537 | default: | ||
538 | break; | ||
539 | } | ||
540 | #else | ||
541 | switch (prop[0]) | ||
542 | { | ||
543 | case XCB_ICCCM_WM_STATE_WITHDRAWN: | ||
544 | hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; | ||
545 | break; | ||
546 | |||
547 | case XCB_ICCCM_WM_STATE_NORMAL: | ||
548 | hint = ECORE_X_WINDOW_STATE_HINT_NORMAL; | ||
549 | break; | ||
550 | |||
551 | case XCB_ICCCM_WM_STATE_ICONIC: | ||
552 | hint = ECORE_X_WINDOW_STATE_HINT_ICONIC; | ||
553 | break; | ||
554 | |||
555 | default: | ||
556 | break; | ||
557 | } | ||
558 | #endif | ||
559 | |||
560 | free(reply); | ||
561 | return hint; | ||
562 | } | ||
563 | |||
564 | EAPI void | ||
565 | ecore_x_icccm_state_set(Ecore_X_Window win, | ||
566 | Ecore_X_Window_State_Hint state) | ||
567 | { | ||
568 | #ifdef OLD_XCB_VERSION | ||
569 | xcb_wm_hints_t hints; | ||
570 | #else | ||
571 | xcb_icccm_wm_hints_t hints; | ||
572 | #endif | ||
573 | |||
574 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
575 | CHECK_XCB_CONN; | ||
576 | |||
577 | #ifdef OLD_XCB_VERSION | ||
578 | xcb_wm_hints_set_none(&hints); | ||
579 | |||
580 | hints.flags = XCB_WM_HINT_STATE; | ||
581 | |||
582 | if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) | ||
583 | xcb_wm_hints_set_withdrawn(&hints); | ||
584 | else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL) | ||
585 | xcb_wm_hints_set_normal(&hints); | ||
586 | else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC) | ||
587 | xcb_wm_hints_set_iconic(&hints); | ||
588 | |||
589 | xcb_set_wm_hints(_ecore_xcb_conn, win, &hints); | ||
590 | #else | ||
591 | xcb_icccm_wm_hints_set_none(&hints); | ||
592 | |||
593 | hints.flags = XCB_ICCCM_WM_HINT_STATE; | ||
594 | |||
595 | if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) | ||
596 | xcb_icccm_wm_hints_set_withdrawn(&hints); | ||
597 | else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL) | ||
598 | xcb_icccm_wm_hints_set_normal(&hints); | ||
599 | else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC) | ||
600 | xcb_icccm_wm_hints_set_iconic(&hints); | ||
601 | |||
602 | xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints); | ||
603 | #endif | ||
604 | } | ||
605 | |||
606 | EAPI void | ||
607 | ecore_x_icccm_delete_window_send(Ecore_X_Window win, | ||
608 | Ecore_X_Time t) | ||
609 | { | ||
610 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
611 | ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, | ||
612 | ECORE_X_EVENT_MASK_NONE, | ||
613 | ECORE_X_ATOM_WM_DELETE_WINDOW, t, 0, 0, 0); | ||
614 | } | ||
615 | |||
616 | EAPI void | ||
617 | ecore_x_icccm_hints_set(Ecore_X_Window win, | ||
618 | Eina_Bool accepts_focus, | ||
619 | Ecore_X_Window_State_Hint initial_state, | ||
620 | Ecore_X_Pixmap icon_pixmap, | ||
621 | Ecore_X_Pixmap icon_mask, | ||
622 | Ecore_X_Window icon_window, | ||
623 | Ecore_X_Window window_group, | ||
624 | Eina_Bool is_urgent) | ||
625 | { | ||
626 | #ifdef OLD_XCB_VERSION | ||
627 | xcb_wm_hints_t hints; | ||
628 | #else | ||
629 | xcb_icccm_wm_hints_t hints; | ||
630 | #endif | ||
631 | |||
632 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
633 | CHECK_XCB_CONN; | ||
634 | |||
635 | #ifdef OLD_XCB_VERSION | ||
636 | xcb_wm_hints_set_none(&hints); | ||
637 | xcb_wm_hints_set_input(&hints, accepts_focus); | ||
638 | |||
639 | if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) | ||
640 | xcb_wm_hints_set_withdrawn(&hints); | ||
641 | else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL) | ||
642 | xcb_wm_hints_set_normal(&hints); | ||
643 | else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC) | ||
644 | xcb_wm_hints_set_iconic(&hints); | ||
645 | |||
646 | if (icon_pixmap != 0) xcb_wm_hints_set_icon_pixmap(&hints, icon_pixmap); | ||
647 | if (icon_mask != 0) xcb_wm_hints_set_icon_mask(&hints, icon_mask); | ||
648 | if (icon_window != 0) xcb_wm_hints_set_icon_window(&hints, icon_window); | ||
649 | if (window_group != 0) xcb_wm_hints_set_window_group(&hints, window_group); | ||
650 | if (is_urgent) xcb_wm_hints_set_urgency(&hints); | ||
651 | |||
652 | xcb_set_wm_hints(_ecore_xcb_conn, win, &hints); | ||
653 | #else | ||
654 | xcb_icccm_wm_hints_set_none(&hints); | ||
655 | xcb_icccm_wm_hints_set_input(&hints, accepts_focus); | ||
656 | |||
657 | if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) | ||
658 | xcb_icccm_wm_hints_set_withdrawn(&hints); | ||
659 | else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL) | ||
660 | xcb_icccm_wm_hints_set_normal(&hints); | ||
661 | else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC) | ||
662 | xcb_icccm_wm_hints_set_iconic(&hints); | ||
663 | |||
664 | if (icon_pixmap != 0) | ||
665 | xcb_icccm_wm_hints_set_icon_pixmap(&hints, icon_pixmap); | ||
666 | if (icon_mask != 0) | ||
667 | xcb_icccm_wm_hints_set_icon_mask(&hints, icon_mask); | ||
668 | if (icon_window != 0) | ||
669 | xcb_icccm_wm_hints_set_icon_window(&hints, icon_window); | ||
670 | if (window_group != 0) | ||
671 | xcb_icccm_wm_hints_set_window_group(&hints, window_group); | ||
672 | if (is_urgent) | ||
673 | xcb_icccm_wm_hints_set_urgency(&hints); | ||
674 | |||
675 | xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints); | ||
676 | #endif | ||
677 | } | ||
678 | |||
679 | EAPI Eina_Bool | ||
680 | ecore_x_icccm_hints_get(Ecore_X_Window win, | ||
681 | Eina_Bool *accepts_focus, | ||
682 | Ecore_X_Window_State_Hint *initial_state, | ||
683 | Ecore_X_Pixmap *icon_pixmap, | ||
684 | Ecore_X_Pixmap *icon_mask, | ||
685 | Ecore_X_Window *icon_window, | ||
686 | Ecore_X_Window *window_group, | ||
687 | Eina_Bool *is_urgent) | ||
688 | { | ||
689 | xcb_get_property_cookie_t cookie; | ||
690 | #ifdef OLD_XCB_VERSION | ||
691 | xcb_wm_hints_t hints; | ||
692 | #else | ||
693 | xcb_icccm_wm_hints_t hints; | ||
694 | #endif | ||
695 | uint8_t ret = 0; | ||
696 | |||
697 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
698 | CHECK_XCB_CONN; | ||
699 | |||
700 | if (accepts_focus) *accepts_focus = EINA_TRUE; | ||
701 | if (initial_state) *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; | ||
702 | if (icon_pixmap) *icon_pixmap = 0; | ||
703 | if (icon_mask) *icon_mask = 0; | ||
704 | if (icon_window) *icon_window = 0; | ||
705 | if (window_group) *window_group = 0; | ||
706 | if (is_urgent) *is_urgent = EINA_FALSE; | ||
707 | |||
708 | #ifdef OLD_XCB_VERSION | ||
709 | xcb_wm_hints_set_none(&hints); | ||
710 | cookie = xcb_get_wm_hints_unchecked(_ecore_xcb_conn, win); | ||
711 | ret = xcb_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); | ||
712 | #else | ||
713 | xcb_icccm_wm_hints_set_none(&hints); | ||
714 | cookie = xcb_icccm_get_wm_hints_unchecked(_ecore_xcb_conn, win); | ||
715 | ret = xcb_icccm_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); | ||
716 | #endif | ||
717 | if (!ret) return EINA_FALSE; | ||
718 | |||
719 | #ifdef OLD_XCB_VERSION | ||
720 | if ((hints.flags & XCB_WM_HINT_INPUT) && (accepts_focus)) | ||
721 | #else | ||
722 | if ((hints.flags & XCB_ICCCM_WM_HINT_INPUT) && (accepts_focus)) | ||
723 | #endif | ||
724 | { | ||
725 | if (hints.input) | ||
726 | *accepts_focus = EINA_TRUE; | ||
727 | else | ||
728 | *accepts_focus = EINA_FALSE; | ||
729 | } | ||
730 | |||
731 | #ifdef OLD_XCB_VERSION | ||
732 | if ((hints.flags & XCB_WM_HINT_STATE) && (initial_state)) | ||
733 | { | ||
734 | if (hints.initial_state == XCB_WM_STATE_WITHDRAWN) | ||
735 | *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; | ||
736 | else if (hints.initial_state == XCB_WM_STATE_NORMAL) | ||
737 | *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; | ||
738 | else if (hints.initial_state == XCB_WM_STATE_ICONIC) | ||
739 | *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC; | ||
740 | } | ||
741 | |||
742 | if ((hints.flags & XCB_WM_HINT_ICON_PIXMAP) && (icon_pixmap)) | ||
743 | *icon_pixmap = hints.icon_pixmap; | ||
744 | |||
745 | if ((hints.flags & XCB_WM_HINT_ICON_MASK) && (icon_mask)) | ||
746 | *icon_mask = hints.icon_mask; | ||
747 | |||
748 | if ((hints.flags & XCB_WM_HINT_ICON_WINDOW) && (icon_window)) | ||
749 | *icon_window = hints.icon_window; | ||
750 | |||
751 | if ((hints.flags & XCB_WM_HINT_WINDOW_GROUP) && (window_group)) | ||
752 | *window_group = hints.window_group; | ||
753 | |||
754 | if ((hints.flags & XCB_WM_HINT_X_URGENCY) && (is_urgent)) | ||
755 | *is_urgent = EINA_TRUE; | ||
756 | #else | ||
757 | if ((hints.flags & XCB_ICCCM_WM_HINT_STATE) && (initial_state)) | ||
758 | { | ||
759 | if (hints.initial_state == XCB_ICCCM_WM_STATE_WITHDRAWN) | ||
760 | *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; | ||
761 | else if (hints.initial_state == XCB_ICCCM_WM_STATE_NORMAL) | ||
762 | *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; | ||
763 | else if (hints.initial_state == XCB_ICCCM_WM_STATE_ICONIC) | ||
764 | *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC; | ||
765 | } | ||
766 | |||
767 | if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_PIXMAP) && (icon_pixmap)) | ||
768 | *icon_pixmap = hints.icon_pixmap; | ||
769 | |||
770 | if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_MASK) && (icon_mask)) | ||
771 | *icon_mask = hints.icon_mask; | ||
772 | |||
773 | if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_WINDOW) && (icon_window)) | ||
774 | *icon_window = hints.icon_window; | ||
775 | |||
776 | if ((hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) && (window_group)) | ||
777 | *window_group = hints.window_group; | ||
778 | |||
779 | if ((hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) && (is_urgent)) | ||
780 | *is_urgent = EINA_TRUE; | ||
781 | #endif | ||
782 | |||
783 | return EINA_TRUE; | ||
784 | } | ||
785 | |||
786 | /** | ||
787 | * Get a window icon name. | ||
788 | * @param win The window | ||
789 | * @return The windows icon name string | ||
790 | * | ||
791 | * Return the icon name of a window. String must be free'd when done with. | ||
792 | */ | ||
793 | EAPI char * | ||
794 | ecore_x_icccm_icon_name_get(Ecore_X_Window win) | ||
795 | { | ||
796 | xcb_get_property_cookie_t cookie; | ||
797 | #ifdef OLD_XCB_VERSION | ||
798 | xcb_get_text_property_reply_t prop; | ||
799 | #else | ||
800 | xcb_icccm_get_text_property_reply_t prop; | ||
801 | #endif | ||
802 | uint8_t ret = 0; | ||
803 | char *tmp = NULL; | ||
804 | |||
805 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
806 | CHECK_XCB_CONN; | ||
807 | |||
808 | if (!win) return NULL; | ||
809 | |||
810 | #ifdef OLD_XCB_VERSION | ||
811 | cookie = xcb_get_wm_icon_name_unchecked(_ecore_xcb_conn, win); | ||
812 | ret = xcb_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); | ||
813 | #else | ||
814 | cookie = xcb_icccm_get_wm_icon_name_unchecked(_ecore_xcb_conn, win); | ||
815 | ret = xcb_icccm_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); | ||
816 | #endif | ||
817 | if (ret == 0) return NULL; | ||
818 | |||
819 | if (prop.name_len < 1) | ||
820 | { | ||
821 | #ifdef OLD_XCB_VERSION | ||
822 | xcb_get_text_property_reply_wipe(&prop); | ||
823 | #else | ||
824 | xcb_icccm_get_text_property_reply_wipe(&prop); | ||
825 | #endif | ||
826 | return NULL; | ||
827 | } | ||
828 | |||
829 | if (!(tmp = malloc((prop.name_len + 1) * sizeof(char *)))) | ||
830 | { | ||
831 | #ifdef OLD_XCB_VERSION | ||
832 | xcb_get_text_property_reply_wipe(&prop); | ||
833 | #else | ||
834 | xcb_icccm_get_text_property_reply_wipe(&prop); | ||
835 | #endif | ||
836 | return NULL; | ||
837 | } | ||
838 | memcpy(tmp, prop.name, sizeof(char *) * prop.name_len); | ||
839 | tmp[prop.name_len] = '\0'; | ||
840 | |||
841 | if (prop.encoding != ECORE_X_ATOM_UTF8_STRING) | ||
842 | { | ||
843 | Ecore_Xcb_Textproperty tp; | ||
844 | int count = 0; | ||
845 | char **list = NULL; | ||
846 | Eina_Bool ret = EINA_FALSE; | ||
847 | |||
848 | tp.value = strdup(tmp); | ||
849 | tp.nitems = prop.name_len; | ||
850 | tp.encoding = prop.encoding; | ||
851 | #ifdef HAVE_ICONV | ||
852 | ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count); | ||
853 | #else | ||
854 | ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count); | ||
855 | #endif | ||
856 | if (ret) | ||
857 | { | ||
858 | if (count > 0) | ||
859 | tmp = strdup(list[0]); | ||
860 | |||
861 | if (list) free(list); | ||
862 | } | ||
863 | } | ||
864 | |||
865 | #ifdef OLD_XCB_VERSION | ||
866 | xcb_get_text_property_reply_wipe(&prop); | ||
867 | #else | ||
868 | xcb_icccm_get_text_property_reply_wipe(&prop); | ||
869 | #endif | ||
870 | return tmp; | ||
871 | } | ||
872 | |||
873 | /** | ||
874 | * Set a window icon name. | ||
875 | * @param win The window | ||
876 | * @param t The icon name string | ||
877 | * | ||
878 | * Set a window icon name | ||
879 | */ | ||
880 | EAPI void | ||
881 | ecore_x_icccm_icon_name_set(Ecore_X_Window win, | ||
882 | const char *name) | ||
883 | { | ||
884 | Ecore_Xcb_Textproperty prop; | ||
885 | char *list[1]; | ||
886 | Eina_Bool ret = EINA_FALSE; | ||
887 | |||
888 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
889 | CHECK_XCB_CONN; | ||
890 | |||
891 | if ((!win) || (!name)) return; | ||
892 | |||
893 | prop.value = NULL; | ||
894 | list[0] = strdup(name); | ||
895 | |||
896 | #ifdef HAVE_ICONV | ||
897 | ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle, | ||
898 | &prop); | ||
899 | #else | ||
900 | ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle, | ||
901 | &prop); | ||
902 | #endif | ||
903 | |||
904 | if (ret) | ||
905 | { | ||
906 | #ifdef OLD_XCB_VERSION | ||
907 | xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, | ||
908 | strlen(prop.value), prop.value); | ||
909 | #else | ||
910 | xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, | ||
911 | 8, strlen(prop.value), prop.value); | ||
912 | #endif | ||
913 | if (prop.value) free(prop.value); | ||
914 | } | ||
915 | else | ||
916 | #ifdef OLD_XCB_VERSION | ||
917 | xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, | ||
918 | strlen(name), name); | ||
919 | #else | ||
920 | xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, | ||
921 | 8, strlen(name), name); | ||
922 | #endif | ||
923 | |||
924 | free(list[0]); | ||
925 | } | ||
926 | |||
927 | EAPI void | ||
928 | ecore_x_icccm_iconic_request_send(Ecore_X_Window win, | ||
929 | Ecore_X_Window root) | ||
930 | { | ||
931 | xcb_client_message_event_t ev; | ||
932 | |||
933 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
934 | CHECK_XCB_CONN; | ||
935 | |||
936 | if (!win) return; | ||
937 | if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; | ||
938 | |||
939 | memset(&ev, 0, sizeof(xcb_client_message_event_t)); | ||
940 | |||
941 | ev.response_type = XCB_CLIENT_MESSAGE; | ||
942 | ev.format = 32; | ||
943 | ev.window = win; | ||
944 | ev.type = ECORE_X_ATOM_WM_CHANGE_STATE; | ||
945 | #ifdef OLD_XCB_VERSION | ||
946 | ev.data.data32[0] = XCB_WM_STATE_ICONIC; | ||
947 | #else | ||
948 | ev.data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC; | ||
949 | #endif | ||
950 | |||
951 | xcb_send_event(_ecore_xcb_conn, 0, root, | ||
952 | (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | | ||
953 | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT), | ||
954 | (const char *)&ev); | ||
955 | // ecore_x_flush(); | ||
956 | } | ||
957 | |||
958 | /** | ||
959 | * Set or unset a wm protocol property. | ||
960 | * @param win The Window | ||
961 | * @param protocol The protocol to enable/disable | ||
962 | * @param on On/Off | ||
963 | */ | ||
964 | EAPI void | ||
965 | ecore_x_icccm_protocol_set(Ecore_X_Window win, | ||
966 | Ecore_X_WM_Protocol protocol, | ||
967 | Eina_Bool on) | ||
968 | { | ||
969 | Ecore_X_Atom proto; | ||
970 | xcb_get_property_cookie_t cookie; | ||
971 | #ifdef OLD_XCB_VERSION | ||
972 | xcb_get_wm_protocols_reply_t protos; | ||
973 | #else | ||
974 | xcb_icccm_get_wm_protocols_reply_t protos; | ||
975 | #endif | ||
976 | int i = 0, count = 0, set = 0; | ||
977 | |||
978 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
979 | CHECK_XCB_CONN; | ||
980 | |||
981 | if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return; | ||
982 | proto = _ecore_xcb_atoms_wm_protocol[protocol]; | ||
983 | #ifdef OLD_XCB_VERSION | ||
984 | cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); | ||
985 | if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL)) | ||
986 | #else | ||
987 | cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); | ||
988 | if (!xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL)) | ||
989 | #endif | ||
990 | count = 0; | ||
991 | else | ||
992 | count = protos.atoms_len; | ||
993 | |||
994 | for (i = 0; i < count; i++) | ||
995 | { | ||
996 | if (protos.atoms[i] == proto) | ||
997 | { | ||
998 | set = 1; | ||
999 | break; | ||
1000 | } | ||
1001 | } | ||
1002 | |||
1003 | if (on) | ||
1004 | { | ||
1005 | if (!set) | ||
1006 | { | ||
1007 | Ecore_X_Atom *atoms = NULL; | ||
1008 | |||
1009 | atoms = malloc((count + 1) * sizeof(Ecore_X_Atom)); | ||
1010 | if (atoms) | ||
1011 | { | ||
1012 | for (i = 0; i < count; i++) | ||
1013 | atoms[i] = protos.atoms[i]; | ||
1014 | atoms[count] = proto; | ||
1015 | #ifdef OLD_XCB_VERSION | ||
1016 | xcb_set_wm_protocols(_ecore_xcb_conn, | ||
1017 | ECORE_X_ATOM_WM_PROTOCOLS, | ||
1018 | win, count, atoms); | ||
1019 | #else | ||
1020 | xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, | ||
1021 | ECORE_X_ATOM_WM_PROTOCOLS, | ||
1022 | count, atoms); | ||
1023 | #endif | ||
1024 | free(atoms); | ||
1025 | } | ||
1026 | } | ||
1027 | } | ||
1028 | else | ||
1029 | { | ||
1030 | if (set) | ||
1031 | { | ||
1032 | for (i = 0; i < count; i++) | ||
1033 | { | ||
1034 | if (protos.atoms[i] == proto) | ||
1035 | { | ||
1036 | int j = 0; | ||
1037 | |||
1038 | for (j = (i + 1); j < count; j++) | ||
1039 | protos.atoms[j - 1] = protos.atoms[j]; | ||
1040 | if (count > 1) | ||
1041 | #ifdef OLD_XCB_VERSION | ||
1042 | xcb_set_wm_protocols(_ecore_xcb_conn, | ||
1043 | ECORE_X_ATOM_WM_PROTOCOLS, | ||
1044 | win, count - 1, protos.atoms); | ||
1045 | #else | ||
1046 | xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, | ||
1047 | ECORE_X_ATOM_WM_PROTOCOLS, | ||
1048 | count - 1, protos.atoms); | ||
1049 | #endif | ||
1050 | else | ||
1051 | ecore_x_window_prop_property_del(win, | ||
1052 | ECORE_X_ATOM_WM_PROTOCOLS); | ||
1053 | break; | ||
1054 | } | ||
1055 | } | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | #ifdef OLD_XCB_VERSION | ||
1060 | xcb_get_wm_protocols_reply_wipe(&protos); | ||
1061 | #else | ||
1062 | xcb_icccm_get_wm_protocols_reply_wipe(&protos); | ||
1063 | #endif | ||
1064 | } | ||
1065 | |||
1066 | /** | ||
1067 | * Determines whether a protocol is set for a window. | ||
1068 | * @param win The Window | ||
1069 | * @param protocol The protocol to query | ||
1070 | * @return 1 if the protocol is set, else 0. | ||
1071 | */ | ||
1072 | EAPI Eina_Bool | ||
1073 | ecore_x_icccm_protocol_isset(Ecore_X_Window win, | ||
1074 | Ecore_X_WM_Protocol protocol) | ||
1075 | { | ||
1076 | Ecore_X_Atom proto; | ||
1077 | Eina_Bool ret = EINA_FALSE; | ||
1078 | xcb_get_property_cookie_t cookie; | ||
1079 | #ifdef OLD_XCB_VERSION | ||
1080 | xcb_get_wm_protocols_reply_t reply; | ||
1081 | #else | ||
1082 | xcb_icccm_get_wm_protocols_reply_t reply; | ||
1083 | #endif | ||
1084 | uint8_t val = 0; | ||
1085 | unsigned int i = 0; | ||
1086 | |||
1087 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1088 | CHECK_XCB_CONN; | ||
1089 | |||
1090 | if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE; | ||
1091 | |||
1092 | proto = _ecore_xcb_atoms_wm_protocol[protocol]; | ||
1093 | #ifdef OLD_XCB_VERSION | ||
1094 | cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); | ||
1095 | val = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL); | ||
1096 | #else | ||
1097 | cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); | ||
1098 | val = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL); | ||
1099 | #endif | ||
1100 | if (!val) return EINA_FALSE; | ||
1101 | |||
1102 | for (i = 0; i < reply.atoms_len; i++) | ||
1103 | if (reply.atoms[i] == proto) | ||
1104 | { | ||
1105 | ret = EINA_TRUE; | ||
1106 | break; | ||
1107 | } | ||
1108 | |||
1109 | #ifdef OLD_XCB_VERSION | ||
1110 | xcb_get_wm_protocols_reply_wipe(&reply); | ||
1111 | #else | ||
1112 | xcb_icccm_get_wm_protocols_reply_wipe(&reply); | ||
1113 | #endif | ||
1114 | |||
1115 | return ret; | ||
1116 | } | ||
1117 | |||
1118 | /** | ||
1119 | * Set protocol atoms explicitly | ||
1120 | * @param win The Window | ||
1121 | * @param protos An array of protocol atoms | ||
1122 | * @param num the number of members of the array | ||
1123 | */ | ||
1124 | EAPI void | ||
1125 | ecore_x_icccm_protocol_atoms_set(Ecore_X_Window win, | ||
1126 | Ecore_X_Atom *protos, | ||
1127 | int num) | ||
1128 | { | ||
1129 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1130 | CHECK_XCB_CONN; | ||
1131 | |||
1132 | if (num > 0) | ||
1133 | #ifdef OLD_XCB_VERSION | ||
1134 | xcb_set_wm_protocols(_ecore_xcb_conn, ECORE_X_ATOM_WM_PROTOCOLS, | ||
1135 | win, num, protos); | ||
1136 | #else | ||
1137 | xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, | ||
1138 | ECORE_X_ATOM_WM_PROTOCOLS, num, protos); | ||
1139 | #endif | ||
1140 | else | ||
1141 | ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_PROTOCOLS); | ||
1142 | } | ||
1143 | |||
1144 | EAPI Eina_Bool | ||
1145 | ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, | ||
1146 | Eina_Bool *request_pos, | ||
1147 | Ecore_X_Gravity *gravity, | ||
1148 | int *min_w, | ||
1149 | int *min_h, | ||
1150 | int *max_w, | ||
1151 | int *max_h, | ||
1152 | int *base_w, | ||
1153 | int *base_h, | ||
1154 | int *step_x, | ||
1155 | int *step_y, | ||
1156 | double *min_aspect, | ||
1157 | double *max_aspect) | ||
1158 | { | ||
1159 | xcb_size_hints_t hints; | ||
1160 | xcb_get_property_cookie_t cookie; | ||
1161 | uint8_t ret = 0; | ||
1162 | int32_t minw = 0, minh = 0; | ||
1163 | int32_t maxw = 32767, maxh = 32767; | ||
1164 | int32_t basew = -1, baseh = -1; | ||
1165 | int32_t stepx = -1, stepy = -1; | ||
1166 | double mina = 0.0, maxa = 0.0; | ||
1167 | |||
1168 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1169 | CHECK_XCB_CONN; | ||
1170 | |||
1171 | if (request_pos) *request_pos = EINA_FALSE; | ||
1172 | if (gravity) *gravity = ECORE_X_GRAVITY_NW; | ||
1173 | if (min_w) *min_w = minw; | ||
1174 | if (min_h) *min_h = minh; | ||
1175 | if (max_w) *max_w = maxw; | ||
1176 | if (max_h) *max_h = maxh; | ||
1177 | if (base_w) *base_w = basew; | ||
1178 | if (base_h) *base_h = baseh; | ||
1179 | if (step_x) *step_x = stepx; | ||
1180 | if (step_y) *step_y = stepy; | ||
1181 | if (min_aspect) *min_aspect = mina; | ||
1182 | if (max_aspect) *max_aspect = maxa; | ||
1183 | |||
1184 | #ifdef OLD_XCB_VERSION | ||
1185 | cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); | ||
1186 | ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); | ||
1187 | #else | ||
1188 | cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); | ||
1189 | ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, | ||
1190 | &hints, NULL); | ||
1191 | #endif | ||
1192 | if (!ret) return EINA_FALSE; | ||
1193 | |||
1194 | #ifdef OLD_XCB_VERSION | ||
1195 | if ((hints.flags & XCB_SIZE_HINT_US_POSITION) || | ||
1196 | (hints.flags & XCB_SIZE_HINT_P_POSITION)) | ||
1197 | #else | ||
1198 | if ((hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION) || | ||
1199 | (hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION)) | ||
1200 | #endif | ||
1201 | { | ||
1202 | if (request_pos) *request_pos = EINA_TRUE; | ||
1203 | } | ||
1204 | |||
1205 | #ifdef OLD_XCB_VERSION | ||
1206 | if (hints.flags & XCB_SIZE_HINT_P_WIN_GRAVITY) | ||
1207 | #else | ||
1208 | if (hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY) | ||
1209 | #endif | ||
1210 | { | ||
1211 | if (gravity) *gravity = hints.win_gravity; | ||
1212 | } | ||
1213 | |||
1214 | #ifdef OLD_XCB_VERSION | ||
1215 | if (hints.flags & XCB_SIZE_HINT_P_MIN_SIZE) | ||
1216 | #else | ||
1217 | if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE) | ||
1218 | #endif | ||
1219 | { | ||
1220 | minw = hints.min_width; | ||
1221 | minh = hints.min_height; | ||
1222 | } | ||
1223 | |||
1224 | #ifdef OLD_XCB_VERSION | ||
1225 | if (hints.flags & XCB_SIZE_HINT_P_MAX_SIZE) | ||
1226 | #else | ||
1227 | if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE) | ||
1228 | #endif | ||
1229 | { | ||
1230 | maxw = hints.max_width; | ||
1231 | maxh = hints.max_height; | ||
1232 | if (maxw < minw) maxw = minw; | ||
1233 | if (maxh < minh) maxh = minh; | ||
1234 | } | ||
1235 | |||
1236 | #ifdef OLD_XCB_VERSION | ||
1237 | if (hints.flags & XCB_SIZE_HINT_BASE_SIZE) | ||
1238 | #else | ||
1239 | if (hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE) | ||
1240 | #endif | ||
1241 | { | ||
1242 | basew = hints.base_width; | ||
1243 | baseh = hints.base_height; | ||
1244 | if (basew > minw) minw = basew; | ||
1245 | if (baseh > minh) minh = baseh; | ||
1246 | } | ||
1247 | |||
1248 | #ifdef OLD_XCB_VERSION | ||
1249 | if (hints.flags & XCB_SIZE_HINT_P_RESIZE_INC) | ||
1250 | #else | ||
1251 | if (hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC) | ||
1252 | #endif | ||
1253 | { | ||
1254 | stepx = hints.width_inc; | ||
1255 | stepy = hints.height_inc; | ||
1256 | if (stepx < 1) stepx = 1; | ||
1257 | if (stepy < 1) stepy = 1; | ||
1258 | } | ||
1259 | |||
1260 | #ifdef OLD_XCB_VERSION | ||
1261 | if (hints.flags & XCB_SIZE_HINT_P_ASPECT) | ||
1262 | #else | ||
1263 | if (hints.flags & XCB_ICCCM_SIZE_HINT_P_ASPECT) | ||
1264 | #endif | ||
1265 | { | ||
1266 | if (hints.min_aspect_den > 0) | ||
1267 | mina = ((double)hints.min_aspect_num) / ((double)hints.min_aspect_den); | ||
1268 | |||
1269 | if (hints.max_aspect_den > 0) | ||
1270 | maxa = ((double)hints.max_aspect_num) / ((double)hints.max_aspect_den); | ||
1271 | } | ||
1272 | |||
1273 | if (min_w) *min_w = minw; | ||
1274 | if (min_h) *min_h = minh; | ||
1275 | if (max_w) *max_w = maxw; | ||
1276 | if (max_h) *max_h = maxh; | ||
1277 | if (base_w) *base_w = basew; | ||
1278 | if (base_h) *base_h = baseh; | ||
1279 | if (step_x) *step_x = stepx; | ||
1280 | if (step_y) *step_y = stepy; | ||
1281 | if (min_aspect) *min_aspect = mina; | ||
1282 | if (max_aspect) *max_aspect = maxa; | ||
1283 | |||
1284 | return EINA_TRUE; | ||
1285 | } | ||
1286 | |||
1287 | EAPI void | ||
1288 | ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, | ||
1289 | Eina_Bool request_pos, | ||
1290 | Ecore_X_Gravity gravity, | ||
1291 | int min_w, | ||
1292 | int min_h, | ||
1293 | int max_w, | ||
1294 | int max_h, | ||
1295 | int base_w, | ||
1296 | int base_h, | ||
1297 | int step_x, | ||
1298 | int step_y, | ||
1299 | double min_aspect, | ||
1300 | double max_aspect) | ||
1301 | { | ||
1302 | xcb_get_property_cookie_t cookie; | ||
1303 | xcb_size_hints_t hints; | ||
1304 | uint8_t ret = 0; | ||
1305 | |||
1306 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1307 | CHECK_XCB_CONN; | ||
1308 | |||
1309 | #ifdef OLD_XCB_VERSION | ||
1310 | cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); | ||
1311 | ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); | ||
1312 | #else | ||
1313 | cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); | ||
1314 | ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, | ||
1315 | &hints, NULL); | ||
1316 | #endif | ||
1317 | if (!ret) memset(&hints, 0, sizeof(xcb_size_hints_t)); | ||
1318 | |||
1319 | hints.flags = 0; | ||
1320 | |||
1321 | #ifdef OLD_XCB_VERSION | ||
1322 | if (request_pos) | ||
1323 | hints.flags |= XCB_SIZE_HINT_US_POSITION; | ||
1324 | |||
1325 | if (gravity != ECORE_X_GRAVITY_NW) | ||
1326 | xcb_size_hints_set_win_gravity(&hints, gravity); | ||
1327 | if ((min_w > 0) || (min_h > 0)) | ||
1328 | xcb_size_hints_set_min_size(&hints, min_w, min_h); | ||
1329 | if ((max_w > 0) || (max_h > 0)) | ||
1330 | xcb_size_hints_set_max_size(&hints, max_w, max_h); | ||
1331 | if ((base_w > 0) || (base_h > 0)) | ||
1332 | xcb_size_hints_set_base_size(&hints, base_w, base_h); | ||
1333 | if ((step_x > 1) || (step_y > 1)) | ||
1334 | xcb_size_hints_set_resize_inc(&hints, step_x, step_y); | ||
1335 | if ((min_aspect > 0.0) || (max_aspect > 0.0)) | ||
1336 | xcb_size_hints_set_aspect(&hints, | ||
1337 | (int32_t)(min_aspect * 10000), 10000, | ||
1338 | (int32_t)(max_aspect * 10000), 10000); | ||
1339 | |||
1340 | xcb_set_wm_normal_hints(_ecore_xcb_conn, win, &hints); | ||
1341 | #else | ||
1342 | if (request_pos) | ||
1343 | hints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION; | ||
1344 | |||
1345 | if (gravity != ECORE_X_GRAVITY_NW) | ||
1346 | xcb_icccm_size_hints_set_win_gravity(&hints, gravity); | ||
1347 | if ((min_w > 0) || (min_h > 0)) | ||
1348 | xcb_icccm_size_hints_set_min_size(&hints, min_w, min_h); | ||
1349 | if ((max_w > 0) || (max_h > 0)) | ||
1350 | xcb_icccm_size_hints_set_max_size(&hints, max_w, max_h); | ||
1351 | if ((base_w > 0) || (base_h > 0)) | ||
1352 | xcb_icccm_size_hints_set_base_size(&hints, base_w, base_h); | ||
1353 | if ((step_x > 1) || (step_y > 1)) | ||
1354 | xcb_icccm_size_hints_set_resize_inc(&hints, step_x, step_y); | ||
1355 | if ((min_aspect > 0.0) || (max_aspect > 0.0)) | ||
1356 | xcb_icccm_size_hints_set_aspect(&hints, | ||
1357 | (int32_t)(min_aspect * 10000), 10000, | ||
1358 | (int32_t)(max_aspect * 10000), 10000); | ||
1359 | |||
1360 | xcb_icccm_set_wm_normal_hints(_ecore_xcb_conn, win, &hints); | ||
1361 | #endif | ||
1362 | } | ||
1363 | |||
1364 | EAPI void | ||
1365 | ecore_x_icccm_move_resize_send(Ecore_X_Window win, | ||
1366 | int x, | ||
1367 | int y, | ||
1368 | int w, | ||
1369 | int h) | ||
1370 | { | ||
1371 | xcb_configure_notify_event_t ev; | ||
1372 | |||
1373 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1374 | CHECK_XCB_CONN; | ||
1375 | |||
1376 | if (!win) return; | ||
1377 | |||
1378 | memset(&ev, 0, sizeof(xcb_configure_notify_event_t)); | ||
1379 | |||
1380 | ev.response_type = XCB_CONFIGURE_NOTIFY; | ||
1381 | ev.event = win; | ||
1382 | ev.window = win; | ||
1383 | ev.above_sibling = XCB_NONE; | ||
1384 | ev.x = x; | ||
1385 | ev.y = y; | ||
1386 | ev.width = w; | ||
1387 | ev.height = h; | ||
1388 | ev.border_width = 0; | ||
1389 | ev.override_redirect = 0; | ||
1390 | |||
1391 | xcb_send_event(_ecore_xcb_conn, 0, win, | ||
1392 | XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev); | ||
1393 | // ecore_x_flush(); | ||
1394 | } | ||
1395 | |||
1396 | /** | ||
1397 | * Get a window client machine string. | ||
1398 | * @param win The window | ||
1399 | * @return The windows client machine string | ||
1400 | * | ||
1401 | * Return the client machine of a window. String must be free'd when done with. | ||
1402 | */ | ||
1403 | EAPI char * | ||
1404 | ecore_x_icccm_client_machine_get(Ecore_X_Window win) | ||
1405 | { | ||
1406 | xcb_get_property_cookie_t cookie; | ||
1407 | #ifdef OLD_XCB_VERSION | ||
1408 | xcb_get_text_property_reply_t prop; | ||
1409 | #else | ||
1410 | xcb_icccm_get_text_property_reply_t prop; | ||
1411 | #endif | ||
1412 | uint8_t ret = 0; | ||
1413 | char *tmp = NULL; | ||
1414 | |||
1415 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1416 | CHECK_XCB_CONN; | ||
1417 | |||
1418 | #ifdef OLD_XCB_VERSION | ||
1419 | cookie = xcb_get_wm_client_machine_unchecked(_ecore_xcb_conn, win); | ||
1420 | ret = xcb_get_wm_client_machine_reply(_ecore_xcb_conn, cookie, &prop, NULL); | ||
1421 | #else | ||
1422 | cookie = xcb_icccm_get_wm_client_machine_unchecked(_ecore_xcb_conn, win); | ||
1423 | ret = xcb_icccm_get_wm_client_machine_reply(_ecore_xcb_conn, cookie, | ||
1424 | &prop, NULL); | ||
1425 | #endif | ||
1426 | if (ret == 0) return NULL; | ||
1427 | |||
1428 | tmp = malloc((prop.name_len + 1) * sizeof(char *)); | ||
1429 | if (!tmp) | ||
1430 | { | ||
1431 | #ifdef OLD_XCB_VERSION | ||
1432 | xcb_get_text_property_reply_wipe(&prop); | ||
1433 | #else | ||
1434 | xcb_icccm_get_text_property_reply_wipe(&prop); | ||
1435 | #endif | ||
1436 | return NULL; | ||
1437 | } | ||
1438 | memcpy(tmp, prop.name, sizeof(char *) * prop.name_len); | ||
1439 | tmp[prop.name_len] = '\0'; | ||
1440 | |||
1441 | #ifdef OLD_XCB_VERSION | ||
1442 | xcb_get_text_property_reply_wipe(&prop); | ||
1443 | #else | ||
1444 | xcb_icccm_get_text_property_reply_wipe(&prop); | ||
1445 | #endif | ||
1446 | |||
1447 | return tmp; | ||
1448 | } | ||
1449 | |||
1450 | EAPI void | ||
1451 | ecore_x_icccm_take_focus_send(Ecore_X_Window win, | ||
1452 | Ecore_X_Time t) | ||
1453 | { | ||
1454 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1455 | |||
1456 | ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, | ||
1457 | XCB_EVENT_MASK_NO_EVENT, | ||
1458 | ECORE_X_ATOM_WM_TAKE_FOCUS, t, 0, 0, 0); | ||
1459 | } | ||
1460 | |||
1461 | EAPI void | ||
1462 | ecore_x_icccm_save_yourself_send(Ecore_X_Window win, | ||
1463 | Ecore_X_Time t) | ||
1464 | { | ||
1465 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1466 | ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, | ||
1467 | XCB_EVENT_MASK_NO_EVENT, | ||
1468 | ECORE_X_ATOM_WM_SAVE_YOURSELF, t, 0, 0, 0); | ||
1469 | } | ||
1470 | |||
1471 | /** | ||
1472 | * Add a subwindow to the list of windows that need a different colormap installed. | ||
1473 | * @param win The toplevel window | ||
1474 | * @param subwin The subwindow to be added to the colormap windows list | ||
1475 | */ | ||
1476 | EAPI void | ||
1477 | ecore_x_icccm_colormap_window_set(Ecore_X_Window win, | ||
1478 | Ecore_X_Window subwin) | ||
1479 | { | ||
1480 | int num = 0, i = 0; | ||
1481 | unsigned char *odata = NULL, *data = NULL; | ||
1482 | Ecore_X_Window *newset = NULL, *oldset = NULL; | ||
1483 | |||
1484 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1485 | |||
1486 | if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, | ||
1487 | ECORE_X_ATOM_WINDOW, 32, &odata, &num)) | ||
1488 | { | ||
1489 | if (!(newset = calloc(1, sizeof(Ecore_X_Window)))) return; | ||
1490 | newset[0] = subwin; | ||
1491 | num = 1; | ||
1492 | data = (unsigned char *)newset; | ||
1493 | } | ||
1494 | else | ||
1495 | { | ||
1496 | if (!(newset = calloc(num + 1, sizeof(Ecore_X_Window)))) return; | ||
1497 | oldset = (Ecore_X_Window *)odata; | ||
1498 | for (i = 0; i < num; i++) | ||
1499 | { | ||
1500 | if (oldset[i] == subwin) | ||
1501 | { | ||
1502 | if (odata) free(odata); | ||
1503 | odata = NULL; | ||
1504 | free(newset); | ||
1505 | return; | ||
1506 | } | ||
1507 | newset[i] = oldset[i]; | ||
1508 | } | ||
1509 | newset[num++] = subwin; | ||
1510 | if (odata) free(odata); | ||
1511 | data = (unsigned char *)newset; | ||
1512 | } | ||
1513 | ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, | ||
1514 | ECORE_X_ATOM_WINDOW, 32, data, num); | ||
1515 | free(newset); | ||
1516 | } | ||
1517 | |||
1518 | /** | ||
1519 | * Remove a window from the list of colormap windows. | ||
1520 | * @param win The toplevel window | ||
1521 | * @param subwin The window to be removed from the colormap window list. | ||
1522 | */ | ||
1523 | EAPI void | ||
1524 | ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, | ||
1525 | Ecore_X_Window subwin) | ||
1526 | { | ||
1527 | int num = 0, i = 0, j = 0, k = 0; | ||
1528 | unsigned char *odata = NULL, *data = NULL; | ||
1529 | Ecore_X_Window *newset = NULL, *oldset = NULL; | ||
1530 | |||
1531 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1532 | |||
1533 | if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, | ||
1534 | ECORE_X_ATOM_WINDOW, 32, &odata, &num)) | ||
1535 | return; | ||
1536 | |||
1537 | oldset = (Ecore_X_Window *)odata; | ||
1538 | for (i = 0; i < num; i++) | ||
1539 | { | ||
1540 | if (oldset[i] == subwin) | ||
1541 | { | ||
1542 | if (num == 1) | ||
1543 | { | ||
1544 | ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS); | ||
1545 | if (odata) free(odata); | ||
1546 | odata = NULL; | ||
1547 | return; | ||
1548 | } | ||
1549 | else | ||
1550 | { | ||
1551 | newset = calloc(num - 1, sizeof(Ecore_X_Window)); | ||
1552 | data = (unsigned char *)newset; | ||
1553 | for (j = 0; j < num; ++j) | ||
1554 | if (oldset[j] != subwin) | ||
1555 | newset[k++] = oldset[j]; | ||
1556 | |||
1557 | ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, | ||
1558 | ECORE_X_ATOM_WINDOW, 32, data, k); | ||
1559 | if (odata) free(odata); | ||
1560 | odata = NULL; | ||
1561 | free(newset); | ||
1562 | return; | ||
1563 | } | ||
1564 | } | ||
1565 | } | ||
1566 | if (odata) free(odata); | ||
1567 | } | ||
1568 | |||