2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
20 #include "ecore_private.h"
21 #include "ecore_x_private.h"
23 #include "Ecore_X_Atoms.h"
24 #include "Ecore_Input.h"
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);
31 static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL;
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
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;
44 static int _ecore_x_event_randr_id = 0;
47 static int _ecore_x_event_fixes_selection_id = 0;
50 static int _ecore_x_event_damage_id = 0;
52 static int _ecore_x_event_handlers_num = 0;
53 static void (**_ecore_x_event_handlers) (XEvent * event) = NULL;
55 static int _ecore_x_init_count = 0;
56 static int _ecore_x_grab_count = 0;
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 */
67 Ecore_X_Window _ecore_x_private_win = 0;
69 Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
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;
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;
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;
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;
129 EAPI int ECORE_X_EVENT_GENERIC = 0;
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;
136 EAPI int ECORE_X_LOCK_SCROLL = 0;
137 EAPI int ECORE_X_LOCK_NUM = 0;
138 EAPI int ECORE_X_LOCK_CAPS = 0;
141 static double t0 = 0.0;
142 static Status (*_logrt_real_reply) (Display *disp, void *rep, int extra, Bool discard) = NULL;
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();
156 _XReply(Display *disp, void *rep, int extra, Bool discard)
162 n = backtrace(bt, 128);
165 sym = backtrace_symbols(bt, n);
166 printf("ROUNDTRIP: %4.4f :", ecore_time_get() - t0);
169 for (i = n - 1; i > 0; i--)
171 char *fname = strchr(sym[i], '(');
174 char *tsym = alloca(strlen(fname) + 1);
176 strcpy(tsym, fname + 1);
177 end = strchr(tsym, '+');
188 if (i > 1) printf(" > ");
194 return _logrt_real_reply(disp, rep, extra, discard);
199 * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions
201 * Functions that start and shut down the Ecore X Library.
205 * Initialize the X display connection to the given display.
207 * @param name Display target name. If @c NULL, the default display is
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
214 ecore_x_init(const char *name)
217 int shape_err_base = 0;
219 int screensaver_base = 0;
220 int screensaver_err_base = 0;
223 int sync_err_base = 0;
226 int randr_err_base = 0;
230 int fixes_err_base = 0;
234 int damage_err_base = 0;
237 if (++_ecore_x_init_count != 1)
238 return _ecore_x_init_count;
240 LOGFN(__FILE__, __LINE__, __FUNCTION__);
245 _ecore_xlib_log_dom = eina_log_domain_register("EcoreX11", ECORE_XLIB_DEFAULT_LOG_COLOR);
246 if(_ecore_xlib_log_dom < 0)
248 EINA_LOG_ERR("Impossible to create a log domain for the Ecore Xlib module.");
249 return --_ecore_x_init_count;
251 if (!ecore_event_init())
253 eina_log_domain_unregister(_ecore_xlib_log_dom);
254 _ecore_xlib_log_dom = -1;
255 return --_ecore_x_init_count;
257 _ecore_x_disp = XOpenDisplay((char *)name);
259 goto shutdown_ecore_event;
261 _ecore_x_error_handler_init();
262 _ecore_x_event_handlers_num = LASTEvent;
264 #define ECORE_X_EVENT_HANDLERS_GROW(ext_base, ext_num_events) \
266 if (_ecore_x_event_handlers_num < (ext_base + ext_num_events)) \
267 _ecore_x_event_handlers_num = (ext_base + ext_num_events); \
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);
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);
280 if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base))
284 _ecore_x_event_sync_id = sync_base;
285 if (!XSyncInitialize(_ecore_x_disp, &major, &minor))
286 _ecore_x_event_sync_id = 0;
288 ECORE_X_EVENT_HANDLERS_GROW(sync_base, XSyncNumberEvents);
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);
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);
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);
308 _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *));
309 if (!_ecore_x_event_handlers)
313 _ecore_x_xcursor = XcursorSupportsARGB(_ecore_x_disp);
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;
349 _ecore_x_event_handlers[GenericEvent] = _ecore_x_event_handle_generic_event;
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)
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;
364 if (_ecore_x_event_randr_id)
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;
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;
375 if (_ecore_x_event_damage_id)
376 _ecore_x_event_handlers[_ecore_x_event_damage_id] = _ecore_x_event_handle_damage_notify;
379 // set x autorepeat detection to on. that means instead of
380 // press-release-press-release-press-release
382 // press-press-press-press-press-release
386 XkbSetDetectableAutoRepeat(_ecore_x_disp, 1, &works);
391 if (!ECORE_X_EVENT_ANY)
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();
430 ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
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();
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();
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();
452 ECORE_X_EVENT_GENERIC = ecore_event_type_new();
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);
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);
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);
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;
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);
482 _ecore_x_fd_handler_handle =
483 ecore_main_fd_handler_add(ConnectionNumber(_ecore_x_disp),
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;
490 _ecore_x_atoms_init();
492 /* Set up the ICCCM hints */
493 ecore_x_icccm_init();
495 /* Set up the _NET_... hints */
496 ecore_x_netwm_init();
498 /* old e hints init */
501 /* This is just to be anal about naming conventions */
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;
508 _ecore_x_selection_data_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();
517 _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456);
521 if (!_ecore_x_ic && XSupportsLocale())
525 XIMStyles *supported_styles;
526 XIMStyle chosen_style = 0;
527 Ecore_X_Window client_window = ecore_x_window_root_get(_ecore_x_private_win);
531 XSetLocaleModifiers("@im=none");
532 if ((im = XOpenIM(_ecore_x_disp, NULL, NULL, NULL)) == NULL)
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);
542 goto _im_create_error;
543 ic = XCreateIC(im, XNInputStyle, chosen_style, XNClientWindow, client_window, NULL);
554 return _ecore_x_init_count;
557 free(_ecore_x_event_handlers);
558 _ecore_x_event_handlers = NULL;
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();
566 return --_ecore_x_init_count;
570 _ecore_x_shutdown(int close_display)
572 if (--_ecore_x_init_count != 0)
573 return _ecore_x_init_count;
575 if (!_ecore_x_disp) return _ecore_x_init_count;
576 LOGFN(__FILE__, __LINE__, __FUNCTION__);
582 xim = XIMOfIC(_ecore_x_ic);
583 XDestroyIC(_ecore_x_ic);
589 XCloseDisplay(_ecore_x_disp);
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;
608 * Shuts down the Ecore X library.
610 * In shutting down the library, the X display connection is terminated
611 * and any event handlers for it are removed.
613 * @return The number of times the library has been initialized without
615 * @ingroup Ecore_X_Init_Group
618 ecore_x_shutdown(void)
620 return _ecore_x_shutdown(1);
624 * Shuts down the Ecore X library.
626 * As ecore_x_shutdown, except do not close Display, only connection.
628 * @ingroup Ecore_X_Init_Group
631 ecore_x_disconnect(void)
633 return _ecore_x_shutdown(0);
637 * @defgroup Ecore_X_Display_Attr_Group X Display Attributes
639 * Functions that set and retrieve X display attributes.
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
647 EAPI Ecore_X_Display *
648 ecore_x_display_get(void)
650 return (Ecore_X_Display *)_ecore_x_disp;
654 * Retrieves the X display file descriptor.
655 * @return The current X display file descriptor.
656 * @ingroup Ecore_X_Display_Attr_Group
661 LOGFN(__FILE__, __LINE__, __FUNCTION__);
662 return ConnectionNumber(_ecore_x_disp);
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
671 ecore_x_default_screen_get(void)
673 LOGFN(__FILE__, __LINE__, __FUNCTION__);
674 return (Ecore_X_Screen*) DefaultScreenOfDisplay(_ecore_x_disp);
678 * Sets the timeout for a double and triple clicks to be flagged.
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.
684 * @param t The time in seconds
685 * @ingroup Ecore_X_Display_Attr_Group
688 ecore_x_double_click_time_set(double t)
690 if (t < 0.0) t = 0.0;
691 _ecore_x_double_click_time = t;
695 * Retrieves the double and triple click flag timeout.
697 * See @ref ecore_x_double_click_time_set for more information.
699 * @return The timeout for double clicks in seconds.
700 * @ingroup Ecore_X_Display_Attr_Group
703 ecore_x_double_click_time_get(void)
705 return _ecore_x_double_click_time;
709 * @defgroup Ecore_X_Flush_Group X Synchronization Functions
711 * Functions that ensure that all commands that have been issued by the
712 * Ecore X library have been sent to the server.
716 * Sends all X commands in the X Display buffer.
717 * @ingroup Ecore_X_Flush_Group
722 LOGFN(__FILE__, __LINE__, __FUNCTION__);
723 XFlush(_ecore_x_disp);
727 * Flushes the command buffer and waits until all requests have been
728 * processed by the server.
729 * @ingroup Ecore_X_Flush_Group
734 LOGFN(__FILE__, __LINE__, __FUNCTION__);
735 XSync(_ecore_x_disp, False);
739 * Kill all clients with subwindows under a given window.
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.
745 * @param root The window whose children will be killed.
748 ecore_x_killall(Ecore_X_Window root)
753 Window *children_r = NULL;
754 unsigned int num_children = 0;
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))
763 for (j = 0; j < num_children; ++j)
765 XKillClient(_ecore_x_disp, children_r[j]);
770 XUngrabServer(_ecore_x_disp);
771 XSync(_ecore_x_disp, False);
775 * Kill a specific client
777 * You can kill a specific client owning window @p win
779 * @param win Window of the client to be killed
782 ecore_x_kill(Ecore_X_Window win)
784 LOGFN(__FILE__, __LINE__, __FUNCTION__);
785 XKillClient(_ecore_x_disp, win);
789 * Return the last event time
792 ecore_x_current_time_get(void)
794 return _ecore_x_event_last_time;
798 * Return the screen DPI
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.
804 * @return the general screen DPI (dots/pixels per inch).
807 ecore_x_dpi_get(void)
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;
818 _ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
830 /* Filter event for XIM */
831 if (XFilterEvent(&ev, ev.xkey.window)) continue;
834 if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num))
836 if (_ecore_x_event_handlers[AnyXEvent])
837 _ecore_x_event_handlers[AnyXEvent] (&ev);
839 if (_ecore_x_event_handlers[ev.type])
840 _ecore_x_event_handlers[ev.type] (&ev);
847 _ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
852 if (XPending(d)) return 1;
857 _ecore_x_key_mask_get(KeySym sym)
859 XModifierKeymap *mod;
864 ShiftMask, LockMask, ControlMask,
865 Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
868 mod = XGetModifierMapping(_ecore_x_disp);
869 if ((mod) && (mod->max_keypermod > 0))
871 for (i = 0; i < (8 * mod->max_keypermod); i++)
873 for (j = 0; j < 8; j++)
875 sym2 = XKeycodeToKeysym(_ecore_x_disp, mod->modifiermap[i], j);
876 if (sym2 != 0) break;
882 mask = masks[i / mod->max_keypermod];
883 if (mod->modifiermap) XFree(mod->modifiermap);
891 if (mod->modifiermap) XFree(mod->modifiermap);
918 /*****************************************************************************/
919 /*****************************************************************************/
920 /*****************************************************************************/
921 /* FIXME: these funcs need categorising */
922 /*****************************************************************************/
925 * Get a list of all the root windows on the server.
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.
932 EAPI Ecore_X_Window *
933 ecore_x_window_root_list(int *num_ret)
936 Ecore_X_Window *roots;
938 int xp_base, xp_err_base;
941 if (!num_ret) return NULL;
944 LOGFN(__FILE__, __LINE__, __FUNCTION__);
946 num = ScreenCount(_ecore_x_disp);
947 if (XpQueryExtension(_ecore_x_disp, &xp_base, &xp_err_base))
952 ps = XpQueryScreens(_ecore_x_disp, &psnum);
958 for (i = 0; i < num; i++)
960 for (j = 0; j < psnum; j++)
962 if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
966 roots = malloc((num - overlap) * sizeof(Window));
972 for (i = 0; i < num; i++)
977 for (j = 0; j < psnum; j++)
979 if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
987 roots[k] = RootWindow(_ecore_x_disp, i);
997 roots = malloc(num * sizeof(Window));
998 if (!roots) return NULL;
1000 for (i = 0; i < num; i++)
1001 roots[i] = RootWindow(_ecore_x_disp, i);
1006 roots = malloc(num * sizeof(Window));
1007 if (!roots) return NULL;
1009 for (i = 0; i < num; i++)
1010 roots[i] = RootWindow(_ecore_x_disp, i);
1013 num = ScreenCount(_ecore_x_disp);
1014 roots = malloc(num * sizeof(Window));
1015 if (!roots) return NULL;
1017 for (i = 0; i < num; i++)
1018 roots[i] = RootWindow(_ecore_x_disp, i);
1024 ecore_x_window_root_first_get(void)
1026 return RootWindow(_ecore_x_disp, 0);
1029 Ecore_X_Window root, *roots = NULL;
1031 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1032 roots = ecore_x_window_root_list(&num);
1033 if (!(roots)) return 0;
1046 static void _ecore_x_window_manage_error(void *data);
1048 static int _ecore_x_window_manage_failed = 0;
1050 _ecore_x_window_manage_error(void *data __UNUSED__)
1052 if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) &&
1053 (ecore_x_error_code_get() == BadAccess))
1054 _ecore_x_window_manage_failed = 1;
1058 ecore_x_window_manage(Ecore_X_Window win)
1060 XWindowAttributes att;
1062 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1063 if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True) return 0;
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,
1070 PropertyChangeMask |
1071 ResizeRedirectMask |
1072 SubstructureRedirectMask |
1073 SubstructureNotifyMask |
1074 StructureNotifyMask |
1077 att.your_event_mask);
1079 ecore_x_error_handler_set(NULL, NULL);
1080 if (_ecore_x_window_manage_failed)
1082 _ecore_x_window_manage_failed = 0;
1089 ecore_x_window_container_manage(Ecore_X_Window win)
1091 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1092 XSelectInput(_ecore_x_disp, win,
1093 SubstructureRedirectMask |
1094 SubstructureNotifyMask);
1098 ecore_x_window_client_manage(Ecore_X_Window win)
1100 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1101 XSelectInput(_ecore_x_disp, win,
1102 PropertyChangeMask |
1103 // ResizeRedirectMask |
1105 ColormapChangeMask |
1106 VisibilityChangeMask |
1107 StructureNotifyMask |
1108 SubstructureNotifyMask
1110 XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1114 ecore_x_window_sniff(Ecore_X_Window win)
1116 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1117 XSelectInput(_ecore_x_disp, win,
1118 PropertyChangeMask |
1119 SubstructureNotifyMask);
1123 ecore_x_window_client_sniff(Ecore_X_Window win)
1125 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1126 XSelectInput(_ecore_x_disp, win,
1127 PropertyChangeMask |
1129 ColormapChangeMask |
1130 VisibilityChangeMask |
1131 StructureNotifyMask |
1132 SubstructureNotifyMask);
1133 XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1142 ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret)
1144 XWindowAttributes att;
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;
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;
1172 ecore_x_window_save_set_add(Ecore_X_Window win)
1174 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1175 XAddToSaveSet(_ecore_x_disp, win);
1179 ecore_x_window_save_set_del(Ecore_X_Window win)
1181 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1182 XRemoveFromSaveSet(_ecore_x_disp, win);
1185 EAPI Ecore_X_Window *
1186 ecore_x_window_children_get(Ecore_X_Window win, int *num)
1188 Ecore_X_Window *windows = NULL;
1189 Window root_ret = 0, parent_ret = 0, *children_ret = NULL;
1190 unsigned int children_ret_num = 0;
1192 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1193 if (!XQueryTree(_ecore_x_disp, win, &root_ret, &parent_ret, &children_ret,
1200 windows = malloc(children_ret_num * sizeof(Ecore_X_Window));
1205 for (i = 0; i < children_ret_num; i++)
1206 windows[i] = children_ret[i];
1207 *num = children_ret_num;
1209 XFree(children_ret);
1215 ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold)
1217 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1218 return XChangePointerControl(_ecore_x_disp, 1, 1,
1219 accel_num, accel_denom, threshold);
1223 ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold)
1225 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1226 return XGetPointerControl(_ecore_x_disp,
1227 accel_num, accel_denom, threshold);
1231 ecore_x_pointer_mapping_set(unsigned char *map, int nmap)
1233 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1234 return XSetPointerMapping(_ecore_x_disp, map, nmap);
1238 ecore_x_pointer_mapping_get(unsigned char *map, int nmap)
1240 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1241 return XGetPointerMapping(_ecore_x_disp, map, nmap);
1245 ecore_x_pointer_grab(Ecore_X_Window win)
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;
1257 ecore_x_pointer_confine_grab(Ecore_X_Window win)
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;
1269 ecore_x_pointer_ungrab(void)
1271 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1272 XUngrabPointer(_ecore_x_disp, CurrentTime);
1276 ecore_x_pointer_warp(Ecore_X_Window win, int x, int y)
1278 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1279 return XWarpPointer(_ecore_x_disp, None, win, 0, 0, 0, 0, x, y);
1283 ecore_x_keyboard_grab(Ecore_X_Window win)
1285 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1286 if (XGrabKeyboard(_ecore_x_disp, win, False,
1287 GrabModeAsync, GrabModeAsync,
1288 CurrentTime) == GrabSuccess) return 1;
1293 ecore_x_keyboard_ungrab(void)
1295 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1296 XUngrabKeyboard(_ecore_x_disp, CurrentTime);
1302 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1303 _ecore_x_grab_count++;
1304 if (_ecore_x_grab_count == 1) XGrabServer(_ecore_x_disp);
1308 ecore_x_ungrab(void)
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);
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;
1322 ecore_x_passive_grab_replay_func_set(int (*func) (void *data, int event_type, void *event), void *data)
1324 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1325 _ecore_window_grab_replay_func = func;
1326 _ecore_window_grab_replay_data = data;
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)
1336 unsigned int locks[8];
1339 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1341 if (b == 0) b = AnyButton;
1342 m = _ecore_x_event_modifier(mod);
1343 if (any_mod) m = AnyModifier;
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;
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;
1363 _ecore_x_sync_magic_send(int val, Ecore_X_Window swin)
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);
1381 _ecore_x_window_grab_remove(Ecore_X_Window win)
1385 if (_ecore_window_grabs_num > 0)
1387 for (i = 0; i < _ecore_window_grabs_num; i++)
1389 if (shuffle) _ecore_window_grabs[i - 1] = _ecore_window_grabs[i];
1390 if ((!shuffle) && (_ecore_window_grabs[i] == win))
1395 _ecore_window_grabs_num--;
1396 _ecore_window_grabs = realloc(_ecore_window_grabs,
1397 _ecore_window_grabs_num * sizeof(Window));
1403 ecore_x_window_button_ungrab(Ecore_X_Window win, int button,
1404 int mod, int any_mod)
1408 unsigned int locks[8];
1411 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1413 if (b == 0) b = AnyButton;
1414 m = _ecore_x_event_modifier(mod);
1415 if (any_mod) m = AnyModifier;
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);
1429 int _ecore_key_grabs_num = 0;
1430 Window *_ecore_key_grabs = NULL;
1433 ecore_x_window_key_grab(Ecore_X_Window win, const char *key,
1434 int mod, int any_mod)
1436 KeyCode keycode = 0;
1439 unsigned int locks[8];
1442 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1443 if (!strncmp(key, "Keycode-", 8))
1444 keycode = atoi(key + 8);
1447 keysym = XStringToKeysym(key);
1448 if (keysym == NoSymbol) return;
1449 keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
1451 if (keycode == 0) return;
1453 m = _ecore_x_event_modifier(mod);
1454 if (any_mod) m = AnyModifier;
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;
1473 _ecore_x_key_grab_remove(Ecore_X_Window win)
1477 if (_ecore_key_grabs_num > 0)
1479 for (i = 0; i < _ecore_key_grabs_num; i++)
1481 if (shuffle) _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
1482 if ((!shuffle) && (_ecore_key_grabs[i] == win))
1487 _ecore_key_grabs_num--;
1488 _ecore_key_grabs = realloc(_ecore_key_grabs,
1489 _ecore_key_grabs_num * sizeof(Window));
1495 ecore_x_window_key_ungrab(Ecore_X_Window win, const char *key,
1496 int mod, int any_mod)
1498 KeyCode keycode = 0;
1501 unsigned int locks[8];
1504 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1505 if (!strncmp(key, "Keycode-", 8))
1506 keycode = atoi(key + 8);
1509 keysym = XStringToKeysym(key);
1510 if (keysym == NoSymbol) return;
1511 keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
1513 if (keycode == 0) return;
1515 m = _ecore_x_event_modifier(mod);
1516 if (any_mod) m = AnyModifier;
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);
1531 * Send client message with given type and format 32.
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
1541 * @return !0 on success.
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)
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;
1561 return XSendEvent(_ecore_x_disp, win, False, mask, &xev);
1565 * Send client message with given type and format 8.
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.
1572 * @return !0 on success.
1575 ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type,
1576 const void *data, int len)
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);
1589 return XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
1593 ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y)
1596 XWindowAttributes att;
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;
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);
1619 ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b)
1622 XWindowAttributes att;
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;
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);
1645 ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b)
1648 XWindowAttributes att;
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;
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);
1671 ecore_x_focus_reset(void)
1673 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1674 XSetInputFocus(_ecore_x_disp, PointerRoot, RevertToPointerRoot, CurrentTime);
1678 ecore_x_events_allow_all(void)
1680 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1681 XAllowEvents(_ecore_x_disp, AsyncBoth, CurrentTime);
1685 ecore_x_pointer_last_xy_get(int *x, int *y)
1687 if (x) *x = _ecore_x_event_last_root_x;
1688 if (y) *y = _ecore_x_event_last_root_y;
1692 ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y)
1695 int rx, ry, wx, wy, ret;
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;
1704 /*****************************************************************************/
1705 /*****************************************************************************/
1706 /*****************************************************************************/
1709 _ecore_x_event_modifier(unsigned int state)
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;