2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
7 #include <X11/keysym.h>
10 #include <Ecore_Input.h>
12 #include "ecore_xcb_private.h"
13 #include "Ecore_X_Atoms.h"
15 static int _ecore_xcb_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
16 static int _ecore_xcb_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler);
17 static int _ecore_xcb_key_mask_get(xcb_keysym_t sym);
18 static int _ecore_xcb_event_modifier(unsigned int state);
20 static void *_ecore_xcb_event_filter_start(void *data);
21 static int _ecore_xcb_event_filter_filter(void *data, void *loop_data,int type, void *event);
22 static void _ecore_xcb_event_filter_end(void *data, void *loop_data);
24 static Ecore_Fd_Handler *_ecore_xcb_fd_handler_handle = NULL;
25 static Ecore_Event_Filter *_ecore_xcb_filter_handler = NULL;
27 static const int XCB_EVENT_ANY = 0; /* 0 can be used as there are no event types
28 * with index 0 and 1 as they are used for
32 #ifdef ECORE_XCB_DAMAGE
33 static int _ecore_xcb_event_damage_id = 0;
34 #endif /* ECORE_XCB_DAMAGE */
35 #ifdef ECORE_XCB_RANDR
36 static int _ecore_xcb_event_randr_id = 0;
37 #endif /* ECORE_XCB_RANDR */
38 #ifdef ECORE_XCB_SCREENSAVER
39 static int _ecore_xcb_event_screensaver_id = 0;
40 #endif /* ECORE_XCB_SCREENSAVER */
41 #ifdef ECORE_XCB_SHAPE
42 static int _ecore_xcb_event_shape_id = 0;
43 #endif /* ECORE_XCB_SHAPE */
45 static int _ecore_xcb_event_sync_id = 0;
46 #endif /* ECORE_XCB_SYNC */
47 #ifdef ECORE_XCB_FIXES
48 static int _ecore_xcb_event_fixes_selection_id = 0;
49 #endif /* ECORE_XCB_FIXES */
51 static int _ecore_xcb_event_handlers_num = 0;
52 static void (**_ecore_xcb_event_handlers) (xcb_generic_event_t * event) = NULL;
53 static xcb_generic_event_t *_ecore_xcb_event_buffered = NULL;
55 static int _ecore_xcb_init_count = 0;
56 static int _ecore_xcb_grab_count = 0;
57 int _ecore_x11xcb_log_dom = -1;
59 Ecore_X_Connection *_ecore_xcb_conn = NULL;
60 Ecore_X_Screen *_ecore_xcb_screen = NULL;
61 double _ecore_xcb_double_click_time = 0.25;
62 Ecore_X_Time _ecore_xcb_event_last_time = XCB_NONE;
63 Ecore_X_Window _ecore_xcb_event_last_window = XCB_NONE;
64 int16_t _ecore_xcb_event_last_root_x = 0;
65 int16_t _ecore_xcb_event_last_root_y = 0;
66 int _ecore_xcb_xcursor = 0;
68 Ecore_X_Window _ecore_xcb_private_window = 0;
70 /* FIXME - These are duplicates after making ecore atoms public */
72 Ecore_X_Atom _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
75 EAPI int ECORE_X_EVENT_ANY = 0;
76 EAPI int ECORE_X_EVENT_MOUSE_IN = 0;
77 EAPI int ECORE_X_EVENT_MOUSE_OUT = 0;
78 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0;
79 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0;
80 EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0;
81 EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0;
82 EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0;
83 EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0;
84 EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0;
85 EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0;
86 EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0;
87 EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0;
88 EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0;
89 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0;
90 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0;
91 EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0;
92 EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0;
93 EAPI int ECORE_X_EVENT_WINDOW_STACK = 0;
94 EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0;
95 EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0;
96 EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0;
97 EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0;
98 EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
99 EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
100 EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
101 EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
102 EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
103 EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
104 EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0;
105 EAPI int ECORE_X_EVENT_SYNC_ALARM = 0;
106 EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0;
107 EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0;
109 EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
111 EAPI int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = 0;
112 EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = 0;
113 EAPI int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = 0;
114 EAPI int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = 0;
115 EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = 0;
116 EAPI int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = 0;
117 EAPI int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = 0;
118 EAPI int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = 0;
121 EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0;
122 EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0;
123 EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0;
124 EAPI int ECORE_X_EVENT_PING = 0;
125 EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0;
127 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0;
128 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0;
129 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0;
131 EAPI int ECORE_X_MODIFIER_SHIFT = 0;
132 EAPI int ECORE_X_MODIFIER_CTRL = 0;
133 EAPI int ECORE_X_MODIFIER_ALT = 0;
134 EAPI 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 * @defgroup Ecore_Xcb_Init_Group X Library Init and Shutdown Functions
143 * Functions that start and shut down the Ecore X Library.
147 * Initialize the X display connection to the given display.
149 * @param name Display target name. If @c NULL, the default display is
151 * @return The number of times the library has been initialized without
152 * being shut down. 0 is returned if an error occurs.
153 * @ingroup Ecore_Xcb_Init_Group
156 ecore_x_init(const char *name)
158 xcb_screen_iterator_t iter;
160 uint32_t max_request_length;
161 const xcb_query_extension_reply_t *reply_big_requests;
162 #ifdef ECORE_XCB_DAMAGE
163 const xcb_query_extension_reply_t *reply_damage;
164 #endif /* ECORE_XCB_DAMAGE */
165 #ifdef ECORE_XCB_COMPOSITE
166 const xcb_query_extension_reply_t *reply_composite;
167 #endif /* ECORE_XCB_COMPOSITE */
168 #ifdef ECORE_XCB_DPMS
169 const xcb_query_extension_reply_t *reply_dpms;
170 #endif /* ECORE_XCB_DPMS */
171 #ifdef ECORE_XCB_RANDR
172 const xcb_query_extension_reply_t *reply_randr;
173 #endif /* ECORE_XCB_RANDR */
174 #ifdef ECORE_XCB_SCREENSAVER
175 const xcb_query_extension_reply_t *reply_screensaver;
176 #endif /* ECORE_XCB_SCREENSAVER */
177 #ifdef ECORE_XCB_SHAPE
178 const xcb_query_extension_reply_t *reply_shape;
179 #endif /* ECORE_XCB_SHAPE */
180 #ifdef ECORE_XCB_SYNC
181 xcb_sync_initialize_cookie_t cookie_sync_init;
182 xcb_sync_initialize_reply_t *reply_sync_init;
183 const xcb_query_extension_reply_t *reply_sync;
184 #endif /* ECORE_XCB_SYNC */
185 #ifdef ECORE_XCB_FIXES
186 const xcb_query_extension_reply_t *reply_xfixes;
187 #endif /* ECORE_XCB_FIXES */
188 #ifdef ECORE_XCB_XINERAMA
189 const xcb_query_extension_reply_t *reply_xinerama;
190 #endif /* ECORE_XCB_XINERAMA */
191 #ifdef ECORE_XCB_XPRINT
192 const xcb_query_extension_reply_t *reply_xprint;
193 #endif /* ECORE_XCB_XPRINT */
195 xcb_intern_atom_cookie_t atom_cookies[ECORE_X_ATOMS_COUNT];
197 if (++_ecore_xcb_init_count != 1)
198 return _ecore_xcb_init_count;
199 _ecore_x11xcb_log_dom = eina_log_domain_register("EcoreXCB", ECORE_XLIB_XCB_DEFAULT_LOG_COLOR);
200 if(_ecore_x11xcb_log_dom < 0)
202 EINA_LOG_ERR("Impossible to create a log domain the Ecore XCB module.");
203 return --_ecore_xcb_init_count;
205 _ecore_xcb_conn = xcb_connect(name, &screen);
206 if (xcb_connection_has_error(_ecore_xcb_conn)) {
207 eina_log_domain_unregister(_ecore_x11xcb_log_dom);
208 _ecore_x11xcb_log_dom = -1;
209 return --_ecore_xcb_init_count;
211 /* FIXME: no error code right now */
212 /* _ecore_xcb_error_handler_init(); */
214 /********************/
215 /* First round trip */
216 /********************/
219 * Non blocking stuff:
221 * 1. We request the atoms
222 * 2. We Prefetch the extension data
227 /* We request the atoms (non blocking) */
228 _ecore_x_atom_init(atom_cookies);
230 /* We prefetch all the extension data (non blocking) */
232 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_big_requests_id);
234 #ifdef ECORE_XCB_DAMAGE
235 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_damage_id);
236 #endif /* ECORE_XCB_DAMAGE */
238 #ifdef ECORE_XCB_COMPOSITE
239 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_composite_id);
240 #endif /* ECORE_XCB_COMPOSITE */
242 #ifdef ECORE_XCB_DPMS
243 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_dpms_id);
244 #endif /* ECORE_XCB_DPMS */
246 #ifdef ECORE_XCB_RANDR
247 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_randr_id);
248 #endif /* ECORE_XCB_RANDR */
250 #ifdef ECORE_XCB_SCREENSAVER
251 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_screensaver_id);
252 #endif /* ECORE_XCB_SCREENSAVER */
254 #ifdef ECORE_XCB_SHAPE
255 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shape_id);
256 #endif /* ECORE_XCB_SHAPE */
258 #ifdef ECORE_XCB_SYNC
259 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_sync_id);
260 cookie_sync_init = xcb_sync_initialize_unchecked(_ecore_xcb_conn,
261 XCB_SYNC_MAJOR_VERSION,
262 XCB_SYNC_MINOR_VERSION);
263 #endif /* ECORE_XCB_SYNC */
265 #ifdef ECORE_XCB_FIXES
266 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xfixes_id);
267 #endif /* ECORE_XCB_FIXES */
269 #ifdef ECORE_XCB_XINERAMA
270 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xinerama_id);
271 #endif /* ECORE_XCB_XINERAMA */
273 #ifdef ECORE_XCB_XPRINT
274 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_x_print_id);
275 #endif /* ECORE_XCB_XPRINT */
277 /* We init some components (not related to XCB) */
278 if (!ecore_event_init())
279 goto close_connection;
281 _ecore_x_reply_init();
283 ecore_x_netwm_init();
284 _ecore_x_selection_init();
286 /* There is no LASTEvent constant in XCB */
287 /* LASTevent is equal to 35 */
288 _ecore_xcb_event_handlers_num = 35;
290 /* We get the default screen */
291 iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
292 for (; iter.rem; --screen, xcb_screen_next (&iter))
295 _ecore_xcb_screen = iter.data;
302 * 1. We get the atoms
303 * 2. We ask for the extension data
307 /* We get the atoms (blocking) */
308 _ecore_x_atom_init_finalize(atom_cookies);
310 /* We then ask for the extension data (blocking) */
311 reply_big_requests = xcb_get_extension_data(_ecore_xcb_conn, &xcb_big_requests_id);
313 #ifdef ECORE_XCB_DAMAGE
314 reply_damage = xcb_get_extension_data(_ecore_xcb_conn, &xcb_damage_id);
316 _ecore_xcb_event_damage_id = reply_damage->first_event + XCB_DAMAGE_NOTIFY;
317 if (_ecore_xcb_event_damage_id >= _ecore_xcb_event_handlers_num)
318 _ecore_xcb_event_handlers_num = _ecore_xcb_event_damage_id + 1;
319 #endif /* ECORE_XCB_DAMAGE */
321 #ifdef ECORE_XCB_COMPOSITE
322 reply_composite = xcb_get_extension_data(_ecore_xcb_conn, &xcb_composite_id);
323 #endif /* ECORE_XCB_COMPOSITE */
325 #ifdef ECORE_XCB_DPMS
326 reply_dpms = xcb_get_extension_data(_ecore_xcb_conn, &xcb_dpms_id);
327 #endif /* ECORE_XCB_DPMS */
329 #ifdef ECORE_XCB_RANDR
330 reply_randr = xcb_get_extension_data(_ecore_xcb_conn, &xcb_randr_id);
332 _ecore_xcb_event_randr_id = reply_randr->first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY;
333 if (_ecore_xcb_event_randr_id >= _ecore_xcb_event_handlers_num)
334 _ecore_xcb_event_handlers_num = _ecore_xcb_event_randr_id + 1;
335 #endif /* ECORE_XCB_RANDR */
337 #ifdef ECORE_XCB_SCREENSAVER
338 reply_screensaver = xcb_get_extension_data(_ecore_xcb_conn, &xcb_screensaver_id);
339 if (reply_screensaver)
340 _ecore_xcb_event_screensaver_id = reply_screensaver->first_event + XCB_SCREENSAVER_NOTIFY;
341 if (_ecore_xcb_event_screensaver_id >= _ecore_xcb_event_handlers_num)
342 _ecore_xcb_event_handlers_num = _ecore_xcb_event_screensaver_id + 1;
343 #endif /* ECORE_XCB_SCREENSAVER */
345 #ifdef ECORE_XCB_SHAPE
346 reply_shape = xcb_get_extension_data(_ecore_xcb_conn, &xcb_shape_id);
348 _ecore_xcb_event_shape_id = reply_shape->first_event + XCB_SHAPE_NOTIFY;
349 if (_ecore_xcb_event_shape_id >= _ecore_xcb_event_handlers_num)
350 _ecore_xcb_event_handlers_num = _ecore_xcb_event_shape_id + 1;
351 #endif /* ECORE_XCB_SHAPE */
353 #ifdef ECORE_XCB_SYNC
354 reply_sync = xcb_get_extension_data(_ecore_xcb_conn, &xcb_sync_id);
357 _ecore_xcb_event_sync_id = reply_sync->first_event;
358 reply_sync_init = xcb_sync_initialize_reply(_ecore_xcb_conn,
359 cookie_sync_init, NULL);
360 if (!reply_sync_init)
361 _ecore_xcb_event_sync_id = 0;
363 free(reply_sync_init);
365 if (_ecore_xcb_event_sync_id + XCB_SYNC_ALARM_NOTIFY >= _ecore_xcb_event_handlers_num)
366 _ecore_xcb_event_handlers_num = _ecore_xcb_event_sync_id + XCB_SYNC_ALARM_NOTIFY + 1;
367 #endif /* ECORE_XCB_SYNC */
369 #ifdef ECORE_XCB_FIXES
370 reply_xfixes = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xfixes_id);
372 _ecore_xcb_event_fixes_selection_id = reply_xfixes->first_event + XCB_XFIXES_SELECTION_NOTIFY;
373 if (_ecore_xcb_event_fixes_selection_id >= _ecore_xcb_event_handlers_num)
374 _ecore_xcb_event_handlers_num = _ecore_xcb_event_fixes_selection_id + 1;
375 #endif /* ECORE_XCB_FIXES */
377 #ifdef ECORE_XCB_XINERAMA
378 reply_xinerama = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xinerama_id);
379 #endif /* ECORE_XCB_XINERAMA */
381 #ifdef ECORE_XCB_XPRINT
382 reply_xprint = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id);
383 #endif /* ECORE_XCB_XPRINT */
385 /*********************/
386 /* Second round trip */
387 /*********************/
389 /* We ask for the QueryVersion request of the extensions */
390 #ifdef ECORE_XCB_DAMAGE
391 _ecore_x_damage_init(reply_damage);
392 #endif /* ECORE_XCB_DAMAGE */
393 #ifdef ECORE_XCB_COMPOSITE
394 _ecore_x_composite_init(reply_composite);
395 #endif /* ECORE_XCB_COMPOSITE */
396 #ifdef ECORE_XCB_DPMS
397 _ecore_x_dpms_init(reply_dpms);
398 #endif /* ECORE_XCB_DPMS */
399 #ifdef ECORE_XCB_RANDR
400 _ecore_x_randr_init(reply_randr);
401 #endif /* ECORE_XCB_RANDR */
402 #ifdef ECORE_XCB_SCREENSAVER
403 _ecore_x_screensaver_init(reply_screensaver);
404 #endif /* ECORE_XCB_SCREENSAVER */
405 #ifdef ECORE_XCB_SHAPE
406 _ecore_x_shape_init(reply_shape);
407 #endif /* ECORE_XCB_SHAPE */
408 #ifdef ECORE_XCB_SYNC
409 _ecore_x_sync_init(reply_sync);
410 #endif /* ECORE_XCB_SYNC */
411 #ifdef ECORE_XCB_FIXES
412 _ecore_x_xfixes_init(reply_xfixes);
413 #endif /* ECORE_XCB_FIXES */
414 #ifdef ECORE_XCB_XINERAMA
415 _ecore_x_xinerama_init(reply_xinerama);
416 #endif /* ECORE_XCB_XINERAMA */
418 /* we enable the Big Request extension if present */
419 max_request_length = xcb_get_maximum_request_length(_ecore_xcb_conn);
421 _ecore_xcb_event_handlers = calloc(_ecore_xcb_event_handlers_num, sizeof(void *));
422 if (!_ecore_xcb_event_handlers)
423 goto finalize_extensions;
425 #ifdef ECORE_XCB_CURSOR
426 _ecore_xcb_xcursor = XcursorSupportsARGB(_ecore_xcb_conn);
427 #endif /* ECORE_XCB_CURSOR */
429 _ecore_xcb_event_handlers[XCB_EVENT_ANY] = _ecore_x_event_handle_any_event;
430 _ecore_xcb_event_handlers[XCB_KEY_PRESS] = _ecore_x_event_handle_key_press;
431 _ecore_xcb_event_handlers[XCB_KEY_RELEASE] = _ecore_x_event_handle_key_release;
432 _ecore_xcb_event_handlers[XCB_BUTTON_PRESS] = _ecore_x_event_handle_button_press;
433 _ecore_xcb_event_handlers[XCB_BUTTON_RELEASE] = _ecore_x_event_handle_button_release;
434 _ecore_xcb_event_handlers[XCB_MOTION_NOTIFY] = _ecore_x_event_handle_motion_notify;
435 _ecore_xcb_event_handlers[XCB_ENTER_NOTIFY] = _ecore_x_event_handle_enter_notify;
436 _ecore_xcb_event_handlers[XCB_LEAVE_NOTIFY] = _ecore_x_event_handle_leave_notify;
437 _ecore_xcb_event_handlers[XCB_FOCUS_IN] = _ecore_x_event_handle_focus_in;
438 _ecore_xcb_event_handlers[XCB_FOCUS_OUT] = _ecore_x_event_handle_focus_out;
439 _ecore_xcb_event_handlers[XCB_KEYMAP_NOTIFY] = _ecore_x_event_handle_keymap_notify;
440 _ecore_xcb_event_handlers[XCB_EXPOSE] = _ecore_x_event_handle_expose;
441 _ecore_xcb_event_handlers[XCB_GRAPHICS_EXPOSURE] = _ecore_x_event_handle_graphics_expose;
442 _ecore_xcb_event_handlers[XCB_VISIBILITY_NOTIFY] = _ecore_x_event_handle_visibility_notify;
443 _ecore_xcb_event_handlers[XCB_CREATE_NOTIFY] = _ecore_x_event_handle_create_notify;
444 _ecore_xcb_event_handlers[XCB_DESTROY_NOTIFY] = _ecore_x_event_handle_destroy_notify;
445 _ecore_xcb_event_handlers[XCB_UNMAP_NOTIFY] = _ecore_x_event_handle_unmap_notify;
446 _ecore_xcb_event_handlers[XCB_MAP_NOTIFY] = _ecore_x_event_handle_map_notify;
447 _ecore_xcb_event_handlers[XCB_MAP_REQUEST] = _ecore_x_event_handle_map_request;
448 _ecore_xcb_event_handlers[XCB_REPARENT_NOTIFY] = _ecore_x_event_handle_reparent_notify;
449 _ecore_xcb_event_handlers[XCB_CONFIGURE_NOTIFY] = _ecore_x_event_handle_configure_notify;
450 _ecore_xcb_event_handlers[XCB_CONFIGURE_REQUEST] = _ecore_x_event_handle_configure_request;
451 _ecore_xcb_event_handlers[XCB_GRAVITY_NOTIFY] = _ecore_x_event_handle_gravity_notify;
452 _ecore_xcb_event_handlers[XCB_RESIZE_REQUEST] = _ecore_x_event_handle_resize_request;
453 _ecore_xcb_event_handlers[XCB_CIRCULATE_NOTIFY] = _ecore_x_event_handle_circulate_notify;
454 _ecore_xcb_event_handlers[XCB_CIRCULATE_REQUEST] = _ecore_x_event_handle_circulate_request;
455 _ecore_xcb_event_handlers[XCB_PROPERTY_NOTIFY] = _ecore_x_event_handle_property_notify;
456 _ecore_xcb_event_handlers[XCB_SELECTION_CLEAR] = _ecore_x_event_handle_selection_clear;
457 _ecore_xcb_event_handlers[XCB_SELECTION_REQUEST] = _ecore_x_event_handle_selection_request;
458 _ecore_xcb_event_handlers[XCB_SELECTION_NOTIFY] = _ecore_x_event_handle_selection_notify;
459 _ecore_xcb_event_handlers[XCB_COLORMAP_NOTIFY] = _ecore_x_event_handle_colormap_notify;
460 _ecore_xcb_event_handlers[XCB_CLIENT_MESSAGE] = _ecore_x_event_handle_client_message;
461 _ecore_xcb_event_handlers[XCB_MAPPING_NOTIFY] = _ecore_x_event_handle_mapping_notify;
462 #ifdef ECORE_XCB_DAMAGE
463 if (_ecore_xcb_event_damage_id)
464 _ecore_xcb_event_handlers[_ecore_xcb_event_damage_id] = _ecore_x_event_handle_damage_notify;
465 #endif /* ECORE_XCB_DAMAGE */
466 #ifdef ECORE_XCB_RANDR
467 if (_ecore_xcb_event_randr_id)
468 _ecore_xcb_event_handlers[_ecore_xcb_event_randr_id] = _ecore_x_event_handle_randr_change;
469 #endif /* ECORE_XCB_RANDR */
470 #ifdef ECORE_XCB_SCREENSAVER
471 if (_ecore_xcb_event_screensaver_id)
472 _ecore_xcb_event_handlers[_ecore_xcb_event_screensaver_id] = _ecore_x_event_handle_screensaver_notify;
473 #endif /* ECORE_XCB_SCREENSAVER */
474 #ifdef ECORE_XCB_SHAPE
475 if (_ecore_xcb_event_shape_id)
476 _ecore_xcb_event_handlers[_ecore_xcb_event_shape_id] = _ecore_x_event_handle_shape_change;
477 #endif /* ECORE_XCB_SHAPE */
478 #ifdef ECORE_XCB_SYNC
479 if (_ecore_xcb_event_sync_id)
481 _ecore_xcb_event_handlers[_ecore_xcb_event_sync_id + XCB_SYNC_COUNTER_NOTIFY] =
482 _ecore_x_event_handle_sync_counter;
483 _ecore_xcb_event_handlers[_ecore_xcb_event_sync_id + XCB_SYNC_ALARM_NOTIFY] =
484 _ecore_x_event_handle_sync_alarm;
486 #endif /* ECORE_XCB_SYNC */
487 #ifdef ECORE_XCB_FIXES
488 if (_ecore_xcb_event_fixes_selection_id)
489 _ecore_xcb_event_handlers[_ecore_xcb_event_fixes_selection_id] = _ecore_x_event_handle_fixes_selection_notify;
490 #endif /* ECORE_XCB_FIXES */
492 if (!ECORE_X_EVENT_ANY)
494 ECORE_X_EVENT_ANY = ecore_event_type_new();
495 ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new();
496 ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new();
497 ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
498 ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
499 ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new();
500 ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
501 ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new();
502 ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new();
503 ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new();
504 ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new();
505 ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new();
506 ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new();
507 ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new();
508 ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
509 ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new();
510 ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new();
511 ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new();
512 ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new();
513 ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new();
514 ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new();
515 ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new();
516 ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new();
517 ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new();
518 ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new();
519 ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new();
520 ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new();
521 ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new();
522 ECORE_X_EVENT_SCREENSAVER_NOTIFY = ecore_event_type_new();
523 ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new();
524 ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new();
525 ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new();
526 ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new();
528 ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
530 ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = ecore_event_type_new();
531 ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = ecore_event_type_new();
532 ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = ecore_event_type_new();
533 ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = ecore_event_type_new();
534 ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = ecore_event_type_new();
535 ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = ecore_event_type_new();
536 ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = ecore_event_type_new();
537 ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = ecore_event_type_new();
540 ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new();
541 ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new();
542 ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new();
543 ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new();
544 ECORE_X_EVENT_PING = ecore_event_type_new();
546 ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new();
547 ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new();
548 ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new();
551 /* everything has these... unless its like a pda... :) */
552 ECORE_X_MODIFIER_SHIFT = _ecore_xcb_key_mask_get(XK_Shift_L);
553 ECORE_X_MODIFIER_CTRL = _ecore_xcb_key_mask_get(XK_Control_L);
555 /* apple's xdarwin has no alt!!!! */
556 ECORE_X_MODIFIER_ALT = _ecore_xcb_key_mask_get(XK_Alt_L);
557 if (!ECORE_X_MODIFIER_ALT)
558 ECORE_X_MODIFIER_ALT = _ecore_xcb_key_mask_get(XK_Meta_L);
559 if (!ECORE_X_MODIFIER_ALT)
560 ECORE_X_MODIFIER_ALT = _ecore_xcb_key_mask_get(XK_Super_L);
562 /* the windows key... a valid modifier :) */
563 ECORE_X_MODIFIER_WIN = _ecore_xcb_key_mask_get(XK_Super_L);
564 if (!ECORE_X_MODIFIER_WIN)
565 ECORE_X_MODIFIER_WIN = _ecore_xcb_key_mask_get(XK_Mode_switch);
566 if (!ECORE_X_MODIFIER_WIN)
567 ECORE_X_MODIFIER_WIN = _ecore_xcb_key_mask_get(XK_Meta_L);
569 if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT)
570 ECORE_X_MODIFIER_WIN = 0;
571 if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL)
572 ECORE_X_MODIFIER_ALT = 0;
574 ECORE_X_LOCK_SCROLL = _ecore_xcb_key_mask_get(XK_Scroll_Lock);
575 ECORE_X_LOCK_NUM = _ecore_xcb_key_mask_get(XK_Num_Lock);
576 ECORE_X_LOCK_CAPS = _ecore_xcb_key_mask_get(XK_Caps_Lock);
578 _ecore_xcb_fd_handler_handle =
579 ecore_main_fd_handler_add(xcb_get_file_descriptor(_ecore_xcb_conn),
581 _ecore_xcb_fd_handler, _ecore_xcb_conn,
582 _ecore_xcb_fd_handler_buf, _ecore_xcb_conn);
583 if (!_ecore_xcb_fd_handler_handle)
584 goto free_event_handlers;
586 _ecore_xcb_filter_handler = ecore_event_filter_add(_ecore_xcb_event_filter_start, _ecore_xcb_event_filter_filter, _ecore_xcb_event_filter_end, NULL);
588 /* This is just to be anal about naming conventions */
590 _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = ECORE_X_ATOM_WM_DELETE_WINDOW;
591 _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = ECORE_X_ATOM_WM_TAKE_FOCUS;
592 _ecore_xcb_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] = ECORE_X_ATOM_NET_WM_PING;
593 _ecore_xcb_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
595 _ecore_xcb_init_count++;
597 _ecore_xcb_private_window = ecore_x_window_override_new(0, -77, -777, 123, 456);
599 /* We finally get the replies of the QueryVersion request */
600 #ifdef ECORE_XCB_DAMAGE
601 _ecore_x_damage_init_finalize();
602 #endif /* ECORE_XCB_DAMAGE */
603 #ifdef ECORE_XCB_COMPOSITE
604 _ecore_x_composite_init_finalize();
605 #endif /* ECORE_XCB_COMPOSITE */
606 #ifdef ECORE_XCB_DPMS
607 _ecore_x_dpms_init_finalize();
608 #endif /* ECORE_XCB_DPMS */
609 #ifdef ECORE_XCB_RANDR
610 _ecore_x_randr_init_finalize();
611 #endif /* ECORE_XCB_RANDR */
612 #ifdef ECORE_XCB_SCREENSAVER
613 _ecore_x_screensaver_init_finalize();
614 #endif /* ECORE_XCB_SCREENSAVER */
615 #ifdef ECORE_XCB_SHAPE
616 _ecore_x_shape_init_finalize();
617 #endif /* ECORE_XCB_SHAPE */
618 #ifdef ECORE_XCB_SYNC
619 _ecore_x_sync_init_finalize();
620 #endif /* ECORE_XCB_SYNC */
621 #ifdef ECORE_XCB_FIXES
622 _ecore_x_xfixes_init_finalize();
623 #endif /* ECORE_XCB_FIXES */
624 #ifdef ECORE_XCB_XINERAMA
625 _ecore_x_xinerama_init_finalize();
626 #endif /* ECORE_XCB_XINERAMA */
628 return _ecore_xcb_init_count;
631 free(_ecore_xcb_event_handlers);
632 _ecore_xcb_event_handlers = NULL;
634 /* We get the replies of the QueryVersion request because we leave */
635 #ifdef ECORE_XCB_DAMAGE
636 _ecore_x_damage_init_finalize();
637 #endif /* ECORE_XCB_DAMAGE */
638 #ifdef ECORE_XCB_COMPOSITE
639 _ecore_x_composite_init_finalize();
640 #endif /* ECORE_XCB_COMPOSITE */
641 #ifdef ECORE_XCB_DPMS
642 _ecore_x_dpms_init_finalize();
643 #endif /* ECORE_XCB_DPMS */
644 #ifdef ECORE_XCB_RANDR
645 _ecore_x_randr_init_finalize();
646 #endif /* ECORE_XCB_RANDR */
647 #ifdef ECORE_XCB_SCREENSAVER
648 _ecore_x_screensaver_init_finalize();
649 #endif /* ECORE_XCB_SCREENSAVER */
650 #ifdef ECORE_XCB_SHAPE
651 _ecore_x_shape_init_finalize();
652 #endif /* ECORE_XCB_SHAPE */
653 #ifdef ECORE_XCB_SYNC
654 _ecore_x_sync_init_finalize();
655 #endif /* ECORE_XCB_SYNC */
656 #ifdef ECORE_XCB_FIXES
657 _ecore_x_xfixes_init_finalize();
658 #endif /* ECORE_XCB_FIXES */
659 #ifdef ECORE_XCB_XINERAMA
660 _ecore_x_xinerama_init_finalize();
661 #endif /* ECORE_XCB_XINERAMA */
662 ecore_event_shutdown();
664 _ecore_x_atom_init_finalize(atom_cookies);
665 xcb_disconnect(_ecore_xcb_conn);
666 _ecore_xcb_fd_handler_handle = NULL;
667 _ecore_xcb_conn = NULL;
669 return --_ecore_xcb_init_count;
673 _ecore_x_shutdown(int close_display)
675 if (--_ecore_xcb_init_count != 0)
676 return _ecore_xcb_init_count;
678 if (!_ecore_xcb_conn) return _ecore_xcb_init_count;
681 xcb_disconnect(_ecore_xcb_conn);
683 close(xcb_get_file_descriptor(_ecore_xcb_conn));
684 ecore_event_shutdown();
685 free(_ecore_xcb_event_handlers);
686 ecore_main_fd_handler_del(_ecore_xcb_fd_handler_handle);
687 ecore_event_filter_del(_ecore_xcb_filter_handler);
688 _ecore_xcb_fd_handler_handle = NULL;
689 _ecore_xcb_filter_handler = NULL;
690 _ecore_xcb_conn = NULL;
691 _ecore_xcb_event_handlers = NULL;
692 _ecore_x_selection_shutdown();
693 _ecore_x_dnd_shutdown();
694 ecore_x_netwm_shutdown();
695 _ecore_x_reply_shutdown();
697 return _ecore_xcb_init_count;
701 * Shuts down the Ecore X library.
703 * In shutting down the library, the X display connection is terminated
704 * and any event handlers for it are removed.
706 * @return The number of times the library has been initialized without
708 * @ingroup Ecore_Xcb_Init_Group
711 ecore_x_shutdown(void)
713 return _ecore_x_shutdown(1);
717 * Shuts down the Ecore X library.
719 * As ecore_xcb_shutdown, except do not close Display, only connection.
721 * @ingroup Ecore_Xcb_Init_Group
724 ecore_x_disconnect(void)
726 return _ecore_x_shutdown(0);
730 * @defgroup Ecore_Xcb_Display_Attr_Group X Display Attributes
732 * Functions that set and retrieve X display attributes.
735 EAPI Ecore_X_Display *
736 ecore_x_display_get(void)
742 * Retrieves the Ecore_X_Connection handle used for the current X connection.
743 * @return The current X connection.
744 * @ingroup Ecore_Xcb_Display_Attr_Group
746 EAPI Ecore_X_Connection *
747 ecore_x_connection_get(void)
749 return (Ecore_X_Connection *)_ecore_xcb_conn;
753 * Retrieves the X display file descriptor.
754 * @return The current X display file descriptor.
755 * @ingroup Ecore_Xcb_Display_Attr_Group
760 return xcb_get_file_descriptor(_ecore_xcb_conn);
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 return (Ecore_X_Screen *)_ecore_xcb_screen;
775 * Sets the timeout for a double and triple clicks to be flagged.
777 * This sets the time between clicks before the double_click flag is
778 * set in a button down event. If 3 clicks occur within double this
779 * time, the triple_click flag is also set.
781 * @param t The time in seconds
782 * @ingroup Ecore_Xcb_Display_Attr_Group
785 ecore_x_double_click_time_set(double t)
787 if (t < 0.0) t = 0.0;
788 _ecore_xcb_double_click_time = t;
792 * Retrieves the double and triple click flag timeout.
794 * See @ref ecore_xcb_double_click_time_set for more information.
796 * @return The timeout for double clicks in seconds.
797 * @ingroup Ecore_Xcb_Display_Attr_Group
800 ecore_x_double_click_time_get(void)
802 return _ecore_xcb_double_click_time;
806 * @defgroup Ecore_Xcb_Flush_Group X Synchronization Functions
808 * Functions that ensure that all commands that have been issued by the
809 * Ecore X library have been sent to the server.
813 * Sends all X commands in the X Display buffer.
814 * @ingroup Ecore_Xcb_Flush_Group
819 xcb_flush(_ecore_xcb_conn);
823 * Flushes the command buffer and waits until all requests have been
824 * processed by the server.
825 * @ingroup Ecore_Xcb_Flush_Group
830 free(xcb_get_input_focus_reply(_ecore_xcb_conn, xcb_get_input_focus(_ecore_xcb_conn), NULL));
834 * Kill all clients with subwindows under a given window.
836 * You can kill all clients connected to the X server by using
837 * @ref ecore_x_window_root_list to get a list of root windows, and
838 * then passing each root window to this function.
840 * @param root The window whose children will be killed.
843 ecore_x_killall(Ecore_X_Window root)
848 xcb_grab_server(_ecore_xcb_conn);
849 screens = xcb_setup_roots_iterator (xcb_get_setup (_ecore_xcb_conn)).rem;
851 /* Tranverse window tree starting from root, and drag each
852 * before the firing squad */
853 for (i = 0; i < screens; ++i)
855 xcb_query_tree_cookie_t cookie;
856 xcb_query_tree_reply_t *reply;
858 cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, root);
859 reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
862 xcb_window_iterator_t iter;
864 iter = xcb_query_tree_children_iterator(reply);
865 for (; iter.rem; xcb_window_next(&iter))
866 xcb_kill_client(_ecore_xcb_conn, *iter.data);
871 xcb_ungrab_server(_ecore_xcb_conn);
872 free(xcb_get_input_focus_reply(_ecore_xcb_conn, xcb_get_input_focus(_ecore_xcb_conn), NULL));
876 * Kill a specific client
878 * You can kill a specific client woning window @p window
880 * @param window Window of the client to be killed
883 ecore_x_kill(Ecore_X_Window window)
885 xcb_kill_client(_ecore_xcb_conn, window);
889 * Return the last event time
892 ecore_x_current_time_get(void)
894 return _ecore_xcb_event_last_time;
898 handle_event(xcb_generic_event_t *ev)
900 uint8_t response_type = ev->response_type & ~0x80;
902 if (response_type < _ecore_xcb_event_handlers_num)
904 if (_ecore_xcb_event_handlers[XCB_EVENT_ANY])
905 _ecore_xcb_event_handlers[XCB_EVENT_ANY] (ev);
907 if (_ecore_xcb_event_handlers[response_type])
908 _ecore_xcb_event_handlers[response_type] (ev);
913 _ecore_xcb_fd_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
916 xcb_generic_event_t *ev;
918 c = (xcb_connection_t *)data;
920 /* INF ("nbr events: %d", _ecore_xcb_event_handlers_num); */
922 /* We check if _ecore_xcb_event_buffered is NULL or not */
923 if (_ecore_xcb_event_buffered)
924 handle_event(_ecore_xcb_event_buffered);
926 while ((ev = xcb_poll_for_event(c)))
933 _ecore_xcb_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
937 c = (xcb_connection_t *)data;
939 _ecore_xcb_event_buffered = xcb_poll_for_event(c);
940 if (!_ecore_xcb_event_buffered)
946 /* FIXME: possible roundtrip */
947 /* FIXME: fix xcb_keysyms. It's ugly !! (reply in xcb_key_symbols_get_keysym) */
949 _ecore_xcb_key_mask_get(xcb_keysym_t sym)
951 xcb_keycode_iterator_t iter;
952 xcb_get_modifier_mapping_cookie_t cookie;
953 xcb_get_modifier_mapping_reply_t *reply;
954 xcb_key_symbols_t *symbols;
961 XCB_MOD_MASK_CONTROL,
969 cookie = xcb_get_modifier_mapping_unchecked(_ecore_xcb_conn);
970 symbols = xcb_key_symbols_alloc(_ecore_xcb_conn);
972 reply = xcb_get_modifier_mapping_reply(_ecore_xcb_conn, cookie, NULL);
975 xcb_key_symbols_free(symbols);
980 iter = xcb_get_modifier_mapping_keycodes_iterator(reply);
982 for (i = 0; iter.rem; xcb_keycode_next(&iter), i++)
984 for (j = 0; j < 8; j++)
986 sym2 = xcb_key_symbols_get_keysym(symbols, *iter.data, j);
987 if (sym2 != 0) break;
995 xcb_key_symbols_free(symbols);
1001 xcb_key_symbols_free(symbols);
1006 typedef struct _Ecore_X_Filter_Data Ecore_X_Filter_Data;
1008 struct _Ecore_X_Filter_Data
1010 int last_event_type;
1014 _ecore_xcb_event_filter_start(void *data __UNUSED__)
1016 Ecore_X_Filter_Data *filter_data;
1018 filter_data = calloc(1, sizeof(Ecore_X_Filter_Data));
1023 _ecore_xcb_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__)
1025 Ecore_X_Filter_Data *filter_data;
1027 filter_data = loop_data;
1028 if (!filter_data) return 1;
1029 if (type == ECORE_EVENT_MOUSE_MOVE)
1031 if ((filter_data->last_event_type) == ECORE_EVENT_MOUSE_MOVE)
1033 filter_data->last_event_type = type;
1037 filter_data->last_event_type = type;
1042 _ecore_xcb_event_filter_end(void *data __UNUSED__, void *loop_data)
1044 Ecore_X_Filter_Data *filter_data;
1046 filter_data = loop_data;
1047 if (filter_data) free(filter_data);
1071 /*****************************************************************************/
1072 /*****************************************************************************/
1073 /*****************************************************************************/
1074 /* FIXME: these funcs need categorising */
1075 /*****************************************************************************/
1081 * Get a list of all the root windows on the server.
1083 * @note The returned array will need to be freed after use.
1084 * @param num_ret Pointer to integer to put number of windows returned in.
1085 * @return An array of all the root windows. @c NULL is returned if memory
1086 * could not be allocated for the list, or if @p num_ret is @c NULL.
1088 EAPI Ecore_X_Window *
1089 ecore_x_window_root_list(int *num_ret)
1091 xcb_screen_iterator_t iter;
1092 const xcb_setup_t *setup;
1095 Ecore_X_Window *roots;
1096 /* #ifdef ECORE_XCBXPRINT */
1097 /* int xp_base, xp_err_base; */
1098 /* #endif /\* ECORE_XCBXPRINT *\/ */
1100 if (!num_ret) return NULL;
1103 /* FIXME: todo... */
1104 /* #ifdef ECORE_XCBXPRINT */
1105 /* num = ScreenCount(_ecore_xcb_conn); */
1106 /* if (ecore_xcb_xprint_query()) */
1108 /* Screen **ps = NULL; */
1109 /* int psnum = 0; */
1111 /* ps = XpQueryScreens(_ecore_xcb_conn, &psnum); */
1114 /* int overlap, j; */
1117 /* for (i = 0; i < num; i++) */
1119 /* for (j = 0; j < psnum; j++) */
1121 /* if (ScreenOfDisplay(_ecore_xcb_conn, i) == ps[j]) */
1125 /* roots = malloc((num - overlap) * sizeof(Ecore_X_Window)); */
1131 /* for (i = 0; i < num; i++) */
1136 /* for (j = 0; j < psnum; j++) */
1138 /* if (ScreenOfDisplay(_ecore_xcb_conn, i) == ps[j]) */
1144 /* if (!is_print) */
1146 /* roots[k] = RootWindow(_ecore_xcb_conn, i); */
1156 /* roots = malloc(num * sizeof(Ecore_X_Window)); */
1157 /* if (!roots) return NULL; */
1158 /* *num_ret = num; */
1159 /* for (i = 0; i < num; i++) */
1160 /* roots[i] = RootWindow(_ecore_xcb_conn, i); */
1165 /* roots = malloc(num * sizeof(Ecore_X_Window)); */
1166 /* if (!roots) return NULL; */
1167 /* *num_ret = num; */
1168 /* for (i = 0; i < num; i++) */
1169 /* roots[i] = RootWindow(_ecore_xcb_conn, i); */
1172 setup = xcb_get_setup (_ecore_xcb_conn);
1173 iter = xcb_setup_roots_iterator (setup);
1174 num = setup->roots_len;
1175 roots = malloc(num * sizeof(Ecore_X_Window));
1176 if (!roots) return NULL;
1179 for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
1180 roots[i] = iter.data->root;
1181 /* #endif /\* ECORE_XCBXPRINT *\/ */
1187 ecore_x_window_root_first_get(void)
1189 Ecore_X_Window *roots = NULL;
1190 Ecore_X_Window root;
1193 roots = ecore_x_window_root_list(&num);
1194 if(!(roots)) return 0;
1207 static void _ecore_x_window_manage_error(void *data);
1209 static int _ecore_xcb_window_manage_failed = 0;
1211 _ecore_x_window_manage_error(void *data __UNUSED__)
1213 /* if ((ecore_xcb_error_request_get() == X_ChangeWindowAttributes) && */
1214 /* (ecore_xcb_error_code_get() == BadAccess)) */
1215 /* _ecore_xcb_window_manage_failed = 1; */
1218 /* FIXME: round trip */
1220 ecore_x_window_manage(Ecore_X_Window window)
1222 xcb_get_window_attributes_cookie_t cookie_attr;
1223 xcb_get_input_focus_cookie_t cookie_sync;
1224 xcb_get_window_attributes_reply_t *reply_attr;
1225 xcb_get_input_focus_reply_t *reply_sync;
1226 uint32_t value_list;
1228 cookie_attr = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
1229 cookie_sync = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
1231 reply_attr = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_attr, NULL);
1234 reply_sync = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie_sync, NULL);
1235 if (reply_sync) free(reply_sync);
1239 reply_sync = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie_sync, NULL);
1240 if (reply_sync) free(reply_sync);
1242 _ecore_xcb_window_manage_failed = 0;
1243 /* FIXME: no error code yet */
1244 /* ecore_xcb_error_handler_set(_ecore_xcb_window_manage_error, NULL); */
1247 XCB_EVENT_MASK_KEY_PRESS |
1248 XCB_EVENT_MASK_KEY_RELEASE |
1249 XCB_EVENT_MASK_ENTER_WINDOW |
1250 XCB_EVENT_MASK_LEAVE_WINDOW |
1251 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1252 XCB_EVENT_MASK_RESIZE_REDIRECT |
1253 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1254 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1255 XCB_EVENT_MASK_PROPERTY_CHANGE |
1256 reply_attr->your_event_mask;
1257 xcb_change_window_attributes(_ecore_xcb_conn, window,
1262 cookie_sync = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
1263 if (reply_sync) free(reply_sync);
1265 /* FIXME: no error code yet */
1266 /* ecore_xcb_error_handler_set(NULL, NULL); */
1267 if (_ecore_xcb_window_manage_failed)
1269 _ecore_xcb_window_manage_failed = 0;
1284 ecore_x_pointer_control_set(int accel_num,
1288 xcb_change_pointer_control(_ecore_xcb_conn,
1289 accel_num, accel_denom, threshold,
1295 ecore_x_pointer_control_get_prefetch(void)
1297 xcb_get_pointer_control_cookie_t cookie;
1299 cookie = xcb_get_pointer_control_unchecked(_ecore_xcb_conn);
1300 _ecore_xcb_cookie_cache(cookie.sequence);
1304 ecore_x_pointer_control_get_fetch(void)
1306 xcb_get_pointer_control_cookie_t cookie;
1307 xcb_get_pointer_control_reply_t *reply;
1309 cookie.sequence = _ecore_xcb_cookie_get();
1310 reply = xcb_get_pointer_control_reply(_ecore_xcb_conn, cookie, NULL);
1311 _ecore_xcb_reply_cache(reply);
1315 ecore_x_pointer_control_get(int *accel_num,
1319 xcb_get_pointer_control_reply_t *reply;
1321 if (accel_num) *accel_num = 0;
1322 if (accel_denom) *accel_denom = 1;
1323 if (threshold) *threshold = 0;
1325 reply = _ecore_xcb_reply_get();
1326 if (!reply) return 0;
1328 if (accel_num) *accel_num = reply->acceleration_numerator;
1329 if (accel_denom) *accel_denom = reply->acceleration_denominator;
1330 if (threshold) *threshold = reply->threshold;
1336 ecore_x_pointer_mapping_set(unsigned char *map,
1339 xcb_set_pointer_mapping(_ecore_xcb_conn, nmap, map);
1344 ecore_x_pointer_mapping_get_prefetch(void)
1346 xcb_get_pointer_mapping_cookie_t cookie;
1348 cookie = xcb_get_pointer_mapping_unchecked(_ecore_xcb_conn);
1349 _ecore_xcb_cookie_cache(cookie.sequence);
1353 ecore_x_pointer_mapping_get_fetch(void)
1355 xcb_get_pointer_mapping_cookie_t cookie;
1356 xcb_get_pointer_mapping_reply_t *reply;
1358 cookie.sequence = _ecore_xcb_cookie_get();
1359 reply = xcb_get_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL);
1360 _ecore_xcb_reply_cache(reply);
1364 ecore_x_pointer_mapping_get(unsigned char *map,
1367 xcb_get_pointer_mapping_cookie_t cookie;
1368 xcb_get_pointer_mapping_reply_t *reply;
1372 cookie = xcb_get_pointer_mapping_unchecked(_ecore_xcb_conn);
1373 reply = xcb_get_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL);
1374 if (!reply) return 0;
1376 if (nmap > xcb_get_pointer_mapping_map_length(reply))
1379 tmp = xcb_get_pointer_mapping_map(reply);
1381 for (i = 0; i < nmap; i++)
1388 ecore_x_pointer_grab(Ecore_X_Window window)
1390 xcb_grab_pointer_cookie_t cookie;
1391 xcb_grab_pointer_reply_t *reply;
1393 cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, window,
1394 XCB_EVENT_MASK_BUTTON_PRESS |
1395 XCB_EVENT_MASK_BUTTON_RELEASE |
1396 XCB_EVENT_MASK_ENTER_WINDOW |
1397 XCB_EVENT_MASK_LEAVE_WINDOW |
1398 XCB_EVENT_MASK_POINTER_MOTION,
1399 XCB_GRAB_MODE_ASYNC,
1400 XCB_GRAB_MODE_ASYNC,
1403 reply = xcb_grab_pointer_reply(_ecore_xcb_conn, cookie, NULL);
1413 ecore_x_pointer_confine_grab(Ecore_X_Window window)
1415 xcb_grab_pointer_cookie_t cookie;
1416 xcb_grab_pointer_reply_t *reply;
1418 cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, window,
1419 XCB_EVENT_MASK_BUTTON_PRESS |
1420 XCB_EVENT_MASK_BUTTON_RELEASE |
1421 XCB_EVENT_MASK_ENTER_WINDOW |
1422 XCB_EVENT_MASK_LEAVE_WINDOW |
1423 XCB_EVENT_MASK_POINTER_MOTION,
1424 XCB_GRAB_MODE_ASYNC,
1425 XCB_GRAB_MODE_ASYNC,
1428 reply = xcb_grab_pointer_reply(_ecore_xcb_conn, cookie, NULL);
1438 ecore_x_pointer_ungrab(void)
1440 xcb_ungrab_pointer(_ecore_xcb_conn, XCB_CURRENT_TIME);
1444 ecore_x_pointer_warp(Ecore_X_Window window,
1448 xcb_warp_pointer(_ecore_xcb_conn, XCB_NONE, window, 0, 0, 0, 0, x, y);
1454 ecore_x_keyboard_grab(Ecore_X_Window window)
1456 xcb_grab_keyboard_cookie_t cookie;
1457 xcb_grab_keyboard_reply_t *reply;
1459 cookie = xcb_grab_keyboard_unchecked(_ecore_xcb_conn, 0, window,
1461 XCB_GRAB_MODE_ASYNC,
1462 XCB_GRAB_MODE_ASYNC);
1463 reply = xcb_grab_keyboard_reply(_ecore_xcb_conn, cookie, NULL);
1473 ecore_x_keyboard_ungrab(void)
1475 xcb_ungrab_keyboard(_ecore_xcb_conn, XCB_CURRENT_TIME);
1481 _ecore_xcb_grab_count++;
1483 if (_ecore_xcb_grab_count == 1)
1484 xcb_grab_server(_ecore_xcb_conn);
1488 ecore_x_ungrab(void)
1490 _ecore_xcb_grab_count--;
1491 if (_ecore_xcb_grab_count < 0)
1492 _ecore_xcb_grab_count = 0;
1494 if (_ecore_xcb_grab_count == 0)
1496 xcb_ungrab_server(_ecore_xcb_conn);
1497 free(xcb_get_input_focus_reply(_ecore_xcb_conn, xcb_get_input_focus(_ecore_xcb_conn), NULL));
1501 int _ecore_window_grabs_num = 0;
1502 Ecore_X_Window *_ecore_window_grabs = NULL;
1503 int (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event);
1504 void *_ecore_window_grab_replay_data;
1507 ecore_x_passive_grab_replay_func_set(int (*func) (void *data,
1512 _ecore_window_grab_replay_func = func;
1513 _ecore_window_grab_replay_data = data;
1517 ecore_x_window_button_grab(Ecore_X_Window window,
1519 Ecore_X_Event_Mask event_mask,
1528 m = _ecore_xcb_event_modifier(mod);
1529 if (any_mod) m = XCB_BUTTON_MASK_ANY;
1531 locks[1] = ECORE_X_LOCK_CAPS;
1532 locks[2] = ECORE_X_LOCK_NUM;
1533 locks[3] = ECORE_X_LOCK_SCROLL;
1534 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1535 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1536 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1537 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1539 for (i = 0; i < 8; i++)
1540 xcb_grab_button(_ecore_xcb_conn, 0, window, ev,
1541 XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
1542 XCB_NONE, XCB_NONE, button, m | locks[i]);
1543 _ecore_window_grabs_num++;
1544 _ecore_window_grabs = realloc(_ecore_window_grabs,
1545 _ecore_window_grabs_num * sizeof(Ecore_X_Window));
1546 _ecore_window_grabs[_ecore_window_grabs_num - 1] = window;
1550 _ecore_x_sync_magic_send(int val,
1551 Ecore_X_Window swindow)
1553 xcb_client_message_event_t ev;
1555 ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
1557 ev.window = _ecore_xcb_private_window;
1559 ev.data.data32[0] = 0x7162534;
1560 ev.data.data32[1] = 0x10000000 + val;
1561 ev.data.data32[2] = swindow;
1563 xcb_send_event(_ecore_xcb_conn, 0, _ecore_xcb_private_window,
1564 XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
1568 _ecore_x_window_grab_remove(Ecore_X_Window window)
1572 if (_ecore_window_grabs_num > 0)
1574 for (i = 0; i < _ecore_window_grabs_num; i++)
1576 if (shuffle) _ecore_window_grabs[i - 1] = _ecore_window_grabs[i];
1577 if ((!shuffle) && (_ecore_window_grabs[i] == window))
1582 _ecore_window_grabs_num--;
1583 _ecore_window_grabs = realloc(_ecore_window_grabs,
1584 _ecore_window_grabs_num * sizeof(Ecore_X_Window));
1590 ecore_x_window_button_ungrab(Ecore_X_Window window,
1599 m = _ecore_xcb_event_modifier(mod);
1600 if (any_mod) m = XCB_BUTTON_MASK_ANY;
1602 locks[1] = ECORE_X_LOCK_CAPS;
1603 locks[2] = ECORE_X_LOCK_NUM;
1604 locks[3] = ECORE_X_LOCK_SCROLL;
1605 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1606 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1607 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1608 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1609 for (i = 0; i < 8; i++)
1610 xcb_ungrab_button(_ecore_xcb_conn, button, window, m | locks[i]);
1611 _ecore_x_sync_magic_send(1, window);
1614 int _ecore_key_grabs_num = 0;
1615 Ecore_X_Window *_ecore_key_grabs = NULL;
1618 ecore_x_window_key_grab(Ecore_X_Window window,
1623 xcb_keycode_t keycode = 0;
1628 if (!strncmp(key, "Keycode-", 8))
1629 keycode = atoi(key + 8);
1630 /* FIXME: TODO... */
1634 /* KeySym keysym; */
1636 /* keysym = XStringToKeysym(key); */
1637 /* if (keysym == NoSymbol) return; */
1638 /* keycode = XKeysymToKeycode(_ecore_xcb_conn, XStringToKeysym(key)); */
1640 if (keycode == 0) return;
1642 m = _ecore_xcb_event_modifier(mod);
1643 if (any_mod) m = XCB_BUTTON_MASK_ANY;
1645 locks[1] = ECORE_X_LOCK_CAPS;
1646 locks[2] = ECORE_X_LOCK_NUM;
1647 locks[3] = ECORE_X_LOCK_SCROLL;
1648 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1649 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1650 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1651 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1652 for (i = 0; i < 8; i++)
1653 xcb_grab_key(_ecore_xcb_conn, 1, window, m | locks[i], keycode,
1654 XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
1655 _ecore_key_grabs_num++;
1656 _ecore_key_grabs = realloc(_ecore_key_grabs,
1657 _ecore_key_grabs_num * sizeof(Ecore_X_Window));
1658 _ecore_key_grabs[_ecore_key_grabs_num - 1] = window;
1662 _ecore_x_key_grab_remove(Ecore_X_Window window)
1666 if (_ecore_key_grabs_num > 0)
1668 for (i = 0; i < _ecore_key_grabs_num; i++)
1670 if (shuffle) _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
1671 if ((!shuffle) && (_ecore_key_grabs[i] == window))
1676 _ecore_key_grabs_num--;
1677 _ecore_key_grabs = realloc(_ecore_key_grabs,
1678 _ecore_key_grabs_num * sizeof(Ecore_X_Window));
1684 ecore_x_window_key_ungrab(Ecore_X_Window window,
1689 xcb_keycode_t keycode = 0;
1694 if (!strncmp(key, "Keycode-", 8))
1695 keycode = atoi(key + 8);
1696 /* FIXME: todo... */
1700 /* KeySym keysym; */
1702 /* keysym = XStringToKeysym(key); */
1703 /* if (keysym == NoSymbol) return; */
1704 /* keycode = XKeysymToKeycode(_ecore_xcb_conn, XStringToKeysym(key)); */
1706 if (keycode == 0) return;
1708 m = _ecore_xcb_event_modifier(mod);
1709 if (any_mod) m = XCB_BUTTON_MASK_ANY;
1711 locks[1] = ECORE_X_LOCK_CAPS;
1712 locks[2] = ECORE_X_LOCK_NUM;
1713 locks[3] = ECORE_X_LOCK_SCROLL;
1714 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1715 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1716 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1717 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1718 for (i = 0; i < 8; i++)
1719 xcb_ungrab_key(_ecore_xcb_conn, keycode, window, m | locks[i]);
1720 _ecore_x_sync_magic_send(2, window);
1724 * Send client message with given type and format 32.
1726 * @param window The window the message is sent to.
1727 * @param type The client message type.
1728 * @param mask The client message mask.
1729 * @param d0 The client message data item 1
1730 * @param d1 The client message data item 2
1731 * @param d2 The client message data item 3
1732 * @param d3 The client message data item 4
1733 * @param d4 The client message data item 5
1735 * @return !0 on success.
1738 ecore_x_client_message32_send(Ecore_X_Window window,
1740 Ecore_X_Event_Mask mask,
1747 xcb_client_message_event_t ev;
1749 ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
1753 ev.data.data32[0] = d0;
1754 ev.data.data32[1] = d1;
1755 ev.data.data32[2] = d2;
1756 ev.data.data32[3] = d3;
1757 ev.data.data32[4] = d4;
1759 xcb_send_event(_ecore_xcb_conn, 0, window, mask, (const char *)&ev);
1765 * Send client message with given type and format 8.
1767 * @param window The window the message is sent to.
1768 * @param type The client message type.
1769 * @param data Data to be sent.
1770 * @param len Number of data bytes, max 20.
1772 * @return !0 on success.
1775 ecore_x_client_message8_send(Ecore_X_Window window,
1780 xcb_client_message_event_t ev;
1782 ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
1788 memcpy(ev.data.data8, data, len);
1789 memset(ev.data.data8 + len, 0, 20 - len);
1791 xcb_send_event(_ecore_xcb_conn, 0, window, XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
1796 /* FIXME: round trip */
1798 ecore_x_mouse_move_send(Ecore_X_Window window,
1802 xcb_motion_notify_event_t ev;
1803 xcb_get_geometry_cookie_t cookie_geom;
1804 xcb_translate_coordinates_cookie_t cookie_trans;
1805 xcb_get_geometry_reply_t *reply_geom;
1806 xcb_translate_coordinates_reply_t *reply_trans;
1808 cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window);
1809 reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
1810 if (!reply_geom) return 0;
1812 cookie_trans = xcb_translate_coordinates_unchecked(_ecore_xcb_conn, window, reply_geom->root, x, y);
1813 reply_trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie_trans, NULL);
1820 ev.response_type = XCB_MOTION_NOTIFY;
1822 ev.time = _ecore_xcb_event_last_time;
1823 ev.root = reply_geom->root;
1826 ev.root_x = reply_trans->dst_x;
1827 ev.root_y = reply_trans->dst_y;
1833 xcb_send_event(_ecore_xcb_conn, 1, window, XCB_EVENT_MASK_POINTER_MOTION, (const char *)&ev);
1841 /* FIXME: round trip */
1843 ecore_x_mouse_down_send(Ecore_X_Window window,
1848 xcb_button_press_event_t ev;
1849 xcb_get_geometry_cookie_t cookie_geom;
1850 xcb_translate_coordinates_cookie_t cookie_trans;
1851 xcb_get_geometry_reply_t *reply_geom;
1852 xcb_translate_coordinates_reply_t *reply_trans;
1854 cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window);
1855 reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
1856 if (!reply_geom) return 0;
1858 cookie_trans = xcb_translate_coordinates_unchecked(_ecore_xcb_conn, window, reply_geom->root, x, y);
1859 reply_trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie_trans, NULL);
1866 ev.response_type = XCB_BUTTON_PRESS;
1868 ev.time = _ecore_xcb_event_last_time;
1869 ev.root = reply_geom->root;
1872 ev.root_x = reply_trans->dst_x;
1873 ev.root_y = reply_trans->dst_y;
1876 ev.state = 1 << button;
1879 xcb_send_event(_ecore_xcb_conn, 1, window, XCB_EVENT_MASK_BUTTON_PRESS, (const char *)&ev);
1887 /* FIXME: round trip */
1889 ecore_x_mouse_up_send(Ecore_X_Window window,
1894 xcb_button_release_event_t ev;
1895 xcb_get_geometry_cookie_t cookie_geom;
1896 xcb_translate_coordinates_cookie_t cookie_trans;
1897 xcb_get_geometry_reply_t *reply_geom;
1898 xcb_translate_coordinates_reply_t *reply_trans;
1900 cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window);
1901 reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
1902 if (!reply_geom) return 0;
1904 cookie_trans = xcb_translate_coordinates_unchecked(_ecore_xcb_conn, window, reply_geom->root, x, y);
1905 reply_trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie_trans, NULL);
1912 ev.response_type = XCB_BUTTON_RELEASE;
1914 ev.time = _ecore_xcb_event_last_time;
1915 ev.root = reply_geom->root;
1918 ev.root_x = reply_trans->dst_x;
1919 ev.root_y = reply_trans->dst_y;
1925 xcb_send_event(_ecore_xcb_conn, 1, window, XCB_EVENT_MASK_BUTTON_RELEASE, (const char *)&ev);
1934 ecore_x_focus_reset(void)
1936 xcb_set_input_focus(_ecore_xcb_conn,
1937 (uint8_t)XCB_INPUT_FOCUS_POINTER_ROOT,
1938 XCB_INPUT_FOCUS_POINTER_ROOT,
1943 ecore_x_events_allow_all(void)
1945 xcb_allow_events(_ecore_xcb_conn, XCB_ALLOW_ASYNC_BOTH, XCB_CURRENT_TIME);
1949 ecore_x_pointer_last_xy_get(int *x,
1952 if (x) *x = _ecore_xcb_event_last_root_x;
1953 if (y) *y = _ecore_xcb_event_last_root_y;
1957 /*****************************************************************************/
1958 /*****************************************************************************/
1959 /*****************************************************************************/
1962 _ecore_xcb_event_modifier(unsigned int state)
1966 if (state & ECORE_EVENT_MODIFIER_SHIFT) xmodifiers |= ECORE_X_MODIFIER_SHIFT;
1967 if (state & ECORE_EVENT_MODIFIER_CTRL) xmodifiers |= ECORE_X_MODIFIER_CTRL;
1968 if (state & ECORE_EVENT_MODIFIER_ALT) xmodifiers |= ECORE_X_MODIFIER_ALT;
1969 if (state & ECORE_EVENT_MODIFIER_WIN) xmodifiers |= ECORE_X_MODIFIER_WIN;
1970 if (state & ECORE_EVENT_LOCK_SCROLL) xmodifiers |= ECORE_X_LOCK_SCROLL;
1971 if (state & ECORE_EVENT_LOCK_NUM) xmodifiers |= ECORE_X_LOCK_NUM;
1972 if (state & ECORE_EVENT_LOCK_CAPS) xmodifiers |= ECORE_X_LOCK_CAPS;