svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_x / xlib / ecore_x.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12
13 //#define LOGRT 1
14
15 #ifdef LOGRT
16 #include <dlfcn.h>
17 #endif
18
19 #include "Ecore.h"
20 #include "ecore_private.h"
21 #include "ecore_x_private.h"
22 #include "Ecore_X.h"
23 #include "Ecore_X_Atoms.h"
24 #include "Ecore_Input.h"
25
26 static int _ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
27 static int _ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler);
28 static int _ecore_x_key_mask_get(KeySym sym);
29 static int _ecore_x_event_modifier(unsigned int state);
30
31 static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL;
32
33 static const int AnyXEvent = 0; /* 0 can be used as there are no event types
34                                  * with index 0 and 1 as they are used for
35                                  * errors
36                                  */
37
38 static int _ecore_x_event_shape_id = 0;
39 static int _ecore_x_event_screensaver_id = 0;
40 static int _ecore_x_event_sync_id = 0;
41 int _ecore_xlib_log_dom = -1;
42
43 #ifdef ECORE_XRANDR
44 static int _ecore_x_event_randr_id = 0;
45 #endif
46 #ifdef ECORE_XFIXES
47 static int _ecore_x_event_fixes_selection_id = 0;
48 #endif
49 #ifdef ECORE_XDAMAGE
50 static int _ecore_x_event_damage_id = 0;
51 #endif
52 static int _ecore_x_event_handlers_num = 0;
53 static void (**_ecore_x_event_handlers) (XEvent * event) = NULL;
54
55 static int _ecore_x_init_count = 0;
56 static int _ecore_x_grab_count = 0;
57
58 Display *_ecore_x_disp = NULL;
59 double   _ecore_x_double_click_time = 0.25;
60 Time     _ecore_x_event_last_time = 0;
61 Window   _ecore_x_event_last_win = 0;
62 int      _ecore_x_event_last_root_x = 0;
63 int      _ecore_x_event_last_root_y = 0;
64 int      _ecore_x_xcursor = 0;
65 XIC      _ecore_x_ic = NULL; /* Input context for composed characters */
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_SELECTION_CLEAR = 0;
95 EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
96 EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
97 EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
98 EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
99 EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
100 EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0;
101 EAPI int ECORE_X_EVENT_SYNC_ALARM = 0;
102 EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0;
103 EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0;
104 EAPI int ECORE_X_EVENT_RANDR_CRTC_CHANGE = 0;
105 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = 0;
106 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = 0;
107 EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
108 /*
109 EAPI int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = 0;
110 EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = 0;
111 EAPI int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = 0;
112 EAPI int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = 0;
113 EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = 0;
114 EAPI int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = 0;
115 EAPI int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = 0;
116 EAPI int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = 0;
117 */
118
119 EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0;
120 EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0;
121 EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0;
122 EAPI int ECORE_X_EVENT_PING = 0;
123 EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0;
124
125 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0;
126 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0;
127 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0;
128
129 EAPI int ECORE_X_EVENT_GENERIC = 0;
130
131 int ECORE_X_MODIFIER_SHIFT = 0;
132 int ECORE_X_MODIFIER_CTRL = 0;
133 int ECORE_X_MODIFIER_ALT = 0;
134 int ECORE_X_MODIFIER_WIN = 0;
135
136 EAPI int ECORE_X_LOCK_SCROLL = 0;
137 EAPI int ECORE_X_LOCK_NUM = 0;
138 EAPI int ECORE_X_LOCK_CAPS = 0;
139
140 #ifdef LOGRT
141 static double t0 = 0.0;
142 static Status (*_logrt_real_reply) (Display *disp, void *rep, int extra, Bool discard) = NULL;
143 static void
144 _logrt_init(void)
145 {
146    void *lib;
147    
148    lib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
149    if (!lib) lib = dlopen("libX11.so.6", RTLD_GLOBAL | RTLD_LAZY);
150    if (!lib) lib = dlopen("libX11.so.6.3", RTLD_GLOBAL | RTLD_LAZY);
151    if (!lib) lib = dlopen("libX11.so.6.3.0", RTLD_GLOBAL | RTLD_LAZY);
152    _logrt_real_reply = dlsym(lib, "_XReply");
153    t0 = ecore_time_get();
154 }
155 Status
156 _XReply(Display *disp, void *rep, int extra, Bool discard)
157 {
158    void *bt[128];
159    int i, n;
160    char **sym;
161    
162    n = backtrace(bt, 128);
163    if (n > 0)
164      {
165         sym = backtrace_symbols(bt, n);
166         printf("ROUNDTRIP: %4.4f :", ecore_time_get() - t0);
167         if (sym)
168           {
169              for (i = n - 1; i > 0; i--)
170                {
171                   char *fname = strchr(sym[i], '(');
172                   if (fname)
173                     {
174                        char *tsym = alloca(strlen(fname) + 1);
175                        char *end;
176                        strcpy(tsym, fname + 1);
177                        end = strchr(tsym, '+');
178                        if (end)
179                          {
180                             *end = 0;
181                             printf("%s", tsym);
182                          }
183                        else
184                          printf("???");
185                     }
186                   else
187                     printf("???");
188                   if (i > 1) printf(" > ");
189                }
190              printf("\n");
191           }
192      }
193    // fixme: logme
194    return _logrt_real_reply(disp, rep, extra, discard);
195 }
196 #endif
197
198 /**
199  * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions
200  *
201  * Functions that start and shut down the Ecore X Library.
202  */
203
204 /**
205  * Initialize the X display connection to the given display.
206  *
207  * @param   name Display target name.  If @c NULL, the default display is
208  *               assumed.
209  * @return  The number of times the library has been initialized without
210  *          being shut down.  0 is returned if an error occurs.
211  * @ingroup Ecore_X_Init_Group
212  */
213 EAPI int
214 ecore_x_init(const char *name)
215 {
216    int shape_base = 0;
217    int shape_err_base = 0;
218 #ifdef ECORE_XSS
219    int screensaver_base = 0;
220    int screensaver_err_base = 0;
221 #endif
222    int sync_base = 0;
223    int sync_err_base = 0;
224 #ifdef ECORE_XRANDR
225    int randr_base = 0;
226    int randr_err_base = 0;
227 #endif
228 #ifdef ECORE_XFIXES
229    int fixes_base = 0;
230    int fixes_err_base = 0;
231 #endif
232 #ifdef ECORE_XDAMAGE
233    int damage_base = 0;
234    int damage_err_base = 0;
235 #endif
236    
237    if (++_ecore_x_init_count != 1) 
238      return _ecore_x_init_count;
239
240    LOGFN(__FILE__, __LINE__, __FUNCTION__);
241 #ifdef LOGRT
242    _logrt_init();
243 #endif   
244    
245    _ecore_xlib_log_dom = eina_log_domain_register("EcoreX11", ECORE_XLIB_DEFAULT_LOG_COLOR);
246    if(_ecore_xlib_log_dom < 0)
247      {
248        EINA_LOG_ERR("Impossible to create a log domain for the Ecore Xlib module.");
249        return --_ecore_x_init_count;
250      }
251    if (!ecore_event_init())
252      {
253        eina_log_domain_unregister(_ecore_xlib_log_dom);
254         _ecore_xlib_log_dom = -1;
255        return --_ecore_x_init_count;
256      }
257    _ecore_x_disp = XOpenDisplay((char *)name);
258    if (!_ecore_x_disp)
259      goto shutdown_ecore_event;
260
261    _ecore_x_error_handler_init();
262    _ecore_x_event_handlers_num = LASTEvent;
263
264 #define ECORE_X_EVENT_HANDLERS_GROW(ext_base, ext_num_events)           \
265    do {                                                                 \
266      if (_ecore_x_event_handlers_num < (ext_base + ext_num_events))     \
267        _ecore_x_event_handlers_num = (ext_base + ext_num_events);       \
268    } while (0)
269
270    if (XShapeQueryExtension(_ecore_x_disp, &shape_base, &shape_err_base))
271      _ecore_x_event_shape_id = shape_base;
272    ECORE_X_EVENT_HANDLERS_GROW(shape_base, ShapeNumberEvents);
273
274 #ifdef ECORE_XSS
275    if (XScreenSaverQueryExtension(_ecore_x_disp, &screensaver_base, &screensaver_err_base))
276      _ecore_x_event_screensaver_id = screensaver_base;
277    ECORE_X_EVENT_HANDLERS_GROW(screensaver_base, ScreenSaverNumberEvents);
278 #endif
279
280    if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base))
281      {
282         int major, minor;
283
284         _ecore_x_event_sync_id = sync_base;
285         if (!XSyncInitialize(_ecore_x_disp, &major, &minor))
286           _ecore_x_event_sync_id = 0;
287      }
288    ECORE_X_EVENT_HANDLERS_GROW(sync_base, XSyncNumberEvents);
289
290 #ifdef ECORE_XRANDR
291    if (XRRQueryExtension(_ecore_x_disp, &randr_base, &randr_err_base))
292      _ecore_x_event_randr_id = randr_base;
293    ECORE_X_EVENT_HANDLERS_GROW(randr_base, RRNumberEvents);
294 #endif
295
296 #ifdef ECORE_XFIXES
297    if (XFixesQueryExtension(_ecore_x_disp, &fixes_base, &fixes_err_base))
298      _ecore_x_event_fixes_selection_id = fixes_base;
299    ECORE_X_EVENT_HANDLERS_GROW(fixes_base, XFixesNumberEvents);
300 #endif
301
302 #ifdef ECORE_XDAMAGE
303    if (XDamageQueryExtension(_ecore_x_disp, &damage_base, &damage_err_base))
304      _ecore_x_event_damage_id = damage_base;
305    ECORE_X_EVENT_HANDLERS_GROW(damage_base, XDamageNumberEvents);
306 #endif
307
308    _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *));
309    if (!_ecore_x_event_handlers)
310      goto close_display;
311
312 #ifdef ECORE_XCURSOR   
313    _ecore_x_xcursor = XcursorSupportsARGB(_ecore_x_disp);
314 #endif
315    _ecore_x_event_handlers[AnyXEvent]        = _ecore_x_event_handle_any_event;
316    _ecore_x_event_handlers[KeyPress]         = _ecore_x_event_handle_key_press;
317    _ecore_x_event_handlers[KeyRelease]       = _ecore_x_event_handle_key_release;
318    _ecore_x_event_handlers[ButtonPress]      = _ecore_x_event_handle_button_press;
319    _ecore_x_event_handlers[ButtonRelease]    = _ecore_x_event_handle_button_release;
320    _ecore_x_event_handlers[MotionNotify]     = _ecore_x_event_handle_motion_notify;
321    _ecore_x_event_handlers[EnterNotify]      = _ecore_x_event_handle_enter_notify;
322    _ecore_x_event_handlers[LeaveNotify]      = _ecore_x_event_handle_leave_notify;
323    _ecore_x_event_handlers[FocusIn]          = _ecore_x_event_handle_focus_in;
324    _ecore_x_event_handlers[FocusOut]         = _ecore_x_event_handle_focus_out;
325    _ecore_x_event_handlers[KeymapNotify]     = _ecore_x_event_handle_keymap_notify;
326    _ecore_x_event_handlers[Expose]           = _ecore_x_event_handle_expose;
327    _ecore_x_event_handlers[GraphicsExpose]   = _ecore_x_event_handle_graphics_expose;
328    _ecore_x_event_handlers[VisibilityNotify] = _ecore_x_event_handle_visibility_notify;
329    _ecore_x_event_handlers[CreateNotify]     = _ecore_x_event_handle_create_notify;
330    _ecore_x_event_handlers[DestroyNotify]    = _ecore_x_event_handle_destroy_notify;
331    _ecore_x_event_handlers[UnmapNotify]      = _ecore_x_event_handle_unmap_notify;
332    _ecore_x_event_handlers[MapNotify]        = _ecore_x_event_handle_map_notify;
333    _ecore_x_event_handlers[MapRequest]       = _ecore_x_event_handle_map_request;
334    _ecore_x_event_handlers[ReparentNotify]   = _ecore_x_event_handle_reparent_notify;
335    _ecore_x_event_handlers[ConfigureNotify]  = _ecore_x_event_handle_configure_notify;
336    _ecore_x_event_handlers[ConfigureRequest] = _ecore_x_event_handle_configure_request;
337    _ecore_x_event_handlers[GravityNotify]    = _ecore_x_event_handle_gravity_notify;
338    _ecore_x_event_handlers[ResizeRequest]    = _ecore_x_event_handle_resize_request;
339    _ecore_x_event_handlers[CirculateNotify]  = _ecore_x_event_handle_circulate_notify;
340    _ecore_x_event_handlers[CirculateRequest] = _ecore_x_event_handle_circulate_request;
341    _ecore_x_event_handlers[PropertyNotify]   = _ecore_x_event_handle_property_notify;
342    _ecore_x_event_handlers[SelectionClear]   = _ecore_x_event_handle_selection_clear;
343    _ecore_x_event_handlers[SelectionRequest] = _ecore_x_event_handle_selection_request;
344    _ecore_x_event_handlers[SelectionNotify]  = _ecore_x_event_handle_selection_notify;
345    _ecore_x_event_handlers[ColormapNotify]   = _ecore_x_event_handle_colormap_notify;
346    _ecore_x_event_handlers[ClientMessage]    = _ecore_x_event_handle_client_message;
347    _ecore_x_event_handlers[MappingNotify]    = _ecore_x_event_handle_mapping_notify;
348 #ifdef GenericEvent
349   _ecore_x_event_handlers[GenericEvent]    = _ecore_x_event_handle_generic_event;       
350 #endif
351    
352    if (_ecore_x_event_shape_id)
353      _ecore_x_event_handlers[_ecore_x_event_shape_id] = _ecore_x_event_handle_shape_change;
354    if (_ecore_x_event_screensaver_id)
355      _ecore_x_event_handlers[_ecore_x_event_screensaver_id] = _ecore_x_event_handle_screensaver_notify;
356    if (_ecore_x_event_sync_id)
357      {
358         _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncCounterNotify] =
359            _ecore_x_event_handle_sync_counter;
360         _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncAlarmNotify] =
361            _ecore_x_event_handle_sync_alarm;
362      }
363 #ifdef ECORE_XRANDR
364    if (_ecore_x_event_randr_id)
365      {
366         _ecore_x_event_handlers[_ecore_x_event_randr_id + RRScreenChangeNotify] = _ecore_x_event_handle_randr_change;
367         _ecore_x_event_handlers[_ecore_x_event_randr_id + RRNotify] = _ecore_x_event_handle_randr_notify;
368      }
369 #endif
370 #ifdef ECORE_XFIXES
371    if (_ecore_x_event_fixes_selection_id)
372      _ecore_x_event_handlers[_ecore_x_event_fixes_selection_id] = _ecore_x_event_handle_fixes_selection_notify;
373 #endif
374 #ifdef ECORE_XDAMAGE
375    if (_ecore_x_event_damage_id)
376      _ecore_x_event_handlers[_ecore_x_event_damage_id] = _ecore_x_event_handle_damage_notify;
377 #endif
378 #ifdef ECORE_XKB
379    // set x autorepeat detection to on. that means instead of
380    //   press-release-press-release-press-release
381    // you get
382    //   press-press-press-press-press-release
383    do
384      {
385         Bool works = 0;
386         XkbSetDetectableAutoRepeat(_ecore_x_disp, 1, &works);
387      }
388    while (0);
389 #endif
390    
391    if (!ECORE_X_EVENT_ANY)
392      {
393         ECORE_X_EVENT_ANY                      = ecore_event_type_new();
394         ECORE_X_EVENT_MOUSE_IN                 = ecore_event_type_new();
395         ECORE_X_EVENT_MOUSE_OUT                = ecore_event_type_new();
396         ECORE_X_EVENT_WINDOW_FOCUS_IN          = ecore_event_type_new();
397         ECORE_X_EVENT_WINDOW_FOCUS_OUT         = ecore_event_type_new();
398         ECORE_X_EVENT_WINDOW_KEYMAP            = ecore_event_type_new();
399         ECORE_X_EVENT_WINDOW_DAMAGE            = ecore_event_type_new();
400         ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new();
401         ECORE_X_EVENT_WINDOW_CREATE            = ecore_event_type_new();
402         ECORE_X_EVENT_WINDOW_DESTROY           = ecore_event_type_new();
403         ECORE_X_EVENT_WINDOW_HIDE              = ecore_event_type_new();
404         ECORE_X_EVENT_WINDOW_SHOW              = ecore_event_type_new();
405         ECORE_X_EVENT_WINDOW_SHOW_REQUEST      = ecore_event_type_new();
406         ECORE_X_EVENT_WINDOW_REPARENT          = ecore_event_type_new();
407         ECORE_X_EVENT_WINDOW_CONFIGURE         = ecore_event_type_new();
408         ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new();
409         ECORE_X_EVENT_WINDOW_GRAVITY           = ecore_event_type_new();
410         ECORE_X_EVENT_WINDOW_RESIZE_REQUEST    = ecore_event_type_new();
411         ECORE_X_EVENT_WINDOW_STACK             = ecore_event_type_new();
412         ECORE_X_EVENT_WINDOW_STACK_REQUEST     = ecore_event_type_new();
413         ECORE_X_EVENT_WINDOW_PROPERTY          = ecore_event_type_new();
414         ECORE_X_EVENT_WINDOW_COLORMAP          = ecore_event_type_new();
415         ECORE_X_EVENT_WINDOW_MAPPING           = ecore_event_type_new();
416         ECORE_X_EVENT_SELECTION_CLEAR          = ecore_event_type_new();
417         ECORE_X_EVENT_SELECTION_REQUEST        = ecore_event_type_new();
418         ECORE_X_EVENT_SELECTION_NOTIFY         = ecore_event_type_new();
419         ECORE_X_EVENT_CLIENT_MESSAGE           = ecore_event_type_new();
420         ECORE_X_EVENT_WINDOW_SHAPE             = ecore_event_type_new();
421         ECORE_X_EVENT_SCREENSAVER_NOTIFY       = ecore_event_type_new();
422         ECORE_X_EVENT_SYNC_COUNTER             = ecore_event_type_new();
423         ECORE_X_EVENT_SYNC_ALARM               = ecore_event_type_new();
424         ECORE_X_EVENT_SCREEN_CHANGE            = ecore_event_type_new();
425         ECORE_X_EVENT_RANDR_CRTC_CHANGE        = ecore_event_type_new();
426         ECORE_X_EVENT_RANDR_OUTPUT_CHANGE      = ecore_event_type_new();
427         ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = ecore_event_type_new();
428         ECORE_X_EVENT_DAMAGE_NOTIFY            = ecore_event_type_new();
429         
430         ECORE_X_EVENT_WINDOW_DELETE_REQUEST                = ecore_event_type_new();
431         /*
432         ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE             = ecore_event_type_new();
433         ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE     = ecore_event_type_new();
434         ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE        = ecore_event_type_new();
435         ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE         = ecore_event_type_new();
436         ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = ecore_event_type_new();
437         ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE    = ecore_event_type_new();
438         ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE               = ecore_event_type_new();
439         ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE           = ecore_event_type_new();
440         */
441
442         ECORE_X_EVENT_DESKTOP_CHANGE           = ecore_event_type_new();
443         ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new();
444         ECORE_X_EVENT_WINDOW_STATE_REQUEST     = ecore_event_type_new();
445         ECORE_X_EVENT_FRAME_EXTENTS_REQUEST    = ecore_event_type_new();
446         ECORE_X_EVENT_PING                     = ecore_event_type_new();
447
448         ECORE_X_EVENT_STARTUP_SEQUENCE_NEW     = ecore_event_type_new();
449         ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE  = ecore_event_type_new();
450         ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE  = ecore_event_type_new();
451
452         ECORE_X_EVENT_GENERIC                  = ecore_event_type_new();
453      }
454    
455    /* everything has these... unless its like a pda... :) */
456    ECORE_X_MODIFIER_SHIFT = _ecore_x_key_mask_get(XK_Shift_L);
457    ECORE_X_MODIFIER_CTRL  = _ecore_x_key_mask_get(XK_Control_L);
458    
459    /* apple's xdarwin has no alt!!!! */
460    ECORE_X_MODIFIER_ALT   = _ecore_x_key_mask_get(XK_Alt_L);
461    if (!ECORE_X_MODIFIER_ALT) 
462      ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Meta_L);
463    if (!ECORE_X_MODIFIER_ALT) 
464      ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Super_L);   
465    
466    /* the windows key... a valid modifier :) */
467    ECORE_X_MODIFIER_WIN   = _ecore_x_key_mask_get(XK_Super_L);
468    if (!ECORE_X_MODIFIER_WIN) 
469      ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Mode_switch);
470    if (!ECORE_X_MODIFIER_WIN) 
471      ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Meta_L);
472    
473    if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT)
474      ECORE_X_MODIFIER_WIN = 0;
475    if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL)
476      ECORE_X_MODIFIER_ALT = 0;
477    
478    ECORE_X_LOCK_SCROLL    = _ecore_x_key_mask_get(XK_Scroll_Lock);
479    ECORE_X_LOCK_NUM       = _ecore_x_key_mask_get(XK_Num_Lock);
480    ECORE_X_LOCK_CAPS      = _ecore_x_key_mask_get(XK_Caps_Lock);
481    
482    _ecore_x_fd_handler_handle = 
483      ecore_main_fd_handler_add(ConnectionNumber(_ecore_x_disp),
484                                ECORE_FD_READ,
485                                _ecore_x_fd_handler, _ecore_x_disp,
486                                _ecore_x_fd_handler_buf, _ecore_x_disp);
487    if (!_ecore_x_fd_handler_handle)
488      goto free_event_handlers;
489
490    _ecore_x_atoms_init();
491
492    /* Set up the ICCCM hints */
493    ecore_x_icccm_init();
494
495    /* Set up the _NET_... hints */
496    ecore_x_netwm_init();
497
498    /* old e hints init */
499    ecore_x_e_init();
500    
501    /* This is just to be anal about naming conventions */
502
503    _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = ECORE_X_ATOM_WM_DELETE_WINDOW;
504    _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = ECORE_X_ATOM_WM_TAKE_FOCUS;
505    _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] = ECORE_X_ATOM_NET_WM_PING;
506    _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
507
508    _ecore_x_selection_data_init();
509    _ecore_x_dnd_init();
510    _ecore_x_fixes_init();
511    _ecore_x_damage_init();
512    _ecore_x_composite_init();
513    _ecore_x_dpms_init();
514    _ecore_x_randr_init();
515    _ecore_x_input_init();
516    
517    _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456);
518
519 #ifdef ENABLE_XIM
520    /* Setup XIM */
521    if (!_ecore_x_ic && XSupportsLocale())
522      {
523         XIM im;
524         XIC ic;
525         XIMStyles *supported_styles;
526         XIMStyle chosen_style = 0;
527         Ecore_X_Window client_window = ecore_x_window_root_get(_ecore_x_private_win);
528         char *ret;
529         int i;
530
531         XSetLocaleModifiers("@im=none");
532         if ((im = XOpenIM(_ecore_x_disp, NULL, NULL, NULL)) == NULL)
533           goto _im_create_end;
534         ret = XGetIMValues(im, XNQueryInputStyle, &supported_styles, NULL);
535         if (ret || !supported_styles)
536           goto _im_create_error;
537         for (i = 0; i < supported_styles->count_styles; i++)
538           if (supported_styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing))
539             chosen_style = supported_styles->supported_styles[i];
540         XFree(supported_styles);
541         if (!chosen_style)
542           goto _im_create_error;
543         ic = XCreateIC(im, XNInputStyle, chosen_style, XNClientWindow, client_window, NULL);
544         if (ic)
545           {
546              _ecore_x_ic = ic;
547              goto _im_create_end;
548           }
549 _im_create_error:
550         XCloseIM(im);
551      }
552 _im_create_end:
553 #endif
554    return _ecore_x_init_count;
555
556  free_event_handlers:
557    free(_ecore_x_event_handlers);
558    _ecore_x_event_handlers = NULL;
559  close_display:
560    XCloseDisplay(_ecore_x_disp);
561    _ecore_x_fd_handler_handle = NULL;
562    _ecore_x_disp = NULL;
563  shutdown_ecore_event:
564    ecore_event_shutdown();
565
566    return --_ecore_x_init_count;
567 }
568
569 static int
570 _ecore_x_shutdown(int close_display)
571 {
572    if (--_ecore_x_init_count != 0)
573      return _ecore_x_init_count;
574
575    if (!_ecore_x_disp) return _ecore_x_init_count;
576    LOGFN(__FILE__, __LINE__, __FUNCTION__);
577
578 #ifdef ENABLE_XIM
579    if (_ecore_x_ic)
580      {
581         XIM xim;
582         xim = XIMOfIC(_ecore_x_ic);
583         XDestroyIC(_ecore_x_ic);
584         XCloseIM(xim);
585         _ecore_x_ic = NULL;
586      }
587 #endif
588    if (close_display)
589       XCloseDisplay(_ecore_x_disp);
590    else
591       close(ConnectionNumber(_ecore_x_disp));
592    free(_ecore_x_event_handlers);
593    ecore_main_fd_handler_del(_ecore_x_fd_handler_handle);
594    _ecore_x_fd_handler_handle = NULL;
595    _ecore_x_disp = NULL;
596    _ecore_x_event_handlers = NULL;
597    _ecore_x_input_shutdown();
598    _ecore_x_selection_shutdown();
599    _ecore_x_dnd_shutdown();
600    ecore_x_netwm_shutdown();
601    ecore_event_shutdown();
602    eina_log_domain_unregister(_ecore_xlib_log_dom);
603    _ecore_xlib_log_dom = -1;
604    return _ecore_x_init_count;
605 }
606
607 /**
608  * Shuts down the Ecore X library.
609  *
610  * In shutting down the library, the X display connection is terminated
611  * and any event handlers for it are removed.
612  *
613  * @return  The number of times the library has been initialized without
614  *          being shut down.
615  * @ingroup Ecore_X_Init_Group
616  */
617 EAPI int
618 ecore_x_shutdown(void)
619 {
620    return _ecore_x_shutdown(1);
621 }
622
623 /**
624  * Shuts down the Ecore X library.
625  *
626  * As ecore_x_shutdown, except do not close Display, only connection.
627  *
628  * @ingroup Ecore_X_Init_Group
629  */
630 EAPI int
631 ecore_x_disconnect(void)
632 {
633    return _ecore_x_shutdown(0);
634 }
635
636 /**
637  * @defgroup Ecore_X_Display_Attr_Group X Display Attributes
638  *
639  * Functions that set and retrieve X display attributes.
640  */
641
642 /**
643  * Retrieves the Ecore_X_Display handle used for the current X connection.
644  * @return  The current X display.
645  * @ingroup Ecore_X_Display_Attr_Group
646  */
647 EAPI Ecore_X_Display *
648 ecore_x_display_get(void)
649 {
650    return (Ecore_X_Display *)_ecore_x_disp;
651 }
652
653 /**
654  * Retrieves the X display file descriptor.
655  * @return  The current X display file descriptor.
656  * @ingroup Ecore_X_Display_Attr_Group
657  */
658 EAPI int
659 ecore_x_fd_get(void)
660 {
661    LOGFN(__FILE__, __LINE__, __FUNCTION__);
662    return ConnectionNumber(_ecore_x_disp);
663 }
664
665 /**
666  * Retrieves the Ecore_X_Screen handle used for the current X connection.
667  * @return  The current default screen.
668  * @ingroup Ecore_Xcb_Display_Attr_Group
669  */
670 EAPI Ecore_X_Screen*
671 ecore_x_default_screen_get(void)
672 {
673    LOGFN(__FILE__, __LINE__, __FUNCTION__);
674    return (Ecore_X_Screen*) DefaultScreenOfDisplay(_ecore_x_disp);
675 }
676
677 /**
678  * Sets the timeout for a double and triple clicks to be flagged.
679  * 
680  * This sets the time between clicks before the double_click flag is
681  * set in a button down event. If 3 clicks occur within double this
682  * time, the triple_click flag is also set.
683  *
684  * @param   t The time in seconds
685  * @ingroup Ecore_X_Display_Attr_Group
686  */
687 EAPI void
688 ecore_x_double_click_time_set(double t)
689 {
690    if (t < 0.0) t = 0.0;
691    _ecore_x_double_click_time = t;
692 }
693
694 /**
695  * Retrieves the double and triple click flag timeout.
696  *
697  * See @ref ecore_x_double_click_time_set for more information.
698  *
699  * @return  The timeout for double clicks in seconds.
700  * @ingroup Ecore_X_Display_Attr_Group
701  */
702 EAPI double
703 ecore_x_double_click_time_get(void)
704 {
705    return _ecore_x_double_click_time;
706 }
707
708 /**
709  * @defgroup Ecore_X_Flush_Group X Synchronization Functions
710  *
711  * Functions that ensure that all commands that have been issued by the
712  * Ecore X library have been sent to the server.
713  */
714
715 /**
716  * Sends all X commands in the X Display buffer.
717  * @ingroup Ecore_X_Flush_Group
718  */
719 EAPI void
720 ecore_x_flush(void)
721 {
722    LOGFN(__FILE__, __LINE__, __FUNCTION__);
723    XFlush(_ecore_x_disp);
724 }
725
726 /**
727  * Flushes the command buffer and waits until all requests have been
728  * processed by the server.
729  * @ingroup Ecore_X_Flush_Group
730  */
731 EAPI void
732 ecore_x_sync(void)
733 {
734    LOGFN(__FILE__, __LINE__, __FUNCTION__);
735    XSync(_ecore_x_disp, False);
736 }
737
738 /**
739  * Kill all clients with subwindows under a given window.
740  *
741  * You can kill all clients connected to the X server by using
742  * @ref ecore_x_window_root_list to get a list of root windows, and
743  * then passing each root window to this function.
744  *
745  * @param root The window whose children will be killed.
746  */
747 EAPI void
748 ecore_x_killall(Ecore_X_Window root)
749 {
750    unsigned int j;
751    Window root_r;
752    Window parent_r;
753    Window *children_r = NULL;
754    unsigned int num_children = 0;
755    
756    LOGFN(__FILE__, __LINE__, __FUNCTION__);
757    XGrabServer(_ecore_x_disp);
758    /* Tranverse window tree starting from root, and drag each
759     * before the firing squad */
760    while (XQueryTree(_ecore_x_disp, root, &root_r, &parent_r,
761                      &children_r, &num_children) && (num_children > 0))
762      {
763         for (j = 0; j < num_children; ++j)
764           {
765              XKillClient(_ecore_x_disp, children_r[j]);
766           }
767         
768         XFree(children_r);
769      }
770    XUngrabServer(_ecore_x_disp);
771    XSync(_ecore_x_disp, False);
772 }
773
774 /**
775  * Kill a specific client
776  *
777  * You can kill a specific client owning window @p win
778  *
779  * @param win Window of the client to be killed
780  */
781 EAPI void
782 ecore_x_kill(Ecore_X_Window win)
783 {
784    LOGFN(__FILE__, __LINE__, __FUNCTION__);
785    XKillClient(_ecore_x_disp, win);
786 }
787
788 /**
789  * Return the last event time
790  */
791 EAPI Ecore_X_Time
792 ecore_x_current_time_get(void)
793 {
794    return _ecore_x_event_last_time;
795 }
796
797 /**
798  * Return the screen DPI
799  *
800  * This is a simplistic call to get DPI. It does not account for differing
801  * DPI in the x amd y axes nor does it accoutn for multihead or xinerama and
802  * xrander where different parts of the screen may have differen DPI etc.
803  *
804  * @return the general screen DPI (dots/pixels per inch).
805  */
806 EAPI int
807 ecore_x_dpi_get(void)
808 {
809    Screen *s;
810    
811    LOGFN(__FILE__, __LINE__, __FUNCTION__);
812    s = DefaultScreenOfDisplay(_ecore_x_disp);
813    if (s->mwidth <= 0) return 75;
814    return (((s->width * 254) / s->mwidth) + 5) / 10;
815 }
816
817 static int
818 _ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
819 {
820    Display *d;
821    
822    d = data;
823    while (XPending(d))
824      {
825         XEvent ev;
826         
827         XNextEvent(d, &ev);
828
829 #ifdef ENABLE_XIM
830         /* Filter event for XIM */
831         if (XFilterEvent(&ev, ev.xkey.window)) continue;
832 #endif
833
834         if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num))
835           {
836              if (_ecore_x_event_handlers[AnyXEvent])
837                _ecore_x_event_handlers[AnyXEvent] (&ev);
838
839              if (_ecore_x_event_handlers[ev.type])
840                _ecore_x_event_handlers[ev.type] (&ev);
841           }
842      }
843    return 1;
844 }
845
846 static int
847 _ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
848 {
849    Display *d;
850
851    d = data;
852    if (XPending(d)) return 1;
853    return 0;
854 }
855
856 static int
857 _ecore_x_key_mask_get(KeySym sym)
858 {
859    XModifierKeymap    *mod;
860    KeySym              sym2;
861    int                 i, j;
862    const int           masks[8] = 
863      {
864         ShiftMask, LockMask, ControlMask, 
865           Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
866      };
867    
868    mod = XGetModifierMapping(_ecore_x_disp);
869    if ((mod) && (mod->max_keypermod > 0))
870      {
871         for (i = 0; i < (8 * mod->max_keypermod); i++)
872           {
873              for (j = 0; j < 8; j++)
874                {
875                   sym2 = XKeycodeToKeysym(_ecore_x_disp, mod->modifiermap[i], j);
876                   if (sym2 != 0) break;
877                }
878              if (sym2 == sym)
879                {
880                   int mask;
881                   
882                   mask = masks[i / mod->max_keypermod];
883                   if (mod->modifiermap) XFree(mod->modifiermap);
884                   XFree(mod);
885                   return mask;
886                }
887           }
888      }
889    if (mod)
890      {
891         if (mod->modifiermap) XFree(mod->modifiermap);
892         XFree(mod);
893      }
894   return 0;
895 }
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918 /*****************************************************************************/
919 /*****************************************************************************/
920 /*****************************************************************************/
921 /* FIXME: these funcs need categorising */
922 /*****************************************************************************/
923
924 /**
925  * Get a list of all the root windows on the server.
926  *
927  * @note   The returned array will need to be freed after use.
928  * @param  num_ret Pointer to integer to put number of windows returned in.
929  * @return An array of all the root windows.  @c NULL is returned if memory
930  *         could not be allocated for the list, or if @p num_ret is @c NULL.
931  */
932 EAPI Ecore_X_Window *
933 ecore_x_window_root_list(int *num_ret)
934 {
935    int num, i;
936    Ecore_X_Window *roots;
937 #ifdef ECORE_XPRINT
938    int xp_base, xp_err_base;
939 #endif
940    
941    if (!num_ret) return NULL;
942    *num_ret = 0;
943
944    LOGFN(__FILE__, __LINE__, __FUNCTION__);
945 #ifdef ECORE_XPRINT
946    num = ScreenCount(_ecore_x_disp);
947    if (XpQueryExtension(_ecore_x_disp, &xp_base, &xp_err_base))
948      {
949         Screen **ps = NULL;
950         int psnum = 0;
951         
952         ps = XpQueryScreens(_ecore_x_disp, &psnum);
953         if (ps)
954           {
955              int overlap, j;
956              
957              overlap = 0;
958              for (i = 0; i < num; i++)
959                {
960                   for (j = 0; j < psnum; j++)
961                     {
962                        if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
963                          overlap++;
964                     }
965                }
966              roots = malloc((num - overlap) * sizeof(Window));
967              if (roots)
968                {
969                   int k;
970                   
971                   k = 0;
972                   for (i = 0; i < num; i++)
973                     {
974                        int is_print;
975                        
976                        is_print = 0;
977                        for (j = 0; j < psnum; j++)
978                          {
979                             if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
980                               {
981                                  is_print = 1;
982                                  break;
983                               }
984                          }
985                        if (!is_print)
986                          {
987                             roots[k] = RootWindow(_ecore_x_disp, i);
988                             k++;
989                          }
990                     }
991                   *num_ret = k;
992                }
993              XFree(ps);
994           }
995         else
996           {
997              roots = malloc(num * sizeof(Window));
998              if (!roots) return NULL;
999              *num_ret = num;
1000              for (i = 0; i < num; i++)
1001                roots[i] = RootWindow(_ecore_x_disp, i);
1002           }
1003      }
1004    else
1005      {
1006         roots = malloc(num * sizeof(Window));
1007         if (!roots) return NULL;
1008         *num_ret = num;
1009         for (i = 0; i < num; i++)
1010           roots[i] = RootWindow(_ecore_x_disp, i);
1011      }
1012 #else   
1013    num = ScreenCount(_ecore_x_disp);
1014    roots = malloc(num * sizeof(Window));
1015    if (!roots) return NULL;
1016    *num_ret = num;
1017    for (i = 0; i < num; i++)
1018      roots[i] = RootWindow(_ecore_x_disp, i);
1019 #endif   
1020    return roots;
1021 }
1022
1023 EAPI Ecore_X_Window
1024 ecore_x_window_root_first_get(void)
1025 {
1026    return RootWindow(_ecore_x_disp, 0);
1027 /*   
1028    int num;
1029    Ecore_X_Window root, *roots = NULL;
1030
1031    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1032    roots = ecore_x_window_root_list(&num);
1033    if (!(roots)) return 0;
1034    
1035    if (num > 0)
1036      root = roots[0];
1037    else
1038      root = 0;
1039    
1040    free(roots);
1041    return root;
1042  */
1043 }
1044
1045
1046 static void _ecore_x_window_manage_error(void *data);
1047
1048 static int _ecore_x_window_manage_failed = 0;
1049 static void
1050 _ecore_x_window_manage_error(void *data __UNUSED__)
1051 {
1052    if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) &&
1053        (ecore_x_error_code_get() == BadAccess))
1054      _ecore_x_window_manage_failed = 1;
1055 }
1056
1057 EAPI int
1058 ecore_x_window_manage(Ecore_X_Window win)
1059 {
1060    XWindowAttributes   att;
1061    
1062    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1063    if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True) return 0;
1064    ecore_x_sync();
1065    _ecore_x_window_manage_failed = 0;
1066    ecore_x_error_handler_set(_ecore_x_window_manage_error, NULL);
1067    XSelectInput(_ecore_x_disp, win, 
1068                 EnterWindowMask | 
1069                 LeaveWindowMask | 
1070                 PropertyChangeMask | 
1071                 ResizeRedirectMask |
1072                 SubstructureRedirectMask | 
1073                 SubstructureNotifyMask |
1074                 StructureNotifyMask |
1075                 KeyPressMask | 
1076                 KeyReleaseMask |
1077                 att.your_event_mask);
1078    ecore_x_sync();
1079    ecore_x_error_handler_set(NULL, NULL);
1080    if (_ecore_x_window_manage_failed)
1081      {
1082         _ecore_x_window_manage_failed = 0;
1083         return 0;
1084      }
1085    return 1;
1086 }
1087
1088 EAPI void
1089 ecore_x_window_container_manage(Ecore_X_Window win)
1090 {
1091    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1092    XSelectInput(_ecore_x_disp, win, 
1093                 SubstructureRedirectMask | 
1094                 SubstructureNotifyMask);
1095 }
1096
1097 EAPI void
1098 ecore_x_window_client_manage(Ecore_X_Window win)
1099 {
1100    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1101    XSelectInput(_ecore_x_disp, win, 
1102                 PropertyChangeMask | 
1103 //              ResizeRedirectMask |
1104                 FocusChangeMask |
1105                 ColormapChangeMask |
1106                 VisibilityChangeMask |
1107                 StructureNotifyMask |
1108                 SubstructureNotifyMask
1109                 );
1110    XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1111 }
1112
1113 EAPI void
1114 ecore_x_window_sniff(Ecore_X_Window win)
1115 {
1116    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1117    XSelectInput(_ecore_x_disp, win,
1118                 PropertyChangeMask |
1119                 SubstructureNotifyMask);
1120 }
1121
1122 EAPI void
1123 ecore_x_window_client_sniff(Ecore_X_Window win)
1124 {
1125    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1126    XSelectInput(_ecore_x_disp, win,
1127                 PropertyChangeMask |
1128                 FocusChangeMask |
1129                 ColormapChangeMask |
1130                 VisibilityChangeMask |
1131                 StructureNotifyMask |
1132                 SubstructureNotifyMask);
1133    XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1134 }
1135
1136
1137
1138
1139
1140
1141 EAPI int
1142 ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret)
1143 {
1144    XWindowAttributes att;
1145    
1146    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1147    if (!XGetWindowAttributes(_ecore_x_disp, win, &att)) return 0;
1148    memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
1149    att_ret->root = att.root;
1150    att_ret->x = att.x;
1151    att_ret->y = att.y;
1152    att_ret->w = att.width;
1153    att_ret->h = att.height;
1154    att_ret->border = att.border_width;
1155    att_ret->depth = att.depth;
1156    if (att.map_state != IsUnmapped) att_ret->visible = 1;
1157    if (att.map_state == IsViewable) att_ret->viewable = 1;
1158    if (att.override_redirect) att_ret->override = 1;
1159    if (att.class == InputOnly) att_ret->input_only = 1;
1160    if (att.save_under) att_ret->save_under = 1;
1161    att_ret->event_mask.mine = att.your_event_mask;
1162    att_ret->event_mask.all = att.all_event_masks;
1163    att_ret->event_mask.no_propagate = att.do_not_propagate_mask;
1164    att_ret->window_gravity = att.win_gravity;
1165    att_ret->pixel_gravity = att.bit_gravity;
1166    att_ret->colormap = att.colormap;
1167    att_ret->visual = att.visual;
1168    return 1;
1169 }
1170
1171 EAPI void
1172 ecore_x_window_save_set_add(Ecore_X_Window win)
1173 {
1174    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1175    XAddToSaveSet(_ecore_x_disp, win);
1176 }
1177
1178 EAPI void
1179 ecore_x_window_save_set_del(Ecore_X_Window win)
1180 {
1181    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1182    XRemoveFromSaveSet(_ecore_x_disp, win);
1183 }
1184
1185 EAPI Ecore_X_Window *
1186 ecore_x_window_children_get(Ecore_X_Window win, int *num)
1187 {
1188    Ecore_X_Window     *windows = NULL;
1189    Window              root_ret = 0, parent_ret = 0, *children_ret = NULL;
1190    unsigned int        children_ret_num = 0;
1191    
1192    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1193    if (!XQueryTree(_ecore_x_disp, win, &root_ret, &parent_ret, &children_ret,
1194                    &children_ret_num))
1195      {
1196         return NULL;
1197      }
1198    if (children_ret)
1199      {
1200         windows = malloc(children_ret_num * sizeof(Ecore_X_Window));
1201         if (windows)
1202           {
1203              unsigned int i;
1204              
1205              for (i = 0; i < children_ret_num; i++)
1206                windows[i] = children_ret[i];
1207              *num = children_ret_num;
1208           }
1209         XFree(children_ret);
1210      }
1211    return windows;
1212 }
1213
1214 EAPI int
1215 ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold)
1216 {
1217    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1218    return XChangePointerControl(_ecore_x_disp, 1, 1, 
1219                                 accel_num, accel_denom, threshold);
1220 }
1221
1222 EAPI int
1223 ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold)
1224 {
1225    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1226    return XGetPointerControl(_ecore_x_disp, 
1227                                 accel_num, accel_denom, threshold);
1228 }
1229
1230 EAPI int
1231 ecore_x_pointer_mapping_set(unsigned char *map, int nmap)
1232 {
1233    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1234    return XSetPointerMapping(_ecore_x_disp, map, nmap);
1235 }
1236
1237 EAPI int
1238 ecore_x_pointer_mapping_get(unsigned char *map, int nmap)
1239 {
1240    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1241    return XGetPointerMapping(_ecore_x_disp, map, nmap);
1242 }
1243
1244 EAPI int
1245 ecore_x_pointer_grab(Ecore_X_Window win)
1246 {
1247    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1248    if (XGrabPointer(_ecore_x_disp, win, False,
1249                     ButtonPressMask | ButtonReleaseMask | 
1250                     EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1251                     GrabModeAsync, GrabModeAsync,
1252                     None, None, CurrentTime) == GrabSuccess) return 1;
1253    return 0;
1254 }
1255
1256 EAPI int
1257 ecore_x_pointer_confine_grab(Ecore_X_Window win)
1258 {
1259    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1260    if (XGrabPointer(_ecore_x_disp, win, False,
1261                     ButtonPressMask | ButtonReleaseMask | 
1262                     EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1263                     GrabModeAsync, GrabModeAsync,
1264                     win, None, CurrentTime) == GrabSuccess) return 1;
1265    return 0;
1266 }
1267
1268 EAPI void
1269 ecore_x_pointer_ungrab(void)
1270 {
1271    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1272    XUngrabPointer(_ecore_x_disp, CurrentTime);
1273 }
1274
1275 EAPI int
1276 ecore_x_pointer_warp(Ecore_X_Window win, int x, int y)
1277 {
1278    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1279    return XWarpPointer(_ecore_x_disp, None, win, 0, 0, 0, 0, x, y);
1280 }
1281
1282 EAPI int
1283 ecore_x_keyboard_grab(Ecore_X_Window win)
1284 {
1285    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1286    if (XGrabKeyboard(_ecore_x_disp, win, False,
1287                      GrabModeAsync, GrabModeAsync,
1288                      CurrentTime) == GrabSuccess) return 1;
1289    return 0;
1290 }
1291
1292 EAPI void
1293 ecore_x_keyboard_ungrab(void)
1294 {
1295    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1296    XUngrabKeyboard(_ecore_x_disp, CurrentTime);   
1297 }
1298
1299 EAPI void
1300 ecore_x_grab(void)
1301 {
1302    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1303    _ecore_x_grab_count++;
1304    if (_ecore_x_grab_count == 1) XGrabServer(_ecore_x_disp);
1305 }
1306
1307 EAPI void
1308 ecore_x_ungrab(void)
1309 {
1310    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1311    _ecore_x_grab_count--;
1312    if (_ecore_x_grab_count < 0) _ecore_x_grab_count = 0;
1313    if (_ecore_x_grab_count == 0) XUngrabServer(_ecore_x_disp);
1314 }
1315
1316 int      _ecore_window_grabs_num = 0;
1317 Window  *_ecore_window_grabs = NULL;
1318 int    (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event);
1319 void    *_ecore_window_grab_replay_data;
1320
1321 EAPI void
1322 ecore_x_passive_grab_replay_func_set(int (*func) (void *data, int event_type, void *event), void *data)
1323 {
1324    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1325    _ecore_window_grab_replay_func = func;
1326    _ecore_window_grab_replay_data = data;
1327 }
1328
1329 EAPI void
1330 ecore_x_window_button_grab(Ecore_X_Window win, int button, 
1331                            Ecore_X_Event_Mask event_mask,
1332                            int mod, int any_mod)
1333 {
1334    unsigned int        b;
1335    unsigned int        m;
1336    unsigned int        locks[8];
1337    int                 i, ev;
1338    
1339    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1340    b = button;
1341    if (b == 0) b = AnyButton;
1342    m = _ecore_x_event_modifier(mod);
1343    if (any_mod) m = AnyModifier;
1344    locks[0] = 0;
1345    locks[1] = ECORE_X_LOCK_CAPS;
1346    locks[2] = ECORE_X_LOCK_NUM;
1347    locks[3] = ECORE_X_LOCK_SCROLL;
1348    locks[4] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_NUM;
1349    locks[5] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_SCROLL;
1350    locks[6] = ECORE_X_LOCK_NUM    | ECORE_X_LOCK_SCROLL;
1351    locks[7] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_NUM    | ECORE_X_LOCK_SCROLL;
1352    ev = event_mask;
1353    for (i = 0; i < 8; i++)
1354      XGrabButton(_ecore_x_disp, b, m | locks[i],
1355                  win, False, ev, GrabModeSync, GrabModeAsync, None, None);
1356    _ecore_window_grabs_num++;
1357    _ecore_window_grabs = realloc(_ecore_window_grabs, 
1358                                  _ecore_window_grabs_num * sizeof(Window));
1359    _ecore_window_grabs[_ecore_window_grabs_num - 1] = win;
1360 }
1361
1362 void
1363 _ecore_x_sync_magic_send(int val, Ecore_X_Window swin)
1364 {
1365    XEvent xev;
1366    
1367    xev.xclient.type = ClientMessage;
1368    xev.xclient.serial = 0;
1369    xev.xclient.send_event = True;
1370    xev.xclient.display = _ecore_x_disp;
1371    xev.xclient.window = _ecore_x_private_win;
1372    xev.xclient.format = 32;
1373    xev.xclient.message_type = 27777;
1374    xev.xclient.data.l[0] = 0x7162534;
1375    xev.xclient.data.l[1] = 0x10000000 + val;
1376    xev.xclient.data.l[2] = swin;
1377    XSendEvent(_ecore_x_disp, _ecore_x_private_win, False, NoEventMask, &xev);
1378 }
1379
1380 void
1381 _ecore_x_window_grab_remove(Ecore_X_Window win)
1382 {
1383    int i, shuffle = 0;
1384    
1385    if (_ecore_window_grabs_num > 0)
1386      {
1387         for (i = 0; i < _ecore_window_grabs_num; i++)
1388           {
1389              if (shuffle) _ecore_window_grabs[i - 1] = _ecore_window_grabs[i];
1390              if ((!shuffle) && (_ecore_window_grabs[i] == win))
1391                shuffle = 1;
1392           }
1393         if (shuffle)
1394           {
1395              _ecore_window_grabs_num--;
1396              _ecore_window_grabs = realloc(_ecore_window_grabs, 
1397                                            _ecore_window_grabs_num * sizeof(Window));
1398           }
1399      }
1400 }
1401
1402 EAPI void
1403 ecore_x_window_button_ungrab(Ecore_X_Window win, int button, 
1404                              int mod, int any_mod)
1405 {
1406    unsigned int        b;
1407    unsigned int        m;
1408    unsigned int        locks[8];
1409    int                 i;
1410    
1411    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1412    b = button;
1413    if (b == 0) b = AnyButton;
1414    m = _ecore_x_event_modifier(mod);
1415    if (any_mod) m = AnyModifier;
1416    locks[0] = 0;
1417    locks[1] = ECORE_X_LOCK_CAPS;
1418    locks[2] = ECORE_X_LOCK_NUM;
1419    locks[3] = ECORE_X_LOCK_SCROLL;
1420    locks[4] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_NUM;
1421    locks[5] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_SCROLL;
1422    locks[6] = ECORE_X_LOCK_NUM    | ECORE_X_LOCK_SCROLL;
1423    locks[7] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_NUM    | ECORE_X_LOCK_SCROLL;
1424    for (i = 0; i < 8; i++)
1425      XUngrabButton(_ecore_x_disp, b, m | locks[i], win);
1426    _ecore_x_sync_magic_send(1, win);
1427 }
1428
1429 int      _ecore_key_grabs_num = 0;
1430 Window  *_ecore_key_grabs = NULL;
1431
1432 EAPI void
1433 ecore_x_window_key_grab(Ecore_X_Window win, const char *key, 
1434                         int mod, int any_mod)
1435 {
1436    KeyCode             keycode = 0;
1437    KeySym              keysym;
1438    unsigned int        m;
1439    unsigned int        locks[8];
1440    int                 i;
1441    
1442    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1443    if (!strncmp(key, "Keycode-", 8))
1444      keycode = atoi(key + 8);
1445    else
1446      {
1447         keysym = XStringToKeysym(key);
1448         if (keysym == NoSymbol) return;
1449         keycode  = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
1450      }
1451    if (keycode == 0) return;
1452    
1453    m = _ecore_x_event_modifier(mod);
1454    if (any_mod) m = AnyModifier;
1455    locks[0] = 0;
1456    locks[1] = ECORE_X_LOCK_CAPS;
1457    locks[2] = ECORE_X_LOCK_NUM;
1458    locks[3] = ECORE_X_LOCK_SCROLL;
1459    locks[4] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_NUM;
1460    locks[5] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_SCROLL;
1461    locks[6] = ECORE_X_LOCK_NUM    | ECORE_X_LOCK_SCROLL;
1462    locks[7] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_NUM    | ECORE_X_LOCK_SCROLL;
1463    for (i = 0; i < 8; i++)
1464      XGrabKey(_ecore_x_disp, keycode, m | locks[i],
1465               win, False, GrabModeSync, GrabModeAsync);
1466    _ecore_key_grabs_num++;
1467    _ecore_key_grabs = realloc(_ecore_key_grabs,
1468                               _ecore_key_grabs_num * sizeof(Window));
1469    _ecore_key_grabs[_ecore_key_grabs_num - 1] = win;
1470 }
1471
1472 void
1473 _ecore_x_key_grab_remove(Ecore_X_Window win)
1474 {
1475    int i, shuffle = 0;
1476    
1477    if (_ecore_key_grabs_num > 0)
1478      {
1479         for (i = 0; i < _ecore_key_grabs_num; i++)
1480           {
1481              if (shuffle) _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
1482              if ((!shuffle) && (_ecore_key_grabs[i] == win))
1483                shuffle = 1;
1484           }
1485         if (shuffle)
1486           {
1487              _ecore_key_grabs_num--;
1488              _ecore_key_grabs = realloc(_ecore_key_grabs, 
1489                                         _ecore_key_grabs_num * sizeof(Window));
1490           }
1491      }
1492 }
1493
1494 EAPI void
1495 ecore_x_window_key_ungrab(Ecore_X_Window win, const char *key,
1496                           int mod, int any_mod)
1497 {
1498    KeyCode             keycode = 0;
1499    KeySym              keysym;
1500    unsigned int        m;
1501    unsigned int        locks[8];
1502    int                 i;
1503
1504    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1505    if (!strncmp(key, "Keycode-", 8))
1506      keycode = atoi(key + 8);
1507    else
1508      {
1509         keysym = XStringToKeysym(key);
1510         if (keysym == NoSymbol) return;
1511         keycode  = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
1512      }
1513    if (keycode == 0) return;
1514    
1515    m = _ecore_x_event_modifier(mod);
1516    if (any_mod) m = AnyModifier;
1517    locks[0] = 0;
1518    locks[1] = ECORE_X_LOCK_CAPS;
1519    locks[2] = ECORE_X_LOCK_NUM;
1520    locks[3] = ECORE_X_LOCK_SCROLL;
1521    locks[4] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_NUM;
1522    locks[5] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_SCROLL;
1523    locks[6] = ECORE_X_LOCK_NUM    | ECORE_X_LOCK_SCROLL;
1524    locks[7] = ECORE_X_LOCK_CAPS   | ECORE_X_LOCK_NUM    | ECORE_X_LOCK_SCROLL;
1525    for (i = 0; i < 8; i++)
1526      XUngrabKey(_ecore_x_disp, keycode, m | locks[i], win);
1527    _ecore_x_sync_magic_send(2, win);
1528 }
1529
1530 /**
1531  * Send client message with given type and format 32.
1532  *
1533  * @param win     The window the message is sent to.
1534  * @param type    The client message type.
1535  * @param d0      The client message data item 1
1536  * @param d1      The client message data item 2
1537  * @param d2      The client message data item 3
1538  * @param d3      The client message data item 4
1539  * @param d4      The client message data item 5
1540  *
1541  * @return !0 on success.
1542  */
1543 EAPI int
1544 ecore_x_client_message32_send(Ecore_X_Window win, Ecore_X_Atom type,
1545                               Ecore_X_Event_Mask mask,
1546                               long d0, long d1, long d2, long d3, long d4)
1547 {
1548    XEvent xev;
1549
1550    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1551    xev.xclient.window = win;
1552    xev.xclient.type = ClientMessage;
1553    xev.xclient.message_type = type;
1554    xev.xclient.format = 32;
1555    xev.xclient.data.l[0] = d0;
1556    xev.xclient.data.l[1] = d1;
1557    xev.xclient.data.l[2] = d2;
1558    xev.xclient.data.l[3] = d3;
1559    xev.xclient.data.l[4] = d4;
1560    
1561    return XSendEvent(_ecore_x_disp, win, False, mask, &xev);
1562 }
1563
1564 /**
1565  * Send client message with given type and format 8.
1566  *
1567  * @param win     The window the message is sent to.
1568  * @param type    The client message type.
1569  * @param data    Data to be sent.
1570  * @param len     Number of data bytes, max 20.
1571  *
1572  * @return !0 on success.
1573  */
1574 EAPI int
1575 ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type,
1576                              const void *data, int len)
1577 {
1578    XEvent xev;
1579    
1580    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1581    xev.xclient.window = win;
1582    xev.xclient.type = ClientMessage;
1583    xev.xclient.message_type = type;
1584    xev.xclient.format = 8;
1585    if (len > 20) len = 20;
1586    memcpy(xev.xclient.data.b, data, len);
1587    memset(xev.xclient.data.b + len, 0, 20 - len);
1588    
1589    return XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
1590 }
1591
1592 EAPI int
1593 ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y)
1594 {
1595    XEvent xev;
1596    XWindowAttributes att;
1597    Window tw;
1598    int rx, ry;
1599
1600    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1601    XGetWindowAttributes(_ecore_x_disp, win, &att);
1602    XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1603    xev.xmotion.type = MotionNotify;
1604    xev.xmotion.window = win;
1605    xev.xmotion.root = att.root;
1606    xev.xmotion.subwindow = win;
1607    xev.xmotion.time = _ecore_x_event_last_time;
1608    xev.xmotion.x = x;
1609    xev.xmotion.y = y;
1610    xev.xmotion.x_root = rx;
1611    xev.xmotion.y_root = ry;
1612    xev.xmotion.state = 0;
1613    xev.xmotion.is_hint = 0;
1614    xev.xmotion.same_screen = 1;
1615    return XSendEvent(_ecore_x_disp, win, True, PointerMotionMask, &xev);
1616 }
1617
1618 EAPI int
1619 ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b)
1620 {
1621    XEvent xev;
1622    XWindowAttributes att;
1623    Window tw;
1624    int rx, ry;
1625
1626    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1627    XGetWindowAttributes(_ecore_x_disp, win, &att);
1628    XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1629    xev.xbutton.type = ButtonPress;
1630    xev.xbutton.window = win;
1631    xev.xbutton.root = att.root;
1632    xev.xbutton.subwindow = win;
1633    xev.xbutton.time = _ecore_x_event_last_time;
1634    xev.xbutton.x = x;
1635    xev.xbutton.y = y;
1636    xev.xbutton.x_root = rx;
1637    xev.xbutton.y_root = ry;
1638    xev.xbutton.state = 1 << b;
1639    xev.xbutton.button = b;
1640    xev.xbutton.same_screen = 1;
1641    return XSendEvent(_ecore_x_disp, win, True, ButtonPressMask, &xev);
1642 }
1643
1644 EAPI int
1645 ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b)
1646 {
1647    XEvent xev;
1648    XWindowAttributes att;
1649    Window tw;
1650    int rx, ry;
1651
1652    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1653    XGetWindowAttributes(_ecore_x_disp, win, &att);
1654    XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1655    xev.xbutton.type = ButtonRelease;
1656    xev.xbutton.window = win;
1657    xev.xbutton.root = att.root;
1658    xev.xbutton.subwindow = win;
1659    xev.xbutton.time = _ecore_x_event_last_time;
1660    xev.xbutton.x = x;
1661    xev.xbutton.y = y;
1662    xev.xbutton.x_root = rx;
1663    xev.xbutton.y_root = ry;
1664    xev.xbutton.state = 0;
1665    xev.xbutton.button = b;
1666    xev.xbutton.same_screen = 1;
1667    return XSendEvent(_ecore_x_disp, win, True, ButtonReleaseMask, &xev);
1668 }
1669
1670 EAPI void
1671 ecore_x_focus_reset(void)
1672 {
1673    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1674    XSetInputFocus(_ecore_x_disp, PointerRoot, RevertToPointerRoot, CurrentTime);
1675 }
1676
1677 EAPI void
1678 ecore_x_events_allow_all(void)
1679 {
1680    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1681    XAllowEvents(_ecore_x_disp, AsyncBoth, CurrentTime);
1682 }
1683
1684 EAPI void
1685 ecore_x_pointer_last_xy_get(int *x, int *y)
1686 {
1687    if (x) *x = _ecore_x_event_last_root_x;
1688    if (y) *y = _ecore_x_event_last_root_y;
1689 }
1690
1691 EAPI void
1692 ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y)
1693 {
1694    Window rwin, cwin;
1695    int rx, ry, wx, wy, ret;
1696    unsigned int mask;
1697    
1698    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1699    ret = XQueryPointer(_ecore_x_disp, win, &rwin, &cwin, &rx, &ry, &wx, &wy, &mask);
1700    if (!ret) wx = wy = -1;
1701    if (x) *x = wx;
1702    if (y) *y = wy;
1703 }
1704 /*****************************************************************************/
1705 /*****************************************************************************/
1706 /*****************************************************************************/
1707
1708 static int
1709 _ecore_x_event_modifier(unsigned int state)
1710 {
1711    int xmodifiers = 0;
1712
1713    if (state & ECORE_EVENT_MODIFIER_SHIFT) xmodifiers |= ECORE_X_MODIFIER_SHIFT;
1714    if (state & ECORE_EVENT_MODIFIER_CTRL) xmodifiers |= ECORE_X_MODIFIER_CTRL;
1715    if (state & ECORE_EVENT_MODIFIER_ALT) xmodifiers |= ECORE_X_MODIFIER_ALT;
1716    if (state & ECORE_EVENT_MODIFIER_WIN) xmodifiers |= ECORE_X_MODIFIER_WIN;
1717    if (state & ECORE_EVENT_LOCK_SCROLL) xmodifiers |= ECORE_X_LOCK_SCROLL;
1718    if (state & ECORE_EVENT_LOCK_NUM) xmodifiers |= ECORE_X_LOCK_NUM;
1719    if (state & ECORE_EVENT_LOCK_CAPS) xmodifiers |= ECORE_X_LOCK_CAPS;
1720
1721    return xmodifiers;
1722 }