3 #endif /* ifdef HAVE_CONFIG_H */
13 #endif /* ifdef LOGRT */
16 #include "ecore_private.h"
17 #include "ecore_x_private.h"
19 #include "Ecore_X_Atoms.h"
20 #include "Ecore_Input.h"
22 static Eina_Bool _ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
23 static Eina_Bool _ecore_x_fd_handler_buf(void *data,
24 Ecore_Fd_Handler *fd_handler);
25 static int _ecore_x_key_mask_get(KeySym sym);
26 static int _ecore_x_event_modifier(unsigned int state);
28 static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL;
30 static const int AnyXEvent = 0; /* 0 can be used as there are no event types
31 * with index 0 and 1 as they are used for
35 static int _ecore_x_event_shape_id = 0;
36 static int _ecore_x_event_screensaver_id = 0;
37 static int _ecore_x_event_sync_id = 0;
38 int _ecore_xlib_log_dom = -1;
41 static int _ecore_x_event_randr_id = 0;
42 #endif /* ifdef ECORE_XRANDR */
44 static int _ecore_x_event_fixes_selection_id = 0;
45 #endif /* ifdef ECORE_XFIXES */
47 static int _ecore_x_event_damage_id = 0;
48 #endif /* ifdef ECORE_XDAMAGE */
49 static int _ecore_x_event_handlers_num = 0;
50 static void (**_ecore_x_event_handlers) (XEvent * event) = NULL;
52 static int _ecore_x_init_count = 0;
53 static int _ecore_x_grab_count = 0;
55 Display *_ecore_x_disp = NULL;
56 double _ecore_x_double_click_time = 0.25;
57 Time _ecore_x_event_last_time = 0;
58 Window _ecore_x_event_last_win = 0;
59 int _ecore_x_event_last_root_x = 0;
60 int _ecore_x_event_last_root_y = 0;
61 Eina_Bool _ecore_x_xcursor = EINA_FALSE;
62 XIC _ecore_x_ic = NULL; /* Input context for composed characters */
63 XIM _ecore_x_im = NULL;
65 Ecore_X_Window _ecore_x_private_win = 0;
67 Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
69 EAPI int ECORE_X_EVENT_ANY = 0;
70 EAPI int ECORE_X_EVENT_MOUSE_IN = 0;
71 EAPI int ECORE_X_EVENT_MOUSE_OUT = 0;
72 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0;
73 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0;
74 EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0;
75 EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0;
76 EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0;
77 EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0;
78 EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0;
79 EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0;
80 EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0;
81 EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0;
82 EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0;
83 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0;
84 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0;
85 EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0;
86 EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0;
87 EAPI int ECORE_X_EVENT_WINDOW_STACK = 0;
88 EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0;
89 EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0;
90 EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0;
91 EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0;
92 EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
93 EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
94 EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
95 EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
96 EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
97 EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
98 EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0;
99 EAPI int ECORE_X_EVENT_SYNC_ALARM = 0;
100 EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0;
101 EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0;
102 EAPI int ECORE_X_EVENT_RANDR_CRTC_CHANGE = 0;
103 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = 0;
104 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = 0;
105 EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
107 EAPI int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = 0;
108 EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = 0;
109 EAPI int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = 0;
110 EAPI int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = 0;
111 EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = 0;
112 EAPI int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = 0;
113 EAPI int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = 0;
114 EAPI int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = 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;
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;
127 EAPI int ECORE_X_EVENT_GENERIC = 0;
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;
134 EAPI int ECORE_X_LOCK_SCROLL = 0;
135 EAPI int ECORE_X_LOCK_NUM = 0;
136 EAPI int ECORE_X_LOCK_CAPS = 0;
139 static double t0 = 0.0;
140 static Status (*_logrt_real_reply)(Display *disp, void *rep, int extra,
141 Bool discard) = NULL;
147 lib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
149 lib = dlopen("libX11.so.6", RTLD_GLOBAL | RTLD_LAZY);
152 lib = dlopen("libX11.so.6.3", RTLD_GLOBAL | RTLD_LAZY);
155 lib = dlopen("libX11.so.6.3.0", RTLD_GLOBAL | RTLD_LAZY);
157 _logrt_real_reply = dlsym(lib, "_XReply");
158 t0 = ecore_time_get();
162 _XReply(Display *disp, void *rep, int extra, Bool discard)
168 n = backtrace(bt, 128);
171 sym = backtrace_symbols(bt, n);
172 printf("ROUNDTRIP: %4.4f :", ecore_time_get() - t0);
175 for (i = n - 1; i > 0; i--)
177 char *fname = strchr(sym[i], '(');
180 char *tsym = alloca(strlen(fname) + 1);
182 strcpy(tsym, fname + 1);
183 end = strchr(tsym, '+');
203 return _logrt_real_reply(disp, rep, extra, discard);
206 #endif /* ifdef LOGRT */
209 * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions
211 * Functions that start and shut down the Ecore X Library.
215 * Initialize the X display connection to the given display.
217 * @param name Display target name. If @c NULL, the default display is
219 * @return The number of times the library has been initialized without
220 * being shut down. 0 is returned if an error occurs.
221 * @ingroup Ecore_X_Init_Group
224 ecore_x_init(const char *name)
227 int shape_err_base = 0;
229 int screensaver_base = 0;
230 int screensaver_err_base = 0;
231 #endif /* ifdef ECORE_XSS */
233 int sync_err_base = 0;
236 int randr_err_base = 0;
237 #endif /* ifdef ECORE_XRANDR */
240 int fixes_err_base = 0;
241 #endif /* ifdef ECORE_XFIXES */
244 int damage_err_base = 0;
245 #endif /* ifdef ECORE_XDAMAGE */
247 if (++_ecore_x_init_count != 1)
248 return _ecore_x_init_count;
250 LOGFN(__FILE__, __LINE__, __FUNCTION__);
253 #endif /* ifdef LOGRT */
256 _ecore_xlib_log_dom = eina_log_domain_register
257 ("ecore_x", ECORE_XLIB_DEFAULT_LOG_COLOR);
258 if(_ecore_xlib_log_dom < 0)
261 "Impossible to create a log domain for the Ecore Xlib module.");
262 return --_ecore_x_init_count;
267 if (!ecore_event_init())
270 #ifdef EVAS_FRAME_QUEUING
272 #endif /* ifdef EVAS_FRAME_QUEUING */
273 _ecore_x_disp = XOpenDisplay((char *)name);
275 goto shutdown_ecore_event;
277 _ecore_x_error_handler_init();
278 _ecore_x_event_handlers_num = LASTEvent;
280 #define ECORE_X_EVENT_HANDLERS_GROW(ext_base, ext_num_events)\
282 if (_ecore_x_event_handlers_num < (ext_base + ext_num_events)) {\
283 _ecore_x_event_handlers_num = (ext_base + ext_num_events); }\
286 if (XShapeQueryExtension(_ecore_x_disp, &shape_base, &shape_err_base))
287 _ecore_x_event_shape_id = shape_base;
289 ECORE_X_EVENT_HANDLERS_GROW(shape_base, ShapeNumberEvents);
292 if (XScreenSaverQueryExtension(_ecore_x_disp, &screensaver_base,
293 &screensaver_err_base))
294 _ecore_x_event_screensaver_id = screensaver_base;
296 ECORE_X_EVENT_HANDLERS_GROW(screensaver_base, ScreenSaverNumberEvents);
297 #endif /* ifdef ECORE_XSS */
299 if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base))
303 _ecore_x_event_sync_id = sync_base;
304 if (!XSyncInitialize(_ecore_x_disp, &major, &minor))
305 _ecore_x_event_sync_id = 0;
308 ECORE_X_EVENT_HANDLERS_GROW(sync_base, XSyncNumberEvents);
311 if (XRRQueryExtension(_ecore_x_disp, &randr_base, &randr_err_base))
312 _ecore_x_event_randr_id = randr_base;
314 ECORE_X_EVENT_HANDLERS_GROW(randr_base, RRNumberEvents);
315 #endif /* ifdef ECORE_XRANDR */
318 if (XFixesQueryExtension(_ecore_x_disp, &fixes_base, &fixes_err_base))
319 _ecore_x_event_fixes_selection_id = fixes_base;
321 ECORE_X_EVENT_HANDLERS_GROW(fixes_base, XFixesNumberEvents);
322 #endif /* ifdef ECORE_XFIXES */
325 if (XDamageQueryExtension(_ecore_x_disp, &damage_base, &damage_err_base))
326 _ecore_x_event_damage_id = damage_base;
328 ECORE_X_EVENT_HANDLERS_GROW(damage_base, XDamageNumberEvents);
329 #endif /* ifdef ECORE_XDAMAGE */
331 _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *));
332 if (!_ecore_x_event_handlers)
336 _ecore_x_xcursor = XcursorSupportsARGB(_ecore_x_disp) ? EINA_TRUE : EINA_FALSE;
337 #endif /* ifdef ECORE_XCURSOR */
338 _ecore_x_event_handlers[AnyXEvent] = _ecore_x_event_handle_any_event;
339 _ecore_x_event_handlers[KeyPress] = _ecore_x_event_handle_key_press;
340 _ecore_x_event_handlers[KeyRelease] = _ecore_x_event_handle_key_release;
341 _ecore_x_event_handlers[ButtonPress] = _ecore_x_event_handle_button_press;
342 _ecore_x_event_handlers[ButtonRelease] =
343 _ecore_x_event_handle_button_release;
344 _ecore_x_event_handlers[MotionNotify] = _ecore_x_event_handle_motion_notify;
345 _ecore_x_event_handlers[EnterNotify] = _ecore_x_event_handle_enter_notify;
346 _ecore_x_event_handlers[LeaveNotify] = _ecore_x_event_handle_leave_notify;
347 _ecore_x_event_handlers[FocusIn] = _ecore_x_event_handle_focus_in;
348 _ecore_x_event_handlers[FocusOut] = _ecore_x_event_handle_focus_out;
349 _ecore_x_event_handlers[KeymapNotify] = _ecore_x_event_handle_keymap_notify;
350 _ecore_x_event_handlers[Expose] = _ecore_x_event_handle_expose;
351 _ecore_x_event_handlers[GraphicsExpose] =
352 _ecore_x_event_handle_graphics_expose;
353 _ecore_x_event_handlers[VisibilityNotify] =
354 _ecore_x_event_handle_visibility_notify;
355 _ecore_x_event_handlers[CreateNotify] = _ecore_x_event_handle_create_notify;
356 _ecore_x_event_handlers[DestroyNotify] =
357 _ecore_x_event_handle_destroy_notify;
358 _ecore_x_event_handlers[UnmapNotify] = _ecore_x_event_handle_unmap_notify;
359 _ecore_x_event_handlers[MapNotify] = _ecore_x_event_handle_map_notify;
360 _ecore_x_event_handlers[MapRequest] = _ecore_x_event_handle_map_request;
361 _ecore_x_event_handlers[ReparentNotify] =
362 _ecore_x_event_handle_reparent_notify;
363 _ecore_x_event_handlers[ConfigureNotify] =
364 _ecore_x_event_handle_configure_notify;
365 _ecore_x_event_handlers[ConfigureRequest] =
366 _ecore_x_event_handle_configure_request;
367 _ecore_x_event_handlers[GravityNotify] =
368 _ecore_x_event_handle_gravity_notify;
369 _ecore_x_event_handlers[ResizeRequest] =
370 _ecore_x_event_handle_resize_request;
371 _ecore_x_event_handlers[CirculateNotify] =
372 _ecore_x_event_handle_circulate_notify;
373 _ecore_x_event_handlers[CirculateRequest] =
374 _ecore_x_event_handle_circulate_request;
375 _ecore_x_event_handlers[PropertyNotify] =
376 _ecore_x_event_handle_property_notify;
377 _ecore_x_event_handlers[SelectionClear] =
378 _ecore_x_event_handle_selection_clear;
379 _ecore_x_event_handlers[SelectionRequest] =
380 _ecore_x_event_handle_selection_request;
381 _ecore_x_event_handlers[SelectionNotify] =
382 _ecore_x_event_handle_selection_notify;
383 _ecore_x_event_handlers[ColormapNotify] =
384 _ecore_x_event_handle_colormap_notify;
385 _ecore_x_event_handlers[ClientMessage] =
386 _ecore_x_event_handle_client_message;
387 _ecore_x_event_handlers[MappingNotify] =
388 _ecore_x_event_handle_mapping_notify;
390 _ecore_x_event_handlers[GenericEvent] = _ecore_x_event_handle_generic_event;
391 #endif /* ifdef GenericEvent */
393 if (_ecore_x_event_shape_id)
394 _ecore_x_event_handlers[_ecore_x_event_shape_id] =
395 _ecore_x_event_handle_shape_change;
397 if (_ecore_x_event_screensaver_id)
398 _ecore_x_event_handlers[_ecore_x_event_screensaver_id] =
399 _ecore_x_event_handle_screensaver_notify;
401 if (_ecore_x_event_sync_id)
403 _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncCounterNotify] =
404 _ecore_x_event_handle_sync_counter;
405 _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncAlarmNotify] =
406 _ecore_x_event_handle_sync_alarm;
410 if (_ecore_x_event_randr_id)
412 _ecore_x_event_handlers[_ecore_x_event_randr_id +
413 RRScreenChangeNotify] =
414 _ecore_x_event_handle_randr_change;
415 _ecore_x_event_handlers[_ecore_x_event_randr_id +
416 RRNotify] = _ecore_x_event_handle_randr_notify;
419 #endif /* ifdef ECORE_XRANDR */
421 if (_ecore_x_event_fixes_selection_id)
422 _ecore_x_event_handlers[_ecore_x_event_fixes_selection_id] =
423 _ecore_x_event_handle_fixes_selection_notify;
425 #endif /* ifdef ECORE_XFIXES */
427 if (_ecore_x_event_damage_id)
428 _ecore_x_event_handlers[_ecore_x_event_damage_id] =
429 _ecore_x_event_handle_damage_notify;
431 #endif /* ifdef ECORE_XDAMAGE */
433 // set x autorepeat detection to on. that means instead of
434 // press-release-press-release-press-release
436 // press-press-press-press-press-release
440 XkbSetDetectableAutoRepeat(_ecore_x_disp, 1, &works);
443 #endif /* ifdef ECORE_XKB */
445 if (!ECORE_X_EVENT_ANY)
447 ECORE_X_EVENT_ANY = ecore_event_type_new();
448 ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new();
449 ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new();
450 ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
451 ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
452 ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new();
453 ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
454 ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new();
455 ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new();
456 ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new();
457 ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new();
458 ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new();
459 ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new();
460 ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new();
461 ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
462 ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new();
463 ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new();
464 ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new();
465 ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new();
466 ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new();
467 ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new();
468 ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new();
469 ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new();
470 ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new();
471 ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new();
472 ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new();
473 ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new();
474 ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new();
475 ECORE_X_EVENT_SCREENSAVER_NOTIFY = ecore_event_type_new();
476 ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new();
477 ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new();
478 ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new();
479 ECORE_X_EVENT_RANDR_CRTC_CHANGE = ecore_event_type_new();
480 ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = ecore_event_type_new();
481 ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = ecore_event_type_new();
482 ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new();
484 ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
486 ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = ecore_event_type_new();
487 ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = ecore_event_type_new();
488 ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = ecore_event_type_new();
489 ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = ecore_event_type_new();
490 ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = ecore_event_type_new();
491 ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = ecore_event_type_new();
492 ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = ecore_event_type_new();
493 ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = ecore_event_type_new();
496 ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new();
497 ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new();
498 ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new();
499 ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new();
500 ECORE_X_EVENT_PING = ecore_event_type_new();
502 ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new();
503 ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new();
504 ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new();
506 ECORE_X_EVENT_GENERIC = ecore_event_type_new();
509 /* everything has these... unless its like a pda... :) */
510 ECORE_X_MODIFIER_SHIFT = _ecore_x_key_mask_get(XK_Shift_L);
511 ECORE_X_MODIFIER_CTRL = _ecore_x_key_mask_get(XK_Control_L);
513 /* apple's xdarwin has no alt!!!! */
514 ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Alt_L);
515 if (!ECORE_X_MODIFIER_ALT)
516 ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Meta_L);
518 if (!ECORE_X_MODIFIER_ALT)
519 ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Super_L);
521 /* the windows key... a valid modifier :) */
522 ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Super_L);
523 if (!ECORE_X_MODIFIER_WIN)
524 ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Mode_switch);
526 if (!ECORE_X_MODIFIER_WIN)
527 ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Meta_L);
529 if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT)
530 ECORE_X_MODIFIER_WIN = 0;
532 if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL)
533 ECORE_X_MODIFIER_ALT = 0;
535 ECORE_X_LOCK_SCROLL = _ecore_x_key_mask_get(XK_Scroll_Lock);
536 ECORE_X_LOCK_NUM = _ecore_x_key_mask_get(XK_Num_Lock);
537 ECORE_X_LOCK_CAPS = _ecore_x_key_mask_get(XK_Caps_Lock);
539 _ecore_x_fd_handler_handle =
540 ecore_main_fd_handler_add(ConnectionNumber(_ecore_x_disp),
542 _ecore_x_fd_handler, _ecore_x_disp,
543 _ecore_x_fd_handler_buf, _ecore_x_disp);
544 if (!_ecore_x_fd_handler_handle)
545 goto free_event_handlers;
547 _ecore_x_atoms_init();
549 /* Set up the ICCCM hints */
550 ecore_x_icccm_init();
552 /* Set up the _NET_... hints */
553 ecore_x_netwm_init();
555 /* old e hints init */
558 /* This is just to be anal about naming conventions */
560 _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] =
561 ECORE_X_ATOM_WM_DELETE_WINDOW;
562 _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] =
563 ECORE_X_ATOM_WM_TAKE_FOCUS;
564 _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] =
565 ECORE_X_ATOM_NET_WM_PING;
566 _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] =
567 ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
569 _ecore_x_selection_data_init();
571 _ecore_x_fixes_init();
572 _ecore_x_damage_init();
573 _ecore_x_composite_init();
574 _ecore_x_dpms_init();
575 _ecore_x_randr_init();
576 _ecore_x_input_init();
578 _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456);
582 if (!_ecore_x_ic && XSupportsLocale())
586 XIMStyles *supported_styles;
587 XIMStyle chosen_style = 0;
588 Ecore_X_Window client_window = ecore_x_window_root_get(
589 _ecore_x_private_win);
593 XSetLocaleModifiers("@im=none");
594 if (!(im = XOpenIM(_ecore_x_disp, NULL, NULL, NULL)))
597 ret = XGetIMValues(im, XNQueryInputStyle, &supported_styles, NULL);
598 if (ret || !supported_styles)
599 goto _im_create_error;
601 for (i = 0; i < supported_styles->count_styles; i++)
603 if (supported_styles->supported_styles[i] ==
604 (XIMPreeditNothing | XIMStatusNothing))
605 chosen_style = supported_styles->supported_styles[i];
607 XFree(supported_styles);
609 goto _im_create_error;
629 #endif /* ifdef ENABLE_XIM */
630 return _ecore_x_init_count;
633 free(_ecore_x_event_handlers);
634 _ecore_x_event_handlers = NULL;
636 XCloseDisplay(_ecore_x_disp);
637 _ecore_x_fd_handler_handle = NULL;
638 _ecore_x_disp = NULL;
639 shutdown_ecore_event:
640 ecore_event_shutdown();
644 eina_log_domain_unregister(_ecore_xlib_log_dom);
645 _ecore_xlib_log_dom = -1;
648 return --_ecore_x_init_count;
652 _ecore_x_shutdown(int close_display)
654 if (--_ecore_x_init_count != 0)
655 return _ecore_x_init_count;
658 return _ecore_x_init_count;
660 LOGFN(__FILE__, __LINE__, __FUNCTION__);
665 XDestroyIC(_ecore_x_ic);
671 XCloseIM(_ecore_x_im);
675 #endif /* ifdef ENABLE_XIM */
676 ecore_main_fd_handler_del(_ecore_x_fd_handler_handle);
678 XCloseDisplay(_ecore_x_disp);
681 close(ConnectionNumber(_ecore_x_disp));
682 // FIXME: may have to clean up x display internal here
683 XFree(_ecore_x_disp);
686 free(_ecore_x_event_handlers);
687 _ecore_x_fd_handler_handle = NULL;
688 _ecore_x_disp = NULL;
689 _ecore_x_event_handlers = NULL;
690 _ecore_x_input_shutdown();
691 _ecore_x_selection_shutdown();
692 _ecore_x_dnd_shutdown();
693 ecore_x_netwm_shutdown();
695 ecore_event_shutdown();
698 eina_log_domain_unregister(_ecore_xlib_log_dom);
699 _ecore_xlib_log_dom = -1;
702 return _ecore_x_init_count;
703 } /* _ecore_x_shutdown */
706 * Shuts down the Ecore X library.
708 * In shutting down the library, the X display connection is terminated
709 * and any event handlers for it are removed.
711 * @return The number of times the library has been initialized without
713 * @ingroup Ecore_X_Init_Group
716 ecore_x_shutdown(void)
718 return _ecore_x_shutdown(1);
719 } /* ecore_x_shutdown */
722 * Shuts down the Ecore X library.
724 * As ecore_x_shutdown, except do not close Display, only connection.
726 * @ingroup Ecore_X_Init_Group
729 ecore_x_disconnect(void)
731 return _ecore_x_shutdown(0);
732 } /* ecore_x_disconnect */
735 * @defgroup Ecore_X_Display_Attr_Group X Display Attributes
737 * Functions that set and retrieve X display attributes.
741 * Retrieves the Ecore_X_Display handle used for the current X connection.
742 * @return The current X display.
743 * @ingroup Ecore_X_Display_Attr_Group
745 EAPI Ecore_X_Display *
746 ecore_x_display_get(void)
748 return (Ecore_X_Display *)_ecore_x_disp;
749 } /* ecore_x_display_get */
752 * Retrieves the X display file descriptor.
753 * @return The current X display file descriptor.
754 * @ingroup Ecore_X_Display_Attr_Group
759 LOGFN(__FILE__, __LINE__, __FUNCTION__);
760 return ConnectionNumber(_ecore_x_disp);
761 } /* ecore_x_fd_get */
764 * Retrieves the Ecore_X_Screen handle used for the current X connection.
765 * @return The current default screen.
766 * @ingroup Ecore_Xcb_Display_Attr_Group
768 EAPI Ecore_X_Screen *
769 ecore_x_default_screen_get(void)
771 LOGFN(__FILE__, __LINE__, __FUNCTION__);
772 return (Ecore_X_Screen *)DefaultScreenOfDisplay(_ecore_x_disp);
773 } /* ecore_x_default_screen_get */
776 * Sets the timeout for a double and triple clicks to be flagged.
778 * This sets the time between clicks before the double_click flag is
779 * set in a button down event. If 3 clicks occur within double this
780 * time, the triple_click flag is also set.
782 * @param t The time in seconds
783 * @ingroup Ecore_X_Display_Attr_Group
786 ecore_x_double_click_time_set(double t)
791 _ecore_x_double_click_time = t;
792 } /* ecore_x_double_click_time_set */
795 * Retrieves the double and triple click flag timeout.
797 * See @ref ecore_x_double_click_time_set for more information.
799 * @return The timeout for double clicks in seconds.
800 * @ingroup Ecore_X_Display_Attr_Group
803 ecore_x_double_click_time_get(void)
805 return _ecore_x_double_click_time;
806 } /* ecore_x_double_click_time_get */
809 * @defgroup Ecore_X_Flush_Group X Synchronization Functions
811 * Functions that ensure that all commands that have been issued by the
812 * Ecore X library have been sent to the server.
816 * Sends all X commands in the X Display buffer.
817 * @ingroup Ecore_X_Flush_Group
822 LOGFN(__FILE__, __LINE__, __FUNCTION__);
823 XFlush(_ecore_x_disp);
824 } /* ecore_x_flush */
827 * Flushes the command buffer and waits until all requests have been
828 * processed by the server.
829 * @ingroup Ecore_X_Flush_Group
834 LOGFN(__FILE__, __LINE__, __FUNCTION__);
835 XSync(_ecore_x_disp, False);
839 * Kill all clients with subwindows under a given window.
841 * You can kill all clients connected to the X server by using
842 * @ref ecore_x_window_root_list to get a list of root windows, and
843 * then passing each root window to this function.
845 * @param root The window whose children will be killed.
848 ecore_x_killall(Ecore_X_Window root)
853 Window *children_r = NULL;
854 unsigned int num_children = 0;
856 LOGFN(__FILE__, __LINE__, __FUNCTION__);
857 XGrabServer(_ecore_x_disp);
858 /* Tranverse window tree starting from root, and drag each
859 * before the firing squad */
860 while (XQueryTree(_ecore_x_disp, root, &root_r, &parent_r,
861 &children_r, &num_children) && (num_children > 0))
863 for (j = 0; j < num_children; ++j)
865 XKillClient(_ecore_x_disp, children_r[j]);
870 XUngrabServer(_ecore_x_disp);
871 XSync(_ecore_x_disp, False);
872 } /* ecore_x_killall */
875 * Kill a specific client
877 * You can kill a specific client owning window @p win
879 * @param win Window of the client to be killed
882 ecore_x_kill(Ecore_X_Window win)
884 LOGFN(__FILE__, __LINE__, __FUNCTION__);
885 XKillClient(_ecore_x_disp, win);
889 * Return the last event time
892 ecore_x_current_time_get(void)
894 return _ecore_x_event_last_time;
895 } /* ecore_x_current_time_get */
898 * Return the screen DPI
900 * This is a simplistic call to get DPI. It does not account for differing
901 * DPI in the x amd y axes nor does it accoutn for multihead or xinerama and
902 * xrander where different parts of the screen may have differen DPI etc.
904 * @return the general screen DPI (dots/pixels per inch).
907 ecore_x_dpi_get(void)
911 LOGFN(__FILE__, __LINE__, __FUNCTION__);
912 s = DefaultScreenOfDisplay(_ecore_x_disp);
916 return (((s->width * 254) / s->mwidth) + 5) / 10;
917 } /* ecore_x_dpi_get */
920 * Invoke the standard system beep to alert users
922 * @param percent The volume at which the bell rings. Must be in the range
923 * [-100,+100]. If percent >= 0, the final volume will be:
924 * base - [(base * percent) / 100] + percent
925 * Otherwise, it's calculated as:
926 * base + [(base * percent) / 100]
927 * where @c base is the bell's base volume as set by XChangeKeyboardControl(3).
929 * @returns EINA_TRUE on success, EINA_FALSE otherwise.
932 ecore_x_bell(int percent)
936 ret = XBell(_ecore_x_disp, percent);
944 _ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
956 /* Filter event for XIM */
957 if (XFilterEvent(&ev, ev.xkey.window))
960 #endif /* ifdef ENABLE_XIM */
962 if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num))
964 if (_ecore_x_event_handlers[AnyXEvent])
965 _ecore_x_event_handlers[AnyXEvent] (&ev);
967 if (_ecore_x_event_handlers[ev.type])
968 _ecore_x_event_handlers[ev.type] (&ev);
971 return ECORE_CALLBACK_RENEW;
972 } /* _ecore_x_fd_handler */
975 _ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
981 return ECORE_CALLBACK_RENEW;
983 return ECORE_CALLBACK_CANCEL;
984 } /* _ecore_x_fd_handler_buf */
987 _ecore_x_key_mask_get(KeySym sym)
989 XModifierKeymap *mod;
994 ShiftMask, LockMask, ControlMask,
995 Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
998 mod = XGetModifierMapping(_ecore_x_disp);
999 if ((mod) && (mod->max_keypermod > 0))
1000 for (i = 0; i < (8 * mod->max_keypermod); i++)
1002 for (j = 0; j < 8; j++)
1004 sym2 = XKeycodeToKeysym(_ecore_x_disp, mod->modifiermap[i], j);
1012 mask = masks[i / mod->max_keypermod];
1013 if (mod->modifiermap)
1014 XFree(mod->modifiermap);
1023 if (mod->modifiermap)
1024 XFree(mod->modifiermap);
1030 } /* _ecore_x_key_mask_get */
1032 /*****************************************************************************/
1033 /*****************************************************************************/
1034 /*****************************************************************************/
1035 /* FIXME: these funcs need categorising */
1036 /*****************************************************************************/
1039 * Get a list of all the root windows on the server.
1041 * @note The returned array will need to be freed after use.
1042 * @param num_ret Pointer to integer to put number of windows returned in.
1043 * @return An array of all the root windows. @c NULL is returned if memory
1044 * could not be allocated for the list, or if @p num_ret is @c NULL.
1046 EAPI Ecore_X_Window *
1047 ecore_x_window_root_list(int *num_ret)
1050 Ecore_X_Window *roots;
1052 int xp_base, xp_err_base;
1053 #endif /* ifdef ECORE_XPRINT */
1060 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1062 num = ScreenCount(_ecore_x_disp);
1063 if (XpQueryExtension(_ecore_x_disp, &xp_base, &xp_err_base))
1068 ps = XpQueryScreens(_ecore_x_disp, &psnum);
1074 for (i = 0; i < num; i++)
1076 for (j = 0; j < psnum; j++)
1078 if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
1082 roots = malloc((num - overlap) * sizeof(Window));
1088 for (i = 0; i < num; i++)
1093 for (j = 0; j < psnum; j++)
1095 if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
1103 roots[k] = RootWindow(_ecore_x_disp, i);
1114 roots = malloc(num * sizeof(Window));
1119 for (i = 0; i < num; i++)
1120 roots[i] = RootWindow(_ecore_x_disp, i);
1125 roots = malloc(num * sizeof(Window));
1130 for (i = 0; i < num; i++)
1131 roots[i] = RootWindow(_ecore_x_disp, i);
1134 #else /* ifdef ECORE_XPRINT */
1135 num = ScreenCount(_ecore_x_disp);
1136 roots = malloc(num * sizeof(Window));
1141 for (i = 0; i < num; i++)
1142 roots[i] = RootWindow(_ecore_x_disp, i);
1143 #endif /* ifdef ECORE_XPRINT */
1145 } /* ecore_x_window_root_list */
1148 ecore_x_window_root_first_get(void)
1150 return RootWindow(_ecore_x_disp, 0);
1153 Ecore_X_Window root, *roots = NULL;
1155 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1156 roots = ecore_x_window_root_list(&num);
1157 if (!(roots)) return 0;
1167 } /* ecore_x_window_root_first_get */
1169 static void _ecore_x_window_manage_error(void *data);
1171 static int _ecore_x_window_manage_failed = 0;
1173 _ecore_x_window_manage_error(void *data __UNUSED__)
1175 if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) &&
1176 (ecore_x_error_code_get() == BadAccess))
1177 _ecore_x_window_manage_failed = 1;
1178 } /* _ecore_x_window_manage_error */
1181 ecore_x_window_manage(Ecore_X_Window win)
1183 XWindowAttributes att;
1185 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1186 if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True)
1190 _ecore_x_window_manage_failed = 0;
1191 ecore_x_error_handler_set(_ecore_x_window_manage_error, NULL);
1192 XSelectInput(_ecore_x_disp, win,
1195 PropertyChangeMask |
1196 ResizeRedirectMask |
1197 SubstructureRedirectMask |
1198 SubstructureNotifyMask |
1199 StructureNotifyMask |
1202 att.your_event_mask);
1204 ecore_x_error_handler_set(NULL, NULL);
1205 if (_ecore_x_window_manage_failed)
1207 _ecore_x_window_manage_failed = 0;
1212 } /* ecore_x_window_manage */
1215 ecore_x_window_container_manage(Ecore_X_Window win)
1217 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1218 XSelectInput(_ecore_x_disp, win,
1219 SubstructureRedirectMask |
1220 SubstructureNotifyMask);
1221 } /* ecore_x_window_container_manage */
1224 ecore_x_window_client_manage(Ecore_X_Window win)
1226 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1227 XSelectInput(_ecore_x_disp, win,
1228 PropertyChangeMask |
1229 // ResizeRedirectMask |
1231 ColormapChangeMask |
1232 VisibilityChangeMask |
1233 StructureNotifyMask |
1234 SubstructureNotifyMask
1236 XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1237 } /* ecore_x_window_client_manage */
1240 ecore_x_window_sniff(Ecore_X_Window win)
1242 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1243 XSelectInput(_ecore_x_disp, win,
1244 PropertyChangeMask |
1245 SubstructureNotifyMask);
1246 } /* ecore_x_window_sniff */
1249 ecore_x_window_client_sniff(Ecore_X_Window win)
1251 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1252 XSelectInput(_ecore_x_disp, win,
1253 PropertyChangeMask |
1255 ColormapChangeMask |
1256 VisibilityChangeMask |
1257 StructureNotifyMask |
1258 SubstructureNotifyMask);
1259 XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1260 } /* ecore_x_window_client_sniff */
1263 ecore_x_window_attributes_get(Ecore_X_Window win,
1264 Ecore_X_Window_Attributes *att_ret)
1266 XWindowAttributes att;
1268 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1269 if (!XGetWindowAttributes(_ecore_x_disp, win, &att))
1272 memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
1273 att_ret->root = att.root;
1276 att_ret->w = att.width;
1277 att_ret->h = att.height;
1278 att_ret->border = att.border_width;
1279 att_ret->depth = att.depth;
1280 if (att.map_state != IsUnmapped)
1281 att_ret->visible = 1;
1283 if (att.map_state == IsViewable)
1284 att_ret->viewable = 1;
1286 if (att.override_redirect)
1287 att_ret->override = 1;
1289 if (att.class == InputOnly)
1290 att_ret->input_only = 1;
1293 att_ret->save_under = 1;
1295 att_ret->event_mask.mine = att.your_event_mask;
1296 att_ret->event_mask.all = att.all_event_masks;
1297 att_ret->event_mask.no_propagate = att.do_not_propagate_mask;
1298 att_ret->window_gravity = att.win_gravity;
1299 att_ret->pixel_gravity = att.bit_gravity;
1300 att_ret->colormap = att.colormap;
1301 att_ret->visual = att.visual;
1303 } /* ecore_x_window_attributes_get */
1306 ecore_x_window_save_set_add(Ecore_X_Window win)
1308 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1309 XAddToSaveSet(_ecore_x_disp, win);
1310 } /* ecore_x_window_save_set_add */
1313 ecore_x_window_save_set_del(Ecore_X_Window win)
1315 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1316 XRemoveFromSaveSet(_ecore_x_disp, win);
1317 } /* ecore_x_window_save_set_del */
1319 EAPI Ecore_X_Window *
1320 ecore_x_window_children_get(Ecore_X_Window win, int *num)
1322 Ecore_X_Window *windows = NULL;
1323 Window root_ret = 0, parent_ret = 0, *children_ret = NULL;
1324 unsigned int children_ret_num = 0;
1326 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1327 if (!XQueryTree(_ecore_x_disp, win, &root_ret, &parent_ret, &children_ret,
1333 windows = malloc(children_ret_num * sizeof(Ecore_X_Window));
1338 for (i = 0; i < children_ret_num; i++)
1339 windows[i] = children_ret[i];
1340 *num = children_ret_num;
1343 XFree(children_ret);
1347 } /* ecore_x_window_children_get */
1350 ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold)
1352 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1353 return XChangePointerControl(_ecore_x_disp, 1, 1,
1354 accel_num, accel_denom, threshold) ? EINA_TRUE : EINA_FALSE;
1355 } /* ecore_x_pointer_control_set */
1358 ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold)
1360 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1361 return XGetPointerControl(_ecore_x_disp,
1362 accel_num, accel_denom, threshold) ? EINA_TRUE : EINA_FALSE;
1363 } /* ecore_x_pointer_control_get */
1366 ecore_x_pointer_mapping_set(unsigned char *map, int nmap)
1368 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1369 return XSetPointerMapping(_ecore_x_disp, map, nmap) ? EINA_TRUE : EINA_FALSE;
1370 } /* ecore_x_pointer_mapping_set */
1373 ecore_x_pointer_mapping_get(unsigned char *map, int nmap)
1375 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1376 return XGetPointerMapping(_ecore_x_disp, map, nmap) ? EINA_TRUE : EINA_FALSE;
1377 } /* ecore_x_pointer_mapping_get */
1380 ecore_x_pointer_grab(Ecore_X_Window win)
1382 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1383 if (XGrabPointer(_ecore_x_disp, win, False,
1384 ButtonPressMask | ButtonReleaseMask |
1385 EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1386 GrabModeAsync, GrabModeAsync,
1387 None, None, CurrentTime) == GrabSuccess)
1391 } /* ecore_x_pointer_grab */
1394 ecore_x_pointer_confine_grab(Ecore_X_Window win)
1396 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1397 if (XGrabPointer(_ecore_x_disp, win, False,
1398 ButtonPressMask | ButtonReleaseMask |
1399 EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1400 GrabModeAsync, GrabModeAsync,
1401 win, None, CurrentTime) == GrabSuccess)
1405 } /* ecore_x_pointer_confine_grab */
1408 ecore_x_pointer_ungrab(void)
1410 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1411 XUngrabPointer(_ecore_x_disp, CurrentTime);
1412 } /* ecore_x_pointer_ungrab */
1415 ecore_x_pointer_warp(Ecore_X_Window win, int x, int y)
1417 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1418 return XWarpPointer(_ecore_x_disp, None, win, 0, 0, 0, 0, x, y) ? EINA_TRUE : EINA_FALSE;
1419 } /* ecore_x_pointer_warp */
1422 ecore_x_keyboard_grab(Ecore_X_Window win)
1424 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1425 if (XGrabKeyboard(_ecore_x_disp, win, False,
1426 GrabModeAsync, GrabModeAsync,
1427 CurrentTime) == GrabSuccess)
1431 } /* ecore_x_keyboard_grab */
1434 ecore_x_keyboard_ungrab(void)
1436 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1437 XUngrabKeyboard(_ecore_x_disp, CurrentTime);
1438 } /* ecore_x_keyboard_ungrab */
1443 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1444 _ecore_x_grab_count++;
1445 if (_ecore_x_grab_count == 1)
1446 XGrabServer(_ecore_x_disp);
1447 } /* ecore_x_grab */
1450 ecore_x_ungrab(void)
1452 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1453 _ecore_x_grab_count--;
1454 if (_ecore_x_grab_count < 0)
1455 _ecore_x_grab_count = 0;
1457 if (_ecore_x_grab_count == 0)
1458 XUngrabServer(_ecore_x_disp);
1459 } /* ecore_x_ungrab */
1461 int _ecore_window_grabs_num = 0;
1462 Window *_ecore_window_grabs = NULL;
1463 Eina_Bool (*_ecore_window_grab_replay_func)(void *data, int event_type,
1465 void *_ecore_window_grab_replay_data;
1468 ecore_x_passive_grab_replay_func_set(Eina_Bool (*func)(void *data,
1470 void *event), void *data)
1472 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1473 _ecore_window_grab_replay_func = func;
1474 _ecore_window_grab_replay_data = data;
1475 } /* ecore_x_passive_grab_replay_func_set */
1478 ecore_x_window_button_grab(Ecore_X_Window win, int button,
1479 Ecore_X_Event_Mask event_mask,
1480 int mod, int any_mod)
1484 unsigned int locks[8];
1487 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1492 m = _ecore_x_event_modifier(mod);
1497 locks[1] = ECORE_X_LOCK_CAPS;
1498 locks[2] = ECORE_X_LOCK_NUM;
1499 locks[3] = ECORE_X_LOCK_SCROLL;
1500 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1501 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1502 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1503 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1505 for (i = 0; i < 8; i++)
1506 XGrabButton(_ecore_x_disp, b, m | locks[i],
1507 win, False, ev, GrabModeSync, GrabModeAsync, None, None);
1508 _ecore_window_grabs_num++;
1509 _ecore_window_grabs = realloc(_ecore_window_grabs,
1510 _ecore_window_grabs_num * sizeof(Window));
1511 _ecore_window_grabs[_ecore_window_grabs_num - 1] = win;
1512 } /* ecore_x_window_button_grab */
1515 _ecore_x_sync_magic_send(int val, Ecore_X_Window swin)
1519 xev.xclient.type = ClientMessage;
1520 xev.xclient.serial = 0;
1521 xev.xclient.send_event = True;
1522 xev.xclient.display = _ecore_x_disp;
1523 xev.xclient.window = _ecore_x_private_win;
1524 xev.xclient.format = 32;
1525 xev.xclient.message_type = 27777;
1526 xev.xclient.data.l[0] = 0x7162534;
1527 xev.xclient.data.l[1] = 0x10000000 + val;
1528 xev.xclient.data.l[2] = swin;
1529 XSendEvent(_ecore_x_disp, _ecore_x_private_win, False, NoEventMask, &xev);
1530 } /* _ecore_x_sync_magic_send */
1533 _ecore_x_window_grab_remove(Ecore_X_Window win)
1537 if (_ecore_window_grabs_num > 0)
1539 for (i = 0; i < _ecore_window_grabs_num; i++)
1542 _ecore_window_grabs[i - 1] = _ecore_window_grabs[i];
1544 if ((!shuffle) && (_ecore_window_grabs[i] == win))
1549 _ecore_window_grabs_num--;
1550 _ecore_window_grabs = realloc(_ecore_window_grabs,
1551 _ecore_window_grabs_num *
1555 } /* _ecore_x_window_grab_remove */
1558 ecore_x_window_button_ungrab(Ecore_X_Window win, int button,
1559 int mod, int any_mod)
1563 unsigned int locks[8];
1566 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1571 m = _ecore_x_event_modifier(mod);
1576 locks[1] = ECORE_X_LOCK_CAPS;
1577 locks[2] = ECORE_X_LOCK_NUM;
1578 locks[3] = ECORE_X_LOCK_SCROLL;
1579 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1580 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1581 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1582 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1583 for (i = 0; i < 8; i++)
1584 XUngrabButton(_ecore_x_disp, b, m | locks[i], win);
1585 _ecore_x_sync_magic_send(1, win);
1586 } /* ecore_x_window_button_ungrab */
1588 int _ecore_key_grabs_num = 0;
1589 Window *_ecore_key_grabs = NULL;
1592 ecore_x_window_key_grab(Ecore_X_Window win, const char *key,
1593 int mod, int any_mod)
1595 KeyCode keycode = 0;
1598 unsigned int locks[8];
1601 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1602 if (!strncmp(key, "Keycode-", 8))
1603 keycode = atoi(key + 8);
1606 keysym = XStringToKeysym(key);
1607 if (keysym == NoSymbol)
1610 keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
1616 m = _ecore_x_event_modifier(mod);
1621 locks[1] = ECORE_X_LOCK_CAPS;
1622 locks[2] = ECORE_X_LOCK_NUM;
1623 locks[3] = ECORE_X_LOCK_SCROLL;
1624 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1625 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1626 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1627 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1628 for (i = 0; i < 8; i++)
1629 XGrabKey(_ecore_x_disp, keycode, m | locks[i],
1630 win, False, GrabModeSync, GrabModeAsync);
1631 _ecore_key_grabs_num++;
1632 _ecore_key_grabs = realloc(_ecore_key_grabs,
1633 _ecore_key_grabs_num * sizeof(Window));
1634 _ecore_key_grabs[_ecore_key_grabs_num - 1] = win;
1635 } /* ecore_x_window_key_grab */
1638 _ecore_x_key_grab_remove(Ecore_X_Window win)
1642 if (_ecore_key_grabs_num > 0)
1644 for (i = 0; i < _ecore_key_grabs_num; i++)
1647 _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
1649 if ((!shuffle) && (_ecore_key_grabs[i] == win))
1654 _ecore_key_grabs_num--;
1655 _ecore_key_grabs = realloc(_ecore_key_grabs,
1656 _ecore_key_grabs_num * sizeof(Window));
1659 } /* _ecore_x_key_grab_remove */
1662 ecore_x_window_key_ungrab(Ecore_X_Window win, const char *key,
1663 int mod, int any_mod)
1665 KeyCode keycode = 0;
1668 unsigned int locks[8];
1671 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1672 if (!strncmp(key, "Keycode-", 8))
1673 keycode = atoi(key + 8);
1676 keysym = XStringToKeysym(key);
1677 if (keysym == NoSymbol)
1680 keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
1686 m = _ecore_x_event_modifier(mod);
1691 locks[1] = ECORE_X_LOCK_CAPS;
1692 locks[2] = ECORE_X_LOCK_NUM;
1693 locks[3] = ECORE_X_LOCK_SCROLL;
1694 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1695 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1696 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1697 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1698 for (i = 0; i < 8; i++)
1699 XUngrabKey(_ecore_x_disp, keycode, m | locks[i], win);
1700 _ecore_x_sync_magic_send(2, win);
1701 } /* ecore_x_window_key_ungrab */
1704 * Send client message with given type and format 32.
1706 * @param win The window the message is sent to.
1707 * @param type The client message type.
1708 * @param d0 The client message data item 1
1709 * @param d1 The client message data item 2
1710 * @param d2 The client message data item 3
1711 * @param d3 The client message data item 4
1712 * @param d4 The client message data item 5
1714 * @return EINA_TRUE on success EINA_FALSE otherwise.
1717 ecore_x_client_message32_send(Ecore_X_Window win, Ecore_X_Atom type,
1718 Ecore_X_Event_Mask mask,
1719 long d0, long d1, long d2, long d3, long d4)
1723 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1724 xev.xclient.window = win;
1725 xev.xclient.type = ClientMessage;
1726 xev.xclient.message_type = type;
1727 xev.xclient.format = 32;
1728 xev.xclient.data.l[0] = d0;
1729 xev.xclient.data.l[1] = d1;
1730 xev.xclient.data.l[2] = d2;
1731 xev.xclient.data.l[3] = d3;
1732 xev.xclient.data.l[4] = d4;
1734 return XSendEvent(_ecore_x_disp, win, False, mask, &xev) ? EINA_TRUE : EINA_FALSE;
1735 } /* ecore_x_client_message32_send */
1738 * Send client message with given type and format 8.
1740 * @param win The window the message is sent to.
1741 * @param type The client message type.
1742 * @param data Data to be sent.
1743 * @param len Number of data bytes, max 20.
1745 * @return EINA_TRUE on success EINA_FALSE otherwise.
1748 ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type,
1749 const void *data, int len)
1753 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1754 xev.xclient.window = win;
1755 xev.xclient.type = ClientMessage;
1756 xev.xclient.message_type = type;
1757 xev.xclient.format = 8;
1761 memcpy(xev.xclient.data.b, data, len);
1762 memset(xev.xclient.data.b + len, 0, 20 - len);
1764 return XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev) ? EINA_TRUE : EINA_FALSE;
1765 } /* ecore_x_client_message8_send */
1768 ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y)
1771 XWindowAttributes att;
1775 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1776 XGetWindowAttributes(_ecore_x_disp, win, &att);
1777 XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1778 xev.xmotion.type = MotionNotify;
1779 xev.xmotion.window = win;
1780 xev.xmotion.root = att.root;
1781 xev.xmotion.subwindow = win;
1782 xev.xmotion.time = _ecore_x_event_last_time;
1785 xev.xmotion.x_root = rx;
1786 xev.xmotion.y_root = ry;
1787 xev.xmotion.state = 0;
1788 xev.xmotion.is_hint = 0;
1789 xev.xmotion.same_screen = 1;
1790 return XSendEvent(_ecore_x_disp, win, True, PointerMotionMask, &xev) ? EINA_TRUE : EINA_FALSE;
1791 } /* ecore_x_mouse_move_send */
1794 ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b)
1797 XWindowAttributes att;
1801 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1802 XGetWindowAttributes(_ecore_x_disp, win, &att);
1803 XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1804 xev.xbutton.type = ButtonPress;
1805 xev.xbutton.window = win;
1806 xev.xbutton.root = att.root;
1807 xev.xbutton.subwindow = win;
1808 xev.xbutton.time = _ecore_x_event_last_time;
1811 xev.xbutton.x_root = rx;
1812 xev.xbutton.y_root = ry;
1813 xev.xbutton.state = 1 << b;
1814 xev.xbutton.button = b;
1815 xev.xbutton.same_screen = 1;
1816 return XSendEvent(_ecore_x_disp, win, True, ButtonPressMask, &xev) ? EINA_TRUE : EINA_FALSE;
1817 } /* ecore_x_mouse_down_send */
1820 ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b)
1823 XWindowAttributes att;
1827 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1828 XGetWindowAttributes(_ecore_x_disp, win, &att);
1829 XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
1830 xev.xbutton.type = ButtonRelease;
1831 xev.xbutton.window = win;
1832 xev.xbutton.root = att.root;
1833 xev.xbutton.subwindow = win;
1834 xev.xbutton.time = _ecore_x_event_last_time;
1837 xev.xbutton.x_root = rx;
1838 xev.xbutton.y_root = ry;
1839 xev.xbutton.state = 0;
1840 xev.xbutton.button = b;
1841 xev.xbutton.same_screen = 1;
1842 return XSendEvent(_ecore_x_disp, win, True, ButtonReleaseMask, &xev) ? EINA_TRUE : EINA_FALSE;
1843 } /* ecore_x_mouse_up_send */
1846 ecore_x_focus_reset(void)
1848 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1849 XSetInputFocus(_ecore_x_disp, PointerRoot, RevertToPointerRoot, CurrentTime);
1850 } /* ecore_x_focus_reset */
1853 ecore_x_events_allow_all(void)
1855 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1856 XAllowEvents(_ecore_x_disp, AsyncBoth, CurrentTime);
1857 } /* ecore_x_events_allow_all */
1860 ecore_x_pointer_last_xy_get(int *x, int *y)
1863 *x = _ecore_x_event_last_root_x;
1866 *y = _ecore_x_event_last_root_y;
1867 } /* ecore_x_pointer_last_xy_get */
1870 ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y)
1873 int rx, ry, wx, wy, ret;
1876 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1877 ret = XQueryPointer(_ecore_x_disp,
1894 } /* ecore_x_pointer_xy_get */
1896 /*****************************************************************************/
1897 /*****************************************************************************/
1898 /*****************************************************************************/
1901 _ecore_x_event_modifier(unsigned int state)
1905 if (state & ECORE_EVENT_MODIFIER_SHIFT)
1906 xmodifiers |= ECORE_X_MODIFIER_SHIFT;
1908 if (state & ECORE_EVENT_MODIFIER_CTRL)
1909 xmodifiers |= ECORE_X_MODIFIER_CTRL;
1911 if (state & ECORE_EVENT_MODIFIER_ALT)
1912 xmodifiers |= ECORE_X_MODIFIER_ALT;
1914 if (state & ECORE_EVENT_MODIFIER_WIN)
1915 xmodifiers |= ECORE_X_MODIFIER_WIN;
1917 if (state & ECORE_EVENT_LOCK_SCROLL)
1918 xmodifiers |= ECORE_X_LOCK_SCROLL;
1920 if (state & ECORE_EVENT_LOCK_NUM)
1921 xmodifiers |= ECORE_X_LOCK_NUM;
1923 if (state & ECORE_EVENT_LOCK_CAPS)
1924 xmodifiers |= ECORE_X_LOCK_CAPS;
1927 } /* _ecore_x_event_modifier */