Add ecore_x_mouse_in_send() and ecore_x_mouse_out_send()
[framework/uifw/ecore.git] / src / lib / ecore_x / xlib / ecore_x.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif /* ifdef HAVE_CONFIG_H */
4
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8
9 //#define LOGRT 1
10
11 #ifdef LOGRT
12 #include <dlfcn.h>
13 #endif /* ifdef LOGRT */
14
15 #include "Ecore.h"
16 #include "ecore_private.h"
17 #include "ecore_x_private.h"
18 #include "Ecore_X.h"
19 #include "Ecore_X_Atoms.h"
20 #include "Ecore_Input.h"
21
22 static Eina_Bool _ecore_x_fd_handler(void *data,
23                                      Ecore_Fd_Handler *fd_handler);
24 static Eina_Bool _ecore_x_fd_handler_buf(void *data,
25                                          Ecore_Fd_Handler *fd_handler);
26 static int       _ecore_x_key_mask_get(KeySym sym);
27 static int       _ecore_x_event_modifier(unsigned int state);
28
29 static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL;
30
31 static const int AnyXEvent = 0; /* 0 can be used as there are no event types
32                                  * with index 0 and 1 as they are used for
33                                  * errors
34                                  */
35
36 static int _ecore_x_event_shape_id = 0;
37 static int _ecore_x_event_screensaver_id = 0;
38 static int _ecore_x_event_sync_id = 0;
39 int _ecore_xlib_log_dom = -1;
40
41 #ifdef ECORE_XRANDR
42 static int _ecore_x_event_randr_id = 0;
43 #endif /* ifdef ECORE_XRANDR */
44 #ifdef ECORE_XFIXES
45 static int _ecore_x_event_fixes_selection_id = 0;
46 #endif /* ifdef ECORE_XFIXES */
47 #ifdef ECORE_XDAMAGE
48 static int _ecore_x_event_damage_id = 0;
49 #endif /* ifdef ECORE_XDAMAGE */
50 #ifdef ECORE_XGESTURE
51 static int _ecore_x_event_gesture_id = 0;
52 #endif /* ifdef ECORE_XGESTURE */
53 static int _ecore_x_event_handlers_num = 0;
54 static void (**_ecore_x_event_handlers) (XEvent * event) = NULL;
55
56 static int _ecore_x_init_count = 0;
57 static int _ecore_x_grab_count = 0;
58
59 Display *_ecore_x_disp = NULL;
60 double _ecore_x_double_click_time = 0.25;
61 Time _ecore_x_event_last_time = 0;
62 Window _ecore_x_event_last_win = 0;
63 int _ecore_x_event_last_root_x = 0;
64 int _ecore_x_event_last_root_y = 0;
65 Eina_Bool _ecore_x_xcursor = EINA_FALSE;
66
67 Ecore_X_Window _ecore_x_private_win = 0;
68
69 Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
70
71 EAPI int ECORE_X_EVENT_ANY = 0;
72 EAPI int ECORE_X_EVENT_MOUSE_IN = 0;
73 EAPI int ECORE_X_EVENT_MOUSE_OUT = 0;
74 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0;
75 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0;
76 EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0;
77 EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0;
78 EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0;
79 EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0;
80 EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0;
81 EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0;
82 EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0;
83 EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0;
84 EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0;
85 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0;
86 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0;
87 EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0;
88 EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0;
89 EAPI int ECORE_X_EVENT_WINDOW_STACK = 0;
90 EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0;
91 EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0;
92 EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0;
93 EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0;
94 EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0;
95 EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
96 EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
97 EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
98 EAPI int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = 0;
99 EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
100 EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
101 EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
102 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_FLICK;
103 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN;
104 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION;
105 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP;
106 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD;
107 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD;
108 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP;
109 EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0;
110 EAPI int ECORE_X_EVENT_SYNC_ALARM = 0;
111 EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0;
112 EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0;
113 EAPI int ECORE_X_EVENT_RANDR_CRTC_CHANGE = 0;
114 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = 0;
115 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = 0;
116 EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
117 EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0;
118 EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0;
119 EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0;
120 EAPI int ECORE_X_EVENT_PING = 0;
121 EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0;
122
123 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0;
124 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0;
125 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0;
126
127 EAPI int ECORE_X_EVENT_GENERIC = 0;
128
129 int ECORE_X_MODIFIER_SHIFT = 0;
130 int ECORE_X_MODIFIER_CTRL = 0;
131 int ECORE_X_MODIFIER_ALT = 0;
132 int ECORE_X_MODIFIER_WIN = 0;
133
134 EAPI int ECORE_X_LOCK_SCROLL = 0;
135 EAPI int ECORE_X_LOCK_NUM = 0;
136 EAPI int ECORE_X_LOCK_CAPS = 0;
137 EAPI int ECORE_X_LOCK_SHIFT = 0;
138
139 #ifdef LOGRT
140 static double t0 = 0.0;
141 static Status (*_logrt_real_reply)(Display *disp,
142                                    void *rep,
143                                    int extra,
144                                    Bool discard) = NULL;
145 static void
146 _logrt_init(void)
147 {
148    void *lib;
149
150    lib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
151    if (!lib)
152      lib = dlopen("libX11.so.6", RTLD_GLOBAL | RTLD_LAZY);
153
154    if (!lib)
155      lib = dlopen("libX11.so.6.3", RTLD_GLOBAL | RTLD_LAZY);
156
157    if (!lib)
158      lib = dlopen("libX11.so.6.3.0", RTLD_GLOBAL | RTLD_LAZY);
159
160    _logrt_real_reply = dlsym(lib, "_XReply");
161    t0 = ecore_time_get();
162 }
163
164 Status
165 _XReply(Display *disp,
166         void *rep,
167         int extra,
168         Bool discard)
169 {
170    void *bt[128];
171    int i, n;
172    char **sym;
173
174    n = backtrace(bt, 128);
175    if (n > 0)
176      {
177         sym = backtrace_symbols(bt, n);
178         printf("ROUNDTRIP: %4.4f :", ecore_time_get() - t0);
179         if (sym)
180           {
181              for (i = n - 1; i > 0; i--)
182                {
183                   char *fname = strchr(sym[i], '(');
184                   if (fname)
185                     {
186                        char *tsym = alloca(strlen(fname) + 1);
187                        char *end;
188                        strcpy(tsym, fname + 1);
189                        end = strchr(tsym, '+');
190                        if (end)
191                          {
192                             *end = 0;
193                             printf("%s", tsym);
194                          }
195                        else
196                          printf("???");
197                     }
198                   else
199                     printf("???");
200
201                   if (i > 1)
202                     printf(" > ");
203                }
204              printf("\n");
205           }
206      }
207
208    // fixme: logme
209    return _logrt_real_reply(disp, rep, extra, discard);
210 }
211
212 #endif /* ifdef LOGRT */
213
214 void
215 _ecore_x_modifiers_get(void)
216 {
217    /* everything has these... unless its like a pda... :) */
218    ECORE_X_MODIFIER_SHIFT = _ecore_x_key_mask_get(XK_Shift_L);
219    ECORE_X_MODIFIER_CTRL = _ecore_x_key_mask_get(XK_Control_L);
220
221    /* apple's xdarwin has no alt!!!! */
222    ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Alt_L);
223    if (!ECORE_X_MODIFIER_ALT)
224      ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Meta_L);
225
226    if (!ECORE_X_MODIFIER_ALT)
227      ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Super_L);
228
229    /* the windows key... a valid modifier :) */
230    ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Super_L);
231    if (!ECORE_X_MODIFIER_WIN)
232      ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Mode_switch);
233
234    if (!ECORE_X_MODIFIER_WIN)
235      ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Meta_L);
236
237    if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT)
238      ECORE_X_MODIFIER_WIN = 0;
239
240    if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL)
241      ECORE_X_MODIFIER_ALT = 0;
242
243    ECORE_X_LOCK_SCROLL = _ecore_x_key_mask_get(XK_Scroll_Lock);
244    ECORE_X_LOCK_NUM = _ecore_x_key_mask_get(XK_Num_Lock);
245    ECORE_X_LOCK_CAPS = _ecore_x_key_mask_get(XK_Caps_Lock);
246    ECORE_X_LOCK_SHIFT = _ecore_x_key_mask_get(XK_Shift_Lock);
247 }
248
249 /**
250  * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions
251  *
252  * Functions that start and shut down the Ecore X Library.
253  */
254
255 /**
256  * Initialize the X display connection to the given display.
257  *
258  * @param   name Display target name.  If @c NULL, the default display is
259  *               assumed.
260  * @return  The number of times the library has been initialized without
261  *          being shut down.  0 is returned if an error occurs.
262  * @ingroup Ecore_X_Init_Group
263  */
264 EAPI int
265 ecore_x_init(const char *name)
266 {
267    int shape_base = 0;
268    int shape_err_base = 0;
269 #ifdef ECORE_XSS
270    int screensaver_base = 0;
271    int screensaver_err_base = 0;
272 #endif /* ifdef ECORE_XSS */
273    int sync_base = 0;
274    int sync_err_base = 0;
275 #ifdef ECORE_XRANDR
276    int randr_base = 0;
277    int randr_err_base = 0;
278 #endif /* ifdef ECORE_XRANDR */
279 #ifdef ECORE_XFIXES
280    int fixes_base = 0;
281    int fixes_err_base = 0;
282 #endif /* ifdef ECORE_XFIXES */
283 #ifdef ECORE_XDAMAGE
284    int damage_base = 0;
285    int damage_err_base = 0;
286 #endif /* ifdef ECORE_XDAMAGE */
287 #ifdef ECORE_XGESTURE
288    int gesture_base = 0;
289    int gesture_err_base = 0;
290 #endif /* ifdef ECORE_XGESTURE */
291
292    if (++_ecore_x_init_count != 1)
293      return _ecore_x_init_count;
294
295    LOGFN(__FILE__, __LINE__, __FUNCTION__);
296 #ifdef LOGRT
297    _logrt_init();
298 #endif /* ifdef LOGRT */
299
300    eina_init();
301    _ecore_xlib_log_dom = eina_log_domain_register
302        ("ecore_x", ECORE_XLIB_DEFAULT_LOG_COLOR);
303    if (_ecore_xlib_log_dom < 0)
304      {
305         EINA_LOG_ERR(
306           "Impossible to create a log domain for the Ecore Xlib module.");
307         return --_ecore_x_init_count;
308      }
309
310    if (!ecore_init())
311      goto shutdown_eina;
312    if (!ecore_event_init())
313      goto shutdown_ecore;
314
315 #ifdef EVAS_FRAME_QUEUING
316    XInitThreads();
317 #endif /* ifdef EVAS_FRAME_QUEUING */
318    _ecore_x_disp = XOpenDisplay((char *)name);
319    if (!_ecore_x_disp)
320      goto shutdown_ecore_event;
321
322    _ecore_x_error_handler_init();
323    _ecore_x_event_handlers_num = LASTEvent;
324
325 #define ECORE_X_EVENT_HANDLERS_GROW(ext_base, ext_num_events)            \
326   do {                                                                   \
327        if (_ecore_x_event_handlers_num < (ext_base + ext_num_events)) {  \
328             _ecore_x_event_handlers_num = (ext_base + ext_num_events); } \
329     } while (0)
330
331    if (XShapeQueryExtension(_ecore_x_disp, &shape_base, &shape_err_base))
332      _ecore_x_event_shape_id = shape_base;
333
334    ECORE_X_EVENT_HANDLERS_GROW(shape_base, ShapeNumberEvents);
335
336 #ifdef ECORE_XSS
337    if (XScreenSaverQueryExtension(_ecore_x_disp, &screensaver_base,
338                                   &screensaver_err_base))
339      _ecore_x_event_screensaver_id = screensaver_base;
340
341    ECORE_X_EVENT_HANDLERS_GROW(screensaver_base, ScreenSaverNumberEvents);
342 #endif /* ifdef ECORE_XSS */
343
344    if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base))
345      {
346         int major, minor;
347
348         _ecore_x_event_sync_id = sync_base;
349         if (!XSyncInitialize(_ecore_x_disp, &major, &minor))
350           _ecore_x_event_sync_id = 0;
351      }
352
353    ECORE_X_EVENT_HANDLERS_GROW(sync_base, XSyncNumberEvents);
354
355 #ifdef ECORE_XRANDR
356    if (XRRQueryExtension(_ecore_x_disp, &randr_base, &randr_err_base))
357      _ecore_x_event_randr_id = randr_base;
358
359    ECORE_X_EVENT_HANDLERS_GROW(randr_base, RRNumberEvents);
360 #endif /* ifdef ECORE_XRANDR */
361
362 #ifdef ECORE_XFIXES
363    if (XFixesQueryExtension(_ecore_x_disp, &fixes_base, &fixes_err_base))
364      _ecore_x_event_fixes_selection_id = fixes_base;
365
366    ECORE_X_EVENT_HANDLERS_GROW(fixes_base, XFixesNumberEvents);
367 #endif /* ifdef ECORE_XFIXES */
368
369 #ifdef ECORE_XDAMAGE
370    if (XDamageQueryExtension(_ecore_x_disp, &damage_base, &damage_err_base))
371      _ecore_x_event_damage_id = damage_base;
372
373    ECORE_X_EVENT_HANDLERS_GROW(damage_base, XDamageNumberEvents);
374 #endif /* ifdef ECORE_XDAMAGE */
375
376 #ifdef ECORE_XGESTURE
377    if (XGestureQueryExtension(_ecore_x_disp, &gesture_base, &gesture_err_base))
378      _ecore_x_event_gesture_id = gesture_base;
379
380    ECORE_X_EVENT_HANDLERS_GROW(gesture_base, GestureNumberEvents);
381 #endif /* ifdef ECORE_XGESTURE */
382
383    _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *));
384    if (!_ecore_x_event_handlers)
385      goto close_display;
386
387 #ifdef ECORE_XCURSOR
388    _ecore_x_xcursor = XcursorSupportsARGB(_ecore_x_disp) ? EINA_TRUE : EINA_FALSE;
389 #endif /* ifdef ECORE_XCURSOR */
390    _ecore_x_event_handlers[AnyXEvent] = _ecore_x_event_handle_any_event;
391    _ecore_x_event_handlers[KeyPress] = _ecore_x_event_handle_key_press;
392    _ecore_x_event_handlers[KeyRelease] = _ecore_x_event_handle_key_release;
393    _ecore_x_event_handlers[ButtonPress] = _ecore_x_event_handle_button_press;
394    _ecore_x_event_handlers[ButtonRelease] =
395      _ecore_x_event_handle_button_release;
396    _ecore_x_event_handlers[MotionNotify] = _ecore_x_event_handle_motion_notify;
397    _ecore_x_event_handlers[EnterNotify] = _ecore_x_event_handle_enter_notify;
398    _ecore_x_event_handlers[LeaveNotify] = _ecore_x_event_handle_leave_notify;
399    _ecore_x_event_handlers[FocusIn] = _ecore_x_event_handle_focus_in;
400    _ecore_x_event_handlers[FocusOut] = _ecore_x_event_handle_focus_out;
401    _ecore_x_event_handlers[KeymapNotify] = _ecore_x_event_handle_keymap_notify;
402    _ecore_x_event_handlers[Expose] = _ecore_x_event_handle_expose;
403    _ecore_x_event_handlers[GraphicsExpose] =
404      _ecore_x_event_handle_graphics_expose;
405    _ecore_x_event_handlers[VisibilityNotify] =
406      _ecore_x_event_handle_visibility_notify;
407    _ecore_x_event_handlers[CreateNotify] = _ecore_x_event_handle_create_notify;
408    _ecore_x_event_handlers[DestroyNotify] =
409      _ecore_x_event_handle_destroy_notify;
410    _ecore_x_event_handlers[UnmapNotify] = _ecore_x_event_handle_unmap_notify;
411    _ecore_x_event_handlers[MapNotify] = _ecore_x_event_handle_map_notify;
412    _ecore_x_event_handlers[MapRequest] = _ecore_x_event_handle_map_request;
413    _ecore_x_event_handlers[ReparentNotify] =
414      _ecore_x_event_handle_reparent_notify;
415    _ecore_x_event_handlers[ConfigureNotify] =
416      _ecore_x_event_handle_configure_notify;
417    _ecore_x_event_handlers[ConfigureRequest] =
418      _ecore_x_event_handle_configure_request;
419    _ecore_x_event_handlers[GravityNotify] =
420      _ecore_x_event_handle_gravity_notify;
421    _ecore_x_event_handlers[ResizeRequest] =
422      _ecore_x_event_handle_resize_request;
423    _ecore_x_event_handlers[CirculateNotify] =
424      _ecore_x_event_handle_circulate_notify;
425    _ecore_x_event_handlers[CirculateRequest] =
426      _ecore_x_event_handle_circulate_request;
427    _ecore_x_event_handlers[PropertyNotify] =
428      _ecore_x_event_handle_property_notify;
429    _ecore_x_event_handlers[SelectionClear] =
430      _ecore_x_event_handle_selection_clear;
431    _ecore_x_event_handlers[SelectionRequest] =
432      _ecore_x_event_handle_selection_request;
433    _ecore_x_event_handlers[SelectionNotify] =
434      _ecore_x_event_handle_selection_notify;
435    _ecore_x_event_handlers[ColormapNotify] =
436      _ecore_x_event_handle_colormap_notify;
437    _ecore_x_event_handlers[ClientMessage] =
438      _ecore_x_event_handle_client_message;
439    _ecore_x_event_handlers[MappingNotify] =
440      _ecore_x_event_handle_mapping_notify;
441 #ifdef GenericEvent
442    _ecore_x_event_handlers[GenericEvent] = _ecore_x_event_handle_generic_event;
443 #endif /* ifdef GenericEvent */
444
445    if (_ecore_x_event_shape_id)
446      _ecore_x_event_handlers[_ecore_x_event_shape_id] =
447        _ecore_x_event_handle_shape_change;
448
449    if (_ecore_x_event_screensaver_id)
450      _ecore_x_event_handlers[_ecore_x_event_screensaver_id] =
451        _ecore_x_event_handle_screensaver_notify;
452
453    if (_ecore_x_event_sync_id)
454      {
455         _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncCounterNotify] =
456           _ecore_x_event_handle_sync_counter;
457         _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncAlarmNotify] =
458           _ecore_x_event_handle_sync_alarm;
459      }
460
461 #ifdef ECORE_XRANDR
462    if (_ecore_x_event_randr_id)
463      {
464         _ecore_x_event_handlers[_ecore_x_event_randr_id +
465                                 RRScreenChangeNotify] =
466           _ecore_x_event_handle_randr_change;
467         _ecore_x_event_handlers[_ecore_x_event_randr_id +
468                                 RRNotify] = _ecore_x_event_handle_randr_notify;
469      }
470
471 #endif /* ifdef ECORE_XRANDR */
472 #ifdef ECORE_XFIXES
473    if (_ecore_x_event_fixes_selection_id)
474      _ecore_x_event_handlers[_ecore_x_event_fixes_selection_id] =
475        _ecore_x_event_handle_fixes_selection_notify;
476
477 #endif /* ifdef ECORE_XFIXES */
478 #ifdef ECORE_XDAMAGE
479    if (_ecore_x_event_damage_id)
480      _ecore_x_event_handlers[_ecore_x_event_damage_id] =
481        _ecore_x_event_handle_damage_notify;
482
483 #endif /* ifdef ECORE_XDAMAGE */
484 #ifdef ECORE_XKB
485    // set x autorepeat detection to on. that means instead of
486    //   press-release-press-release-press-release
487    // you get
488    //   press-press-press-press-press-release
489    do
490      {
491         Bool works = 0;
492         XkbSetDetectableAutoRepeat(_ecore_x_disp, 1, &works);
493      }
494    while (0);
495 #endif /* ifdef ECORE_XKB */
496
497 #ifdef ECORE_XGESTURE
498    if (_ecore_x_event_gesture_id)
499      {
500         _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyFlick] =
501           _ecore_x_event_handle_gesture_notify_flick;
502         _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyPan] =
503           _ecore_x_event_handle_gesture_notify_pan;
504         _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyPinchRotation] =
505           _ecore_x_event_handle_gesture_notify_pinchrotation;
506         _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyTap] =
507           _ecore_x_event_handle_gesture_notify_tap;
508         _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyTapNHold] =
509           _ecore_x_event_handle_gesture_notify_tapnhold;
510         _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyHold] =
511           _ecore_x_event_handle_gesture_notify_hold;
512         _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyGroup] =
513           _ecore_x_event_handle_gesture_notify_group;
514      }
515
516 #endif /* ifdef ECORE_XGESTURE */
517
518    if (!ECORE_X_EVENT_ANY)
519      {
520         ECORE_X_EVENT_ANY = ecore_event_type_new();
521         ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new();
522         ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new();
523         ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
524         ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
525         ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new();
526         ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
527         ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new();
528         ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new();
529         ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new();
530         ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new();
531         ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new();
532         ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new();
533         ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new();
534         ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
535         ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new();
536         ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new();
537         ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new();
538         ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new();
539         ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new();
540         ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new();
541         ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new();
542         ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new();
543         ECORE_X_EVENT_MAPPING_CHANGE = ecore_event_type_new();
544         ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new();
545         ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new();
546         ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new();
547         ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new();
548         ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new();
549         ECORE_X_EVENT_SCREENSAVER_NOTIFY = ecore_event_type_new();
550         ECORE_X_EVENT_GESTURE_NOTIFY_FLICK = ecore_event_type_new();
551         ECORE_X_EVENT_GESTURE_NOTIFY_PAN = ecore_event_type_new();
552         ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = ecore_event_type_new();
553         ECORE_X_EVENT_GESTURE_NOTIFY_TAP = ecore_event_type_new();
554         ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = ecore_event_type_new();
555         ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = ecore_event_type_new();
556         ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = ecore_event_type_new();
557         ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new();
558         ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new();
559         ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new();
560         ECORE_X_EVENT_RANDR_CRTC_CHANGE = ecore_event_type_new();
561         ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = ecore_event_type_new();
562         ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = ecore_event_type_new();
563         ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new();
564
565         ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
566
567         ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new();
568         ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new();
569         ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new();
570         ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new();
571         ECORE_X_EVENT_PING = ecore_event_type_new();
572
573         ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new();
574         ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new();
575         ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new();
576
577         ECORE_X_EVENT_GENERIC = ecore_event_type_new();
578      }
579
580    _ecore_x_modifiers_get();
581
582    _ecore_x_fd_handler_handle =
583      ecore_main_fd_handler_add(ConnectionNumber(_ecore_x_disp),
584                                ECORE_FD_READ,
585                                _ecore_x_fd_handler, _ecore_x_disp,
586                                _ecore_x_fd_handler_buf, _ecore_x_disp);
587    if (!_ecore_x_fd_handler_handle)
588      goto free_event_handlers;
589
590    _ecore_x_atoms_init();
591
592    /* Set up the ICCCM hints */
593    ecore_x_icccm_init();
594
595    /* Set up the _NET_... hints */
596    ecore_x_netwm_init();
597
598    /* old e hints init */
599    ecore_x_e_init();
600
601    /* This is just to be anal about naming conventions */
602
603    _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] =
604      ECORE_X_ATOM_WM_DELETE_WINDOW;
605    _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] =
606      ECORE_X_ATOM_WM_TAKE_FOCUS;
607    _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] =
608      ECORE_X_ATOM_NET_WM_PING;
609    _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] =
610      ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
611
612    _ecore_x_selection_data_init();
613    _ecore_x_dnd_init();
614    _ecore_x_fixes_init();
615    _ecore_x_damage_init();
616    _ecore_x_composite_init();
617    _ecore_x_dpms_init();
618    _ecore_x_randr_init();
619    _ecore_x_gesture_init();
620    _ecore_x_input_init();
621    _ecore_x_events_init();
622
623    _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456);
624
625    return _ecore_x_init_count;
626
627 free_event_handlers:
628    free(_ecore_x_event_handlers);
629    _ecore_x_event_handlers = NULL;
630 close_display:
631    XCloseDisplay(_ecore_x_disp);
632    _ecore_x_fd_handler_handle = NULL;
633    _ecore_x_disp = NULL;
634 shutdown_ecore_event:
635    ecore_event_shutdown();
636 shutdown_ecore:
637    ecore_shutdown();
638 shutdown_eina:
639    eina_log_domain_unregister(_ecore_xlib_log_dom);
640    _ecore_xlib_log_dom = -1;
641    eina_shutdown();
642
643    return --_ecore_x_init_count;
644 }
645
646 static int
647 _ecore_x_shutdown(int close_display)
648 {
649    if (--_ecore_x_init_count != 0)
650      return _ecore_x_init_count;
651
652    if (!_ecore_x_disp)
653      return _ecore_x_init_count;
654
655    LOGFN(__FILE__, __LINE__, __FUNCTION__);
656
657    ecore_main_fd_handler_del(_ecore_x_fd_handler_handle);
658    if (close_display)
659      XCloseDisplay(_ecore_x_disp);
660    else
661      {
662         close(ConnectionNumber(_ecore_x_disp));
663         // FIXME: may have to clean up x display internal here
664 // getting segv here? hmmm. odd. disable
665 //        XFree(_ecore_x_disp);
666      }
667
668    free(_ecore_x_event_handlers);
669    _ecore_x_fd_handler_handle = NULL;
670    _ecore_x_disp = NULL;
671    _ecore_x_event_handlers = NULL;
672    _ecore_x_events_shutdown();
673    _ecore_x_input_shutdown();
674    _ecore_x_selection_shutdown();
675    _ecore_x_dnd_shutdown();
676    ecore_x_netwm_shutdown();
677
678    ecore_event_shutdown();
679    ecore_shutdown();
680
681    eina_log_domain_unregister(_ecore_xlib_log_dom);
682    _ecore_xlib_log_dom = -1;
683    eina_shutdown();
684
685    return _ecore_x_init_count;
686 }
687
688 /**
689  * Shuts down the Ecore X library.
690  *
691  * In shutting down the library, the X display connection is terminated
692  * and any event handlers for it are removed.
693  *
694  * @return  The number of times the library has been initialized without
695  *          being shut down. 0 is returned if an error occurs.
696  * @ingroup Ecore_X_Init_Group
697  */
698 EAPI int
699 ecore_x_shutdown(void)
700 {
701    return _ecore_x_shutdown(1);
702 }
703
704 /**
705  * Shuts down the Ecore X library.
706  *
707  * As ecore_x_shutdown, except do not close Display, only connection.
708  *
709  * @ingroup Ecore_X_Init_Group
710  */
711 EAPI int
712 ecore_x_disconnect(void)
713 {
714    return _ecore_x_shutdown(0);
715 }
716
717 /**
718  * @defgroup Ecore_X_Display_Attr_Group X Display Attributes
719  *
720  * Functions that set and retrieve X display attributes.
721  */
722
723 /**
724  * Retrieves the Ecore_X_Display handle used for the current X connection.
725  * @return  The current X display.
726  * @ingroup Ecore_X_Display_Attr_Group
727  */
728 EAPI Ecore_X_Display *
729 ecore_x_display_get(void)
730 {
731    return (Ecore_X_Display *)_ecore_x_disp;
732 }
733
734 /**
735  * Retrieves the X display file descriptor.
736  * @return  The current X display file descriptor.
737  * @ingroup Ecore_X_Display_Attr_Group
738  */
739 EAPI int
740 ecore_x_fd_get(void)
741 {
742    LOGFN(__FILE__, __LINE__, __FUNCTION__);
743    return ConnectionNumber(_ecore_x_disp);
744 }
745
746 /**
747  * Retrieves the Ecore_X_Screen handle used for the current X connection.
748  * @return  The current default screen.
749  * @ingroup Ecore_X_Display_Attr_Group
750  */
751 EAPI Ecore_X_Screen *
752 ecore_x_default_screen_get(void)
753 {
754    LOGFN(__FILE__, __LINE__, __FUNCTION__);
755    return (Ecore_X_Screen *)DefaultScreenOfDisplay(_ecore_x_disp);
756 }
757
758 /**
759  * Retrieves the size of an Ecore_X_Screen.
760  * @param screen the handle to the screen to query.
761  * @param w where to return the width. May be NULL. Returns 0 on errors.
762  * @param h where to return the height. May be NULL. Returns 0 on errors.
763  * @ingroup Ecore_X_Display_Attr_Group
764  * @see ecore_x_default_screen_get()
765  *
766  * @since 1.1
767  */
768 EAPI void
769 ecore_x_screen_size_get(const Ecore_X_Screen *screen,
770                         int *w,
771                         int *h)
772 {
773    Screen *s = (Screen *)screen;
774    LOGFN(__FILE__, __LINE__, __FUNCTION__);
775    if (w) *w = 0;
776    if (h) *h = 0;
777    if (!s) return;
778    if (w) *w = s->width;
779    if (h) *h = s->height;
780 }
781
782 /**
783  * Retrieves the number of screens.
784  *
785  * @return  The count of the number of screens.
786  * @ingroup Ecore_X_Display_Attr_Group
787  *
788  * @since 1.1
789  */
790 EAPI int
791 ecore_x_screen_count_get(void)
792 {
793    LOGFN(__FILE__, __LINE__, __FUNCTION__);
794
795    return ScreenCount(_ecore_x_disp);
796 }
797
798 /**
799  * Retrieves the index number of the given screen.
800  *
801  * @param screen The screen for which the index will be retrieved.
802  * @return  The index number of the screen.
803  * @ingroup Ecore_X_Display_Attr_Group
804  *
805  * @since 1.1
806  */
807 EAPI int
808 ecore_x_screen_index_get(const Ecore_X_Screen *screen)
809 {
810    return XScreenNumberOfScreen((Screen *)screen);
811 }
812
813 /**
814  * Retrieves the screen based on index number.
815  *
816  * @param index The index that will be used to retrieve the screen.
817  * @return  The Ecore_X_Screen at this index.
818  * @ingroup Ecore_X_Display_Attr_Group
819  *
820  * @since 1.1
821  */
822 EAPI Ecore_X_Screen *
823 ecore_x_screen_get(int index)
824 {
825    return XScreenOfDisplay(_ecore_x_disp, index);
826 }
827
828 /**
829  * Sets the timeout for a double and triple clicks to be flagged.
830  *
831  * This sets the time between clicks before the double_click flag is
832  * set in a button down event. If 3 clicks occur within double this
833  * time, the triple_click flag is also set.
834  *
835  * @param   t The time in seconds
836  * @ingroup Ecore_X_Display_Attr_Group
837  */
838 EAPI void
839 ecore_x_double_click_time_set(double t)
840 {
841    if (t < 0.0)
842      t = 0.0;
843
844    _ecore_x_double_click_time = t;
845 }
846
847 /**
848  * Retrieves the double and triple click flag timeout.
849  *
850  * See @ref ecore_x_double_click_time_set for more information.
851  *
852  * @return  The timeout for double clicks in seconds.
853  * @ingroup Ecore_X_Display_Attr_Group
854  */
855 EAPI double
856 ecore_x_double_click_time_get(void)
857 {
858    return _ecore_x_double_click_time;
859 }
860
861 /**
862  * @defgroup Ecore_X_Flush_Group X Synchronization Functions
863  *
864  * Functions that ensure that all commands that have been issued by the
865  * Ecore X library have been sent to the server.
866  */
867
868 /**
869  * Sends all X commands in the X Display buffer.
870  * @ingroup Ecore_X_Flush_Group
871  */
872 EAPI void
873 ecore_x_flush(void)
874 {
875    LOGFN(__FILE__, __LINE__, __FUNCTION__);
876    XFlush(_ecore_x_disp);
877 }
878
879 /**
880  * Flushes the command buffer and waits until all requests have been
881  * processed by the server.
882  * @ingroup Ecore_X_Flush_Group
883  */
884 EAPI void
885 ecore_x_sync(void)
886 {
887    LOGFN(__FILE__, __LINE__, __FUNCTION__);
888    XSync(_ecore_x_disp, False);
889 }
890
891 /**
892  * Kill all clients with subwindows under a given window.
893  *
894  * You can kill all clients connected to the X server by using
895  * @ref ecore_x_window_root_list to get a list of root windows, and
896  * then passing each root window to this function.
897  *
898  * @param root The window whose children will be killed.
899  */
900 EAPI void
901 ecore_x_killall(Ecore_X_Window root)
902 {
903    unsigned int j;
904    Window root_r;
905    Window parent_r;
906    Window *children_r = NULL;
907    unsigned int num_children = 0;
908
909    LOGFN(__FILE__, __LINE__, __FUNCTION__);
910    XGrabServer(_ecore_x_disp);
911    /* Tranverse window tree starting from root, and drag each
912     * before the firing squad */
913    while (XQueryTree(_ecore_x_disp, root, &root_r, &parent_r,
914                      &children_r, &num_children) && (num_children > 0))
915      {
916         for (j = 0; j < num_children; ++j)
917           {
918              XKillClient(_ecore_x_disp, children_r[j]);
919           }
920
921         XFree(children_r);
922      }
923    XUngrabServer(_ecore_x_disp);
924    XSync(_ecore_x_disp, False);
925 }
926
927 /**
928  * Kill a specific client
929  *
930  * You can kill a specific client owning window @p win
931  *
932  * @param win Window of the client to be killed
933  */
934 EAPI void
935 ecore_x_kill(Ecore_X_Window win)
936 {
937    LOGFN(__FILE__, __LINE__, __FUNCTION__);
938    XKillClient(_ecore_x_disp, win);
939 }
940
941 /**
942  * Return the last event time
943  */
944 EAPI Ecore_X_Time
945 ecore_x_current_time_get(void)
946 {
947    return _ecore_x_event_last_time;
948 }
949
950 /**
951  * Return the screen DPI
952  *
953  * This is a simplistic call to get DPI. It does not account for differing
954  * DPI in the x amd y axes nor does it account for multihead or xinerama and
955  * xrander where different parts of the screen may have different DPI etc.
956  *
957  * @return the general screen DPI (dots/pixels per inch).
958  */
959 EAPI int
960 ecore_x_dpi_get(void)
961 {
962    Screen *s;
963
964    LOGFN(__FILE__, __LINE__, __FUNCTION__);
965    s = DefaultScreenOfDisplay(_ecore_x_disp);
966    if (s->mwidth <= 0)
967      return 75;
968
969    return (((s->width * 254) / s->mwidth) + 5) / 10;
970 }
971
972 /**
973  * Invoke the standard system beep to alert users
974  *
975  * @param percent The volume at which the bell rings. Must be in the range
976  * [-100,+100]. If percent >= 0, the final volume will be:
977  *       base - [(base * percent) / 100] + percent
978  * Otherwise, it's calculated as:
979  *       base + [(base * percent) / 100]
980  * where @c base is the bell's base volume as set by XChangeKeyboardControl(3).
981  *
982  * @returns @c EINA_TRUE on success, @c EINA_FALSE otherwise.
983  */
984 EAPI Eina_Bool
985 ecore_x_bell(int percent)
986 {
987    int ret;
988
989    ret = XBell(_ecore_x_disp, percent);
990    if (ret == BadValue)
991      return EINA_FALSE;
992
993    return EINA_TRUE;
994 }
995
996 static Eina_Bool
997 _ecore_x_fd_handler(void *data,
998                     Ecore_Fd_Handler *fd_handler __UNUSED__)
999 {
1000    Display *d;
1001
1002    d = data;
1003    while (XPending(d))
1004      {
1005         XEvent ev;
1006
1007         XNextEvent(d, &ev);
1008
1009 #ifdef ENABLE_XIM
1010         /* Filter event for XIM */
1011         if (XFilterEvent(&ev, ev.xkey.window))
1012           continue;
1013
1014 #endif /* ifdef ENABLE_XIM */
1015
1016         if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num))
1017           {
1018              if (_ecore_x_event_handlers[AnyXEvent])
1019                _ecore_x_event_handlers[AnyXEvent] (&ev);
1020
1021              if (_ecore_x_event_handlers[ev.type])
1022                _ecore_x_event_handlers[ev.type] (&ev);
1023           }
1024      }
1025    return ECORE_CALLBACK_RENEW;
1026 }
1027
1028 static Eina_Bool
1029 _ecore_x_fd_handler_buf(void *data,
1030                         Ecore_Fd_Handler *fd_handler __UNUSED__)
1031 {
1032    Display *d;
1033
1034    d = data;
1035    if (XPending(d))
1036      return ECORE_CALLBACK_RENEW;
1037
1038    return ECORE_CALLBACK_CANCEL;
1039 }
1040
1041 static int
1042 _ecore_x_key_mask_get(KeySym sym)
1043 {
1044    XModifierKeymap *mod;
1045    KeySym sym2;
1046    int i, j;
1047    const int masks[8] =
1048    {
1049       ShiftMask, LockMask, ControlMask,
1050       Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
1051    };
1052
1053    mod = XGetModifierMapping(_ecore_x_disp);
1054    if ((mod) && (mod->max_keypermod > 0))
1055      for (i = 0; i < (8 * mod->max_keypermod); i++)
1056        {
1057           for (j = 0; j < 8; j++)
1058             {
1059                sym2 = XKeycodeToKeysym(_ecore_x_disp, mod->modifiermap[i], j);
1060                if (sym2 != 0)
1061                  break;
1062             }
1063           if (sym2 == sym)
1064             {
1065                int mask;
1066
1067                mask = masks[i / mod->max_keypermod];
1068                if (mod->modifiermap)
1069                  XFree(mod->modifiermap);
1070
1071                XFree(mod);
1072                return mask;
1073             }
1074        }
1075
1076    if (mod)
1077      {
1078         if (mod->modifiermap)
1079           XFree(mod->modifiermap);
1080
1081         XFree(mod);
1082      }
1083
1084    return 0;
1085 }
1086
1087 /*****************************************************************************/
1088 /*****************************************************************************/
1089 /*****************************************************************************/
1090 /* FIXME: these funcs need categorising */
1091 /*****************************************************************************/
1092
1093 /**
1094  * Get a list of all the root windows on the server.
1095  *
1096  * @note   The returned array will need to be freed after use.
1097  * @param  num_ret Pointer to integer to put number of windows returned in.
1098  * @return An array of all the root windows.  @c NULL is returned if memory
1099  *         could not be allocated for the list, or if @p num_ret is @c NULL.
1100  */
1101 EAPI Ecore_X_Window *
1102 ecore_x_window_root_list(int *num_ret)
1103 {
1104    int num, i;
1105    Ecore_X_Window *roots;
1106 #ifdef ECORE_XPRINT
1107    int xp_base, xp_err_base;
1108 #endif /* ifdef ECORE_XPRINT */
1109
1110    if (!num_ret)
1111      return NULL;
1112
1113    *num_ret = 0;
1114
1115    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1116 #ifdef ECORE_XPRINT
1117    num = ScreenCount(_ecore_x_disp);
1118    if (XpQueryExtension(_ecore_x_disp, &xp_base, &xp_err_base))
1119      {
1120         Screen **ps = NULL;
1121         int psnum = 0;
1122
1123         ps = XpQueryScreens(_ecore_x_disp, &psnum);
1124         if (ps)
1125           {
1126              int overlap, j;
1127
1128              overlap = 0;
1129              for (i = 0; i < num; i++)
1130                {
1131                   for (j = 0; j < psnum; j++)
1132                     {
1133                        if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
1134                          overlap++;
1135                     }
1136                }
1137              roots = malloc(MAX((num - overlap) * sizeof(Window), 1));
1138              if (roots)
1139                {
1140                   int k;
1141
1142                   k = 0;
1143                   for (i = 0; i < num; i++)
1144                     {
1145                        int is_print;
1146
1147                        is_print = 0;
1148                        for (j = 0; j < psnum; j++)
1149                          {
1150                             if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
1151                               {
1152                                  is_print = 1;
1153                                  break;
1154                               }
1155                          }
1156                        if (!is_print)
1157                          {
1158                             roots[k] = RootWindow(_ecore_x_disp, i);
1159                             k++;
1160                          }
1161                     }
1162                   *num_ret = k;
1163                }
1164
1165              XFree(ps);
1166           }
1167         else
1168           {
1169              roots = malloc(num * sizeof(Window));
1170              if (!roots)
1171                return NULL;
1172
1173              *num_ret = num;
1174              for (i = 0; i < num; i++)
1175                roots[i] = RootWindow(_ecore_x_disp, i);
1176           }
1177      }
1178    else
1179      {
1180         roots = malloc(num * sizeof(Window));
1181         if (!roots)
1182           return NULL;
1183
1184         *num_ret = num;
1185         for (i = 0; i < num; i++)
1186           roots[i] = RootWindow(_ecore_x_disp, i);
1187      }
1188
1189 #else /* ifdef ECORE_XPRINT */
1190    num = ScreenCount(_ecore_x_disp);
1191    roots = malloc(num * sizeof(Window));
1192    if (!roots)
1193      return NULL;
1194
1195    *num_ret = num;
1196    for (i = 0; i < num; i++)
1197      roots[i] = RootWindow(_ecore_x_disp, i);
1198 #endif /* ifdef ECORE_XPRINT */
1199    return roots;
1200 }
1201
1202 EAPI Ecore_X_Window
1203 ecore_x_window_root_first_get(void)
1204 {
1205    return RootWindow(_ecore_x_disp, 0);
1206 /*
1207    int num;
1208    Ecore_X_Window root, *roots = NULL;
1209
1210    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1211    roots = ecore_x_window_root_list(&num);
1212    if (!(roots)) return 0;
1213
1214    if (num > 0)
1215      root = roots[0];
1216    else
1217      root = 0;
1218
1219    free(roots);
1220    return root;
1221  */
1222 }
1223
1224 static void _ecore_x_window_manage_error(void *data);
1225
1226 static int _ecore_x_window_manage_failed = 0;
1227 static void
1228 _ecore_x_window_manage_error(void *data __UNUSED__)
1229 {
1230    if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) &&
1231        (ecore_x_error_code_get() == BadAccess))
1232      _ecore_x_window_manage_failed = 1;
1233 }
1234
1235 EAPI Eina_Bool
1236 ecore_x_window_manage(Ecore_X_Window win)
1237 {
1238    XWindowAttributes att;
1239
1240    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1241    if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True)
1242      return EINA_FALSE;
1243
1244    ecore_x_sync();
1245    _ecore_x_window_manage_failed = 0;
1246    ecore_x_error_handler_set(_ecore_x_window_manage_error, NULL);
1247    XSelectInput(_ecore_x_disp, win,
1248                 EnterWindowMask |
1249                 LeaveWindowMask |
1250                 PropertyChangeMask |
1251                 ResizeRedirectMask |
1252                 SubstructureRedirectMask |
1253                 SubstructureNotifyMask |
1254                 StructureNotifyMask |
1255                 KeyPressMask |
1256                 KeyReleaseMask |
1257                 att.your_event_mask);
1258    ecore_x_sync();
1259    ecore_x_error_handler_set(NULL, NULL);
1260    if (_ecore_x_window_manage_failed)
1261      {
1262         _ecore_x_window_manage_failed = 0;
1263         return EINA_FALSE;
1264      }
1265
1266    return EINA_TRUE;
1267 }
1268
1269 EAPI void
1270 ecore_x_window_container_manage(Ecore_X_Window win)
1271 {
1272    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1273    XSelectInput(_ecore_x_disp, win,
1274                 SubstructureRedirectMask |
1275                 SubstructureNotifyMask);
1276 }
1277
1278 EAPI void
1279 ecore_x_window_client_manage(Ecore_X_Window win)
1280 {
1281    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1282    XSelectInput(_ecore_x_disp, win,
1283                 PropertyChangeMask |
1284 //              ResizeRedirectMask |
1285                 FocusChangeMask |
1286                 ColormapChangeMask |
1287                 VisibilityChangeMask |
1288                 StructureNotifyMask |
1289                 SubstructureNotifyMask
1290                 );
1291    XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1292 }
1293
1294 EAPI void
1295 ecore_x_window_sniff(Ecore_X_Window win)
1296 {
1297    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1298    XSelectInput(_ecore_x_disp, win,
1299                 PropertyChangeMask |
1300                 SubstructureNotifyMask);
1301 }
1302
1303 EAPI void
1304 ecore_x_window_client_sniff(Ecore_X_Window win)
1305 {
1306    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1307    XSelectInput(_ecore_x_disp, win,
1308                 PropertyChangeMask |
1309                 FocusChangeMask |
1310                 ColormapChangeMask |
1311                 VisibilityChangeMask |
1312                 StructureNotifyMask |
1313                 SubstructureNotifyMask);
1314    XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1315 }
1316
1317 EAPI Eina_Bool
1318 ecore_x_window_attributes_get(Ecore_X_Window win,
1319                               Ecore_X_Window_Attributes *att_ret)
1320 {
1321    XWindowAttributes att;
1322
1323    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1324    if (!XGetWindowAttributes(_ecore_x_disp, win, &att))
1325      return EINA_FALSE;
1326
1327    memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
1328    att_ret->root = att.root;
1329    att_ret->x = att.x;
1330    att_ret->y = att.y;
1331    att_ret->w = att.width;
1332    att_ret->h = att.height;
1333    att_ret->border = att.border_width;
1334    att_ret->depth = att.depth;
1335    if (att.map_state != IsUnmapped)
1336      att_ret->visible = 1;
1337
1338    if (att.map_state == IsViewable)
1339      att_ret->viewable = 1;
1340
1341    if (att.override_redirect)
1342      att_ret->override = 1;
1343
1344    if (att.class == InputOnly)
1345      att_ret->input_only = 1;
1346
1347    if (att.save_under)
1348      att_ret->save_under = 1;
1349
1350    att_ret->event_mask.mine = att.your_event_mask;
1351    att_ret->event_mask.all = att.all_event_masks;
1352    att_ret->event_mask.no_propagate = att.do_not_propagate_mask;
1353    att_ret->window_gravity = att.win_gravity;
1354    att_ret->pixel_gravity = att.bit_gravity;
1355    att_ret->colormap = att.colormap;
1356    att_ret->visual = att.visual;
1357    return EINA_TRUE;
1358 }
1359
1360 EAPI void
1361 ecore_x_window_save_set_add(Ecore_X_Window win)
1362 {
1363    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1364    XAddToSaveSet(_ecore_x_disp, win);
1365 }
1366
1367 EAPI void
1368 ecore_x_window_save_set_del(Ecore_X_Window win)
1369 {
1370    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1371    XRemoveFromSaveSet(_ecore_x_disp, win);
1372 }
1373
1374 EAPI Ecore_X_Window *
1375 ecore_x_window_children_get(Ecore_X_Window win,
1376                             int *num)
1377 {
1378    Ecore_X_Window *windows = NULL;
1379    Window root_ret = 0, parent_ret = 0, *children_ret = NULL;
1380    unsigned int children_ret_num = 0;
1381
1382    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1383    if (!XQueryTree(_ecore_x_disp, win, &root_ret, &parent_ret, &children_ret,
1384                    &children_ret_num))
1385      return NULL;
1386
1387    if (children_ret)
1388      {
1389         windows = malloc(children_ret_num * sizeof(Ecore_X_Window));
1390         if (windows)
1391           {
1392              unsigned int i;
1393
1394              for (i = 0; i < children_ret_num; i++)
1395                windows[i] = children_ret[i];
1396              *num = children_ret_num;
1397           }
1398
1399         XFree(children_ret);
1400      }
1401
1402    return windows;
1403 }
1404
1405 EAPI Eina_Bool
1406 ecore_x_pointer_control_set(int accel_num,
1407                             int accel_denom,
1408                             int threshold)
1409 {
1410    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1411    return XChangePointerControl(_ecore_x_disp, 1, 1,
1412                                 accel_num, accel_denom, threshold) ? EINA_TRUE : EINA_FALSE;
1413 }
1414
1415 EAPI Eina_Bool
1416 ecore_x_pointer_control_get(int *accel_num,
1417                             int *accel_denom,
1418                             int *threshold)
1419 {
1420    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1421    return XGetPointerControl(_ecore_x_disp,
1422                              accel_num, accel_denom, threshold) ? EINA_TRUE : EINA_FALSE;
1423 }
1424
1425 EAPI Eina_Bool
1426 ecore_x_pointer_mapping_set(unsigned char *map,
1427                             int nmap)
1428 {
1429    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1430    return (XSetPointerMapping(_ecore_x_disp, map, nmap) == MappingSuccess) ? EINA_TRUE : EINA_FALSE;
1431 }
1432
1433 EAPI Eina_Bool
1434 ecore_x_pointer_mapping_get(unsigned char *map,
1435                             int nmap)
1436 {
1437    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1438    return XGetPointerMapping(_ecore_x_disp, map, nmap) ? EINA_TRUE : EINA_FALSE;
1439 }
1440
1441 EAPI Eina_Bool
1442 ecore_x_pointer_grab(Ecore_X_Window win)
1443 {
1444    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1445    if (XGrabPointer(_ecore_x_disp, win, False,
1446                     ButtonPressMask | ButtonReleaseMask |
1447                     EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1448                     GrabModeAsync, GrabModeAsync,
1449                     None, None, CurrentTime) == GrabSuccess)
1450      return EINA_TRUE;
1451
1452    return EINA_FALSE;
1453 }
1454
1455 EAPI Eina_Bool
1456 ecore_x_pointer_confine_grab(Ecore_X_Window win)
1457 {
1458    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1459    if (XGrabPointer(_ecore_x_disp, win, False,
1460                     ButtonPressMask | ButtonReleaseMask |
1461                     EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1462                     GrabModeAsync, GrabModeAsync,
1463                     win, None, CurrentTime) == GrabSuccess)
1464      return EINA_TRUE;
1465
1466    return EINA_FALSE;
1467 }
1468
1469 EAPI void
1470 ecore_x_pointer_ungrab(void)
1471 {
1472    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1473    XUngrabPointer(_ecore_x_disp, CurrentTime);
1474 }
1475
1476 EAPI Eina_Bool
1477 ecore_x_pointer_warp(Ecore_X_Window win,
1478                      int x,
1479                      int y)
1480 {
1481    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1482    return XWarpPointer(_ecore_x_disp, None, win, 0, 0, 0, 0, x, y) ? EINA_TRUE : EINA_FALSE;
1483 }
1484
1485 EAPI Eina_Bool
1486 ecore_x_keyboard_grab(Ecore_X_Window win)
1487 {
1488    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1489    if (XGrabKeyboard(_ecore_x_disp, win, False,
1490                      GrabModeAsync, GrabModeAsync,
1491                      CurrentTime) == GrabSuccess)
1492      return EINA_TRUE;
1493
1494    return EINA_FALSE;
1495 }
1496
1497 EAPI void
1498 ecore_x_keyboard_ungrab(void)
1499 {
1500    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1501    XUngrabKeyboard(_ecore_x_disp, CurrentTime);
1502 }
1503
1504 EAPI void
1505 ecore_x_grab(void)
1506 {
1507    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1508    _ecore_x_grab_count++;
1509    if (_ecore_x_grab_count == 1)
1510      XGrabServer(_ecore_x_disp);
1511 }
1512
1513 EAPI void
1514 ecore_x_ungrab(void)
1515 {
1516    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1517    _ecore_x_grab_count--;
1518    if (_ecore_x_grab_count < 0)
1519      _ecore_x_grab_count = 0;
1520
1521    if (_ecore_x_grab_count == 0)
1522      XUngrabServer(_ecore_x_disp);
1523 }
1524
1525 int _ecore_window_grabs_num = 0;
1526 Window *_ecore_window_grabs = NULL;
1527 Eina_Bool (*_ecore_window_grab_replay_func)(void *data,
1528                                             int event_type,
1529                                             void *event);
1530 void *_ecore_window_grab_replay_data;
1531
1532 EAPI void
1533 ecore_x_passive_grab_replay_func_set(Eina_Bool (*func)(void *data,
1534                                                        int event_type,
1535                                                        void *event),
1536                                      void *data)
1537 {
1538    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1539    _ecore_window_grab_replay_func = func;
1540    _ecore_window_grab_replay_data = data;
1541 }
1542
1543 EAPI void
1544 ecore_x_window_button_grab(Ecore_X_Window win,
1545                            int button,
1546                            Ecore_X_Event_Mask event_mask,
1547                            int mod,
1548                            int any_mod)
1549 {
1550    unsigned int b;
1551    unsigned int m;
1552    unsigned int locks[8];
1553    int i, ev;
1554    Window *t;
1555
1556    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1557    b = button;
1558    if (b == 0)
1559      b = AnyButton;
1560
1561    m = _ecore_x_event_modifier(mod);
1562    if (any_mod)
1563      m = AnyModifier;
1564
1565    locks[0] = 0;
1566    locks[1] = ECORE_X_LOCK_CAPS;
1567    locks[2] = ECORE_X_LOCK_NUM;
1568    locks[3] = ECORE_X_LOCK_SCROLL;
1569    locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1570    locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1571    locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1572    locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1573    ev = event_mask;
1574    for (i = 0; i < 8; i++)
1575      XGrabButton(_ecore_x_disp, b, m | locks[i],
1576                  win, False, ev, GrabModeSync, GrabModeAsync, None, None);
1577    _ecore_window_grabs_num++;
1578    t = realloc(_ecore_window_grabs,
1579                _ecore_window_grabs_num * sizeof(Window));
1580    if (!t) return;
1581    _ecore_window_grabs = t;
1582    _ecore_window_grabs[_ecore_window_grabs_num - 1] = win;
1583 }
1584
1585 void
1586 _ecore_x_sync_magic_send(int val,
1587                          Ecore_X_Window swin)
1588 {
1589    XEvent xev;
1590
1591    xev.xclient.type = ClientMessage;
1592    xev.xclient.serial = 0;
1593    xev.xclient.send_event = True;
1594    xev.xclient.display = _ecore_x_disp;
1595    xev.xclient.window = _ecore_x_private_win;
1596    xev.xclient.format = 32;
1597    xev.xclient.message_type = 27777;
1598    xev.xclient.data.l[0] = 0x7162534;
1599    xev.xclient.data.l[1] = 0x10000000 + val;
1600    xev.xclient.data.l[2] = swin;
1601    XSendEvent(_ecore_x_disp, _ecore_x_private_win, False, NoEventMask, &xev);
1602 }
1603
1604 void
1605 _ecore_x_window_grab_remove(Ecore_X_Window win)
1606 {
1607    int i, shuffle = 0;
1608    Window *t;
1609
1610    if (_ecore_window_grabs_num > 0)
1611      {
1612         for (i = 0; i < _ecore_window_grabs_num; i++)
1613           {
1614              if (shuffle)
1615                _ecore_window_grabs[i - 1] = _ecore_window_grabs[i];
1616
1617              if ((!shuffle) && (_ecore_window_grabs[i] == win))
1618                shuffle = 1;
1619           }
1620         if (shuffle)
1621           {
1622              _ecore_window_grabs_num--;
1623              if (_ecore_window_grabs_num <= 0)
1624                {
1625                   free(_ecore_window_grabs);
1626                   _ecore_window_grabs = NULL;
1627                   return;
1628                }
1629              t = realloc(_ecore_window_grabs,
1630                          _ecore_window_grabs_num *
1631                          sizeof(Window));
1632              if (!t) return;
1633              _ecore_window_grabs = t;
1634           }
1635      }
1636 }
1637
1638 EAPI void
1639 ecore_x_window_button_ungrab(Ecore_X_Window win,
1640                              int button,
1641                              int mod,
1642                              int any_mod)
1643 {
1644    unsigned int b;
1645    unsigned int m;
1646    unsigned int locks[8];
1647    int i;
1648
1649    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1650    b = button;
1651    if (b == 0)
1652      b = AnyButton;
1653
1654    m = _ecore_x_event_modifier(mod);
1655    if (any_mod)
1656      m = AnyModifier;
1657
1658    locks[0] = 0;
1659    locks[1] = ECORE_X_LOCK_CAPS;
1660    locks[2] = ECORE_X_LOCK_NUM;
1661    locks[3] = ECORE_X_LOCK_SCROLL;
1662    locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1663    locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1664    locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1665    locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1666    for (i = 0; i < 8; i++)
1667      XUngrabButton(_ecore_x_disp, b, m | locks[i], win);
1668    _ecore_x_sync_magic_send(1, win);
1669 }
1670
1671 int _ecore_key_grabs_num = 0;
1672 Window *_ecore_key_grabs = NULL;
1673
1674 EAPI void
1675 ecore_x_window_key_grab(Ecore_X_Window win,
1676                         const char *key,
1677                         int mod,
1678                         int any_mod)
1679 {
1680    KeyCode keycode = 0;
1681    KeySym keysym;
1682    unsigned int m;
1683    unsigned int locks[8];
1684    int i;
1685    Window *t;
1686
1687    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1688    if (!strncmp(key, "Keycode-", 8))
1689      keycode = atoi(key + 8);
1690    else
1691      {
1692         keysym = XStringToKeysym(key);
1693         if (keysym == NoSymbol)
1694           return;
1695
1696         keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
1697      }
1698
1699    if (keycode == 0)
1700      return;
1701
1702    m = _ecore_x_event_modifier(mod);
1703    if (any_mod)
1704      m = AnyModifier;
1705
1706    locks[0] = 0;
1707    locks[1] = ECORE_X_LOCK_CAPS;
1708    locks[2] = ECORE_X_LOCK_NUM;
1709    locks[3] = ECORE_X_LOCK_SCROLL;
1710    locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1711    locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1712    locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1713    locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1714    for (i = 0; i < 8; i++)
1715      XGrabKey(_ecore_x_disp, keycode, m | locks[i],
1716               win, False, GrabModeSync, GrabModeAsync);
1717    _ecore_key_grabs_num++;
1718    t = realloc(_ecore_key_grabs,
1719                _ecore_key_grabs_num * sizeof(Window));
1720    if (!t) return;
1721    _ecore_key_grabs = t;
1722    _ecore_key_grabs[_ecore_key_grabs_num - 1] = win;
1723 }
1724
1725 void
1726 _ecore_x_key_grab_remove(Ecore_X_Window win)
1727 {
1728    int i, shuffle = 0;
1729    Window *t;
1730
1731    if (_ecore_key_grabs_num > 0)
1732      {
1733         for (i = 0; i < _ecore_key_grabs_num; i++)
1734           {
1735              if (shuffle)
1736                _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
1737
1738              if ((!shuffle) && (_ecore_key_grabs[i] == win))
1739                shuffle = 1;
1740           }
1741         if (shuffle)
1742           {
1743              _ecore_key_grabs_num--;
1744              if (_ecore_key_grabs_num <= 0)
1745                {
1746                   free(_ecore_key_grabs);
1747                   _ecore_key_grabs = NULL;
1748                   return;
1749                }
1750              t = realloc(_ecore_key_grabs,
1751                          _ecore_key_grabs_num * sizeof(Window));
1752              if (!t) return;
1753              _ecore_key_grabs = t;
1754           }
1755      }
1756 }
1757
1758 EAPI void
1759 ecore_x_window_key_ungrab(Ecore_X_Window win,
1760                           const char *key,
1761                           int mod,
1762                           int any_mod)
1763 {
1764    KeyCode keycode = 0;
1765    KeySym keysym;
1766    unsigned int m;
1767    unsigned int locks[8];
1768    int i;
1769
1770    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1771    if (!strncmp(key, "Keycode-", 8))
1772      keycode = atoi(key + 8);
1773    else
1774      {
1775         keysym = XStringToKeysym(key);
1776         if (keysym == NoSymbol)
1777           return;
1778
1779         keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
1780      }
1781
1782    if (keycode == 0)
1783      return;
1784
1785    m = _ecore_x_event_modifier(mod);
1786    if (any_mod)
1787      m = AnyModifier;
1788
1789    locks[0] = 0;
1790    locks[1] = ECORE_X_LOCK_CAPS;
1791    locks[2] = ECORE_X_LOCK_NUM;
1792    locks[3] = ECORE_X_LOCK_SCROLL;
1793    locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1794    locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1795    locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1796    locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1797    for (i = 0; i < 8; i++)
1798      XUngrabKey(_ecore_x_disp, keycode, m | locks[i], win);
1799    _ecore_x_sync_magic_send(2, win);
1800 }
1801
1802 /**
1803  * Send client message with given type and format 32.
1804  *
1805  * @param win     The window the message is sent to.
1806  * @param type    The client message type.
1807  * @param mask    The mask of the message to be sent.
1808  * @param d0      The client message data item 1
1809  * @param d1      The client message data item 2
1810  * @param d2      The client message data item 3
1811  * @param d3      The client message data item 4
1812  * @param d4      The client message data item 5
1813  *
1814  * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
1815  */
1816 EAPI Eina_Bool
1817 ecore_x_client_message32_send(Ecore_X_Window win,
1818                               Ecore_X_Atom type,
1819                               Ecore_X_Event_Mask mask,
1820                               long d0,
1821                               long d1,
1822                               long d2,
1823                               long d3,
1824                               long d4)
1825 {
1826    XEvent xev;
1827
1828    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1829    xev.xclient.window = win;
1830    xev.xclient.type = ClientMessage;
1831    xev.xclient.message_type = type;
1832    xev.xclient.format = 32;
1833    xev.xclient.data.l[0] = d0;
1834    xev.xclient.data.l[1] = d1;
1835    xev.xclient.data.l[2] = d2;
1836    xev.xclient.data.l[3] = d3;
1837    xev.xclient.data.l[4] = d4;
1838
1839    return XSendEvent(_ecore_x_disp, win, False, mask, &xev) ? EINA_TRUE : EINA_FALSE;
1840 }
1841
1842 /**
1843  * Send client message with given type and format 8.
1844  *
1845  * @param win     The window the message is sent to.
1846  * @param type    The client message type.
1847  * @param data    Data to be sent.
1848  * @param len     Number of data bytes, max @c 20.
1849  *
1850  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1851  */
1852 EAPI Eina_Bool
1853 ecore_x_client_message8_send(Ecore_X_Window win,
1854                              Ecore_X_Atom type,
1855                              const void *data,
1856                              int len)
1857 {
1858    XEvent xev;
1859
1860    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1861    xev.xclient.window = win;
1862    xev.xclient.type = ClientMessage;
1863    xev.xclient.message_type = type;
1864    xev.xclient.format = 8;
1865    if (len > 20)
1866      len = 20;
1867
1868    memcpy(xev.xclient.data.b, data, len);
1869    memset(xev.xclient.data.b + len, 0, 20 - len);
1870
1871    return XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev) ? EINA_TRUE : EINA_FALSE;
1872 }
1873
1874 EAPI Eina_Bool
1875 ecore_x_mouse_move_send(Ecore_X_Window win,
1876                         int x,
1877                         int y)
1878 {
1879    XEvent xev;
1880    XWindowAttributes att;
1881    Window tw;
1882    int rx, ry;
1883
1884    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1885    XGetWindowAttributes(_ecore_x_disp, win, &att);
1886    XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1887    xev.xmotion.type = MotionNotify;
1888    xev.xmotion.window = win;
1889    xev.xmotion.root = att.root;
1890    xev.xmotion.subwindow = win;
1891    xev.xmotion.time = _ecore_x_event_last_time;
1892    xev.xmotion.x = x;
1893    xev.xmotion.y = y;
1894    xev.xmotion.x_root = rx;
1895    xev.xmotion.y_root = ry;
1896    xev.xmotion.state = 0;
1897    xev.xmotion.is_hint = 0;
1898    xev.xmotion.same_screen = 1;
1899    return XSendEvent(_ecore_x_disp, win, True, PointerMotionMask, &xev) ? EINA_TRUE : EINA_FALSE;
1900 }
1901
1902 EAPI Eina_Bool
1903 ecore_x_mouse_down_send(Ecore_X_Window win,
1904                         int x,
1905                         int y,
1906                         int b)
1907 {
1908    XEvent xev;
1909    XWindowAttributes att;
1910    Window tw;
1911    int rx, ry;
1912
1913    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1914    XGetWindowAttributes(_ecore_x_disp, win, &att);
1915    XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1916    xev.xbutton.type = ButtonPress;
1917    xev.xbutton.window = win;
1918    xev.xbutton.root = att.root;
1919    xev.xbutton.subwindow = win;
1920    xev.xbutton.time = _ecore_x_event_last_time;
1921    xev.xbutton.x = x;
1922    xev.xbutton.y = y;
1923    xev.xbutton.x_root = rx;
1924    xev.xbutton.y_root = ry;
1925    xev.xbutton.state = 1 << b;
1926    xev.xbutton.button = b;
1927    xev.xbutton.same_screen = 1;
1928    return XSendEvent(_ecore_x_disp, win, True, ButtonPressMask, &xev) ? EINA_TRUE : EINA_FALSE;
1929 }
1930
1931 EAPI Eina_Bool
1932 ecore_x_mouse_up_send(Ecore_X_Window win,
1933                       int x,
1934                       int y,
1935                       int b)
1936 {
1937    XEvent xev;
1938    XWindowAttributes att;
1939    Window tw;
1940    int rx, ry;
1941
1942    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1943    XGetWindowAttributes(_ecore_x_disp, win, &att);
1944    XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1945    xev.xbutton.type = ButtonRelease;
1946    xev.xbutton.window = win;
1947    xev.xbutton.root = att.root;
1948    xev.xbutton.subwindow = win;
1949    xev.xbutton.time = _ecore_x_event_last_time;
1950    xev.xbutton.x = x;
1951    xev.xbutton.y = y;
1952    xev.xbutton.x_root = rx;
1953    xev.xbutton.y_root = ry;
1954    xev.xbutton.state = 0;
1955    xev.xbutton.button = b;
1956    xev.xbutton.same_screen = 1;
1957    return XSendEvent(_ecore_x_disp, win, True, ButtonReleaseMask, &xev) ? EINA_TRUE : EINA_FALSE;
1958 }
1959
1960 EAPI Eina_Bool
1961 ecore_x_mouse_in_send(Ecore_X_Window win,
1962                       int x,
1963                       int y)
1964 {
1965    XEvent xev;
1966    XWindowAttributes att;
1967    Window tw;
1968    int rx, ry;
1969
1970    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1971    XGetWindowAttributes(_ecore_x_disp, win, &att);
1972    XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1973    xev.xcrossing.type = EnterNotify;
1974    xev.xcrossing.window = win;
1975    xev.xcrossing.root = att.root;
1976    xev.xcrossing.subwindow = win;
1977    xev.xcrossing.time = _ecore_x_event_last_time;
1978    xev.xcrossing.x = x;
1979    xev.xcrossing.y = y;
1980    xev.xcrossing.x_root = rx;
1981    xev.xcrossing.y_root = ry;
1982    xev.xcrossing.mode = NotifyNormal;
1983    xev.xcrossing.detail = NotifyNonlinear;
1984    xev.xcrossing.same_screen = 1;
1985    xev.xcrossing.focus = 0;
1986    xev.xcrossing.state = 0;
1987    return XSendEvent(_ecore_x_disp, win, True, EnterWindowMask, &xev) ? EINA_TRUE : EINA_FALSE;
1988 }
1989
1990 EAPI Eina_Bool
1991 ecore_x_mouse_out_send(Ecore_X_Window win,
1992                       int x,
1993                       int y)
1994 {
1995    XEvent xev;
1996    XWindowAttributes att;
1997    Window tw;
1998    int rx, ry;
1999
2000    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2001    XGetWindowAttributes(_ecore_x_disp, win, &att);
2002    XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
2003    xev.xcrossing.type = LeaveNotify;
2004    xev.xcrossing.window = win;
2005    xev.xcrossing.root = att.root;
2006    xev.xcrossing.subwindow = win;
2007    xev.xcrossing.time = _ecore_x_event_last_time;
2008    xev.xcrossing.x = x;
2009    xev.xcrossing.y = y;
2010    xev.xcrossing.x_root = rx;
2011    xev.xcrossing.y_root = ry;
2012    xev.xcrossing.mode = NotifyNormal;
2013    xev.xcrossing.detail = NotifyNonlinear;
2014    xev.xcrossing.same_screen = 1;
2015    xev.xcrossing.focus = 0;
2016    xev.xcrossing.state = 0;
2017    return XSendEvent(_ecore_x_disp, win, True, LeaveWindowMask, &xev) ? EINA_TRUE : EINA_FALSE;
2018 }
2019
2020 EAPI void
2021 ecore_x_focus_reset(void)
2022 {
2023    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2024    XSetInputFocus(_ecore_x_disp, PointerRoot, RevertToPointerRoot, CurrentTime);
2025 }
2026
2027 EAPI void
2028 ecore_x_events_allow_all(void)
2029 {
2030    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2031    XAllowEvents(_ecore_x_disp, AsyncBoth, CurrentTime);
2032 }
2033
2034 EAPI void
2035 ecore_x_pointer_last_xy_get(int *x,
2036                             int *y)
2037 {
2038    if (x)
2039      *x = _ecore_x_event_last_root_x;
2040
2041    if (y)
2042      *y = _ecore_x_event_last_root_y;
2043 }
2044
2045 EAPI void
2046 ecore_x_pointer_xy_get(Ecore_X_Window win,
2047                        int *x,
2048                        int *y)
2049 {
2050    Window rwin, cwin;
2051    int rx, ry, wx, wy, ret;
2052    unsigned int mask;
2053
2054    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2055    ret = XQueryPointer(_ecore_x_disp, win, &rwin, &cwin,
2056                        &rx, &ry, &wx, &wy, &mask);
2057    if (!ret)
2058      wx = wy = -1;
2059
2060    if (x) *x = wx;
2061    if (y) *y = wy;
2062 }
2063
2064 /**
2065  * Retrieve the Visual ID from a given Visual.
2066  *
2067  * @param visual  The Visual to get the ID for.
2068  *
2069  * @return The visual id.
2070  * @since 1.1.0
2071  */
2072 EAPI unsigned int
2073 ecore_x_visual_id_get(Ecore_X_Visual visual)
2074 {
2075    return XVisualIDFromVisual(visual);
2076 }
2077
2078 /**
2079  * Retrieve the default Visual.
2080  *
2081  * @param disp  The Display to get the Default Visual from
2082  * @param screen The Screen.
2083  *
2084  * @return The default visual.
2085  * @since 1.1.0
2086  */
2087 EAPI Ecore_X_Visual
2088 ecore_x_default_visual_get(Ecore_X_Display *disp,
2089                            Ecore_X_Screen *screen)
2090 {
2091    return DefaultVisual(disp, ecore_x_screen_index_get(screen));
2092 }
2093
2094 /**
2095  * Retrieve the default Colormap.
2096  *
2097  * @param disp  The Display to get the Default Colormap from
2098  * @param screen The Screen.
2099  *
2100  * @return The default colormap.
2101  * @since 1.1.0
2102  */
2103 EAPI Ecore_X_Colormap
2104 ecore_x_default_colormap_get(Ecore_X_Display *disp,
2105                              Ecore_X_Screen *screen)
2106 {
2107    return DefaultColormap(disp, ecore_x_screen_index_get(screen));
2108 }
2109
2110 /**
2111  * Retrieve the default depth.
2112  *
2113  * @param disp  The Display to get the Default Depth from
2114  * @param screen The Screen.
2115  *
2116  * @return The default depth.
2117  * @since 1.1.0
2118  */
2119 EAPI int
2120 ecore_x_default_depth_get(Ecore_X_Display *disp,
2121                           Ecore_X_Screen *screen)
2122 {
2123    return DefaultDepth(disp, ecore_x_screen_index_get(screen));
2124 }
2125
2126 /*****************************************************************************/
2127 /*****************************************************************************/
2128 /*****************************************************************************/
2129
2130 static int
2131 _ecore_x_event_modifier(unsigned int state)
2132 {
2133    int xmodifiers = 0;
2134
2135    if (state & ECORE_EVENT_MODIFIER_SHIFT)
2136      xmodifiers |= ECORE_X_MODIFIER_SHIFT;
2137
2138    if (state & ECORE_EVENT_MODIFIER_CTRL)
2139      xmodifiers |= ECORE_X_MODIFIER_CTRL;
2140
2141    if (state & ECORE_EVENT_MODIFIER_ALT)
2142      xmodifiers |= ECORE_X_MODIFIER_ALT;
2143
2144    if (state & ECORE_EVENT_MODIFIER_WIN)
2145      xmodifiers |= ECORE_X_MODIFIER_WIN;
2146
2147    if (state & ECORE_EVENT_LOCK_SCROLL)
2148      xmodifiers |= ECORE_X_LOCK_SCROLL;
2149
2150    if (state & ECORE_EVENT_LOCK_NUM)
2151      xmodifiers |= ECORE_X_LOCK_NUM;
2152
2153    if (state & ECORE_EVENT_LOCK_CAPS)
2154      xmodifiers |= ECORE_X_LOCK_CAPS;
2155
2156    if (state & ECORE_EVENT_LOCK_SHIFT)
2157      xmodifiers |= ECORE_X_LOCK_SHIFT;
2158
2159    return xmodifiers;
2160 }
2161