aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_icccm.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_x/xlib/ecore_x_icccm.c')
-rw-r--r--libraries/ecore/src/lib/ecore_x/xlib/ecore_x_icccm.c1214
1 files changed, 0 insertions, 1214 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_icccm.c b/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_icccm.c
deleted file mode 100644
index 8d6ea1f..0000000
--- a/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_icccm.c
+++ /dev/null
@@ -1,1214 +0,0 @@
1/*
2 * Various ICCCM related functions.
3 *
4 * This is ALL the code involving anything ICCCM related. for both WM and
5 * client.
6 */
7
8#ifdef HAVE_CONFIG_H
9# include <config.h>
10#endif /* ifdef HAVE_CONFIG_H */
11
12#include <stdlib.h>
13#include <string.h>
14
15#include "Ecore.h"
16#include "ecore_x_private.h"
17#include "Ecore_X.h"
18#include "Ecore_X_Atoms.h"
19
20EAPI void
21ecore_x_icccm_init(void)
22{
23 LOGFN(__FILE__, __LINE__, __FUNCTION__);
24}
25
26EAPI void
27ecore_x_icccm_state_set(Ecore_X_Window win,
28 Ecore_X_Window_State_Hint state)
29{
30 unsigned long c[2];
31
32 LOGFN(__FILE__, __LINE__, __FUNCTION__);
33 if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
34 c[0] = WithdrawnState;
35 else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
36 c[0] = NormalState;
37 else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
38 c[0] = IconicState;
39
40 c[1] = None;
41 XChangeProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE,
42 ECORE_X_ATOM_WM_STATE, 32, PropModeReplace,
43 (unsigned char *)c, 2);
44}
45
46EAPI Ecore_X_Window_State_Hint
47ecore_x_icccm_state_get(Ecore_X_Window win)
48{
49 unsigned char *prop_ret = NULL;
50 Atom type_ret;
51 unsigned long bytes_after, num_ret;
52 int format_ret;
53 Ecore_X_Window_State_Hint hint;
54
55 LOGFN(__FILE__, __LINE__, __FUNCTION__);
56 hint = ECORE_X_WINDOW_STATE_HINT_NONE;
57 XGetWindowProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE,
58 0, 0x7fffffff, False, ECORE_X_ATOM_WM_STATE,
59 &type_ret, &format_ret, &num_ret, &bytes_after,
60 &prop_ret);
61 if ((prop_ret) && (num_ret == 2))
62 {
63 if (prop_ret[0] == WithdrawnState)
64 hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
65 else if (prop_ret[0] == NormalState)
66 hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
67 else if (prop_ret[0] == IconicState)
68 hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
69 }
70
71 if (prop_ret)
72 XFree(prop_ret);
73
74 return hint;
75}
76
77EAPI void
78ecore_x_icccm_delete_window_send(Ecore_X_Window win,
79 Ecore_X_Time t)
80{
81 LOGFN(__FILE__, __LINE__, __FUNCTION__);
82 ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
83 ECORE_X_EVENT_MASK_NONE,
84 ECORE_X_ATOM_WM_DELETE_WINDOW,
85 t, 0, 0, 0);
86}
87
88EAPI void
89ecore_x_icccm_take_focus_send(Ecore_X_Window win,
90 Ecore_X_Time t)
91{
92 LOGFN(__FILE__, __LINE__, __FUNCTION__);
93 ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
94 ECORE_X_EVENT_MASK_NONE,
95 ECORE_X_ATOM_WM_TAKE_FOCUS,
96 t, 0, 0, 0);
97}
98
99EAPI void
100ecore_x_icccm_save_yourself_send(Ecore_X_Window win,
101 Ecore_X_Time t)
102{
103 LOGFN(__FILE__, __LINE__, __FUNCTION__);
104 ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
105 ECORE_X_EVENT_MASK_NONE,
106 ECORE_X_ATOM_WM_SAVE_YOURSELF,
107 t, 0, 0, 0);
108}
109
110EAPI void
111ecore_x_icccm_move_resize_send(Ecore_X_Window win,
112 int x,
113 int y,
114 int w,
115 int h)
116{
117 XEvent ev;
118
119 LOGFN(__FILE__, __LINE__, __FUNCTION__);
120 ev.type = ConfigureNotify;
121 ev.xconfigure.display = _ecore_x_disp;
122 ev.xconfigure.event = win;
123 ev.xconfigure.window = win;
124 ev.xconfigure.x = x;
125 ev.xconfigure.y = y;
126 ev.xconfigure.width = w;
127 ev.xconfigure.height = h;
128 ev.xconfigure.border_width = 0;
129 ev.xconfigure.above = None;
130 ev.xconfigure.override_redirect = False;
131 XSendEvent(_ecore_x_disp, win, False, StructureNotifyMask, &ev);
132}
133
134EAPI void
135ecore_x_icccm_hints_set(Ecore_X_Window win,
136 Eina_Bool accepts_focus,
137 Ecore_X_Window_State_Hint initial_state,
138 Ecore_X_Pixmap icon_pixmap,
139 Ecore_X_Pixmap icon_mask,
140 Ecore_X_Window icon_window,
141 Ecore_X_Window window_group,
142 Eina_Bool is_urgent)
143{
144 XWMHints *hints;
145
146 hints = XAllocWMHints();
147 if (!hints)
148 return;
149
150 LOGFN(__FILE__, __LINE__, __FUNCTION__);
151 hints->flags = InputHint | StateHint;
152 hints->input = accepts_focus;
153 if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
154 hints->initial_state = WithdrawnState;
155 else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
156 hints->initial_state = NormalState;
157 else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
158 hints->initial_state = IconicState;
159
160 if (icon_pixmap != 0)
161 {
162 hints->icon_pixmap = icon_pixmap;
163 hints->flags |= IconPixmapHint;
164 }
165
166 if (icon_mask != 0)
167 {
168 hints->icon_mask = icon_mask;
169 hints->flags |= IconMaskHint;
170 }
171
172 if (icon_window != 0)
173 {
174 hints->icon_window = icon_window;
175 hints->flags |= IconWindowHint;
176 }
177
178 if (window_group != 0)
179 {
180 hints->window_group = window_group;
181 hints->flags |= WindowGroupHint;
182 }
183
184 if (is_urgent)
185 hints->flags |= XUrgencyHint;
186
187 XSetWMHints(_ecore_x_disp, win, hints);
188 XFree(hints);
189}
190
191EAPI Eina_Bool
192ecore_x_icccm_hints_get(Ecore_X_Window win,
193 Eina_Bool *accepts_focus,
194 Ecore_X_Window_State_Hint *initial_state,
195 Ecore_X_Pixmap *icon_pixmap,
196 Ecore_X_Pixmap *icon_mask,
197 Ecore_X_Window *icon_window,
198 Ecore_X_Window *window_group,
199 Eina_Bool *is_urgent)
200{
201 XWMHints *hints;
202
203 LOGFN(__FILE__, __LINE__, __FUNCTION__);
204 if (accepts_focus)
205 *accepts_focus = EINA_TRUE;
206
207 if (initial_state)
208 *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
209
210 if (icon_pixmap)
211 *icon_pixmap = 0;
212
213 if (icon_mask)
214 *icon_mask = 0;
215
216 if (icon_window)
217 *icon_window = 0;
218
219 if (window_group)
220 *window_group = 0;
221
222 if (is_urgent)
223 *is_urgent = EINA_FALSE;
224
225 hints = XGetWMHints(_ecore_x_disp, win);
226 if (hints)
227 {
228 if ((hints->flags & InputHint) && (accepts_focus))
229 {
230 if (hints->input)
231 *accepts_focus = EINA_TRUE;
232 else
233 *accepts_focus = EINA_FALSE;
234 }
235
236 if ((hints->flags & StateHint) && (initial_state))
237 {
238 if (hints->initial_state == WithdrawnState)
239 *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
240 else if (hints->initial_state == NormalState)
241 *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
242 else if (hints->initial_state == IconicState)
243 *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
244 }
245
246 if ((hints->flags & IconPixmapHint) && (icon_pixmap))
247 *icon_pixmap = hints->icon_pixmap;
248
249 if ((hints->flags & IconMaskHint) && (icon_mask))
250 *icon_mask = hints->icon_mask;
251
252 if ((hints->flags & IconWindowHint) && (icon_window))
253 *icon_window = hints->icon_window;
254
255 if ((hints->flags & WindowGroupHint) && (window_group))
256 *window_group = hints->window_group;
257
258 if ((hints->flags & XUrgencyHint) && (is_urgent))
259 *is_urgent = EINA_TRUE;
260
261 XFree(hints);
262 return EINA_TRUE;
263 }
264
265 return EINA_FALSE;
266}
267
268EAPI void
269ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win,
270 Eina_Bool request_pos,
271 Ecore_X_Gravity gravity,
272 int min_w,
273 int min_h,
274 int max_w,
275 int max_h,
276 int base_w,
277 int base_h,
278 int step_x,
279 int step_y,
280 double min_aspect,
281 double max_aspect)
282{
283 XSizeHints hint;
284 long mask;
285
286 LOGFN(__FILE__, __LINE__, __FUNCTION__);
287 if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask))
288 memset(&hint, 0, sizeof(XSizeHints));
289
290 hint.flags = 0;
291 if (request_pos)
292 hint.flags |= USPosition;
293
294 if (gravity != ECORE_X_GRAVITY_NW)
295 {
296 hint.flags |= PWinGravity;
297 hint.win_gravity = gravity;
298 }
299
300 if ((min_w > 0) || (min_h > 0))
301 {
302 hint.flags |= PMinSize;
303 hint.min_width = min_w;
304 hint.min_height = min_h;
305 }
306
307 if ((max_w > 0) || (max_h > 0))
308 {
309 hint.flags |= PMaxSize;
310 hint.max_width = max_w;
311 hint.max_height = max_h;
312 }
313
314 if ((base_w > 0) || (base_h > 0))
315 {
316 hint.flags |= PBaseSize;
317 hint.base_width = base_w;
318 hint.base_height = base_h;
319 }
320
321 if ((step_x > 1) || (step_y > 1))
322 {
323 hint.flags |= PResizeInc;
324 hint.width_inc = step_x;
325 hint.height_inc = step_y;
326 }
327
328 if ((min_aspect > 0.0) || (max_aspect > 0.0))
329 {
330 hint.flags |= PAspect;
331 hint.min_aspect.x = min_aspect * 10000;
332 hint.min_aspect.y = 10000;
333 hint.max_aspect.x = max_aspect * 10000;
334 hint.max_aspect.y = 10000;
335 }
336
337 XSetWMNormalHints(_ecore_x_disp, win, &hint);
338}
339
340EAPI Eina_Bool
341ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win,
342 Eina_Bool *request_pos,
343 Ecore_X_Gravity *gravity,
344 int *min_w,
345 int *min_h,
346 int *max_w,
347 int *max_h,
348 int *base_w,
349 int *base_h,
350 int *step_x,
351 int *step_y,
352 double *min_aspect,
353 double *max_aspect)
354{
355 XSizeHints hint;
356 long mask;
357
358 int minw = 0, minh = 0;
359 int maxw = 32767, maxh = 32767;
360 int basew = -1, baseh = -1;
361 int stepx = -1, stepy = -1;
362 double mina = 0.0, maxa = 0.0;
363
364 LOGFN(__FILE__, __LINE__, __FUNCTION__);
365 if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask))
366 return EINA_FALSE;
367
368 if ((hint.flags & USPosition) || ((hint.flags & PPosition)))
369 {
370 if (request_pos)
371 *request_pos = EINA_TRUE;
372 }
373 else if (request_pos)
374 *request_pos = EINA_FALSE;
375
376 if (hint.flags & PWinGravity)
377 {
378 if (gravity)
379 *gravity = hint.win_gravity;
380 }
381 else if (gravity)
382 *gravity = ECORE_X_GRAVITY_NW;
383
384 if (hint.flags & PMinSize)
385 {
386 minw = hint.min_width;
387 minh = hint.min_height;
388 }
389
390 if (hint.flags & PMaxSize)
391 {
392 maxw = hint.max_width;
393 maxh = hint.max_height;
394 if (maxw < minw)
395 maxw = minw;
396
397 if (maxh < minh)
398 maxh = minh;
399 }
400
401 if (hint.flags & PBaseSize)
402 {
403 basew = hint.base_width;
404 baseh = hint.base_height;
405 if (basew > minw)
406 minw = basew;
407
408 if (baseh > minh)
409 minh = baseh;
410 }
411
412 if (hint.flags & PResizeInc)
413 {
414 stepx = hint.width_inc;
415 stepy = hint.height_inc;
416 if (stepx < 1)
417 stepx = 1;
418
419 if (stepy < 1)
420 stepy = 1;
421 }
422
423 if (hint.flags & PAspect)
424 {
425 if (hint.min_aspect.y > 0)
426 mina = ((double)hint.min_aspect.x) / ((double)hint.min_aspect.y);
427
428 if (hint.max_aspect.y > 0)
429 maxa = ((double)hint.max_aspect.x) / ((double)hint.max_aspect.y);
430 }
431
432 if (min_w)
433 *min_w = minw;
434
435 if (min_h)
436 *min_h = minh;
437
438 if (max_w)
439 *max_w = maxw;
440
441 if (max_h)
442 *max_h = maxh;
443
444 if (base_w)
445 *base_w = basew;
446
447 if (base_h)
448 *base_h = baseh;
449
450 if (step_x)
451 *step_x = stepx;
452
453 if (step_y)
454 *step_y = stepy;
455
456 if (min_aspect)
457 *min_aspect = mina;
458
459 if (max_aspect)
460 *max_aspect = maxa;
461
462 return EINA_TRUE;
463}
464
465EAPI void
466ecore_x_icccm_title_set(Ecore_X_Window win,
467 const char *t)
468{
469 char *list[1];
470 XTextProperty xprop;
471 int ret;
472
473 if (!t)
474 return;
475
476 LOGFN(__FILE__, __LINE__, __FUNCTION__);
477 xprop.value = NULL;
478#ifdef X_HAVE_UTF8_STRING
479 list[0] = strdup(t);
480 ret =
481 Xutf8TextListToTextProperty(_ecore_x_disp, list, 1, XUTF8StringStyle,
482 &xprop);
483#else /* ifdef X_HAVE_UTF8_STRING */
484 list[0] = strdup(t);
485 ret =
486 XmbTextListToTextProperty(_ecore_x_disp, list, 1, XStdICCTextStyle,
487 &xprop);
488#endif /* ifdef X_HAVE_UTF8_STRING */
489 if (ret >= Success)
490 {
491 XSetWMName(_ecore_x_disp, win, &xprop);
492 if (xprop.value)
493 XFree(xprop.value);
494 }
495 else if (XStringListToTextProperty(list, 1, &xprop) >= Success)
496 {
497 XSetWMName(_ecore_x_disp, win, &xprop);
498 if (xprop.value)
499 XFree(xprop.value);
500 }
501
502 free(list[0]);
503}
504
505EAPI char *
506ecore_x_icccm_title_get(Ecore_X_Window win)
507{
508 XTextProperty xprop;
509
510 LOGFN(__FILE__, __LINE__, __FUNCTION__);
511 xprop.value = NULL;
512 if (XGetWMName(_ecore_x_disp, win, &xprop) >= Success)
513 {
514 if (xprop.value)
515 {
516 char **list = NULL;
517 char *t = NULL;
518 int num = 0;
519 int ret;
520
521 if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING)
522 t = strdup((char *)xprop.value);
523 else
524 {
525 /* convert to utf8 */
526#ifdef X_HAVE_UTF8_STRING
527 ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop,
528 &list, &num);
529#else /* ifdef X_HAVE_UTF8_STRING */
530 ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop,
531 &list, &num);
532#endif /* ifdef X_HAVE_UTF8_STRING */
533
534 if ((ret == XLocaleNotSupported) ||
535 (ret == XNoMemory) || (ret == XConverterNotFound))
536 t = strdup((char *)xprop.value);
537 else if ((ret >= Success) && (num > 0))
538 t = strdup(list[0]);
539
540 if (list)
541 XFreeStringList(list);
542 }
543
544 if (xprop.value)
545 XFree(xprop.value);
546
547 return t;
548 }
549 }
550
551 return NULL;
552}
553
554/**
555 * Set protocol atoms explicitly
556 * @param win The Window
557 * @param protos An array of protocol atoms
558 * @param num the number of members of the array
559 */
560EAPI void
561ecore_x_icccm_protocol_atoms_set(Ecore_X_Window win,
562 Ecore_X_Atom *protos,
563 int num)
564{
565 LOGFN(__FILE__, __LINE__, __FUNCTION__);
566 if (num > 0)
567 XSetWMProtocols(_ecore_x_disp, win, (Atom *)(protos), num);
568 else
569 XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_PROTOCOLS);
570}
571
572/**
573 * Set or unset a wm protocol property.
574 * @param win The Window
575 * @param protocol The protocol to enable/disable
576 * @param on On/Off
577 */
578EAPI void
579ecore_x_icccm_protocol_set(Ecore_X_Window win,
580 Ecore_X_WM_Protocol protocol,
581 Eina_Bool on)
582{
583 Atom *protos = NULL;
584 Atom proto;
585 int protos_count = 0;
586 int already_set = 0;
587 int i;
588
589 /* Check for invalid values */
590 if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
591 return;
592
593 LOGFN(__FILE__, __LINE__, __FUNCTION__);
594 proto = _ecore_x_atoms_wm_protocols[protocol];
595
596 if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
597 {
598 protos = NULL;
599 protos_count = 0;
600 }
601
602 for (i = 0; i < protos_count; i++)
603 {
604 if (protos[i] == proto)
605 {
606 already_set = 1;
607 break;
608 }
609 }
610
611 if (on)
612 {
613 Atom *new_protos = NULL;
614
615 if (already_set)
616 goto leave;
617
618 new_protos = malloc((protos_count + 1) * sizeof(Atom));
619 if (!new_protos)
620 goto leave;
621
622 for (i = 0; i < protos_count; i++)
623 new_protos[i] = protos[i];
624 new_protos[protos_count] = proto;
625 XSetWMProtocols(_ecore_x_disp, win, new_protos, protos_count + 1);
626 free(new_protos);
627 }
628 else
629 {
630 if (!already_set)
631 goto leave;
632
633 for (i = 0; i < protos_count; i++)
634 {
635 if (protos[i] == proto)
636 {
637 int j;
638
639 for (j = i + 1; j < protos_count; j++)
640 protos[j - 1] = protos[j];
641 if (protos_count > 1)
642 XSetWMProtocols(_ecore_x_disp, win, protos,
643 protos_count - 1);
644 else
645 XDeleteProperty(_ecore_x_disp, win,
646 ECORE_X_ATOM_WM_PROTOCOLS);
647
648 goto leave;
649 }
650 }
651 }
652
653leave:
654 if (protos)
655 XFree(protos);
656}
657
658/**
659 * Determines whether a protocol is set for a window.
660 * @param win The Window
661 * @param protocol The protocol to query
662 * @return 1 if the protocol is set, else 0.
663 */
664EAPI Eina_Bool
665ecore_x_icccm_protocol_isset(Ecore_X_Window win,
666 Ecore_X_WM_Protocol protocol)
667{
668 Atom proto, *protos = NULL;
669 int i, protos_count = 0;
670 Eina_Bool ret = EINA_FALSE;
671
672 /* check for invalid values */
673 if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
674 return EINA_FALSE;
675
676 LOGFN(__FILE__, __LINE__, __FUNCTION__);
677 proto = _ecore_x_atoms_wm_protocols[protocol];
678
679 if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
680 return EINA_FALSE;
681
682 for (i = 0; i < protos_count; i++)
683 if (protos[i] == proto)
684 {
685 ret = EINA_TRUE;
686 break;
687 }
688
689 if (protos)
690 XFree(protos);
691
692 return ret;
693}
694
695/**
696 * Set a window name & class.
697 * @param win The window
698 * @param n The name string
699 * @param c The class string
700 *
701 * Set a window name * class
702 */
703EAPI void
704ecore_x_icccm_name_class_set(Ecore_X_Window win,
705 const char *n,
706 const char *c)
707{
708 XClassHint *xch;
709
710 xch = XAllocClassHint();
711 if (!xch)
712 return;
713
714 LOGFN(__FILE__, __LINE__, __FUNCTION__);
715 xch->res_name = (char *)n;
716 xch->res_class = (char *)c;
717 XSetClassHint(_ecore_x_disp, win, xch);
718 XFree(xch);
719}
720
721/**
722 * Get a window name & class.
723 * @param win The window
724 * @param n The name string
725 * @param c The class string
726 *
727 * Get a window name * class
728 */
729EAPI void
730ecore_x_icccm_name_class_get(Ecore_X_Window win,
731 char **n,
732 char **c)
733{
734 XClassHint xch;
735
736 LOGFN(__FILE__, __LINE__, __FUNCTION__);
737 if (n)
738 *n = NULL;
739
740 if (c)
741 *c = NULL;
742
743 xch.res_name = NULL;
744 xch.res_class = NULL;
745 if (XGetClassHint(_ecore_x_disp, win, &xch))
746 {
747 if (n)
748 if (xch.res_name)
749 *n = strdup(xch.res_name);
750
751 if (c)
752 if (xch.res_class)
753 *c = strdup(xch.res_class);
754
755 XFree(xch.res_name);
756 XFree(xch.res_class);
757 }
758}
759
760/**
761 * Get a window client machine string.
762 * @param win The window
763 * @return The windows client machine string
764 *
765 * Return the client machine of a window. String must be free'd when done with.
766 */
767EAPI char *
768ecore_x_icccm_client_machine_get(Ecore_X_Window win)
769{
770 char *name;
771
772 LOGFN(__FILE__, __LINE__, __FUNCTION__);
773 name = ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_CLIENT_MACHINE);
774 return name;
775}
776
777/**
778 * Sets the WM_COMMAND property for @a win.
779 *
780 * @param win The window.
781 * @param argc Number of arguments.
782 * @param argv Arguments.
783 */
784EAPI void
785ecore_x_icccm_command_set(Ecore_X_Window win,
786 int argc,
787 char **argv)
788{
789 LOGFN(__FILE__, __LINE__, __FUNCTION__);
790 XSetCommand(_ecore_x_disp, win, argv, argc);
791}
792
793/**
794 * Get the WM_COMMAND property for @a win.
795 *
796 * Return the command of a window. String must be free'd when done with.
797 *
798 * @param win The window.
799 * @param argc Number of arguments.
800 * @param argv Arguments.
801 */
802EAPI void
803ecore_x_icccm_command_get(Ecore_X_Window win,
804 int *argc,
805 char ***argv)
806{
807 int i, c;
808 char **v;
809
810 if (argc)
811 *argc = 0;
812
813 if (argv)
814 *argv = NULL;
815
816 LOGFN(__FILE__, __LINE__, __FUNCTION__);
817 if (!XGetCommand(_ecore_x_disp, win, &v, &c))
818 return;
819
820 if (c < 1)
821 {
822 if (v)
823 XFreeStringList(v);
824
825 return;
826 }
827
828 if (argc)
829 *argc = c;
830
831 if (argv)
832 {
833 (*argv) = malloc(c * sizeof(char *));
834 if (!*argv)
835 {
836 XFreeStringList(v);
837 if (argc)
838 *argc = 0;
839
840 return;
841 }
842
843 for (i = 0; i < c; i++)
844 {
845 if (v[i])
846 (*argv)[i] = strdup(v[i]);
847 else
848 (*argv)[i] = strdup("");
849 }
850 }
851
852 XFreeStringList(v);
853}
854
855/**
856 * Set a window icon name.
857 * @param win The window
858 * @param t The icon name string
859 *
860 * Set a window icon name
861 */
862EAPI void
863ecore_x_icccm_icon_name_set(Ecore_X_Window win,
864 const char *t)
865{
866 char *list[1];
867 XTextProperty xprop;
868 int ret;
869
870 LOGFN(__FILE__, __LINE__, __FUNCTION__);
871 xprop.value = NULL;
872#ifdef X_HAVE_UTF8_STRING
873 list[0] = strdup(t);
874 ret = Xutf8TextListToTextProperty(_ecore_x_disp, list, 1,
875 XUTF8StringStyle, &xprop);
876#else /* ifdef X_HAVE_UTF8_STRING */
877 list[0] = strdup(t);
878 ret = XmbTextListToTextProperty(_ecore_x_disp, list, 1,
879 XStdICCTextStyle, &xprop);
880#endif /* ifdef X_HAVE_UTF8_STRING */
881 if (ret >= Success)
882 {
883 XSetWMIconName(_ecore_x_disp, win, &xprop);
884 if (xprop.value)
885 XFree(xprop.value);
886 }
887 else if (XStringListToTextProperty(list, 1, &xprop) >= Success)
888 {
889 XSetWMIconName(_ecore_x_disp, win, &xprop);
890 if (xprop.value)
891 XFree(xprop.value);
892 }
893
894 free(list[0]);
895}
896
897/**
898 * Get a window icon name.
899 * @param win The window
900 * @return The windows icon name string
901 *
902 * Return the icon name of a window. String must be free'd when done with.
903 */
904EAPI char *
905ecore_x_icccm_icon_name_get(Ecore_X_Window win)
906{
907 XTextProperty xprop;
908
909 LOGFN(__FILE__, __LINE__, __FUNCTION__);
910 xprop.value = NULL;
911 if (XGetWMIconName(_ecore_x_disp, win, &xprop) >= Success)
912 {
913 if (xprop.value)
914 {
915 char **list = NULL;
916 char *t = NULL;
917 int num = 0;
918 int ret;
919
920 if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING)
921 t = strdup((char *)xprop.value);
922 else
923 {
924 /* convert to utf8 */
925#ifdef X_HAVE_UTF8_STRING
926 ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop,
927 &list, &num);
928#else /* ifdef X_HAVE_UTF8_STRING */
929 ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop,
930 &list, &num);
931#endif /* ifdef X_HAVE_UTF8_STRING */
932
933 if ((ret == XLocaleNotSupported) ||
934 (ret == XNoMemory) || (ret == XConverterNotFound))
935 t = strdup((char *)xprop.value);
936 else if (ret >= Success)
937 {
938 if ((num >= 1) && (list))
939 t = strdup(list[0]);
940
941 if (list)
942 XFreeStringList(list);
943 }
944 }
945
946 if (xprop.value)
947 XFree(xprop.value);
948
949 return t;
950 }
951 }
952
953 return NULL;
954}
955
956/**
957 * Add a subwindow to the list of windows that need a different colormap installed.
958 * @param win The toplevel window
959 * @param subwin The subwindow to be added to the colormap windows list
960 */
961EAPI void
962ecore_x_icccm_colormap_window_set(Ecore_X_Window win,
963 Ecore_X_Window subwin)
964{
965 int num = 0, i;
966 unsigned char *old_data = NULL;
967 unsigned char *data = NULL;
968 Window *oldset = NULL;
969 Window *newset = NULL;
970
971 LOGFN(__FILE__, __LINE__, __FUNCTION__);
972 if (!ecore_x_window_prop_property_get(win,
973 ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
974 XA_WINDOW, 32, &old_data, &num))
975 {
976 newset = calloc(1, sizeof(Window));
977 if (!newset)
978 return;
979
980 newset[0] = subwin;
981 num = 1;
982 data = (unsigned char *)newset;
983 }
984 else
985 {
986 newset = calloc(num + 1, sizeof(Window));
987 oldset = (Window *)old_data;
988 if (!newset)
989 return;
990
991 for (i = 0; i < num; ++i)
992 {
993 if (oldset[i] == subwin)
994 {
995 if (old_data)
996 XFree(old_data);
997
998 old_data = NULL;
999 free(newset);
1000 return;
1001 }
1002
1003 newset[i] = oldset[i];
1004 }
1005
1006 newset[num++] = subwin;
1007 if (old_data)
1008 XFree(old_data);
1009
1010 data = (unsigned char *)newset;
1011 }
1012
1013 ecore_x_window_prop_property_set(win,
1014 ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1015 XA_WINDOW, 32, data, num);
1016 free(newset);
1017}
1018
1019/**
1020 * Remove a window from the list of colormap windows.
1021 * @param win The toplevel window
1022 * @param subwin The window to be removed from the colormap window list.
1023 */
1024EAPI void
1025ecore_x_icccm_colormap_window_unset(Ecore_X_Window win,
1026 Ecore_X_Window subwin)
1027{
1028 int num = 0, i, j, k = 0;
1029 unsigned char *old_data = NULL;
1030 unsigned char *data = NULL;
1031 Window *oldset = NULL;
1032 Window *newset = NULL;
1033
1034 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1035 if (!ecore_x_window_prop_property_get(win,
1036 ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1037 XA_WINDOW, 32, &old_data, &num))
1038 return;
1039
1040 oldset = (Window *)old_data;
1041 for (i = 0; i < num; i++)
1042 {
1043 if (oldset[i] == subwin)
1044 {
1045 if (num == 1)
1046 {
1047 XDeleteProperty(_ecore_x_disp,
1048 win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
1049 if (old_data)
1050 XFree(old_data);
1051
1052 old_data = NULL;
1053 return;
1054 }
1055 else
1056 {
1057 newset = calloc(num - 1, sizeof(Window));
1058 data = (unsigned char *)newset;
1059 for (j = 0; j < num; ++j)
1060 if (oldset[j] != subwin)
1061 newset[k++] = oldset[j];
1062
1063 ecore_x_window_prop_property_set(
1064 win,
1065 ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1066 XA_WINDOW,
1067 32,
1068 data,
1069 k);
1070 if (old_data)
1071 XFree(old_data);
1072
1073 old_data = NULL;
1074 free(newset);
1075 return;
1076 }
1077 }
1078 }
1079
1080 if (old_data)
1081 XFree(old_data);
1082}
1083
1084/**
1085 * Specify that a window is transient for another top-level window and should be handled accordingly.
1086 * @param win the transient window
1087 * @param forwin the toplevel window
1088 */
1089EAPI void
1090ecore_x_icccm_transient_for_set(Ecore_X_Window win,
1091 Ecore_X_Window forwin)
1092{
1093 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1094 XSetTransientForHint(_ecore_x_disp, win, forwin);
1095}
1096
1097/**
1098 * Remove the transient_for setting from a window.
1099 * @param win The window
1100 */
1101EAPI void
1102ecore_x_icccm_transient_for_unset(Ecore_X_Window win)
1103{
1104 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1105 XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_TRANSIENT_FOR);
1106}
1107
1108/**
1109 * Get the window this window is transient for, if any.
1110 * @param win The window to check
1111 * @return The window ID of the top-level window, or 0 if the property does not exist.
1112 */
1113EAPI Ecore_X_Window
1114ecore_x_icccm_transient_for_get(Ecore_X_Window win)
1115{
1116 Window forwin;
1117
1118 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1119 if (XGetTransientForHint(_ecore_x_disp, win, &forwin))
1120 return (Ecore_X_Window)forwin;
1121 else
1122 return 0;
1123}
1124
1125/**
1126 * Set the window role hint.
1127 * @param win The window
1128 * @param role The role string
1129 */
1130EAPI void
1131ecore_x_icccm_window_role_set(Ecore_X_Window win,
1132 const char *role)
1133{
1134 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1135 ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE,
1136 (char *)role);
1137}
1138
1139/**
1140 * Get the window role.
1141 * @param win The window
1142 * @return The window's role string.
1143 */
1144EAPI char *
1145ecore_x_icccm_window_role_get(Ecore_X_Window win)
1146{
1147 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1148 return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE);
1149}
1150
1151/**
1152 * Set the window's client leader.
1153 * @param win The window
1154 * @param l The client leader window
1155 *
1156 * All non-transient top-level windows created by an app other than
1157 * the main window must have this property set to the app's main window.
1158 */
1159EAPI void
1160ecore_x_icccm_client_leader_set(Ecore_X_Window win,
1161 Ecore_X_Window l)
1162{
1163 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1164 ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
1165 &l, 1);
1166}
1167
1168/**
1169 * Get the window's client leader.
1170 * @param win The window
1171 * @return The window's client leader window, or 0 if unset */
1172EAPI Ecore_X_Window
1173ecore_x_icccm_client_leader_get(Ecore_X_Window win)
1174{
1175 Ecore_X_Window l;
1176
1177 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1178 if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
1179 &l, 1) > 0)
1180 return l;
1181
1182 return 0;
1183}
1184
1185EAPI void
1186ecore_x_icccm_iconic_request_send(Ecore_X_Window win,
1187 Ecore_X_Window root)
1188{
1189 XEvent xev;
1190
1191 if (!win)
1192 return;
1193
1194 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1195 if (!root)
1196 root = DefaultRootWindow(_ecore_x_disp);
1197
1198 xev.xclient.type = ClientMessage;
1199 xev.xclient.serial = 0;
1200 xev.xclient.send_event = True;
1201 xev.xclient.display = _ecore_x_disp;
1202 xev.xclient.window = win;
1203 xev.xclient.format = 32;
1204 xev.xclient.message_type = ECORE_X_ATOM_WM_CHANGE_STATE;
1205 xev.xclient.data.l[0] = IconicState;
1206
1207 XSendEvent(_ecore_x_disp, root, False,
1208 SubstructureNotifyMask | SubstructureRedirectMask, &xev);
1209}
1210
1211/* FIXME: there are older E hints, gnome hints and mwm hints and new netwm */
1212/* hints. each should go in their own file/section so we know which */
1213/* is which. also older kde hints too. we should try support as much */
1214/* as makese sense to support */