[ecore] merged svn latest code (svn54830)
[profile/ivi/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_icccm.c
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 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 #include <xcb/xcb_icccm.h>
13
14 #include "ecore_xcb_private.h"
15 #include "Ecore_X_Atoms.h"
16
17 /**
18  * @defgroup Ecore_X_ICCCM_Group ICCCM related functions.
19  *
20  * Functions related to ICCCM.
21  */
22
23 static int _ecore_x_icccm_size_hints_get (const void       *reply,
24                                           Ecore_X_Atom      property,
25                                           xcb_size_hints_t *hints)
26 {
27    uint32_t s;
28
29    if (!hints)
30       return 0;
31
32    if (!reply)
33       return 0;
34
35    if ((((xcb_get_property_reply_t *)reply)->type != ECORE_X_ATOM_WM_SIZE_HINTS) &&
36        ((((xcb_get_property_reply_t *)reply)->format != 8) ||
37         (((xcb_get_property_reply_t *)reply)->format != 16) ||
38         (((xcb_get_property_reply_t *)reply)->format != 32)) &&
39        (((xcb_get_property_reply_t *)reply)->value_len < 15)) /* OldNumPropSizeElements = 15 (pre-ICCCM) */
40       return 0;
41
42    memcpy(hints,
43           xcb_get_property_value((xcb_get_property_reply_t *)reply),
44           ((xcb_get_property_reply_t *)reply)->value_len);
45
46    s = (XCB_SIZE_HINT_US_POSITION | XCB_SIZE_HINT_US_SIZE |
47         XCB_SIZE_HINT_P_POSITION | XCB_SIZE_HINT_P_SIZE |
48         XCB_SIZE_HINT_P_MIN_SIZE | XCB_SIZE_HINT_P_MAX_SIZE |
49         XCB_SIZE_HINT_P_RESIZE_INC | XCB_SIZE_HINT_P_ASPECT);
50
51    if (((xcb_get_property_reply_t *)reply)->value_len >= 18) /* NumPropSizeElements = 18 (ICCCM version 1) */
52       s |= (XCB_SIZE_HINT_BASE_SIZE | XCB_SIZE_HINT_P_WIN_GRAVITY);
53    else
54      {
55         xcb_size_hints_set_base_size(hints, 0, 0);
56         xcb_size_hints_set_win_gravity(hints, 0);
57      }
58
59    /* FIXME: is it necessary ? */
60    /* hints->flags &= s; */         /* get rid of unwanted bits */
61
62    return 1;
63 } /* _ecore_x_icccm_size_hints_get */
64
65 /**
66  * Sets the state of a window.
67  * @param window The window.
68  * @param state  The state.
69  * @ingroup Ecore_X_ICCCM_Group
70  */
71 EAPI void
72 ecore_x_icccm_state_set(Ecore_X_Window            window,
73                         Ecore_X_Window_State_Hint state)
74 {
75    uint32_t c[2];
76
77    if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
78       c[0] = XCB_WM_STATE_WITHDRAWN;
79    else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
80       c[0] = XCB_WM_STATE_NORMAL;
81    else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
82       c[0] = XCB_WM_STATE_ICONIC;
83
84    c[1] = 0;
85    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
86                        ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE, 32,
87                        2, c);
88 } /* ecore_x_icccm_state_set */
89
90 /*
91  * Sends the GetProperty request.
92  * @ingroup Ecore_X_ICCCM_Group
93  */
94 EAPI void
95 ecore_x_icccm_state_get_prefetch(Ecore_X_Window window)
96 {
97    xcb_get_property_cookie_t cookie;
98
99    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
100                                        ECORE_X_ATOM_WM_STATE,
101                                        ECORE_X_ATOM_WM_STATE,
102                                        0L, 0x7fffffff);
103    _ecore_xcb_cookie_cache(cookie.sequence);
104 } /* ecore_x_icccm_state_get_prefetch */
105
106 /*
107  * Gets the reply of the GetProperty request sent by ecore_x_icccm_state_get_prefetch().
108  * @ingroup Ecore_X_ICCCM_Group
109  */
110 EAPI void
111 ecore_x_icccm_state_get_fetch(void)
112 {
113    xcb_get_property_cookie_t cookie;
114    xcb_get_property_reply_t *reply;
115
116    cookie.sequence = _ecore_xcb_cookie_get();
117    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
118    _ecore_xcb_reply_cache(reply);
119 } /* ecore_x_icccm_state_get_fetch */
120
121 /**
122  * Gets the state of a window.
123  * @param window The window.
124  * @return       The state of the window
125  *
126  * To use this function, you must call before, and in order,
127  * ecore_x_icccm_state_get_prefetch(), which sends the GetProperty request,
128  * then ecore_x_icccm_state_get_fetch(), which gets the reply.
129  * @ingroup Ecore_X_ICCCM_Group
130  */
131 EAPI Ecore_X_Window_State_Hint
132 ecore_x_icccm_state_get(Ecore_X_Window window __UNUSED__)
133 {
134    xcb_get_property_reply_t *reply;
135    uint8_t *prop;
136    Ecore_X_Window_State_Hint hint = ECORE_X_WINDOW_STATE_HINT_NONE;
137
138    reply = _ecore_xcb_reply_get();
139    if (!reply)
140       return hint;
141
142    if ((reply->type == 0) ||
143        (reply->format != 8) ||
144        (reply->value_len != 2))
145       return hint;
146
147    prop = (uint8_t *)xcb_get_property_value(reply);
148    switch (prop[0]) {
149       case XCB_WM_STATE_WITHDRAWN:
150          hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
151          break;
152
153       case XCB_WM_STATE_NORMAL:
154          hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
155          break;
156
157       case XCB_WM_STATE_ICONIC:
158          hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
159          break;
160
161       default:
162          hint = ECORE_X_WINDOW_STATE_HINT_NONE;
163          break;
164      } /* switch */
165
166    return hint;
167 } /* ecore_x_icccm_state_get */
168
169 /**
170  * Sends the ClientMessage event with the DeleteWindow property.
171  * @param window The window.
172  * @param time   The time.
173  * @ingroup Ecore_X_ICCCM_Group
174  */
175 EAPI void
176 ecore_x_icccm_delete_window_send(Ecore_X_Window window,
177                                  Ecore_X_Time   time)
178 {
179    ecore_x_client_message32_send(window, ECORE_X_ATOM_WM_PROTOCOLS,
180                                  ECORE_X_EVENT_MASK_NONE,
181                                  ECORE_X_ATOM_WM_DELETE_WINDOW,
182                                  time, 0, 0, 0);
183 } /* ecore_x_icccm_delete_window_send */
184
185 /**
186  * Sends the ClientMessage event with the TakeFocus property.
187  * @param window The window.
188  * @param time   The time.
189  * @ingroup Ecore_X_ICCCM_Group
190  */
191 EAPI void
192 ecore_x_icccm_take_focus_send(Ecore_X_Window window,
193                               Ecore_X_Time   time)
194 {
195    ecore_x_client_message32_send(window, ECORE_X_ATOM_WM_PROTOCOLS,
196                                  ECORE_X_EVENT_MASK_NONE,
197                                  ECORE_X_ATOM_WM_TAKE_FOCUS,
198                                  time, 0, 0, 0);
199 } /* ecore_x_icccm_take_focus_send */
200
201 /**
202  * Sends the ClientMessage event with the SaveYourself property.
203  * @param window The window.
204  * @param time   The time.
205  * @ingroup Ecore_X_ICCCM_Group
206  */
207 EAPI void
208 ecore_x_icccm_save_yourself_send(Ecore_X_Window window,
209                                  Ecore_X_Time   time)
210 {
211    ecore_x_client_message32_send(window, ECORE_X_ATOM_WM_PROTOCOLS,
212                                  ECORE_X_EVENT_MASK_NONE,
213                                  ECORE_X_ATOM_WM_SAVE_YOURSELF,
214                                  time, 0, 0, 0);
215 } /* ecore_x_icccm_save_yourself_send */
216
217 /**
218  * Sends the ConfigureNotify event with the StructureNotify property.
219  * @param window The window.
220  * @param x      The X coordinate.
221  * @param y      The Y coordinate.
222  * @param width  The width.
223  * @param height The height.
224  * @ingroup Ecore_X_ICCCM_Group
225  */
226 EAPI void
227 ecore_x_icccm_move_resize_send(Ecore_X_Window window,
228                                int            x,
229                                int            y,
230                                int            width,
231                                int            height)
232 {
233    xcb_configure_notify_event_t ev;
234
235    ev.response_type = XCB_CONFIGURE_NOTIFY | 0x80;
236    ev.pad0 = 0;
237    ev.sequence = 0;
238    ev.event = window;
239    ev.window = window;
240    ev.above_sibling = 0;
241    ev.x = x;
242    ev.y = y;
243    ev.width = width;
244    ev.height = height;
245    ev.border_width = 0;
246    ev.override_redirect = 0;
247    xcb_send_event(_ecore_xcb_conn, 0, window,
248                   XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev);
249 } /* ecore_x_icccm_move_resize_send */
250
251 /**
252  * Sets the hints of a window.
253  * @param window        The window.
254  * @param accepts_focus AcceptFocus hint
255  * @param initial_state Initial state flags.
256  * @param icon_pixmap   Icon pixmap.
257  * @param icon_mask     Icon mask.
258  * @param icon_window   Icon window.
259  * @param window_group  Group window.
260  * @param is_urgent     IsUrgent flag.
261  * @ingroup Ecore_X_ICCCM_Group
262  */
263 EAPI void
264 ecore_x_icccm_hints_set(Ecore_X_Window            window,
265                         Eina_Bool                 accepts_focus,
266                         Ecore_X_Window_State_Hint initial_state,
267                         Ecore_X_Pixmap            icon_pixmap,
268                         Ecore_X_Pixmap            icon_mask,
269                         Ecore_X_Window            icon_window,
270                         Ecore_X_Window            window_group,
271                         Eina_Bool                 is_urgent)
272 {
273    xcb_wm_hints_t hints;
274
275    memset(&hints, 0, sizeof(hints));
276    xcb_wm_hints_set_input(&hints, accepts_focus);
277    if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
278       xcb_wm_hints_set_withdrawn(&hints);
279    else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
280       xcb_wm_hints_set_normal(&hints);
281    else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
282       xcb_wm_hints_set_iconic(&hints);
283
284    if (icon_pixmap != 0)
285       xcb_wm_hints_set_icon_pixmap(&hints, icon_pixmap);
286
287    if (icon_mask != 0)
288       xcb_wm_hints_set_icon_mask(&hints, icon_mask);
289
290    if (icon_window != 0)
291       xcb_wm_hints_set_icon_window(&hints, icon_window);
292
293    if (window_group != 0)
294       xcb_wm_hints_set_window_group(&hints, window_group);
295
296    if (is_urgent)
297       xcb_wm_hints_set_urgency(&hints);
298
299    xcb_set_wm_hints(_ecore_xcb_conn, window, &hints);
300 } /* ecore_x_icccm_hints_set */
301
302 /*
303  * Sends the GetProperty request.
304  * @ingroup Ecore_X_ICCCM_Group
305  */
306 EAPI void
307 ecore_x_icccm_hints_get_prefetch(Ecore_X_Window window)
308 {
309    xcb_get_property_cookie_t cookie;
310
311    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
312                                        ECORE_X_ATOM_WM_HINTS,
313                                        ECORE_X_ATOM_WM_HINTS,
314                                        0L, XCB_NUM_WM_HINTS_ELEMENTS);
315    _ecore_xcb_cookie_cache(cookie.sequence);
316 } /* ecore_x_icccm_hints_get_prefetch */
317
318 /*
319  * Gets the reply of the GetProperty request sent by ecore_x_icccm_hints_get_prefetch().
320  * @ingroup Ecore_X_ICCCM_Group
321  */
322 EAPI void
323 ecore_x_icccm_hints_get_fetch(void)
324 {
325    xcb_get_property_cookie_t cookie;
326    xcb_get_property_reply_t *reply;
327
328    cookie.sequence = _ecore_xcb_cookie_get();
329    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
330    _ecore_xcb_reply_cache(reply);
331 } /* ecore_x_icccm_hints_get_fetch */
332
333 /**
334  * Gets the hints of a window.
335  * @param window        The window.
336  * @param accepts_focus AcceptFocus hint
337  * @param initial_state Initial state flags.
338  * @param icon_pixmap   Icon pixmap.
339  * @param icon_mask     Icon mask.
340  * @param icon_window   Icon window.
341  * @param window_group  Group window.
342  * @param is_urgent     IsUrgent flag.
343  * @return              1 on success, 0 otherwise.
344  *
345  * To use this function, you must call before, and in order,
346  * ecore_x_icccm_hints_get_prefetch(), which sends the GetProperty request,
347  * then ecore_x_icccm_hints_get_fetch(), which gets the reply.
348  * @ingroup Ecore_X_ICCCM_Group
349  */
350 EAPI Eina_Bool
351 ecore_x_icccm_hints_get(Ecore_X_Window window      __UNUSED__,
352                         Eina_Bool                 *accepts_focus,
353                         Ecore_X_Window_State_Hint *initial_state,
354                         Ecore_X_Pixmap            *icon_pixmap,
355                         Ecore_X_Pixmap            *icon_mask,
356                         Ecore_X_Window            *icon_window,
357                         Ecore_X_Window            *window_group,
358                         Eina_Bool                 *is_urgent)
359 {
360    xcb_wm_hints_t hints;
361    xcb_get_property_reply_t *reply;
362    int32_t hints_flags;
363    uint32_t hints_input;
364    int32_t hints_initial_state;
365    xcb_pixmap_t hints_icon_pixmap;
366    xcb_pixmap_t hints_icon_mask;
367    xcb_window_t hints_icon_window;
368    xcb_window_t hints_window_group;
369
370    if (accepts_focus)
371       *accepts_focus = 1;
372
373    if (initial_state)
374       *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
375
376    if (icon_pixmap)
377       *icon_pixmap = 0;
378
379    if (icon_mask)
380       *icon_mask = 0;
381
382    if (icon_window)
383       *icon_window = 0;
384
385    if (window_group)
386       *window_group = 0;
387
388    if (is_urgent)
389       *is_urgent = 0;
390
391    reply = _ecore_xcb_reply_get();
392    if (!reply)
393       return 0;
394
395    if ((reply->type != ECORE_X_ATOM_WM_HINTS) ||
396        (reply->value_len < (XCB_NUM_WM_HINTS_ELEMENTS - 1)) ||
397        (reply->format != 32))
398       return 0;
399
400    memcpy(&hints, xcb_get_property_value(reply), reply->value_len);
401    hints_flags = hints.flags;
402    hints_input = hints.input;
403    hints_initial_state = hints.initial_state;
404    hints_icon_pixmap = hints.icon_pixmap;
405    hints_icon_mask = hints.icon_mask;
406    hints_icon_window = hints.icon_window;
407    hints_window_group = hints.window_group;
408
409    if ((hints_flags & XCB_WM_HINT_INPUT) && (accepts_focus))
410      {
411         if(hints_input)
412            *accepts_focus = 1;
413         else
414            *accepts_focus = 0;
415      }
416
417    if ((hints_flags & XCB_WM_HINT_STATE) && (initial_state))
418      {
419         if (hints_initial_state == XCB_WM_STATE_WITHDRAWN)
420            *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
421         else if (hints_initial_state == XCB_WM_STATE_NORMAL)
422            *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
423         else if (hints_initial_state == XCB_WM_STATE_ICONIC)
424            *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
425      }
426
427    if ((hints_flags & XCB_WM_HINT_ICON_PIXMAP) && (icon_pixmap))
428      {
429         *icon_pixmap = hints_icon_pixmap;
430      }
431
432    if ((hints_flags & XCB_WM_HINT_ICON_MASK) && (icon_mask))
433      {
434         *icon_mask = hints_icon_mask;
435      }
436
437    if ((hints_flags & XCB_WM_HINT_ICON_WINDOW) && (icon_window))
438      {
439         *icon_window = hints_icon_window;
440      }
441
442    if ((hints_flags & XCB_WM_HINT_WINDOW_GROUP) && (window_group))
443      {
444         if (reply->value_len < XCB_NUM_WM_HINTS_ELEMENTS)
445            *window_group = 0;
446         else
447            *window_group = hints_window_group;
448      }
449
450    if ((hints_flags & XCB_WM_HINT_X_URGENCY) && (is_urgent))
451      {
452         *is_urgent = 1;
453      }
454
455    return 1;
456 } /* ecore_x_icccm_hints_get */
457
458 /*
459  * Sends the GetProperty request.
460  * @ingroup Ecore_X_ICCCM_Group
461  */
462 EAPI void
463 ecore_x_icccm_size_pos_hints_get_prefetch(Ecore_X_Window window)
464 {
465    xcb_get_property_cookie_t cookie;
466
467    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
468                                        ECORE_X_ATOM_WM_NORMAL_HINTS,
469                                        ECORE_X_ATOM_WM_SIZE_HINTS,
470                                        0L, 18);
471    _ecore_xcb_cookie_cache(cookie.sequence);
472 } /* ecore_x_icccm_size_pos_hints_get_prefetch */
473
474 /*
475  * Gets the reply of the GetProperty request sent by ecore_x_icccm_size_pos_hints_get_prefetch().
476  * @ingroup Ecore_X_ICCCM_Group
477  */
478 EAPI void
479 ecore_x_icccm_size_pos_hints_get_fetch(void)
480 {
481    xcb_get_property_cookie_t cookie;
482    xcb_get_property_reply_t *reply;
483
484    cookie.sequence = _ecore_xcb_cookie_get();
485    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
486    _ecore_xcb_reply_cache(reply);
487 } /* ecore_x_icccm_size_pos_hints_get_fetch */
488
489 /**
490  * Sets the hints of a window.
491  * @param window      The window.
492  * @param request_pos Request position flag.
493  * @param gravity     Gravity.
494  * @param min_w       Minimum width.
495  * @param min_h       Minimum height.
496  * @param max_w       Maximum width.
497  * @param max_h       Maximum height.
498  * @param base_w      Base width
499  * @param base_h      Base height
500  * @param step_x      X step coordinate.
501  * @param step_y      Y step coordinate.
502  * @param min_aspect  Minimum aspect ratio.
503  * @param max_aspect  Maximum aspect ratio.
504  *
505  * To use this function, you must call before, and in order,
506  * ecore_x_icccm_size_pos_hints_get_prefetch(), which sends the GetProperty request,
507  * then ecore_x_icccm_size_pos_hints_get_fetch(), which gets the reply.
508  * @ingroup Ecore_X_ICCCM_Group
509  */
510 EAPI void
511 ecore_x_icccm_size_pos_hints_set(Ecore_X_Window  window,
512                                  Eina_Bool       request_pos,
513                                  Ecore_X_Gravity gravity,
514                                  int             min_w,
515                                  int             min_h,
516                                  int             max_w,
517                                  int             max_h,
518                                  int             base_w,
519                                  int             base_h,
520                                  int             step_x,
521                                  int             step_y,
522                                  double          min_aspect,
523                                  double          max_aspect)
524 {
525    xcb_size_hints_t hint;
526    xcb_get_property_reply_t *reply;
527
528    reply = _ecore_xcb_reply_get();
529    if (!reply ||
530        (reply->type != ECORE_X_ATOM_WM_SIZE_HINTS) ||
531        ((reply->format != 8) &&
532         (reply->format != 16) &&
533         (reply->format != 32)) ||
534        (reply->value_len < 15))
535       return;
536
537    hint.flags = 0;
538    if (request_pos)
539      {
540         hint.flags = XCB_SIZE_HINT_US_POSITION;
541      }
542
543    if (gravity != ECORE_X_GRAVITY_NW)
544      {
545         hint.win_gravity = (uint8_t)gravity;
546      }
547
548    if ((min_w > 0) || (min_h > 0))
549      {
550         hint.min_width = min_w;
551         hint.min_height = min_h;
552      }
553
554    if ((max_w > 0) || (max_h > 0))
555      {
556         hint.max_width = max_w;
557         hint.max_height = max_h;
558      }
559
560    if ((base_w > 0) || (base_h > 0))
561      {
562         hint.base_width = base_w;
563         hint.base_height = base_h;
564      }
565
566    if ((step_x > 1) || (step_y > 1))
567      {
568         hint.width_inc = step_x;
569         hint.height_inc = step_y;
570      }
571
572    if ((min_aspect > 0.0) || (max_aspect > 0.0))
573      {
574         xcb_size_hints_set_aspect(&hint,
575                                   (int32_t)(min_aspect * 10000),
576                                   10000,
577                                   (int32_t)(max_aspect * 10000),
578                                   10000);
579      }
580
581    xcb_set_wm_normal_hints(_ecore_xcb_conn, window, &hint);
582 } /* ecore_x_icccm_size_pos_hints_set */
583
584 /**
585  * Gets the hints of a window.
586  * @param window      The window.
587  * @param request_pos Request position flag.
588  * @param gravity     Gravity.
589  * @param min_w       Minimum width.
590  * @param min_h       Minimum height.
591  * @param max_w       Maximum width.
592  * @param max_h       Maximum height.
593  * @param base_w      Base width
594  * @param base_h      Base height
595  * @param step_x      X step coordinate.
596  * @param step_y      Y step coordinate.
597  * @param min_aspect  Minimum aspect ratio.
598  * @param max_aspect  M
599  * @return            1 on success, 0 otherwise.
600  *
601  * To use this function, you must call before, and in order,
602  * ecore_x_icccm_size_pos_hints_get_prefetch(), which sends the GetProperty request,
603  * then ecore_x_icccm_size_pos_hints_get_fetch(), which gets the reply.
604  * @ingroup Ecore_X_ICCCM_Group
605  */
606 EAPI Eina_Bool
607 ecore_x_icccm_size_pos_hints_get(Ecore_X_Window window __UNUSED__,
608                                  Eina_Bool            *request_pos,
609                                  Ecore_X_Gravity      *gravity,
610                                  int                  *min_w,
611                                  int                  *min_h,
612                                  int                  *max_w,
613                                  int                  *max_h,
614                                  int                  *base_w,
615                                  int                  *base_h,
616                                  int                  *step_x,
617                                  int                  *step_y,
618                                  double               *min_aspect,
619                                  double               *max_aspect)
620 {
621    xcb_size_hints_t hint;
622    xcb_get_property_reply_t *reply;
623    uint32_t flags;
624    int32_t minw = 0;
625    int32_t minh = 0;
626    int32_t maxw = 32767;
627    int32_t maxh = 32767;
628    int32_t basew = -1;
629    int32_t baseh = -1;
630    int32_t stepx = -1;
631    int32_t stepy = -1;
632    double mina = 0.0;
633    double maxa = 0.0;
634
635    if (request_pos)
636       *request_pos = 0;
637
638    if (gravity)
639       *gravity = ECORE_X_GRAVITY_NW;
640
641    if (min_w)
642       *min_w = minw;
643
644    if (min_h)
645       *min_h = minh;
646
647    if (max_w)
648       *max_w = maxw;
649
650    if (max_h)
651       *max_h = maxh;
652
653    if (base_w)
654       *base_w = basew;
655
656    if (base_h)
657       *base_h = baseh;
658
659    if (step_x)
660       *step_x = stepx;
661
662    if (step_y)
663       *step_y = stepy;
664
665    if (min_aspect)
666       *min_aspect = mina;
667
668    if (max_aspect)
669       *max_aspect = maxa;
670
671    reply = _ecore_xcb_reply_get();
672    if (!reply)
673       return 0;
674
675    if (!_ecore_x_icccm_size_hints_get(reply, ECORE_X_ATOM_WM_NORMAL_HINTS, &hint))
676       return 0;
677
678    flags = hint.flags;
679    if ((flags & XCB_SIZE_HINT_US_POSITION) || (flags & XCB_SIZE_HINT_P_POSITION))
680      {
681         if (request_pos)
682            *request_pos = 1;
683      }
684
685    if (flags & XCB_SIZE_HINT_P_WIN_GRAVITY)
686      {
687         if (gravity)
688            *gravity = hint.win_gravity;
689      }
690
691    if (flags & XCB_SIZE_HINT_P_MIN_SIZE)
692      {
693         minw = hint.min_width;
694         minh = hint.min_height;
695      }
696
697    if (flags & XCB_SIZE_HINT_P_MAX_SIZE)
698      {
699         maxw = hint.max_width;
700         maxh = hint.max_height;
701         if (maxw < minw)
702            maxw = minw;
703
704         if (maxh < minh)
705            maxh = minh;
706      }
707
708    if (flags & XCB_SIZE_HINT_BASE_SIZE)
709      {
710         basew = hint.base_width;
711         baseh = hint.base_height;
712         if (basew > minw)
713            minw = basew;
714
715         if (baseh > minh)
716            minh = baseh;
717      }
718
719    if (flags & XCB_SIZE_HINT_P_RESIZE_INC)
720      {
721         stepx = hint.width_inc;
722         stepy = hint.height_inc;
723         if (stepx < 1)
724            stepx = 1;
725
726         if (stepy < 1)
727            stepy = 1;
728      }
729
730    if (flags & XCB_SIZE_HINT_P_ASPECT)
731      {
732         if (hint.min_aspect_den > 0)
733            mina = ((double)hint.min_aspect_num) / ((double)hint.min_aspect_den);
734
735         if (hint.max_aspect_den > 0)
736            maxa = ((double)hint.max_aspect_num) / ((double)hint.max_aspect_den);
737      }
738
739    if (min_w)
740       *min_w = minw;
741
742    if (min_h)
743       *min_h = minh;
744
745    if (max_w)
746       *max_w = maxw;
747
748    if (max_h)
749       *max_h = maxh;
750
751    if (base_w)
752       *base_w = basew;
753
754    if (base_h)
755       *base_h = baseh;
756
757    if (step_x)
758       *step_x = stepx;
759
760    if (step_y)
761       *step_y = stepy;
762
763    if (min_aspect)
764       *min_aspect = mina;
765
766    if (max_aspect)
767       *max_aspect = maxa;
768
769    return 1;
770 } /* ecore_x_icccm_size_pos_hints_get */
771
772 /**
773  * Set the title of a window
774  * @param window The window.
775  * @param title  The title.
776  * @ingroup Ecore_X_ICCCM_Group
777  */
778 EAPI void
779 ecore_x_icccm_title_set(Ecore_X_Window window,
780                         const char    *title)
781 {
782    if (!title)
783       return;
784
785    /* FIXME: to do:  utf8 */
786
787 /*    xprop.value = NULL; */
788 /* #ifdef X_HAVE_UTF8_STRING */
789 /*    list[0] = strdup(t); */
790 /*    ret = */
791 /*       Xutf8TextListToTextProperty(_ecore_xcb_conn, list, 1, XUTF8StringStyle, */
792 /*                                &xprop); */
793 /* #else */
794 /*    list[0] = strdup(t); */
795 /*    ret = */
796 /*       XmbTextListToTextProperty(_ecore_xcb_conn, list, 1, XStdICCTextStyle, */
797 /*                              &xprop); */
798 /* #endif */
799
800    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
801                        ECORE_X_ATOM_WM_NAME, ECORE_X_ATOM_STRING, 8,
802                        strlen(title), title);
803 } /* ecore_x_icccm_title_set */
804
805 /*
806  * Sends the GetProperty request.
807  * @ingroup Ecore_X_ICCCM_Group
808  */
809 EAPI void
810 ecore_x_icccm_title_get_prefetch(Ecore_X_Window window)
811 {
812    xcb_get_property_cookie_t cookie;
813
814    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
815                                        ECORE_X_ATOM_WM_NAME,
816                                        XCB_GET_PROPERTY_TYPE_ANY,
817                                        0L, 128);
818    _ecore_xcb_cookie_cache(cookie.sequence);
819 } /* ecore_x_icccm_title_get_prefetch */
820
821 /*
822  * Gets the reply of the GetProperty request sent by ecore_x_icccm_title_get_prefetch().
823  * @ingroup Ecore_X_ICCCM_Group
824  */
825 EAPI void
826 ecore_x_icccm_title_get_fetch(void)
827 {
828    xcb_get_property_cookie_t cookie;
829    xcb_get_property_reply_t *reply;
830
831    cookie.sequence = _ecore_xcb_cookie_get();
832    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
833    _ecore_xcb_reply_cache(reply);
834 } /* ecore_x_icccm_title_get_fetch */
835
836 /**
837  * Gets the title of a window.
838  * @param window The window (Unused).
839  * @return       The title of the window
840  *
841  * To use this function, you must call before, and in order,
842  * ecore_x_icccm_title_get_prefetch(), which sends the GetProperty request,
843  * then ecore_x_icccm_title_get_fetch(), which gets the reply.
844  * @ingroup Ecore_X_ICCCM_Group
845  */
846 EAPI char *
847 ecore_x_icccm_title_get(Ecore_X_Window window __UNUSED__)
848 {
849    char *title = NULL;
850    xcb_get_property_reply_t *reply;
851
852    reply = _ecore_xcb_reply_get();
853    if (!reply)
854       return NULL;
855
856    if (reply->type == ECORE_X_ATOM_UTF8_STRING)
857      {
858         int length;
859
860         /* FIXME: verify the value of length */
861         length = (reply->value_len * reply->format) / 8;
862         title = (char *)malloc((length + 1) * sizeof(char));
863         memcpy(title, xcb_get_property_value(reply), length);
864         title[length] = '\0';
865      }
866    /* not in UTF8, so we convert */
867    else
868      {
869         /* convert to utf8 */
870
871         /* FIXME: to do... */
872
873 /* #ifdef X_HAVE_UTF8_STRING */
874 /*              ret = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xprop, */
875 /*                                                &list, &num); */
876 /* #else */
877 /*              ret = XmbTextPropertyToTextList(_ecore_xcb_conn, &xprop, */
878 /*                                              &list, &num); */
879 /* #endif */
880
881 /*              if ((ret == XLocaleNotSupported) || */
882 /*                  (ret == XNoMemory) || (ret == XConverterNotFound)) */
883 /*                { */
884 /*                   t = strdup((char *)xprop.value); */
885 /*                } */
886 /*              else if ((ret >= Success) && (num > 0)) */
887 /*                { */
888 /*                   t = strdup(list[0]); */
889 /*                } */
890 /*              if (list) */
891 /*                XFreeStringList(list); */
892 /*           } */
893
894 /*         if (xprop.value) XFree(xprop.value); */
895      }
896
897    return title;
898 } /* ecore_x_icccm_title_get */
899
900 /*
901  * Sends the GetProperty request.
902  * @ingroup Ecore_X_ICCCM_Group
903  */
904 EAPI void
905 ecore_x_icccm_protocol_get_prefetch(Ecore_X_Window window)
906 {
907    xcb_get_property_cookie_t cookie;
908
909    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
910                                        ECORE_X_ATOM_WM_PROTOCOLS,
911                                        ECORE_X_ATOM_ATOM, 0, 1000000L);
912    _ecore_xcb_cookie_cache(cookie.sequence);
913 } /* ecore_x_icccm_protocol_get_prefetch */
914
915 /*
916  * Gets the reply of the GetProperty request sent by ecore_x_icccm_protocol_get_prefetch().
917  * @ingroup Ecore_X_ICCCM_Group
918  */
919 EAPI void
920 ecore_x_icccm_protocol_get_fetch(void)
921 {
922    xcb_get_property_cookie_t cookie;
923    xcb_get_property_reply_t *reply;
924
925    cookie.sequence = _ecore_xcb_cookie_get();
926    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
927    _ecore_xcb_reply_cache(reply);
928 } /* ecore_x_icccm_protocol_get_fetch */
929
930 /**
931  * Set or unset a wm protocol property.
932  * @param window   The Window
933  * @param protocol The protocol to enable/disable
934  * @param on       On/Off
935  *
936  * To use this function, you must call before, and in order,
937  * ecore_x_icccm_protocol_get_prefetch(), which sends the GetProperty request,
938  * then ecore_x_icccm_protocol_get_fetch(), which gets the reply.
939  * @ingroup Ecore_X_ICCCM_Group
940  */
941 EAPI void
942 ecore_x_icccm_protocol_set(Ecore_X_Window      window,
943                            Ecore_X_WM_Protocol protocol,
944                            Eina_Bool           on)
945 {
946    xcb_get_property_reply_t *reply;
947    Ecore_X_Atom *protos = NULL;
948    Ecore_X_Atom proto;
949    uint32_t protos_count = 0;
950    uint8_t already_set = 0;
951
952    /* Check for invalid values */
953    if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
954       return;
955
956    proto = _ecore_xcb_atoms_wm_protocols[protocol];
957
958    reply = _ecore_xcb_reply_get();
959    if (!reply)
960       return;
961
962    if ((reply->type == ECORE_X_ATOM_ATOM) && (reply->format == 32))
963      {
964         uint32_t i;
965
966         protos_count = reply->value_len / sizeof(Ecore_X_Atom);
967         protos = (Ecore_X_Atom *)xcb_get_property_value(reply);
968         for (i = 0; i < protos_count; i++)
969           {
970              if (protos[i] == proto)
971                {
972                   already_set = 1;
973                   break;
974                }
975           }
976      }
977
978    if (on)
979      {
980         Ecore_X_Atom *new_protos = NULL;
981
982         if (already_set)
983            return;
984
985         new_protos = (Ecore_X_Atom *)malloc((protos_count + 1) * sizeof(Ecore_X_Atom));
986         if (!new_protos)
987            return;
988
989         memcpy(new_protos, protos, reply->value_len);
990         new_protos[protos_count] = proto;
991         xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
992                             ECORE_X_ATOM_WM_PROTOCOLS,
993                             ECORE_X_ATOM_ATOM, 32,
994                             protos_count + 1, new_protos);
995         free(new_protos);
996      }
997    else
998      {
999         uint32_t i;
1000
1001         if (!already_set)
1002            return;
1003
1004         for (i = 0; i < protos_count; i++)
1005           {
1006              if (protos[i] == proto)
1007                {
1008                   uint32_t j;
1009
1010                   for (j = i + 1; j < protos_count; j++)
1011                      protos[j - 1] = protos[j];
1012                   if (protos_count > 1)
1013                      xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
1014                                          ECORE_X_ATOM_WM_PROTOCOLS,
1015                                          ECORE_X_ATOM_ATOM, 32,
1016                                          protos_count - 1, protos);
1017                   else
1018                      xcb_delete_property(_ecore_xcb_conn, window,
1019                                          ECORE_X_ATOM_WM_PROTOCOLS);
1020
1021                   return;
1022                }
1023           }
1024      }
1025 } /* ecore_x_icccm_protocol_set */
1026
1027 /**
1028  * Determines whether a protocol is set for a window.
1029  * @param window   The Window (Unused).
1030  * @param protocol The protocol to query.
1031  * @return         1 if the protocol is set, else 0.
1032  *
1033  * To use this function, you must call before, and in order,
1034  * ecore_x_icccm_protocol_get_prefetch(), which sends the GetProperty request,
1035  * then ecore_x_icccm_protocol_get_fetch(), which gets the reply.
1036  * @ingroup Ecore_X_ICCCM_Group
1037  */
1038 EAPI Eina_Bool
1039 ecore_x_icccm_protocol_isset(Ecore_X_Window window __UNUSED__,
1040                              Ecore_X_WM_Protocol   protocol)
1041 {
1042    xcb_get_property_reply_t *reply;
1043    Ecore_X_Atom *protos = NULL;
1044    Ecore_X_Atom proto;
1045    uint32_t i;
1046    uint8_t ret = 0;
1047
1048    /* check for invalid values */
1049    if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
1050       return 0;
1051
1052    proto = _ecore_xcb_atoms_wm_protocols[protocol];
1053
1054    reply = _ecore_xcb_reply_get();
1055    if (!reply || (reply->type != ECORE_X_ATOM_ATOM) || (reply->format != 32))
1056      {
1057         return 0;
1058      }
1059
1060    protos = (Ecore_X_Atom *)xcb_get_property_value(reply);
1061    for (i = 0; i < reply->value_len; i++)
1062       if (protos[i] == proto)
1063         {
1064            ret = 1;
1065            break;
1066         }
1067
1068    return ret;
1069 } /* ecore_x_icccm_protocol_isset */
1070
1071 /**
1072  * Set a window name & class.
1073  * @param window The window
1074  * @param name   The name string
1075  * @param class  The class string
1076  *
1077  * Set the name and class of @p window to respectively @p name and @p class.
1078  * @ingroup Ecore_X_ICCCM_Group
1079  */
1080 EAPI void
1081 ecore_x_icccm_name_class_set(Ecore_X_Window window,
1082                              const char    *name,
1083                              const char    *class)
1084 {
1085    char *class_string;
1086    char *s;
1087    int length_name;
1088    int length_class;
1089
1090    length_name = strlen(name);
1091    length_class = strlen(class);
1092    class_string = (char *)malloc(sizeof(char) * (length_name + length_class + 2));
1093    if (!class_string)
1094       return;
1095
1096    s = class_string;
1097    if (length_name)
1098      {
1099         strcpy(s, name);
1100         s += length_name + 1;
1101      }
1102    else
1103       *s++ = '\0';
1104
1105    if(length_class)
1106       strcpy(s, class);
1107    else
1108       *s = '\0';
1109
1110    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
1111                        ECORE_X_ATOM_WM_CLASS, ECORE_X_ATOM_STRING, 8,
1112                        length_name + length_class + 2, (void *)class_string);
1113    free(class_string);
1114 } /* ecore_x_icccm_name_class_set */
1115
1116 /*
1117  * Sends the GetProperty request.
1118  * @ingroup Ecore_X_ICCCM_Group
1119  */
1120 EAPI void
1121 ecore_x_icccm_name_class_get_prefetch(Ecore_X_Window window)
1122 {
1123    xcb_get_property_cookie_t cookie;
1124
1125    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1126                                        ECORE_X_ATOM_WM_CLASS,
1127                                        ECORE_X_ATOM_STRING,
1128                                        0, 2048L);
1129    _ecore_xcb_cookie_cache(cookie.sequence);
1130 } /* ecore_x_icccm_name_class_get_prefetch */
1131
1132 /*
1133  * Gets the reply of the GetProperty request sent by ecore_x_icccm_name_class_get_prefetch().
1134  * @ingroup Ecore_X_ICCCM_Group
1135  */
1136 EAPI void
1137 ecore_x_icccm_name_class_get_fetch(void)
1138 {
1139    xcb_get_property_cookie_t cookie;
1140    xcb_get_property_reply_t *reply;
1141
1142    cookie.sequence = _ecore_xcb_cookie_get();
1143    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1144    _ecore_xcb_reply_cache(reply);
1145 } /* ecore_x_icccm_name_class_get_fetch */
1146
1147 /**
1148  * Get a window name and class.
1149  * @param window The window (Unused).
1150  * @param name   The name string.
1151  * @param class  The class string.
1152  *
1153  * Store the name and class of @p window into respectively @p name and
1154  * @p class.
1155  *
1156  * To use this function, you must call before, and in order,
1157  * ecore_x_icccm_name_class_get_prefetch(), which sends the GetProperty request,
1158  * then ecore_x_icccm_name_class_get_fetch(), which gets the reply.
1159  * @ingroup Ecore_X_ICCCM_Group
1160  */
1161 EAPI void
1162 ecore_x_icccm_name_class_get(Ecore_X_Window window __UNUSED__,
1163                              char                **name,
1164                              char                **class)
1165 {
1166    xcb_get_property_reply_t *reply;
1167    void *data;
1168    char *n = NULL;
1169    char *c = NULL;
1170    int length;
1171    int length_name;
1172    int length_class;
1173
1174    if (name)
1175       *name = NULL;
1176
1177    if (class)
1178       *class = NULL;
1179
1180    reply = _ecore_xcb_reply_get();
1181    if (!reply)
1182       return;
1183
1184    if ((reply->type != ECORE_X_ATOM_STRING) ||
1185        (reply->format != 8))
1186       return;
1187
1188    length = reply->value_len;
1189    data = xcb_get_property_value(reply);
1190    /* data contains the name string and the class string */
1191    /* separated by the NULL character. data is not NULL-terminated */
1192    length_name = strlen(data);
1193    n = (char *)malloc(sizeof(char) * (length_name + 1));
1194    if (!n)
1195       return;
1196
1197    length_class = length - length_name - 1;
1198    c = (char *)malloc(sizeof(char) * (length_class + 1));
1199    if (!c)
1200      {
1201         free(n);
1202         return;
1203      }
1204
1205    memcpy(n, data, length_name);
1206    n[length_name] = '\0';
1207    length_class = length - length_name - 1;
1208    data += length_name + 1;
1209    memcpy(c, data, length_class);
1210    c[length_class] = '\0';
1211
1212    if (name)
1213       *name = n;
1214
1215    if (class)
1216       *class = c;
1217 } /* ecore_x_icccm_name_class_get */
1218
1219 /*
1220  * Sends the GetProperty request.
1221  * @ingroup Ecore_X_ICCCM_Group
1222  */
1223 EAPI void
1224 ecore_x_icccm_client_machine_get_prefetch(Ecore_X_Window window)
1225 {
1226    xcb_get_property_cookie_t cookie;
1227
1228    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
1229                                        window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
1230                                        ECORE_X_ATOM_WM_CLIENT_MACHINE,
1231                                        XCB_GET_PROPERTY_TYPE_ANY,
1232                                        0L, 1000000L);
1233    _ecore_xcb_cookie_cache(cookie.sequence);
1234 } /* ecore_x_icccm_client_machine_get_prefetch */
1235
1236 /*
1237  * Gets the reply of the GetProperty request sent by ecore_x_icccm_client_machine_get_prefetch().
1238  * @ingroup Ecore_X_ICCCM_Group
1239  */
1240 EAPI void
1241 ecore_x_icccm_client_machine_get_fetch(void)
1242 {
1243    xcb_get_property_cookie_t cookie;
1244    xcb_get_property_reply_t *reply;
1245
1246    cookie.sequence = _ecore_xcb_cookie_get();
1247    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1248    _ecore_xcb_reply_cache(reply);
1249 } /* ecore_x_icccm_client_machine_get_fetch */
1250
1251 /**
1252  * Get a window client machine string.
1253  * @param window The window
1254  * @return The windows client machine string
1255  *
1256  * Return the client machine of a window. String must be free'd when done with.
1257  *
1258  * To use this function, you must call before, and in order,
1259  * ecore_x_icccm_client_machine_get_prefetch(), which sends the GetProperty request,
1260  * then ecore_x_icccm_client_machine_get_fetch(), which gets the reply.
1261  * @ingroup Ecore_X_ICCCM_Group
1262  */
1263 EAPI char *
1264 ecore_x_icccm_client_machine_get(Ecore_X_Window window)
1265 {
1266    char *name;
1267
1268    name = ecore_x_window_prop_string_get(window, ECORE_X_ATOM_WM_CLIENT_MACHINE);
1269    return name;
1270 } /* ecore_x_icccm_client_machine_get */
1271
1272 /**
1273  * Sets the WM_COMMAND property for @a win.
1274  *
1275  * @param window The window.
1276  * @param argc   Number of arguments.
1277  * @param argv   Arguments.
1278  * @ingroup Ecore_X_ICCCM_Group
1279  */
1280 EAPI void
1281 ecore_x_icccm_command_set(Ecore_X_Window window,
1282                           int            argc,
1283                           char         **argv)
1284 {
1285    void *buf;
1286    char *b;
1287    int nbytes;
1288    int i;
1289
1290    for (i = 0, nbytes = 0; i < argc; i++)
1291      {
1292         nbytes += strlen(argv[i]) + 1;
1293      }
1294    buf = malloc(sizeof(char) * nbytes);
1295    if (!buf)
1296       return;
1297
1298    b = (char *)buf;
1299    for (i = 0; i < argc; i++)
1300      {
1301         if (argv[i])
1302           {
1303              strcpy(b, argv[i]);
1304              b += strlen(argv[i]) + 1;
1305           }
1306         else
1307            *b++ = '\0';
1308      }
1309    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
1310                        ECORE_X_ATOM_WM_COMMAND, ECORE_X_ATOM_STRING, 8,
1311                        nbytes, buf);
1312    free(buf);
1313 } /* ecore_x_icccm_command_set */
1314
1315 /*
1316  * Sends the GetProperty request.
1317  * @ingroup Ecore_X_ICCCM_Group
1318  */
1319 EAPI void
1320 ecore_x_icccm_command_get_prefetch(Ecore_X_Window window)
1321 {
1322    xcb_get_property_cookie_t cookie;
1323
1324    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1325                                        ECORE_X_ATOM_WM_COMMAND,
1326                                        XCB_GET_PROPERTY_TYPE_ANY,
1327                                        0L, 1000000L);
1328    _ecore_xcb_cookie_cache(cookie.sequence);
1329 } /* ecore_x_icccm_command_get_prefetch */
1330
1331 /*
1332  * Gets the reply of the GetProperty request sent by ecore_x_icccm_command_get_prefetch().
1333  * @ingroup Ecore_X_ICCCM_Group
1334  */
1335 EAPI void
1336 ecore_x_icccm_command_get_fetch(void)
1337 {
1338    xcb_get_property_cookie_t cookie;
1339    xcb_get_property_reply_t *reply;
1340
1341    cookie.sequence = _ecore_xcb_cookie_get();
1342    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1343    _ecore_xcb_reply_cache(reply);
1344 } /* ecore_x_icccm_command_get_fetch */
1345
1346 /**
1347  * Get the WM_COMMAND property for a window.
1348  *
1349  * @param win  The window.
1350  * @param argc Number of arguments.
1351  * @param argv Arguments.
1352  *
1353  * Return the command of @p window and store it in @p argv. @p argc
1354  * contains the number of arguments. String must be free'd when done with.
1355  *
1356  * To use this function, you must call before, and in order,
1357  * ecore_x_icccm_command_get_prefetch(), which sends the GetProperty request,
1358  * then ecore_x_icccm_command_get_fetch(), which gets the reply.
1359  * @ingroup Ecore_X_ICCCM_Group
1360  */
1361 EAPI void
1362 ecore_x_icccm_command_get(Ecore_X_Window window __UNUSED__,
1363                           int                  *argc,
1364                           char               ***argv)
1365 {
1366    xcb_get_property_reply_t *reply;
1367    char **v;
1368    char *data;
1369    char *cp;
1370    char *start;
1371    uint32_t value_len;
1372    int c;
1373    int i;
1374    int j;
1375
1376    if (argc)
1377       *argc = 0;
1378
1379    if (argv)
1380       *argv = NULL;
1381
1382    reply = _ecore_xcb_reply_get();
1383    if (!reply)
1384       return;
1385
1386    if ((reply->type != ECORE_X_ATOM_STRING) ||
1387        (reply->format != 8))
1388       return;
1389
1390    value_len = reply->value_len;
1391    data = (char *)xcb_get_property_value(reply);
1392    if (value_len && (data[value_len - 1] == '\0'))
1393       value_len--;
1394
1395    c = 1;
1396    for (cp = (char *)data, i = value_len; i > 0; cp++, i--)
1397      {
1398         if (*cp == '\0')
1399            c++;
1400      }
1401    v = (char **)malloc((c + 1) * sizeof(char *));
1402    if (!v)
1403       return;
1404
1405    start = (char *)malloc((value_len + 1) * sizeof(char));
1406    if (!start)
1407      {
1408         free(v);
1409         return;
1410      }
1411
1412    memcpy (start, (char *)data, value_len);
1413    start[value_len] = '\0';
1414    for (cp = start, i = value_len + 1, j = 0; i > 0; cp++, i--) {
1415         if (*cp == '\0')
1416           {
1417              v[j] = start;
1418              start = (cp + 1);
1419              j++;
1420           }
1421      }
1422
1423    if (c < 1)
1424      {
1425         free(v);
1426         return;
1427      }
1428
1429    if (argc)
1430       *argc = c;
1431
1432    if (argv)
1433      {
1434         (*argv) = malloc(c * sizeof(char *));
1435         if (!*argv)
1436           {
1437              free(v);
1438              if (argc)
1439                 *argc = 0;
1440
1441              return;
1442           }
1443
1444         for (i = 0; i < c; i++)
1445           {
1446              if (v[i])
1447                 (*argv)[i] = strdup(v[i]);
1448              else
1449                 (*argv)[i] = strdup("");
1450           }
1451      }
1452
1453    free(v);
1454 } /* ecore_x_icccm_command_get */
1455
1456 /**
1457  * Set a window icon name.
1458  * @param window The window.
1459  * @param title  The icon name string.
1460  *
1461  * Set @p window icon name.
1462  * @ingroup Ecore_X_ICCCM_Group
1463  */
1464 EAPI void
1465 ecore_x_icccm_icon_name_set(Ecore_X_Window window,
1466                             const char    *title)
1467 {
1468    /* FIXME: do the UTF8 conversion... */
1469
1470 /* #ifdef X_HAVE_UTF8_STRING */
1471 /*    list[0] = strdup(t); */
1472 /*    ret = Xutf8TextListToTextProperty(_ecore_xcb_conn, list, 1, */
1473 /*                                   XUTF8StringStyle, &xprop); */
1474 /* #else */
1475 /*    list[0] = strdup(t); */
1476 /*    ret = XmbTextListToTextProperty(_ecore_xcb_conn, list, 1, */
1477 /*                                 XStdICCTextStyle, &xprop); */
1478 /* #endif */
1479
1480    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
1481                        ECORE_X_ATOM_WM_ICON_NAME, ECORE_X_ATOM_WM_ICON_NAME,
1482                        8, strlen(title), title);
1483 } /* ecore_x_icccm_icon_name_set */
1484
1485 /*
1486  * Sends the GetProperty request.
1487  * @ingroup Ecore_X_ICCCM_Group
1488  */
1489 EAPI void
1490 ecore_x_icccm_icon_name_get_prefetch(Ecore_X_Window window)
1491 {
1492    xcb_get_property_cookie_t cookie;
1493
1494    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1495                                        ECORE_X_ATOM_WM_ICON_NAME,
1496                                        XCB_GET_PROPERTY_TYPE_ANY,
1497                                        0L, 128L);
1498    _ecore_xcb_cookie_cache(cookie.sequence);
1499 } /* ecore_x_icccm_icon_name_get_prefetch */
1500
1501 /*
1502  * Gets the reply of the GetProperty request sent by ecore_x_icccm_icon_name_get_prefetch().
1503  * @ingroup Ecore_X_ICCCM_Group
1504  */
1505 EAPI void
1506 ecore_x_icccm_icon_name_get_fetch(void)
1507 {
1508    xcb_get_property_cookie_t cookie;
1509    xcb_get_property_reply_t *reply;
1510
1511    cookie.sequence = _ecore_xcb_cookie_get();
1512    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1513    _ecore_xcb_reply_cache(reply);
1514 } /* ecore_x_icccm_icon_name_get_fetch */
1515
1516 /**
1517  * Get a window icon name.
1518  * @param window The window.
1519  * @return       The windows icon name string.
1520  *
1521  * Return the icon name of @p window. String must be free'd when done with.
1522  *
1523  * To use this function, you must call before, and in order,
1524  * ecore_x_icccm_icon_name_get_prefetch(), which sends the GetProperty request,
1525  * then ecore_x_icccm_icon_name_get_fetch(), which gets the reply.
1526  * @ingroup Ecore_X_ICCCM_Group
1527  */
1528 EAPI char *
1529 ecore_x_icccm_icon_name_get(Ecore_X_Window window __UNUSED__)
1530 {
1531    xcb_get_property_reply_t *reply;
1532    char *title = NULL;
1533
1534    reply = _ecore_xcb_reply_get();
1535    if (!reply)
1536       return NULL;
1537
1538    ERR("reply->bytes_afer (should be 0): %d", ((xcb_get_property_reply_t *)reply)->bytes_after);
1539
1540    if (reply->type == ECORE_X_ATOM_UTF8_STRING)
1541      {
1542         int length;
1543
1544         /* FIXME: verify the value of length */
1545         length = reply->value_len * reply->format / 8;
1546         title = (char *)malloc((length + 1) * sizeof(char));
1547         memcpy(title, xcb_get_property_value(reply), length);
1548         title[length] = '\0';
1549      }
1550    /* not in UTF8, so we convert */
1551    else
1552      {
1553         /* FIXME: do the UTF8... */
1554
1555         /* convert to utf8 */
1556 /* #ifdef X_HAVE_UTF8_STRING */
1557 /*                ret = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xprop, */
1558 /*                                                  &list, &num); */
1559 /* #else */
1560 /*                ret = XmbTextPropertyToTextList(_ecore_xcb_conn, &xprop, */
1561 /*                                                &list, &num); */
1562 /* #endif */
1563
1564 /*                if ((ret == XLocaleNotSupported) || */
1565 /*                    (ret == XNoMemory) || (ret == XConverterNotFound)) */
1566 /*                  { */
1567 /*                     t = strdup((char *)xprop.value); */
1568 /*                  } */
1569 /*                else if (ret >= Success) */
1570 /*                  { */
1571 /*                     if ((num >= 1) && (list)) */
1572 /*                       { */
1573 /*                          t = strdup(list[0]); */
1574 /*                       } */
1575 /*                     if (list) */
1576 /*                       XFreeStringList(list); */
1577 /*                  } */
1578 /*             } */
1579
1580 /*           if (xprop.value) XFree(xprop.value); */
1581      }
1582
1583    return title;
1584 } /* ecore_x_icccm_icon_name_get */
1585
1586 /*
1587  * Sends the GetProperty request.
1588  * @ingroup Ecore_X_ICCCM_Group
1589  */
1590 EAPI void
1591 ecore_x_icccm_colormap_window_get_prefetch(Ecore_X_Window window)
1592 {
1593    xcb_get_property_cookie_t cookie;
1594
1595    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
1596                                        window ? ((xcb_screen_t *)_ecore_xcb_screen)->root : window,
1597                                        ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1598                                        ECORE_X_ATOM_WINDOW,
1599                                        0L, LONG_MAX);
1600    _ecore_xcb_cookie_cache(cookie.sequence);
1601 } /* ecore_x_icccm_colormap_window_get_prefetch */
1602
1603 /*
1604  * Gets the reply of the GetProperty request sent by ecore_x_icccm_colormap_window_get_prefetch().
1605  * @ingroup Ecore_X_ICCCM_Group
1606  */
1607 EAPI void
1608 ecore_x_icccm_colormap_window_get_fetch(void)
1609 {
1610    xcb_get_property_cookie_t cookie;
1611    xcb_get_property_reply_t *reply;
1612
1613    cookie.sequence = _ecore_xcb_cookie_get();
1614    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1615    _ecore_xcb_reply_cache(reply);
1616 } /* ecore_x_icccm_colormap_window_get_fetch */
1617
1618 /**
1619  * Add a subwindow to the list of windows that need a different colormap installed.
1620  * @param window     The toplevel window
1621  * @param sub_window The subwindow to be added to the colormap windows list
1622  *
1623  * Add @p sub_window to the list of windows that need a different
1624  * colormap installed.
1625  *
1626  * To use this function, you must call before, and in order,
1627  * ecore_x_icccm_colormap_window_get_prefetch(), which sends the GetProperty request,
1628  * then ecore_x_icccm_colormap_window_get_fetch(), which gets the reply.
1629  * @ingroup Ecore_X_ICCCM_Group
1630  */
1631 EAPI void
1632 ecore_x_icccm_colormap_window_set(Ecore_X_Window window,
1633                                   Ecore_X_Window sub_window)
1634 {
1635    void *data = NULL;
1636    xcb_get_property_reply_t *reply;
1637    uint32_t num;
1638
1639    if (window == 0)
1640       window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1641
1642    reply = _ecore_xcb_reply_get();
1643    if (!reply || (reply->format != 32) || (reply->value_len == 0))
1644      {
1645         data = calloc(1, sizeof(Ecore_X_Window));
1646         if (!data)
1647           {
1648              if (reply)
1649                 free(reply);
1650
1651              return;
1652           }
1653
1654         num = 1;
1655      }
1656    else
1657      {
1658         Ecore_X_Window *newset = NULL;
1659         Ecore_X_Window *oldset = NULL;
1660         uint32_t i;
1661
1662         num = reply->value_len;
1663         data = calloc(num + 1, sizeof(Ecore_X_Window));
1664         if (!data)
1665            return;
1666
1667         newset = (Ecore_X_Window *)data;
1668         oldset = (Ecore_X_Window *)xcb_get_property_value(reply);
1669         for (i = 0; i < num; ++i)
1670           {
1671              if (oldset[i] == sub_window)
1672                {
1673                   free(newset);
1674                   return;
1675                }
1676
1677              newset[i] = oldset[i];
1678           }
1679
1680         newset[num++] = sub_window;
1681      }
1682
1683    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
1684                        ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1685                        ECORE_X_ATOM_WINDOW,
1686                        32, num, data);
1687    free(data);
1688 } /* ecore_x_icccm_colormap_window_set */
1689
1690 /**
1691  * Remove a window from the list of colormap windows.
1692  * @param window     The toplevel window
1693  * @param sub_window The window to be removed from the colormap window list.
1694  *
1695  * Remove @p sub_window from the list of colormap windows.
1696  *
1697  * To use this function, you must call before, and in order,
1698  * ecore_x_icccm_colormap_window_get_prefetch(), which sends the GetProperty request,
1699  * then ecore_x_icccm_colormap_window_get_fetch(), which gets the reply.
1700  * @ingroup Ecore_X_ICCCM_Group
1701  */
1702 EAPI void
1703 ecore_x_icccm_colormap_window_unset(Ecore_X_Window window,
1704                                     Ecore_X_Window sub_window)
1705 {
1706    void *data = NULL;
1707    Ecore_X_Window *oldset = NULL;
1708    Ecore_X_Window *newset = NULL;
1709    xcb_get_property_reply_t *reply;
1710    uint32_t num;
1711    uint32_t i;
1712    uint32_t j;
1713    uint32_t k = 0;
1714
1715    if (window == 0)
1716       window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1717
1718    reply = _ecore_xcb_reply_get();
1719    if (!reply || (reply->format != 32) || (reply->value_len == 0))
1720       return;
1721
1722    num = reply->value_len;
1723    oldset = (Ecore_X_Window *)xcb_get_property_value(reply);
1724    for (i = 0; i < num; i++)
1725      {
1726         if (oldset[i] == sub_window)
1727           {
1728              if (num == 1)
1729                {
1730                   xcb_delete_property(_ecore_xcb_conn, window,
1731                                       ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
1732                   return;
1733                }
1734              else
1735                {
1736                   data = calloc(num - 1, sizeof(Ecore_X_Window));
1737                   newset = (Ecore_X_Window *)data;
1738                   for (j = 0; j < num; ++j)
1739                      if (oldset[j] != sub_window)
1740                         newset[k++] = oldset[j];
1741
1742                   xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
1743                                       ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1744                                       ECORE_X_ATOM_WINDOW,
1745                                       32, k, data);
1746                   free(newset);
1747                   return;
1748                }
1749           }
1750      }
1751 } /* ecore_x_icccm_colormap_window_unset */
1752
1753 /**
1754  * Specify that a window is transient for another top-level window and should be handled accordingly.
1755  * @param window    The transient window
1756  * @param forwindow The toplevel window
1757  * @ingroup Ecore_X_ICCCM_Group
1758  */
1759 EAPI void
1760 ecore_x_icccm_transient_for_set(Ecore_X_Window window,
1761                                 Ecore_X_Window forwindow)
1762 {
1763    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
1764                        ECORE_X_ATOM_WM_TRANSIENT_FOR, ECORE_X_ATOM_WINDOW, 32,
1765                        1, (void *)&forwindow);
1766 } /* ecore_x_icccm_transient_for_set */
1767
1768 /**
1769  * Remove the transient_for setting from a window.
1770  * @param window The window.
1771  * @ingroup Ecore_X_ICCCM_Group
1772  */
1773 EAPI void
1774 ecore_x_icccm_transient_for_unset(Ecore_X_Window window)
1775 {
1776    xcb_delete_property(_ecore_xcb_conn, window, ECORE_X_ATOM_WM_TRANSIENT_FOR);
1777 } /* ecore_x_icccm_transient_for_unset */
1778
1779 /*
1780  * Sends the GetProperty request.
1781  * @ingroup Ecore_X_ICCCM_Group
1782  */
1783 EAPI void
1784 ecore_x_icccm_transient_for_get_prefetch(Ecore_X_Window window)
1785 {
1786    xcb_get_property_cookie_t cookie;
1787
1788    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1789                                        ECORE_X_ATOM_WM_TRANSIENT_FOR,
1790                                        ECORE_X_ATOM_WINDOW,
1791                                        0L, 1L);
1792    _ecore_xcb_cookie_cache(cookie.sequence);
1793 } /* ecore_x_icccm_transient_for_get_prefetch */
1794
1795 /*
1796  * Gets the reply of the GetProperty request sent by ecore_x_icccm_transient_for_get_prefetch().
1797  * @ingroup Ecore_X_ICCCM_Group
1798  */
1799 EAPI void
1800 ecore_x_icccm_transient_for_get_fetch(void)
1801 {
1802    xcb_get_property_cookie_t cookie;
1803    xcb_get_property_reply_t *reply;
1804
1805    cookie.sequence = _ecore_xcb_cookie_get();
1806    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1807    _ecore_xcb_reply_cache(reply);
1808 } /* ecore_x_icccm_transient_for_get_fetch */
1809
1810 /**
1811  * Get the window this window is transient for, if any.
1812  * @param window The window to check (Unused).
1813  * @return       The window ID of the top-level window, or 0 if the property does not exist.
1814  *
1815  * To use this function, you must call before, and in order,
1816  * ecore_x_icccm_transient_for_get_prefetch(), which sends the GetProperty request,
1817  * then ecore_x_icccm_transient_for_get_fetch(), which gets the reply.
1818  * @ingroup Ecore_X_ICCCM_Group
1819  */
1820 EAPI Ecore_X_Window
1821 ecore_x_icccm_transient_for_get(Ecore_X_Window window __UNUSED__)
1822 {
1823    xcb_get_property_reply_t *reply;
1824    Ecore_X_Window forwin = 0;
1825
1826    reply = _ecore_xcb_reply_get();
1827    if (!reply)
1828       return forwin;
1829
1830    if ((reply->format != 32) ||
1831        (reply->value_len == 0) ||
1832        (reply->type != ECORE_X_ATOM_WINDOW))
1833       return forwin;
1834
1835    forwin = *(Ecore_X_Window *)xcb_get_property_value(reply);
1836
1837    return forwin;
1838 } /* ecore_x_icccm_transient_for_get */
1839
1840 /**
1841  * Set the window role hint.
1842  * @param window The window
1843  * @param role   The role string.
1844  * @ingroup Ecore_X_ICCCM_Group
1845  */
1846 EAPI void
1847 ecore_x_icccm_window_role_set(Ecore_X_Window window,
1848                               const char    *role)
1849 {
1850    ecore_x_window_prop_string_set(window, ECORE_X_ATOM_WM_WINDOW_ROLE,
1851                                   (char *)role);
1852 } /* ecore_x_icccm_window_role_set */
1853
1854 /**
1855  * Sends the GetProperty request.
1856  * @param window Window whose properties are requested.
1857  * @ingroup Ecore_X_ICCCM_Group
1858  */
1859 EAPI void
1860 ecore_x_icccm_window_role_get_prefetch(Ecore_X_Window window)
1861 {
1862    xcb_get_property_cookie_t cookie;
1863
1864    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
1865                                        window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
1866                                        ECORE_X_ATOM_WM_WINDOW_ROLE, XCB_GET_PROPERTY_TYPE_ANY,
1867                                        0L, 1000000L);
1868    _ecore_xcb_cookie_cache(cookie.sequence);
1869 } /* ecore_x_icccm_window_role_get_prefetch */
1870
1871 /**
1872  * Gets the reply of the GetProperty request sent by ecore_x_icccm_window_role_get_prefetch().
1873  * @ingroup Ecore_X_ICCCM_Group
1874  */
1875 EAPI void
1876 ecore_x_icccm_window_role_get_fetch(void)
1877 {
1878    xcb_get_property_cookie_t cookie;
1879    xcb_get_property_reply_t *reply;
1880
1881    cookie.sequence = _ecore_xcb_cookie_get();
1882    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1883    _ecore_xcb_reply_cache(reply);
1884 } /* ecore_x_icccm_window_role_get_fetch */
1885
1886 /**
1887  * Get the window role.
1888  * @param window The window.
1889  * @return       The window's role string.
1890  *
1891  * To use this function, you must call before, and in order,
1892  * ecore_x_icccm_window_role_get_prefetch(), which sends the GetProperty request,
1893  * then ecore_x_icccm_window_role_get_fetch(), which gets the reply.
1894  * @ingroup Ecore_X_ICCCM_Group
1895  */
1896 EAPI char *
1897 ecore_x_icccm_window_role_get(Ecore_X_Window window)
1898 {
1899    return ecore_x_window_prop_string_get(window, ECORE_X_ATOM_WM_WINDOW_ROLE);
1900 } /* ecore_x_icccm_window_role_get */
1901
1902 /**
1903  * Set the window's client leader.
1904  * @param window The window
1905  * @param leader The client leader window
1906  *
1907  * All non-transient top-level windows created by an app other than
1908  * the main window must have this property set to the app's main window.
1909  * @ingroup Ecore_X_ICCCM_Group
1910  */
1911 EAPI void
1912 ecore_x_icccm_client_leader_set(Ecore_X_Window window,
1913                                 Ecore_X_Window leader)
1914 {
1915    ecore_x_window_prop_window_set(window, ECORE_X_ATOM_WM_CLIENT_LEADER,
1916                                   &leader, 1);
1917 } /* ecore_x_icccm_client_leader_set */
1918
1919 /**
1920  * Sends the GetProperty request.
1921  * @param window Window whose properties are requested.
1922  * @ingroup Ecore_X_ICCCM_Group
1923  */
1924 EAPI void
1925 ecore_x_icccm_client_leader_get_prefetch(Ecore_X_Window window)
1926 {
1927    xcb_get_property_cookie_t cookie;
1928
1929    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
1930                                        window,
1931                                        ECORE_X_ATOM_WM_CLIENT_LEADER,
1932                                        ECORE_X_ATOM_WINDOW,
1933                                        0, 0x7fffffff);
1934    _ecore_xcb_cookie_cache(cookie.sequence);
1935 } /* ecore_x_icccm_client_leader_get_prefetch */
1936
1937 /**
1938  * Gets the reply of the GetProperty request sent by ecore_x_icccm_client_leader_get_prefetch().
1939  * @ingroup Ecore_X_ICCCM_Group
1940  */
1941 EAPI void
1942 ecore_x_icccm_client_leader_get_fetch(void)
1943 {
1944    xcb_get_property_cookie_t cookie;
1945    xcb_get_property_reply_t *reply;
1946
1947    cookie.sequence = _ecore_xcb_cookie_get();
1948    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1949    _ecore_xcb_reply_cache(reply);
1950 } /* ecore_x_icccm_client_leader_get_fetch */
1951
1952 /**
1953  * Get the window's client leader.
1954  * @param window The window
1955  * @return       The window's client leader window, or 0 if unset.
1956  *
1957  * To use this function, you must call before, and in order,
1958  * ecore_x_icccm_client_leader_get_prefetch(), which sends the GetProperty request,
1959  * then ecore_x_icccm_client_leader_get_fetch(), which gets the reply.
1960  * @ingroup Ecore_X_ICCCM_Group
1961  */
1962 EAPI Ecore_X_Window
1963 ecore_x_icccm_client_leader_get(Ecore_X_Window window)
1964 {
1965    Ecore_X_Window leader;
1966
1967    if (ecore_x_window_prop_window_get(window, ECORE_X_ATOM_WM_CLIENT_LEADER,
1968                                       &leader, 1) > 0)
1969       return leader;
1970
1971    return 0;
1972 } /* ecore_x_icccm_client_leader_get */
1973
1974 /**
1975  * Send the ClientMessage event with the ChangeState property.
1976  * @param window The window.
1977  * @param root   The root window.
1978  * @ingroup Ecore_X_ICCCM_Group
1979  */
1980 EAPI void
1981 ecore_x_icccm_iconic_request_send(Ecore_X_Window window,
1982                                   Ecore_X_Window root)
1983 {
1984    xcb_client_message_event_t ev;
1985
1986    if (!window)
1987       return;
1988
1989    if (!root)
1990       root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1991
1992    /* send_event is bit 7 (0x80) of response_type */
1993    ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
1994    ev.format = 32;
1995    ev.sequence = 0;
1996    ev.window = window;
1997    ev.type = ECORE_X_ATOM_WM_CHANGE_STATE;
1998    ev.data.data32[0] = XCB_WM_STATE_ICONIC;
1999
2000    xcb_send_event(_ecore_xcb_conn, 0, root,
2001                   XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
2002                   (const char *)&ev);
2003 } /* ecore_x_icccm_iconic_request_send */
2004
2005 /* FIXME: there are older E hints, gnome hints and mwm hints and new netwm */
2006 /*        hints. each should go in their own file/section so we know which */
2007 /*        is which. also older kde hints too. we should try support as much */
2008 /*        as makese sense to support */