From d59f4a65a5a1ffc86dba17e7f55551e974cfa6cf Mon Sep 17 00:00:00 2001 From: devilhorns Date: Thu, 14 Jul 2011 15:35:42 +0000 Subject: [PATCH] Ecore_X: Add new xcb code (still not 100% complete tho). git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@61376 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/ecore_x/xcb/Makefile.am | 144 +- src/lib/ecore_x/xcb/ecore_xcb.c | 2591 +++++---------- src/lib/ecore_x/xcb/ecore_xcb_atoms.c | 397 +++ src/lib/ecore_x/xcb/ecore_xcb_composite.c | 260 +- src/lib/ecore_x/xcb/ecore_xcb_cursor.c | 578 ++-- src/lib/ecore_x/xcb/ecore_xcb_damage.c | 169 +- src/lib/ecore_x/xcb/ecore_xcb_dnd.c | 970 +++--- src/lib/ecore_x/xcb/ecore_xcb_dpms.c | 477 +-- src/lib/ecore_x/xcb/ecore_xcb_drawable.c | 184 +- src/lib/ecore_x/xcb/ecore_xcb_e.c | 1005 +++++- src/lib/ecore_x/xcb/ecore_xcb_error.c | 95 + src/lib/ecore_x/xcb/ecore_xcb_events.c | 3313 ++++++++++--------- src/lib/ecore_x/xcb/ecore_xcb_extensions.c | 139 + src/lib/ecore_x/xcb/ecore_xcb_gc.c | 134 +- src/lib/ecore_x/xcb/ecore_xcb_icccm.c | 2621 ++++++---------- src/lib/ecore_x/xcb/ecore_xcb_image.c | 670 ++++ src/lib/ecore_x/xcb/ecore_xcb_input.c | 188 ++ src/lib/ecore_x/xcb/ecore_xcb_keymap.c | 447 +++ src/lib/ecore_x/xcb/ecore_xcb_mwm.c | 167 +- src/lib/ecore_x/xcb/ecore_xcb_netwm.c | 4190 +++++++------------------ src/lib/ecore_x/xcb/ecore_xcb_pixmap.c | 59 +- src/lib/ecore_x/xcb/ecore_xcb_private.h | 627 ++-- src/lib/ecore_x/xcb/ecore_xcb_randr.c | 2497 ++++++++++++--- src/lib/ecore_x/xcb/ecore_xcb_region.c | 115 +- src/lib/ecore_x/xcb/ecore_xcb_render.c | 229 ++ src/lib/ecore_x/xcb/ecore_xcb_reply.c | 114 - src/lib/ecore_x/xcb/ecore_xcb_screensaver.c | 592 ++-- src/lib/ecore_x/xcb/ecore_xcb_selection.c | 1504 ++++----- src/lib/ecore_x/xcb/ecore_xcb_shape.c | 310 +- src/lib/ecore_x/xcb/ecore_xcb_sync.c | 365 ++- src/lib/ecore_x/xcb/ecore_xcb_textlist.c | 469 +++ src/lib/ecore_x/xcb/ecore_xcb_vsync.c | 359 +++ src/lib/ecore_x/xcb/ecore_xcb_window.c | 2955 ++++++++--------- src/lib/ecore_x/xcb/ecore_xcb_window_prop.c | 1247 +++----- src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c | 195 +- src/lib/ecore_x/xcb/ecore_xcb_window_shape.c | 587 ++++ src/lib/ecore_x/xcb/ecore_xcb_xfixes.c | 603 ++++ src/lib/ecore_x/xcb/ecore_xcb_xinerama.c | 274 +- src/lib/ecore_x/xcb/ecore_xcb_xtest.c | 212 ++ 39 files changed, 17189 insertions(+), 14863 deletions(-) create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_atoms.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_error.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_extensions.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_image.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_input.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_keymap.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_render.c delete mode 100644 src/lib/ecore_x/xcb/ecore_xcb_reply.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_textlist.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_vsync.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_window_shape.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_xfixes.c create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_xtest.c diff --git a/src/lib/ecore_x/xcb/Makefile.am b/src/lib/ecore_x/xcb/Makefile.am index f31cadf..7e48f36 100644 --- a/src/lib/ecore_x/xcb/Makefile.am +++ b/src/lib/ecore_x/xcb/Makefile.am @@ -1,79 +1,93 @@ -MAINTAINERCLEANFILES = Makefile.in +MAINTAINERCLEANFILES = Makefile.in ecore_xcb_keysym_table.h if BUILD_ECORE_X_XCB AM_CPPFLAGS = \ -@XCB_DAMAGE_CFLAGS@ \ -@XCB_COMPOSITE_CFLAGS@ \ -@XCB_DPMS_CFLAGS@ \ -@XCB_RANDR_CFLAGS@ \ -@XCB_RENDER_CFLAGS@ \ -@XCB_SCREENSAVER_CFLAGS@ \ -@XCB_SHAPE_CFLAGS@ \ -@XCB_SYNC_CFLAGS@ \ -@XCB_XFIXES_CFLAGS@ \ -@XCB_XINERAMA_CFLAGS@ \ -@XCB_XPRINT_CFLAGS@ \ -@XCB_XTEST_CFLAGS@ \ -@XCB_CFLAGS@ \ --I$(top_srcdir)/src/lib/ecore \ --I$(top_srcdir)/src/lib/ecore_x \ --I$(top_srcdir)/src/lib/ecore_input \ --I$(top_builddir)/src/lib/ecore \ --I$(top_builddir)/src/lib/ecore_x \ --I$(top_builddir)/src/lib/ecore_input \ -@EVAS_CFLAGS@ \ -@EINA_CFLAGS@ + @XCB_DAMAGE_CFLAGS@ \ + @XCB_COMPOSITE_CFLAGS@ \ + @XCB_DPMS_CFLAGS@ \ + @XCB_RANDR_CFLAGS@ \ + @XCB_RENDER_CFLAGS@ \ + @XCB_SCREENSAVER_CFLAGS@ \ + @XCB_SHAPE_CFLAGS@ \ + @XCB_SYNC_CFLAGS@ \ + @XCB_XFIXES_CFLAGS@ \ + @XCB_XINERAMA_CFLAGS@ \ + @XCB_XPRINT_CFLAGS@ \ + @XCB_XTEST_CFLAGS@ \ + @XCB_XINPUT_CFLAGS@ \ + @XCB_CURSOR_CFLAGS@ \ + @XCB_DRI_CFLAGS@ \ + @XCB_CFLAGS@ \ + -I$(top_srcdir)/src/lib/ecore \ + -I$(top_srcdir)/src/lib/ecore_x \ + -I$(top_srcdir)/src/lib/ecore_input \ + -I$(top_builddir)/src/lib/ecore \ + -I$(top_builddir)/src/lib/ecore_x \ + -I$(top_builddir)/src/lib/ecore_input \ + @EINA_CFLAGS@ noinst_LTLIBRARIES = libecore_x_xcb.la libecore_x_xcb_la_SOURCES = \ -ecore_xcb_atom.c \ -ecore_xcb_cursor.c \ -ecore_xcb_damage.c \ -ecore_xcb_composite.c \ -ecore_xcb_dnd.c \ -ecore_xcb_dpms.c \ -ecore_xcb_drawable.c \ -ecore_xcb_e.c \ -ecore_xcb_events.c \ -ecore_xcb_fixes.c \ -ecore_xcb_gc.c \ -ecore_xcb_icccm.c \ -ecore_xcb_mwm.c \ -ecore_xcb_netwm.c \ -ecore_xcb_pixmap.c \ -ecore_xcb_randr.c \ -ecore_xcb_region.c \ -ecore_xcb_reply.c \ -ecore_xcb_screensaver.c \ -ecore_xcb_selection.c \ -ecore_xcb_shape.c \ -ecore_xcb_sync.c \ -ecore_xcb_window.c \ -ecore_xcb_window_prop.c \ -ecore_xcb_window_shadow.c \ -ecore_xcb_xinerama.c \ -ecore_xcb.c + ecore_xcb.c \ + ecore_xcb_atoms.c \ + ecore_xcb_extensions.c \ + ecore_xcb_shape.c \ + ecore_xcb_screensaver.c \ + ecore_xcb_sync.c \ + ecore_xcb_render.c \ + ecore_xcb_randr.c \ + ecore_xcb_xfixes.c \ + ecore_xcb_composite.c \ + ecore_xcb_cursor.c \ + ecore_xcb_damage.c \ + ecore_xcb_dnd.c \ + ecore_xcb_dpms.c \ + ecore_xcb_drawable.c \ + ecore_xcb_e.c \ + ecore_xcb_gc.c \ + ecore_xcb_image.c \ + ecore_xcb_input.c \ + ecore_xcb_mwm.c \ + ecore_xcb_pixmap.c \ + ecore_xcb_region.c \ + ecore_xcb_selection.c \ + ecore_xcb_textlist.c \ + ecore_xcb_events.c \ + ecore_xcb_keymap.c \ + ecore_xcb_netwm.c \ + ecore_xcb_icccm.c \ + ecore_xcb_window.c \ + ecore_xcb_window_prop.c \ + ecore_xcb_window_shape.c \ + ecore_xcb_window_shadow.c \ + ecore_xcb_xinerama.c \ + ecore_xcb_error.c \ + ecore_xcb_xtest.c \ + ecore_xcb_vsync.c libecore_x_xcb_la_LIBADD = \ -@XCB_DAMAGE_LIBS@ \ -@XCB_COMPOSITE_LIBS@ \ -@XCB_DPMS_LIBS@ \ -@XCB_RANDR_LIBS@ \ -@XCB_RENDER_LIBS@ \ -@XCB_SCREENSAVER_LIBS@ \ -@XCB_SHAPE_LIBS@ \ -@XCB_SYNC_LIBS@ \ -@XCB_XFIXES_LIBS@ \ -@XCB_XINERAMA_LIBS@ \ -@XCB_XPRINT_LIBS@ \ -@XCB_XTEST_LIBS@ \ -@XCB_LIBS@ \ -$(top_builddir)/src/lib/ecore/libecore.la \ -$(top_builddir)/src/lib/ecore_input/libecore_input.la \ -@EINA_LIBS@ + @XCB_DAMAGE_LIBS@ \ + @XCB_COMPOSITE_LIBS@ \ + @XCB_DPMS_LIBS@ \ + @XCB_RANDR_LIBS@ \ + @XCB_RENDER_LIBS@ \ + @XCB_SCREENSAVER_LIBS@ \ + @XCB_SHAPE_LIBS@ \ + @XCB_SYNC_LIBS@ \ + @XCB_XFIXES_LIBS@ \ + @XCB_XINERAMA_LIBS@ \ + @XCB_XPRINT_LIBS@ \ + @XCB_XTEST_LIBS@ \ + @XCB_XINPUT_LIBS@ \ + @XCB_CURSOR_LIBS@ \ + @XCB_DRI_LIBS@ \ + @XCB_LIBS@ \ + $(top_builddir)/src/lib/ecore/libecore.la \ + $(top_builddir)/src/lib/ecore_input/libecore_input.la \ + @EINA_LIBS@ endif diff --git a/src/lib/ecore_x/xcb/ecore_xcb.c b/src/lib/ecore_x/xcb/ecore_xcb.c index c74e54c..bb5e4c9 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb.c +++ b/src/lib/ecore_x/xcb/ecore_xcb.c @@ -1,130 +1,27 @@ -#include - -#include - -#include -#include - #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" - -static Eina_Bool _ecore_xcb_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); -static Eina_Bool _ecore_xcb_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler); -static int _ecore_xcb_key_mask_get(xcb_keysym_t sym); -static int _ecore_xcb_event_modifier(unsigned int state); - -static void * _ecore_xcb_event_filter_start(void *data); -static Eina_Bool _ecore_xcb_event_filter_filter(void *data, void *loop_data,int type, void *event); -static void _ecore_xcb_event_filter_end(void *data, void *loop_data); - -static Ecore_Fd_Handler *_ecore_xcb_fd_handler_handle = NULL; -static Ecore_Event_Filter *_ecore_xcb_filter_handler = NULL; - -static const int XCB_EVENT_ANY = 0; /* 0 can be used as there are no event types - * with index 0 and 1 as they are used for - * errors - */ - -#ifdef ECORE_XCB_DAMAGE -static int _ecore_xcb_event_damage_id = 0; -#endif /* ECORE_XCB_DAMAGE */ -#ifdef ECORE_XCB_RANDR -static int _ecore_xcb_event_randr_id = 0; -#endif /* ECORE_XCB_RANDR */ -#ifdef ECORE_XCB_SCREENSAVER -static int _ecore_xcb_event_screensaver_id = 0; -#endif /* ECORE_XCB_SCREENSAVER */ -#ifdef ECORE_XCB_SHAPE -static int _ecore_xcb_event_shape_id = 0; -#endif /* ECORE_XCB_SHAPE */ -#ifdef ECORE_XCB_SYNC -static int _ecore_xcb_event_sync_id = 0; -#endif /* ECORE_XCB_SYNC */ -#ifdef ECORE_XCB_FIXES -static int _ecore_xcb_event_fixes_selection_id = 0; -#endif /* ECORE_XCB_FIXES */ - -static int _ecore_xcb_event_handlers_num = 0; -static void (**_ecore_xcb_event_handlers) (xcb_generic_event_t * event) = NULL; -static xcb_generic_event_t *_ecore_xcb_event_buffered = NULL; +/* local function prototypes */ +static int _ecore_xcb_shutdown(Eina_Bool close_display); +static Eina_Bool _ecore_xcb_fd_handle(void *data, Ecore_Fd_Handler *hdlr __UNUSED__); +static Eina_Bool _ecore_xcb_fd_handle_buff(void *data, Ecore_Fd_Handler *hdlr __UNUSED__); + +/* local variables */ static int _ecore_xcb_init_count = 0; static int _ecore_xcb_grab_count = 0; -int _ecore_x11xcb_log_dom = -1; +static Ecore_Fd_Handler *_ecore_xcb_fd_handler = NULL; +static xcb_generic_event_t *_ecore_xcb_event_buffered = NULL; +/* external variables */ +int _ecore_xcb_log_dom = -1; +Ecore_X_Display *_ecore_xcb_display = NULL; Ecore_X_Connection *_ecore_xcb_conn = NULL; Ecore_X_Screen *_ecore_xcb_screen = NULL; +int _ecore_xcb_event_handlers_num = 0; +Ecore_X_Atom _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_NUM]; double _ecore_xcb_double_click_time = 0.25; -Ecore_X_Time _ecore_xcb_event_last_time = XCB_NONE; -Ecore_X_Window _ecore_xcb_event_last_window = XCB_NONE; -int16_t _ecore_xcb_event_last_root_x = 0; -int16_t _ecore_xcb_event_last_root_y = 0; -int _ecore_xcb_xcursor = 0; - -Ecore_X_Window _ecore_xcb_private_window = 0; - -/* FIXME - These are duplicates after making ecore atoms public */ - -Ecore_X_Atom _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM]; - -EAPI int ECORE_X_EVENT_ANY = 0; -EAPI int ECORE_X_EVENT_MOUSE_IN = 0; -EAPI int ECORE_X_EVENT_MOUSE_OUT = 0; -EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0; -EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0; -EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0; -EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0; -EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0; -EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0; -EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0; -EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0; -EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0; -EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0; -EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0; -EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0; -EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0; -EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0; -EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0; -EAPI int ECORE_X_EVENT_WINDOW_STACK = 0; -EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0; -EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0; -EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0; -EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0; -EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0; -EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0; -EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0; -EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0; -EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0; -EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0; -EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0; -EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0; -EAPI int ECORE_X_EVENT_SYNC_ALARM = 0; -EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0; -EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0; - -EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0; - -EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0; -EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0; -EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0; -EAPI int ECORE_X_EVENT_PING = 0; -EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0; - -EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0; -EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0; -EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0; - -EAPI int ECORE_X_MODIFIER_SHIFT = 0; -EAPI int ECORE_X_MODIFIER_CTRL = 0; -EAPI int ECORE_X_MODIFIER_ALT = 0; -EAPI int ECORE_X_MODIFIER_WIN = 0; - -EAPI int ECORE_X_LOCK_SCROLL = 0; -EAPI int ECORE_X_LOCK_NUM = 0; -EAPI int ECORE_X_LOCK_CAPS = 0; /** - * @defgroup Ecore_Xcb_Init_Group X Library Init and Shutdown Functions + * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions * * Functions that start and shut down the Ecore X Library. */ @@ -136,578 +33,147 @@ EAPI int ECORE_X_LOCK_CAPS = 0; * assumed. * @return The number of times the library has been initialized without * being shut down. 0 is returned if an error occurs. - * @ingroup Ecore_Xcb_Init_Group + * @ingroup Ecore_X_Init_Group */ -EAPI int -ecore_x_init(const char *name) +EAPI int +ecore_x_init(const char *name) { - xcb_screen_iterator_t iter; - int screen; - uint32_t max_request_length; - const xcb_query_extension_reply_t *reply_big_requests; -#ifdef ECORE_XCB_DAMAGE - const xcb_query_extension_reply_t *reply_damage; -#endif /* ECORE_XCB_DAMAGE */ -#ifdef ECORE_XCB_COMPOSITE - const xcb_query_extension_reply_t *reply_composite; -#endif /* ECORE_XCB_COMPOSITE */ -#ifdef ECORE_XCB_DPMS - const xcb_query_extension_reply_t *reply_dpms; -#endif /* ECORE_XCB_DPMS */ -#ifdef ECORE_XCB_RANDR - const xcb_query_extension_reply_t *reply_randr; -#endif /* ECORE_XCB_RANDR */ -#ifdef ECORE_XCB_SCREENSAVER - const xcb_query_extension_reply_t *reply_screensaver; -#endif /* ECORE_XCB_SCREENSAVER */ -#ifdef ECORE_XCB_SHAPE - const xcb_query_extension_reply_t *reply_shape; -#endif /* ECORE_XCB_SHAPE */ -#ifdef ECORE_XCB_SYNC - xcb_sync_initialize_cookie_t cookie_sync_init; - xcb_sync_initialize_reply_t *reply_sync_init; - const xcb_query_extension_reply_t *reply_sync; -#endif /* ECORE_XCB_SYNC */ -#ifdef ECORE_XCB_FIXES - const xcb_query_extension_reply_t *reply_xfixes; -#endif /* ECORE_XCB_FIXES */ -#ifdef ECORE_XCB_XINERAMA - const xcb_query_extension_reply_t *reply_xinerama; -#endif /* ECORE_XCB_XINERAMA */ -#ifdef ECORE_XCB_XPRINT - const xcb_query_extension_reply_t *reply_xprint; -#endif /* ECORE_XCB_XPRINT */ - - xcb_intern_atom_cookie_t atom_cookies[ECORE_X_ATOMS_COUNT]; - - if (++_ecore_xcb_init_count != 1) - return _ecore_xcb_init_count; - - /* We init some components (not related to XCB) */ - if (!eina_init()) - return --_ecore_xcb_init_count; - - _ecore_x11xcb_log_dom = eina_log_domain_register - ("ecore_x", ECORE_XLIB_XCB_DEFAULT_LOG_COLOR); - if (_ecore_x11xcb_log_dom < 0) - { - EINA_LOG_ERR("Impossible to create a log domain the Ecore XCB module."); - goto shutdown_eina; - } + uint32_t mask, list[1]; - if (!ecore_init()) - goto shutdown_eina; - if (!ecore_event_init()) - goto shutdown_ecore; + /* check if we have initialized already */ + if (++_ecore_xcb_init_count != 1) + return _ecore_xcb_init_count; - _ecore_xcb_conn = xcb_connect(name, &screen); - if (xcb_connection_has_error(_ecore_xcb_conn)) - goto shutdown_ecore_event; - - /* FIXME: no error code right now */ - /* _ecore_xcb_error_handler_init(); */ - - /********************/ - /* First round trip */ - /********************/ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* - * Non blocking stuff: - * - * 1. We request the atoms - * 2. We Prefetch the extension data - * + /* try to initialize eina + if (!eina_init()) return --_ecore_xcb_init_count; */ - /* We request the atoms (non blocking) */ - _ecore_x_atom_init(atom_cookies); - - /* We prefetch all the extension data (non blocking) */ - - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_big_requests_id); - -#ifdef ECORE_XCB_DAMAGE - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_damage_id); -#endif /* ECORE_XCB_DAMAGE */ - -#ifdef ECORE_XCB_COMPOSITE - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_composite_id); -#endif /* ECORE_XCB_COMPOSITE */ - -#ifdef ECORE_XCB_DPMS - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_dpms_id); -#endif /* ECORE_XCB_DPMS */ - -#ifdef ECORE_XCB_RANDR - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_randr_id); -#endif /* ECORE_XCB_RANDR */ - -#ifdef ECORE_XCB_SCREENSAVER - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); -#endif /* ECORE_XCB_SCREENSAVER */ - -#ifdef ECORE_XCB_SHAPE - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shape_id); -#endif /* ECORE_XCB_SHAPE */ - -#ifdef ECORE_XCB_SYNC - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_sync_id); - cookie_sync_init = xcb_sync_initialize_unchecked(_ecore_xcb_conn, - XCB_SYNC_MAJOR_VERSION, - XCB_SYNC_MINOR_VERSION); -#endif /* ECORE_XCB_SYNC */ + /* try to initialize ecore */ + if (!ecore_init()) + { + /* unregister log domain */ + /* eina_log_domain_unregister(_ecore_xcb_log_dom); */ + /* _ecore_xcb_log_dom = -1; */ + /* eina_shutdown(); */ + return --_ecore_xcb_init_count; + } -#ifdef ECORE_XCB_FIXES - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xfixes_id); -#endif /* ECORE_XCB_FIXES */ + /* setup ecore_xcb log domain */ + _ecore_xcb_log_dom = + eina_log_domain_register("ecore_x", ECORE_XCB_DEFAULT_LOG_COLOR); + if (_ecore_xcb_log_dom < 0) + { + EINA_LOG_ERR("Cannot create Ecore Xcb log domain"); + ecore_shutdown(); + return --_ecore_xcb_init_count; + } -#ifdef ECORE_XCB_XINERAMA - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xinerama_id); -#endif /* ECORE_XCB_XINERAMA */ + /* try to initialize ecore_event */ + if (!ecore_event_init()) + { + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_shutdown(); +// eina_shutdown(); + return --_ecore_xcb_init_count; + } -#ifdef ECORE_XCB_XPRINT - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_x_print_id); -#endif /* ECORE_XCB_XPRINT */ + /* try to connect to the display server */ + _ecore_xcb_conn = xcb_connect(name, NULL); - _ecore_x_reply_init(); - _ecore_x_dnd_init(); - ecore_x_netwm_init(); - _ecore_x_selection_init(); - - /* There is no LASTEvent constant in XCB */ - /* LASTevent is equal to 35 */ - _ecore_xcb_event_handlers_num = 35; - - /* We get the default screen */ - iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); - for (; iter.rem; --screen, xcb_screen_next (&iter)) - if (screen == 0) - { - _ecore_xcb_screen = iter.data; - break; - } - - /* - * Blocking stuff: - * - * 1. We get the atoms - * 2. We ask for the extension data - * + /* connect this way for opengl + _ecore_xcb_display = XOpenDisplay(name); + _ecore_xcb_conn = XGetXCBConnection(_ecore_xcb_display); + XSetEventQueueOwner(_ecore_xcb_display, XCBOwnsEventQueue); */ - /* We get the atoms (blocking) */ - _ecore_x_atom_init_finalize(atom_cookies); - - /* We then ask for the extension data (blocking) */ - reply_big_requests = xcb_get_extension_data(_ecore_xcb_conn, &xcb_big_requests_id); - -#ifdef ECORE_XCB_DAMAGE - reply_damage = xcb_get_extension_data(_ecore_xcb_conn, &xcb_damage_id); - if (reply_damage) - _ecore_xcb_event_damage_id = reply_damage->first_event + XCB_DAMAGE_NOTIFY; - - if (_ecore_xcb_event_damage_id >= _ecore_xcb_event_handlers_num) - _ecore_xcb_event_handlers_num = _ecore_xcb_event_damage_id + 1; - -#endif /* ECORE_XCB_DAMAGE */ - -#ifdef ECORE_XCB_COMPOSITE - reply_composite = xcb_get_extension_data(_ecore_xcb_conn, &xcb_composite_id); -#endif /* ECORE_XCB_COMPOSITE */ - -#ifdef ECORE_XCB_DPMS - reply_dpms = xcb_get_extension_data(_ecore_xcb_conn, &xcb_dpms_id); -#endif /* ECORE_XCB_DPMS */ - -#ifdef ECORE_XCB_RANDR - reply_randr = xcb_get_extension_data(_ecore_xcb_conn, &xcb_randr_id); - if (reply_randr) - _ecore_xcb_event_randr_id = reply_randr->first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY; - - if (_ecore_xcb_event_randr_id >= _ecore_xcb_event_handlers_num) - _ecore_xcb_event_handlers_num = _ecore_xcb_event_randr_id + 1; - -#endif /* ECORE_XCB_RANDR */ - -#ifdef ECORE_XCB_SCREENSAVER - reply_screensaver = xcb_get_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); - if (reply_screensaver) - _ecore_xcb_event_screensaver_id = reply_screensaver->first_event + XCB_SCREENSAVER_NOTIFY; - - if (_ecore_xcb_event_screensaver_id >= _ecore_xcb_event_handlers_num) - _ecore_xcb_event_handlers_num = _ecore_xcb_event_screensaver_id + 1; + if (xcb_connection_has_error(_ecore_xcb_conn)) + { + CRIT("XCB Connection has error"); + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_event_shutdown(); + ecore_shutdown(); +// eina_shutdown(); + return --_ecore_xcb_init_count; + } -#endif /* ECORE_XCB_SCREENSAVER */ + /* grab the default screen */ + _ecore_xcb_screen = + xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data; -#ifdef ECORE_XCB_SHAPE - reply_shape = xcb_get_extension_data(_ecore_xcb_conn, &xcb_shape_id); - if (reply_shape) - _ecore_xcb_event_shape_id = reply_shape->first_event + XCB_SHAPE_NOTIFY; + /* NB: This method of init/finalize extensions first, then atoms + * Does end up being 2 round trips to X, BUT if we do extensions init then + * atoms init first, and call the 'finalize' functions later, we end up + * being slower, so it's a trade-off. This current method clocks in + * around 0.003 for fetching atoms VS 0.010 for init both then finalize */ - if (_ecore_xcb_event_shape_id >= _ecore_xcb_event_handlers_num) - _ecore_xcb_event_handlers_num = _ecore_xcb_event_shape_id + 1; + /* prefetch extension data */ + _ecore_xcb_extensions_init(); -#endif /* ECORE_XCB_SHAPE */ + /* finalize extensions */ + _ecore_xcb_extensions_finalize(); -#ifdef ECORE_XCB_SYNC - reply_sync = xcb_get_extension_data(_ecore_xcb_conn, &xcb_sync_id); - if (reply_sync) - { - _ecore_xcb_event_sync_id = reply_sync->first_event; - reply_sync_init = xcb_sync_initialize_reply(_ecore_xcb_conn, - cookie_sync_init, NULL); - if (!reply_sync_init) - _ecore_xcb_event_sync_id = 0; - else - free(reply_sync_init); - } + /* setup xcb events */ + _ecore_xcb_events_init(); - if (_ecore_xcb_event_sync_id + XCB_SYNC_ALARM_NOTIFY >= _ecore_xcb_event_handlers_num) - _ecore_xcb_event_handlers_num = _ecore_xcb_event_sync_id + XCB_SYNC_ALARM_NOTIFY + 1; - -#endif /* ECORE_XCB_SYNC */ - -#ifdef ECORE_XCB_FIXES - reply_xfixes = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xfixes_id); - if (reply_xfixes) - _ecore_xcb_event_fixes_selection_id = reply_xfixes->first_event + XCB_XFIXES_SELECTION_NOTIFY; - - if (_ecore_xcb_event_fixes_selection_id >= _ecore_xcb_event_handlers_num) - _ecore_xcb_event_handlers_num = _ecore_xcb_event_fixes_selection_id + 1; - -#endif /* ECORE_XCB_FIXES */ - -#ifdef ECORE_XCB_XINERAMA - reply_xinerama = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xinerama_id); -#endif /* ECORE_XCB_XINERAMA */ - -#ifdef ECORE_XCB_XPRINT - reply_xprint = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id); -#endif /* ECORE_XCB_XPRINT */ - - /*********************/ - /* Second round trip */ - /*********************/ - - /* We ask for the QueryVersion request of the extensions */ -#ifdef ECORE_XCB_DAMAGE - _ecore_x_damage_init(reply_damage); -#endif /* ECORE_XCB_DAMAGE */ -#ifdef ECORE_XCB_COMPOSITE - _ecore_x_composite_init(reply_composite); -#endif /* ECORE_XCB_COMPOSITE */ -#ifdef ECORE_XCB_DPMS - _ecore_x_dpms_init(reply_dpms); -#endif /* ECORE_XCB_DPMS */ -#ifdef ECORE_XCB_RANDR - _ecore_x_randr_init(reply_randr); -#endif /* ECORE_XCB_RANDR */ -#ifdef ECORE_XCB_SCREENSAVER - _ecore_x_screensaver_init(reply_screensaver); -#endif /* ECORE_XCB_SCREENSAVER */ -#ifdef ECORE_XCB_SHAPE - _ecore_x_shape_init(reply_shape); -#endif /* ECORE_XCB_SHAPE */ -#ifdef ECORE_XCB_SYNC - _ecore_x_sync_init(reply_sync); -#endif /* ECORE_XCB_SYNC */ -#ifdef ECORE_XCB_FIXES - _ecore_x_xfixes_init(reply_xfixes); -#endif /* ECORE_XCB_FIXES */ -#ifdef ECORE_XCB_XINERAMA - _ecore_x_xinerama_init(reply_xinerama); -#endif /* ECORE_XCB_XINERAMA */ - - /* we enable the Big Request extension if present */ - max_request_length = xcb_get_maximum_request_length(_ecore_xcb_conn); - - _ecore_xcb_event_handlers = calloc(_ecore_xcb_event_handlers_num, sizeof(void *)); - if (!_ecore_xcb_event_handlers) - goto finalize_extensions; - -#ifdef ECORE_XCB_CURSOR - _ecore_xcb_xcursor = XcursorSupportsARGB(_ecore_xcb_conn); -#endif /* ECORE_XCB_CURSOR */ - - _ecore_xcb_event_handlers[XCB_EVENT_ANY] = _ecore_x_event_handle_any_event; - _ecore_xcb_event_handlers[XCB_KEY_PRESS] = _ecore_x_event_handle_key_press; - _ecore_xcb_event_handlers[XCB_KEY_RELEASE] = _ecore_x_event_handle_key_release; - _ecore_xcb_event_handlers[XCB_BUTTON_PRESS] = _ecore_x_event_handle_button_press; - _ecore_xcb_event_handlers[XCB_BUTTON_RELEASE] = _ecore_x_event_handle_button_release; - _ecore_xcb_event_handlers[XCB_MOTION_NOTIFY] = _ecore_x_event_handle_motion_notify; - _ecore_xcb_event_handlers[XCB_ENTER_NOTIFY] = _ecore_x_event_handle_enter_notify; - _ecore_xcb_event_handlers[XCB_LEAVE_NOTIFY] = _ecore_x_event_handle_leave_notify; - _ecore_xcb_event_handlers[XCB_FOCUS_IN] = _ecore_x_event_handle_focus_in; - _ecore_xcb_event_handlers[XCB_FOCUS_OUT] = _ecore_x_event_handle_focus_out; - _ecore_xcb_event_handlers[XCB_KEYMAP_NOTIFY] = _ecore_x_event_handle_keymap_notify; - _ecore_xcb_event_handlers[XCB_EXPOSE] = _ecore_x_event_handle_expose; - _ecore_xcb_event_handlers[XCB_GRAPHICS_EXPOSURE] = _ecore_x_event_handle_graphics_expose; - _ecore_xcb_event_handlers[XCB_VISIBILITY_NOTIFY] = _ecore_x_event_handle_visibility_notify; - _ecore_xcb_event_handlers[XCB_CREATE_NOTIFY] = _ecore_x_event_handle_create_notify; - _ecore_xcb_event_handlers[XCB_DESTROY_NOTIFY] = _ecore_x_event_handle_destroy_notify; - _ecore_xcb_event_handlers[XCB_UNMAP_NOTIFY] = _ecore_x_event_handle_unmap_notify; - _ecore_xcb_event_handlers[XCB_MAP_NOTIFY] = _ecore_x_event_handle_map_notify; - _ecore_xcb_event_handlers[XCB_MAP_REQUEST] = _ecore_x_event_handle_map_request; - _ecore_xcb_event_handlers[XCB_REPARENT_NOTIFY] = _ecore_x_event_handle_reparent_notify; - _ecore_xcb_event_handlers[XCB_CONFIGURE_NOTIFY] = _ecore_x_event_handle_configure_notify; - _ecore_xcb_event_handlers[XCB_CONFIGURE_REQUEST] = _ecore_x_event_handle_configure_request; - _ecore_xcb_event_handlers[XCB_GRAVITY_NOTIFY] = _ecore_x_event_handle_gravity_notify; - _ecore_xcb_event_handlers[XCB_RESIZE_REQUEST] = _ecore_x_event_handle_resize_request; - _ecore_xcb_event_handlers[XCB_CIRCULATE_NOTIFY] = _ecore_x_event_handle_circulate_notify; - _ecore_xcb_event_handlers[XCB_CIRCULATE_REQUEST] = _ecore_x_event_handle_circulate_request; - _ecore_xcb_event_handlers[XCB_PROPERTY_NOTIFY] = _ecore_x_event_handle_property_notify; - _ecore_xcb_event_handlers[XCB_SELECTION_CLEAR] = _ecore_x_event_handle_selection_clear; - _ecore_xcb_event_handlers[XCB_SELECTION_REQUEST] = _ecore_x_event_handle_selection_request; - _ecore_xcb_event_handlers[XCB_SELECTION_NOTIFY] = _ecore_x_event_handle_selection_notify; - _ecore_xcb_event_handlers[XCB_COLORMAP_NOTIFY] = _ecore_x_event_handle_colormap_notify; - _ecore_xcb_event_handlers[XCB_CLIENT_MESSAGE] = _ecore_x_event_handle_client_message; - _ecore_xcb_event_handlers[XCB_MAPPING_NOTIFY] = _ecore_x_event_handle_mapping_notify; -#ifdef ECORE_XCB_DAMAGE - if (_ecore_xcb_event_damage_id) - _ecore_xcb_event_handlers[_ecore_xcb_event_damage_id] = _ecore_x_event_handle_damage_notify; - -#endif /* ECORE_XCB_DAMAGE */ -#ifdef ECORE_XCB_RANDR - if (_ecore_xcb_event_randr_id) - _ecore_xcb_event_handlers[_ecore_xcb_event_randr_id] = _ecore_x_event_handle_randr_change; - -#endif /* ECORE_XCB_RANDR */ -#ifdef ECORE_XCB_SCREENSAVER - if (_ecore_xcb_event_screensaver_id) - _ecore_xcb_event_handlers[_ecore_xcb_event_screensaver_id] = _ecore_x_event_handle_screensaver_notify; - -#endif /* ECORE_XCB_SCREENSAVER */ -#ifdef ECORE_XCB_SHAPE - if (_ecore_xcb_event_shape_id) - _ecore_xcb_event_handlers[_ecore_xcb_event_shape_id] = _ecore_x_event_handle_shape_change; - -#endif /* ECORE_XCB_SHAPE */ -#ifdef ECORE_XCB_SYNC - if (_ecore_xcb_event_sync_id) - { - _ecore_xcb_event_handlers[_ecore_xcb_event_sync_id + XCB_SYNC_COUNTER_NOTIFY] = - _ecore_x_event_handle_sync_counter; - _ecore_xcb_event_handlers[_ecore_xcb_event_sync_id + XCB_SYNC_ALARM_NOTIFY] = - _ecore_x_event_handle_sync_alarm; - } + /* set keyboard autorepeat */ + mask = XCB_KB_AUTO_REPEAT_MODE; + list[0] = XCB_AUTO_REPEAT_MODE_ON; + xcb_change_keyboard_control(_ecore_xcb_conn, mask, list); -#endif /* ECORE_XCB_SYNC */ -#ifdef ECORE_XCB_FIXES - if (_ecore_xcb_event_fixes_selection_id) - _ecore_xcb_event_handlers[_ecore_xcb_event_fixes_selection_id] = _ecore_x_event_handle_fixes_selection_notify; + /* setup xcb keymasks */ + _ecore_xcb_keymap_init(); -#endif /* ECORE_XCB_FIXES */ + /* finalize xcb keymasks */ + _ecore_xcb_keymap_finalize(); - if (!ECORE_X_EVENT_ANY) - { - ECORE_X_EVENT_ANY = ecore_event_type_new(); - ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new(); - ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new(); - ECORE_X_EVENT_MAPPING_CHANGE = ecore_event_type_new(); - ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new(); - ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new(); - ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new(); - ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new(); - ECORE_X_EVENT_SCREENSAVER_NOTIFY = ecore_event_type_new(); - ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new(); - ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new(); - ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new(); - ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new(); - - ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new(); - ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new(); - ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new(); - ECORE_X_EVENT_PING = ecore_event_type_new(); - - ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new(); - ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new(); - ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new(); - } + /* setup ecore fd handler */ + _ecore_xcb_fd_handler = + ecore_main_fd_handler_add(xcb_get_file_descriptor(_ecore_xcb_conn), + ECORE_FD_READ, _ecore_xcb_fd_handle, + _ecore_xcb_conn, _ecore_xcb_fd_handle_buff, + _ecore_xcb_conn); + if (!_ecore_xcb_fd_handler) + return _ecore_xcb_shutdown(EINA_TRUE); - /* everything has these... unless its like a pda... :) */ - ECORE_X_MODIFIER_SHIFT = _ecore_xcb_key_mask_get(XK_Shift_L); - ECORE_X_MODIFIER_CTRL = _ecore_xcb_key_mask_get(XK_Control_L); - - /* apple's xdarwin has no alt!!!! */ - ECORE_X_MODIFIER_ALT = _ecore_xcb_key_mask_get(XK_Alt_L); - if (!ECORE_X_MODIFIER_ALT) - ECORE_X_MODIFIER_ALT = _ecore_xcb_key_mask_get(XK_Meta_L); - - if (!ECORE_X_MODIFIER_ALT) - ECORE_X_MODIFIER_ALT = _ecore_xcb_key_mask_get(XK_Super_L); - - /* the windows key... a valid modifier :) */ - ECORE_X_MODIFIER_WIN = _ecore_xcb_key_mask_get(XK_Super_L); - if (!ECORE_X_MODIFIER_WIN) - ECORE_X_MODIFIER_WIN = _ecore_xcb_key_mask_get(XK_Mode_switch); - - if (!ECORE_X_MODIFIER_WIN) - ECORE_X_MODIFIER_WIN = _ecore_xcb_key_mask_get(XK_Meta_L); - - if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT) - ECORE_X_MODIFIER_WIN = 0; - - if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL) - ECORE_X_MODIFIER_ALT = 0; - - ECORE_X_LOCK_SCROLL = _ecore_xcb_key_mask_get(XK_Scroll_Lock); - ECORE_X_LOCK_NUM = _ecore_xcb_key_mask_get(XK_Num_Lock); - ECORE_X_LOCK_CAPS = _ecore_xcb_key_mask_get(XK_Caps_Lock); - - _ecore_xcb_fd_handler_handle = - ecore_main_fd_handler_add(xcb_get_file_descriptor(_ecore_xcb_conn), - ECORE_FD_READ, - _ecore_xcb_fd_handler, _ecore_xcb_conn, - _ecore_xcb_fd_handler_buf, _ecore_xcb_conn); - if (!_ecore_xcb_fd_handler_handle) - goto free_event_handlers; - - _ecore_xcb_filter_handler = ecore_event_filter_add(_ecore_xcb_event_filter_start, _ecore_xcb_event_filter_filter, _ecore_xcb_event_filter_end, NULL); - - /* This is just to be anal about naming conventions */ - - _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = ECORE_X_ATOM_WM_DELETE_WINDOW; - _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = ECORE_X_ATOM_WM_TAKE_FOCUS; - _ecore_xcb_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] = ECORE_X_ATOM_NET_WM_PING; - _ecore_xcb_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST; - - _ecore_xcb_init_count++; - - _ecore_xcb_private_window = ecore_x_window_override_new(0, -77, -777, 123, 456); - - /* We finally get the replies of the QueryVersion request */ -#ifdef ECORE_XCB_DAMAGE - _ecore_x_damage_init_finalize(); -#endif /* ECORE_XCB_DAMAGE */ -#ifdef ECORE_XCB_COMPOSITE - _ecore_x_composite_init_finalize(); -#endif /* ECORE_XCB_COMPOSITE */ -#ifdef ECORE_XCB_DPMS - _ecore_x_dpms_init_finalize(); -#endif /* ECORE_XCB_DPMS */ -#ifdef ECORE_XCB_RANDR - _ecore_x_randr_init_finalize(); -#endif /* ECORE_XCB_RANDR */ -#ifdef ECORE_XCB_SCREENSAVER - _ecore_x_screensaver_init_finalize(); -#endif /* ECORE_XCB_SCREENSAVER */ -#ifdef ECORE_XCB_SHAPE - _ecore_x_shape_init_finalize(); -#endif /* ECORE_XCB_SHAPE */ -#ifdef ECORE_XCB_SYNC - _ecore_x_sync_init_finalize(); -#endif /* ECORE_XCB_SYNC */ -#ifdef ECORE_XCB_FIXES - _ecore_x_xfixes_init_finalize(); -#endif /* ECORE_XCB_FIXES */ -#ifdef ECORE_XCB_XINERAMA - _ecore_x_xinerama_init_finalize(); -#endif /* ECORE_XCB_XINERAMA */ + /* prefetch atoms */ + _ecore_xcb_atoms_init(); - return _ecore_xcb_init_count; + /* finalize atoms */ + _ecore_xcb_atoms_finalize(); -free_event_handlers: - free(_ecore_xcb_event_handlers); - _ecore_xcb_event_handlers = NULL; -finalize_extensions: - /* We get the replies of the QueryVersion request because we leave */ -#ifdef ECORE_XCB_DAMAGE - _ecore_x_damage_init_finalize(); -#endif /* ECORE_XCB_DAMAGE */ -#ifdef ECORE_XCB_COMPOSITE - _ecore_x_composite_init_finalize(); -#endif /* ECORE_XCB_COMPOSITE */ -#ifdef ECORE_XCB_DPMS - _ecore_x_dpms_init_finalize(); -#endif /* ECORE_XCB_DPMS */ -#ifdef ECORE_XCB_RANDR - _ecore_x_randr_init_finalize(); -#endif /* ECORE_XCB_RANDR */ -#ifdef ECORE_XCB_SCREENSAVER - _ecore_x_screensaver_init_finalize(); -#endif /* ECORE_XCB_SCREENSAVER */ -#ifdef ECORE_XCB_SHAPE - _ecore_x_shape_init_finalize(); -#endif /* ECORE_XCB_SHAPE */ -#ifdef ECORE_XCB_SYNC - _ecore_x_sync_init_finalize(); -#endif /* ECORE_XCB_SYNC */ -#ifdef ECORE_XCB_FIXES - _ecore_x_xfixes_init_finalize(); -#endif /* ECORE_XCB_FIXES */ -#ifdef ECORE_XCB_XINERAMA - _ecore_x_xinerama_init_finalize(); -#endif /* ECORE_XCB_XINERAMA */ -shutdown_ecore_event: - ecore_event_shutdown(); -shutdown_ecore: - ecore_shutdown(); -shutdown_eina: - eina_log_domain_unregister(_ecore_x11xcb_log_dom); - _ecore_x11xcb_log_dom = -1; - eina_shutdown(); + /* icccm_init: dummy function */ + ecore_x_icccm_init(); - return --_ecore_xcb_init_count; -} /* ecore_x_init */ + /* setup netwm */ + ecore_x_netwm_init(); -static int -_ecore_x_shutdown(int close_display) -{ - if (--_ecore_xcb_init_count != 0) - return _ecore_xcb_init_count; + /* old e hints init: dummy function */ + ecore_x_e_init(); - if (!_ecore_xcb_conn) - return _ecore_xcb_init_count; + _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = + ECORE_X_ATOM_WM_DELETE_WINDOW; + _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = + ECORE_X_ATOM_WM_TAKE_FOCUS; + _ecore_xcb_atoms_wm_protocol[ECORE_X_NET_WM_PROTOCOL_PING] = + ECORE_X_ATOM_NET_WM_PING; + _ecore_xcb_atoms_wm_protocol[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = + ECORE_X_ATOM_NET_WM_SYNC_REQUEST; - ecore_main_fd_handler_del(_ecore_xcb_fd_handler_handle); - if (close_display) - xcb_disconnect(_ecore_xcb_conn); - else - close(xcb_get_file_descriptor(_ecore_xcb_conn)); - - free(_ecore_xcb_event_handlers); - ecore_event_filter_del(_ecore_xcb_filter_handler); - _ecore_xcb_fd_handler_handle = NULL; - _ecore_xcb_filter_handler = NULL; - _ecore_xcb_conn = NULL; - _ecore_xcb_event_handlers = NULL; - _ecore_x_selection_shutdown(); - _ecore_x_dnd_shutdown(); - ecore_x_netwm_shutdown(); - _ecore_x_reply_shutdown(); + /* setup selection */ + _ecore_xcb_selection_init(); - ecore_event_shutdown(); - ecore_shutdown(); + /* setup dnd */ + _ecore_xcb_dnd_init(); - eina_log_domain_unregister(_ecore_x11xcb_log_dom); - _ecore_x11xcb_log_dom = -1; - eina_shutdown(); + // FIXME: XIM support return _ecore_xcb_init_count; -} /* _ecore_x_shutdown */ +} /** * Shuts down the Ecore X library. @@ -717,1341 +183,952 @@ _ecore_x_shutdown(int close_display) * * @return The number of times the library has been initialized without * being shut down. - * @ingroup Ecore_Xcb_Init_Group + * @ingroup Ecore_X_Init_Group */ -EAPI int -ecore_x_shutdown(void) +EAPI int +ecore_x_shutdown(void) { - return _ecore_x_shutdown(1); -} /* ecore_x_shutdown */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_shutdown(EINA_TRUE); +} /** * Shuts down the Ecore X library. * - * As ecore_xcb_shutdown, except do not close Display, only connection. + * As ecore_x_shutdown, except do not close Display, only connection. * - * @ingroup Ecore_Xcb_Init_Group + * @ingroup Ecore_X_Init_Group */ -EAPI int -ecore_x_disconnect(void) +EAPI int +ecore_x_disconnect(void) { - return _ecore_x_shutdown(0); -} /* ecore_x_disconnect */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_shutdown(EINA_FALSE); +} /** - * @defgroup Ecore_Xcb_Display_Attr_Group X Display Attributes + * @defgroup Ecore_X_Flush_Group X Synchronization Functions * - * Functions that set and retrieve X display attributes. + * Functions that ensure that all commands that have been issued by the + * Ecore X library have been sent to the server. */ -EAPI Ecore_X_Display * -ecore_x_display_get(void) -{ - return NULL; -} /* ecore_x_display_get */ - /** - * Retrieves the Ecore_X_Connection handle used for the current X connection. - * @return The current X connection. - * @ingroup Ecore_Xcb_Display_Attr_Group + * Sends all X commands in the X Display buffer. + * @ingroup Ecore_X_Flush_Group */ -EAPI Ecore_X_Connection * -ecore_x_connection_get(void) +EAPI void +ecore_x_flush(void) { - return (Ecore_X_Connection *)_ecore_xcb_conn; -} /* ecore_x_connection_get */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Retrieves the X display file descriptor. - * @return The current X display file descriptor. - * @ingroup Ecore_Xcb_Display_Attr_Group - */ -EAPI int -ecore_x_fd_get(void) -{ - return xcb_get_file_descriptor(_ecore_xcb_conn); -} /* ecore_x_fd_get */ + xcb_flush(_ecore_xcb_conn); +} /** * Retrieves the Ecore_X_Screen handle used for the current X connection. * @return The current default screen. - * @ingroup Ecore_Xcb_Display_Attr_Group + * @ingroup Ecore_X_Display_Attr_Group */ EAPI Ecore_X_Screen * -ecore_x_default_screen_get(void) +ecore_x_default_screen_get(void) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return (Ecore_X_Screen *)_ecore_xcb_screen; -} /* ecore_x_default_screen_get */ +} -/** - * Retrieves the size of an Ecore_X_Screen. - * @param screen the handle to the screen to query. - * @param w where to return the width. May be NULL. Returns 0 on errors. - * @param h where to return the height. May be NULL. Returns 0 on errors. - * @ingroup Ecore_X_Display_Attr_Group - * @see ecore_x_default_screen_get() - * - * @since 1.1 - */ -EAPI void -ecore_x_screen_size_get(const Ecore_X_Screen *screen, int *w, int *h) +EAPI Ecore_X_Connection * +ecore_x_connection_get(void) { - xcb_screen_t *s = (xcb_screen_t *)screen; LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (w) *w = 0; - if (h) *h = 0; - if (!s) return; - if (w) *w = s->width_in_pixels; - if (h) *h = s->height_in_pixels; + + return (Ecore_X_Connection *)_ecore_xcb_conn; } /** - * Sets the timeout for a double and triple clicks to be flagged. - * - * This sets the time between clicks before the double_click flag is - * set in a button down event. If 3 clicks occur within double this - * time, the triple_click flag is also set. - * - * @param t The time in seconds - * @ingroup Ecore_Xcb_Display_Attr_Group + * Return the last event time */ -EAPI void -ecore_x_double_click_time_set(double t) +EAPI Ecore_X_Time +ecore_x_current_time_get(void) { - if (t < 0.0) - t = 0.0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - _ecore_xcb_double_click_time = t; -} /* ecore_x_double_click_time_set */ + return _ecore_xcb_events_last_time_get(); +} /** - * Retrieves the double and triple click flag timeout. - * - * See @ref ecore_xcb_double_click_time_set for more information. - * - * @return The timeout for double clicks in seconds. - * @ingroup Ecore_Xcb_Display_Attr_Group + * Flushes the command buffer and waits until all requests have been + * processed by the server. + * @ingroup Ecore_X_Flush_Group */ -EAPI double -ecore_x_double_click_time_get(void) +EAPI void +ecore_x_sync(void) { - return _ecore_xcb_double_click_time; -} /* ecore_x_double_click_time_get */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * @defgroup Ecore_Xcb_Flush_Group X Synchronization Functions - * - * Functions that ensure that all commands that have been issued by the - * Ecore X library have been sent to the server. - */ + free(xcb_get_input_focus_reply(_ecore_xcb_conn, + xcb_get_input_focus(_ecore_xcb_conn), NULL)); +} -/** - * Sends all X commands in the X Display buffer. - * @ingroup Ecore_Xcb_Flush_Group - */ -EAPI void -ecore_x_flush(void) +EAPI void +ecore_x_grab(void) { - xcb_flush(_ecore_xcb_conn); -} /* ecore_x_flush */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Flushes the command buffer and waits until all requests have been - * processed by the server. - * @ingroup Ecore_Xcb_Flush_Group - */ -EAPI void -ecore_x_sync(void) + _ecore_xcb_grab_count++; + if (_ecore_xcb_grab_count == 1) + xcb_grab_server(_ecore_xcb_conn); +} + +EAPI void +ecore_x_ungrab(void) { - free(xcb_get_input_focus_reply(_ecore_xcb_conn, xcb_get_input_focus(_ecore_xcb_conn), NULL)); -} /* ecore_x_sync */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_grab_count--; + if (_ecore_xcb_grab_count < 0) _ecore_xcb_grab_count = 0; + if (_ecore_xcb_grab_count == 0) + xcb_ungrab_server(_ecore_xcb_conn); +} /** - * Kill all clients with subwindows under a given window. + * Send client message with given type and format 32. * - * You can kill all clients connected to the X server by using - * @ref ecore_x_window_root_list to get a list of root windows, and - * then passing each root window to this function. + * @param win The window the message is sent to. + * @param type The client message type. + * @param d0 The client message data item 1 + * @param d1 The client message data item 2 + * @param d2 The client message data item 3 + * @param d3 The client message data item 4 + * @param d4 The client message data item 5 * - * @param root The window whose children will be killed. + * @return EINA_TRUE on success EINA_FALSE otherwise. */ -EAPI void -ecore_x_killall(Ecore_X_Window root) +EAPI Eina_Bool +ecore_x_client_message32_send(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_Event_Mask mask, long d0, long d1, long d2, long d3, long d4) { - int screens; - int i; - - xcb_grab_server(_ecore_xcb_conn); - screens = xcb_setup_roots_iterator (xcb_get_setup (_ecore_xcb_conn)).rem; + xcb_client_message_event_t ev; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; - /* Tranverse window tree starting from root, and drag each - * before the firing squad */ - for (i = 0; i < screens; ++i) - { - xcb_query_tree_cookie_t cookie; - xcb_query_tree_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, root); - reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - xcb_window_t *wins = NULL; - int tree_c_len; - int i; + memset(&ev, 0, sizeof(xcb_client_message_event_t)); - wins = xcb_query_tree_children(reply); - tree_c_len = xcb_query_tree_children_length(reply); - for (i = 0; i < tree_c_len; i++) - xcb_kill_client(_ecore_xcb_conn, wins[i]); - free(reply); - } + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = type; + ev.data.data32[0] = (uint32_t)d0; + ev.data.data32[1] = (uint32_t)d1; + ev.data.data32[2] = (uint32_t)d2; + ev.data.data32[3] = (uint32_t)d3; + ev.data.data32[4] = (uint32_t)d4; + + // FIXME: Use unchecked version after development is ironed out + cookie = + xcb_send_event_checked(_ecore_xcb_conn, 0, win, mask, (const char *)&ev); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + DBG("Problem Sending Event"); + DBG("\tType: %d", type); + DBG("\tWin: %d", win); + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; } - xcb_ungrab_server(_ecore_xcb_conn); - free(xcb_get_input_focus_reply(_ecore_xcb_conn, xcb_get_input_focus(_ecore_xcb_conn), NULL)); -} /* ecore_x_killall */ + return EINA_TRUE; +} /** - * Kill a specific client + * Send client message with given type and format 8. * - * You can kill a specific client woning window @p window + * @param win The window the message is sent to. + * @param type The client message type. + * @param data Data to be sent. + * @param len Number of data bytes, max 20. * - * @param window Window of the client to be killed + * @return EINA_TRUE on success EINA_FALSE otherwise. */ -EAPI void -ecore_x_kill(Ecore_X_Window window) +EAPI Eina_Bool +ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, const void *data, int len) { - xcb_kill_client(_ecore_xcb_conn, window); -} /* ecore_x_kill */ + xcb_client_message_event_t ev; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; -/** - * TODO: Invoke the standard system beep to alert users - */ -EAPI Eina_Bool -ecore_x_bell(int percent) -{ - return 0; -} /* ecore_x_bell */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Return the last event time - */ -EAPI Ecore_X_Time -ecore_x_current_time_get(void) -{ - return _ecore_xcb_event_last_time; -} /* ecore_x_current_time_get */ + memset(&ev, 0, sizeof(xcb_client_message_event_t)); -static void -handle_event(xcb_generic_event_t *ev) -{ - uint8_t response_type = ev->response_type & ~0x80; + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 8; + ev.window = win; + ev.type = type; + if (len > 20) len = 20; + memcpy(ev.data.data8, data, len); + memset(ev.data.data8 + len, 0, 20 - len); - if (response_type < _ecore_xcb_event_handlers_num) + // FIXME: Use unchecked version after development is ironed out + cookie = + xcb_send_event_checked(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) { - if (_ecore_xcb_event_handlers[XCB_EVENT_ANY]) - _ecore_xcb_event_handlers[XCB_EVENT_ANY] (ev); - - if (_ecore_xcb_event_handlers[response_type]) - _ecore_xcb_event_handlers[response_type] (ev); + DBG("Problem Sending Event"); + DBG("\tType: %d", type); + DBG("\tWin: %d", win); + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; } -} /* handle_event */ -static Eina_Bool -_ecore_xcb_fd_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b) { - xcb_connection_t *c; - xcb_generic_event_t *ev; + xcb_translate_coordinates_cookie_t cookie; + xcb_translate_coordinates_reply_t *reply; + xcb_button_press_event_t ev; + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + Ecore_X_Window root = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + root = ecore_x_window_root_get(win); + cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); + reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; - c = (xcb_connection_t *)data; + memset(&ev, 0, sizeof(xcb_button_press_event_t)); -/* INF ("nbr events: %d", _ecore_xcb_event_handlers_num); */ + ev.response_type = XCB_BUTTON_PRESS; + ev.event = win; + ev.child = win; + ev.root = root; + ev.event_x = x; + ev.event_y = y; + ev.same_screen = 1; + ev.state = 1 << b; + ev.detail = b; // xcb uses detail for button + ev.root_x = reply->dst_x; + ev.root_y = reply->dst_y; + ev.time = ecore_x_current_time_get(); + free(reply); - /* We check if _ecore_xcb_event_buffered is NULL or not */ - if (_ecore_xcb_event_buffered) + // FIXME: Use unchecked version after development is ironed out + vcookie = + xcb_send_event_checked(_ecore_xcb_conn, 1, win, + XCB_EVENT_MASK_BUTTON_PRESS, (const char *)&ev); + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) { - handle_event(_ecore_xcb_event_buffered); - _ecore_xcb_event_buffered = NULL; + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; } - while ((ev = xcb_poll_for_event(c))) - handle_event(ev); - - return ECORE_CALLBACK_RENEW; -} /* _ecore_xcb_fd_handler */ + return EINA_TRUE; +} -static Eina_Bool -_ecore_xcb_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) +EAPI Eina_Bool +ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b) { - xcb_connection_t *c; - - c = (xcb_connection_t *)data; + xcb_translate_coordinates_cookie_t cookie; + xcb_translate_coordinates_reply_t *reply; + xcb_button_release_event_t ev; + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + Ecore_X_Window root = 0; - _ecore_xcb_event_buffered = xcb_poll_for_event(c); - if (!_ecore_xcb_event_buffered) - return ECORE_CALLBACK_CANCEL; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return ECORE_CALLBACK_RENEW; -} /* _ecore_xcb_fd_handler_buf */ + root = ecore_x_window_root_get(win); + cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); + reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; -/* FIXME: possible roundtrip */ -/* FIXME: fix xcb_keysyms. It's ugly !! (reply in xcb_key_symbols_get_keysym) */ -static int -_ecore_xcb_key_mask_get(xcb_keysym_t sym) -{ - xcb_get_modifier_mapping_cookie_t cookie; - xcb_get_modifier_mapping_reply_t *reply; - xcb_key_symbols_t *symbols; - xcb_keysym_t sym2; - int i, j; - xcb_keycode_t *keycodes = NULL; - int mod_keys_len; - const int masks[8] = - { - XCB_MOD_MASK_SHIFT, - XCB_MOD_MASK_LOCK, - XCB_MOD_MASK_CONTROL, - XCB_MOD_MASK_1, - XCB_MOD_MASK_2, - XCB_MOD_MASK_3, - XCB_MOD_MASK_4, - XCB_MOD_MASK_5 - }; - - cookie = xcb_get_modifier_mapping_unchecked(_ecore_xcb_conn); - symbols = xcb_key_symbols_alloc(_ecore_xcb_conn); - - reply = xcb_get_modifier_mapping_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - { - xcb_key_symbols_free(symbols); + memset(&ev, 0, sizeof(xcb_button_release_event_t)); - return 0; - } + ev.response_type = XCB_BUTTON_RELEASE; + ev.event = win; + ev.child = win; + ev.root = root; + ev.event_x = x; + ev.event_y = y; + ev.same_screen = 1; + ev.state = 0; + ev.root_x = reply->dst_x; + ev.root_y = reply->dst_y; + ev.detail = b; // xcb uses detail for button + ev.time = ecore_x_current_time_get(); + free(reply); - keycodes = xcb_get_modifier_mapping_keycodes(reply); - mod_keys_len = xcb_get_modifier_mapping_keycodes_length(reply); - for (i = 0; i < mod_keys_len; i++) + // FIXME: Use unchecked version after development is ironed out + vcookie = + xcb_send_event_checked(_ecore_xcb_conn, 1, win, + XCB_EVENT_MASK_BUTTON_RELEASE, (const char *)&ev); + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) { - for (j = 0; j < 8; j++) - { - sym2 = xcb_key_symbols_get_keysym(symbols, keycodes[i], j); - if (sym2 != 0) - break; - } - if (sym2 == sym) - { - int mask; - - mask = masks[j]; - free(reply); - xcb_key_symbols_free(symbols); - return mask; - } + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; } - free(reply); - xcb_key_symbols_free(symbols); - - return 0; -} /* _ecore_xcb_key_mask_get */ - -typedef struct _Ecore_X_Filter_Data Ecore_X_Filter_Data; + return EINA_TRUE; +} -struct _Ecore_X_Filter_Data +EAPI Eina_Bool +ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y) { - int last_event_type; -}; + xcb_translate_coordinates_cookie_t cookie; + xcb_translate_coordinates_reply_t *reply; + xcb_motion_notify_event_t ev; + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + Ecore_X_Window root = 0; -static void * -_ecore_xcb_event_filter_start(void *data __UNUSED__) -{ - Ecore_X_Filter_Data *filter_data; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - filter_data = calloc(1, sizeof(Ecore_X_Filter_Data)); - return filter_data; -} /* _ecore_xcb_event_filter_start */ + root = ecore_x_window_root_get(win); + cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); + reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; -static Eina_Bool -_ecore_xcb_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__) -{ - Ecore_X_Filter_Data *filter_data; + memset(&ev, 0, sizeof(xcb_motion_notify_event_t)); - filter_data = loop_data; - if (!filter_data) - return EINA_TRUE; + ev.response_type = XCB_MOTION_NOTIFY; + ev.event = win; + ev.child = win; + ev.root = root; + ev.event_x = x; + ev.event_y = y; + ev.same_screen = 1; + ev.state = 0; + ev.detail = 0; // xcb uses 'detail' for is_hint + ev.root_x = reply->dst_x; + ev.root_y = reply->dst_y; + ev.time = ecore_x_current_time_get(); + free(reply); - if (type == ECORE_EVENT_MOUSE_MOVE) + // FIXME: Use unchecked version after development is ironed out + vcookie = + xcb_send_event_checked(_ecore_xcb_conn, 1, win, + XCB_EVENT_MASK_POINTER_MOTION, (const char *)&ev); + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) { - if ((filter_data->last_event_type) == ECORE_EVENT_MOUSE_MOVE) - { - filter_data->last_event_type = type; - return EINA_FALSE; - } + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; } - filter_data->last_event_type = type; return EINA_TRUE; -} /* _ecore_xcb_event_filter_filter */ +} -static void -_ecore_xcb_event_filter_end(void *data __UNUSED__, void *loop_data) +EAPI Eina_Bool +ecore_x_keyboard_grab(Ecore_X_Window win) { - Ecore_X_Filter_Data *filter_data; - - filter_data = loop_data; - if (filter_data) - free(filter_data); -} /* _ecore_xcb_event_filter_end */ + xcb_grab_keyboard_cookie_t cookie; + xcb_grab_keyboard_reply_t *reply; -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -/* FIXME: these funcs need categorising */ -/*****************************************************************************/ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Get a list of all the root windows on the server. - * - * @note The returned array will need to be freed after use. - * @param num_ret Pointer to integer to put number of windows returned in. - * @return An array of all the root windows. @c NULL is returned if memory - * could not be allocated for the list, or if @p num_ret is @c NULL. - */ -EAPI Ecore_X_Window * -ecore_x_window_root_list(int *num_ret) -{ - xcb_screen_iterator_t iter; - const xcb_setup_t *setup; - uint8_t i; - uint8_t num; - Ecore_X_Window *roots; -/* #ifdef ECORE_XCBXPRINT */ -/* int xp_base, xp_err_base; */ -/* #endif /\* ECORE_XCBXPRINT *\/ */ - - if (!num_ret) - return NULL; - - *num_ret = 0; - - /* FIXME: todo... */ -/* #ifdef ECORE_XCBXPRINT */ -/* num = ScreenCount(_ecore_xcb_conn); */ -/* if (ecore_xcb_xprint_query()) */ -/* { */ -/* Screen **ps = NULL; */ -/* int psnum = 0; */ - -/* ps = XpQueryScreens(_ecore_xcb_conn, &psnum); */ -/* if (ps) */ -/* { */ -/* int overlap, j; */ - -/* overlap = 0; */ -/* for (i = 0; i < num; i++) */ -/* { */ -/* for (j = 0; j < psnum; j++) */ -/* { */ -/* if (ScreenOfDisplay(_ecore_xcb_conn, i) == ps[j]) */ -/* overlap++; */ -/* } */ -/* } */ -/* roots = malloc((num - overlap) * sizeof(Ecore_X_Window)); */ -/* if (roots) */ -/* { */ -/* int k; */ - -/* k = 0; */ -/* for (i = 0; i < num; i++) */ -/* { */ -/* int is_print; */ - -/* is_print = 0; */ -/* for (j = 0; j < psnum; j++) */ -/* { */ -/* if (ScreenOfDisplay(_ecore_xcb_conn, i) == ps[j]) */ -/* { */ -/* is_print = 1; */ -/* break; */ -/* } */ -/* } */ -/* if (!is_print) */ -/* { */ -/* roots[k] = RootWindow(_ecore_xcb_conn, i); */ -/* k++; */ -/* } */ -/* } */ -/* *num_ret = k; */ -/* } */ -/* XFree(ps); */ -/* } */ -/* else */ -/* { */ -/* roots = malloc(num * sizeof(Ecore_X_Window)); */ -/* if (!roots) return NULL; */ -/* *num_ret = num; */ -/* for (i = 0; i < num; i++) */ -/* roots[i] = RootWindow(_ecore_xcb_conn, i); */ -/* } */ -/* } */ -/* else */ -/* { */ -/* roots = malloc(num * sizeof(Ecore_X_Window)); */ -/* if (!roots) return NULL; */ -/* *num_ret = num; */ -/* for (i = 0; i < num; i++) */ -/* roots[i] = RootWindow(_ecore_xcb_conn, i); */ -/* } */ -/* #else */ - setup = xcb_get_setup (_ecore_xcb_conn); - iter = xcb_setup_roots_iterator (setup); - num = setup->roots_len; - roots = malloc(num * sizeof(Ecore_X_Window)); - if (!roots) - return NULL; - - *num_ret = num; - for (i = 0; iter.rem; xcb_screen_next(&iter), i++) - roots[i] = iter.data->root; -/* #endif /\* ECORE_XCBXPRINT *\/ */ - - return roots; -} /* ecore_x_window_root_list */ - -EAPI Ecore_X_Window -ecore_x_window_root_first_get(void) -{ - Ecore_X_Window *roots = NULL; - Ecore_X_Window root; - int num; - - roots = ecore_x_window_root_list(&num); - if(!(roots)) - return 0; - - if (num > 0) - root = roots[0]; - else - root = 0; - - free(roots); - return root; -} /* ecore_x_window_root_first_get */ + cookie = + xcb_grab_keyboard_unchecked(_ecore_xcb_conn, 0, win, XCB_CURRENT_TIME, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); + reply = xcb_grab_keyboard_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + free(reply); + return EINA_TRUE; +} -/* FIXME: todo */ +EAPI void +ecore_x_keyboard_ungrab(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -static void _ecore_x_window_manage_error(void *data); + xcb_ungrab_keyboard(_ecore_xcb_conn, XCB_CURRENT_TIME); +} -static int _ecore_xcb_window_manage_failed = 0; -static void -_ecore_x_window_manage_error(void *data __UNUSED__) -{ -/* if ((ecore_xcb_error_request_get() == X_ChangeWindowAttributes) && */ -/* (ecore_xcb_error_code_get() == BadAccess)) */ -/* _ecore_xcb_window_manage_failed = 1; */ -} /* _ecore_x_window_manage_error */ - -/* FIXME: round trip */ -EAPI Eina_Bool -ecore_x_window_manage(Ecore_X_Window window) +EAPI void +ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y) { - xcb_get_window_attributes_cookie_t cookie_attr; - xcb_get_input_focus_cookie_t cookie_sync; - xcb_get_window_attributes_reply_t *reply_attr; - xcb_get_input_focus_reply_t *reply_sync; - uint32_t value_list; + xcb_query_pointer_cookie_t cookie; + xcb_query_pointer_reply_t *reply; - cookie_attr = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window); - cookie_sync = xcb_get_input_focus_unchecked(_ecore_xcb_conn); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply_attr = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_attr, NULL); - if (!reply_attr) - { - reply_sync = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie_sync, NULL); - if (reply_sync) - free(reply_sync); +// if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - return 0; - } + if (x) *x = -1; + if (y) *y = -1; - reply_sync = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie_sync, NULL); - if (reply_sync) - free(reply_sync); - - _ecore_xcb_window_manage_failed = 0; - /* FIXME: no error code yet */ - /* ecore_xcb_error_handler_set(_ecore_xcb_window_manage_error, NULL); */ - - value_list = - XCB_EVENT_MASK_KEY_PRESS | - XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_ENTER_WINDOW | - XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_RESIZE_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | - XCB_EVENT_MASK_PROPERTY_CHANGE | - reply_attr->your_event_mask; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_EVENT_MASK, - &value_list); - free(reply_attr); - - cookie_sync = xcb_get_input_focus_unchecked(_ecore_xcb_conn); - if (reply_sync) - free(reply_sync); - - /* FIXME: no error code yet */ - /* ecore_xcb_error_handler_set(NULL, NULL); */ - if (_ecore_xcb_window_manage_failed) - { - _ecore_xcb_window_manage_failed = 0; - return 0; - } - - return 1; -} /* ecore_x_window_manage */ + cookie = xcb_query_pointer(_ecore_xcb_conn, win); + reply = xcb_query_pointer_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + if (x) *x = reply->win_x; + if (y) *y = reply->win_y; + free(reply); +} -EAPI Eina_Bool -ecore_x_pointer_control_set(int accel_num, - int accel_denom, - int threshold) +EAPI Eina_Bool +ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold) { - xcb_change_pointer_control(_ecore_xcb_conn, - accel_num, accel_denom, threshold, - 1, 1); - return 1; -} /* ecore_x_pointer_control_set */ - -EAPI void -ecore_x_pointer_control_get_prefetch(void) -{ - xcb_get_pointer_control_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_get_pointer_control_unchecked(_ecore_xcb_conn); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_pointer_control_get_prefetch */ + xcb_change_pointer_control(_ecore_xcb_conn, + accel_num, accel_denom, threshold, 1, 1); + return EINA_TRUE; +} -EAPI void -ecore_x_pointer_control_get_fetch(void) +EAPI Eina_Bool +ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold) { xcb_get_pointer_control_cookie_t cookie; xcb_get_pointer_control_reply_t *reply; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_pointer_control_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_pointer_control_get_fetch */ - -EAPI Eina_Bool -ecore_x_pointer_control_get(int *accel_num, - int *accel_denom, - int *threshold) -{ - xcb_get_pointer_control_reply_t *reply; - - if (accel_num) - *accel_num = 0; - - if (accel_denom) - *accel_denom = 1; - - if (threshold) - *threshold = 0; - - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (accel_num) - *accel_num = reply->acceleration_numerator; + if (accel_num) *accel_num = 0; + if (accel_denom) *accel_denom = 0; + if (threshold) *threshold = 0; - if (accel_denom) - *accel_denom = reply->acceleration_denominator; + cookie = xcb_get_pointer_control_unchecked(_ecore_xcb_conn); + reply = xcb_get_pointer_control_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; - if (threshold) - *threshold = reply->threshold; + if (accel_num) *accel_num = reply->acceleration_numerator; + if (accel_denom) *accel_denom = reply->acceleration_denominator; + if (threshold) *threshold = reply->threshold; + free(reply); - return 1; -} /* ecore_x_pointer_control_get */ + return EINA_TRUE; +} -EAPI Eina_Bool -ecore_x_pointer_mapping_set(unsigned char *map, - int nmap) +EAPI Eina_Bool +ecore_x_pointer_mapping_set(unsigned char *map, int nmap) { - xcb_set_pointer_mapping(_ecore_xcb_conn, nmap, map); - return 1; -} /* ecore_x_pointer_mapping_set */ + xcb_set_pointer_mapping_cookie_t cookie; + xcb_set_pointer_mapping_reply_t *reply; + Eina_Bool ret = EINA_FALSE; -EAPI void -ecore_x_pointer_mapping_get_prefetch(void) -{ - xcb_get_pointer_mapping_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_get_pointer_mapping_unchecked(_ecore_xcb_conn); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_pointer_mapping_get_prefetch */ + cookie = xcb_set_pointer_mapping_unchecked(_ecore_xcb_conn, nmap, map); + reply = xcb_set_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + ret = + (reply->status == XCB_MAPPING_STATUS_SUCCESS) ? EINA_TRUE : EINA_FALSE; -EAPI void -ecore_x_pointer_mapping_get_fetch(void) + free(reply); + return ret; +} + +EAPI Eina_Bool +ecore_x_pointer_mapping_get(unsigned char *map, int nmap) { xcb_get_pointer_mapping_cookie_t cookie; xcb_get_pointer_mapping_reply_t *reply; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_pointer_mapping_get_fetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -EAPI Eina_Bool -ecore_x_pointer_mapping_get(unsigned char *map, - int nmap) -{ - xcb_get_pointer_mapping_cookie_t cookie; - xcb_get_pointer_mapping_reply_t *reply; - uint8_t *tmp; - int i; + if (map) *map = 0; + nmap = 0; cookie = xcb_get_pointer_mapping_unchecked(_ecore_xcb_conn); reply = xcb_get_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - return 0; + if (!reply) return EINA_FALSE; - if (nmap > xcb_get_pointer_mapping_map_length(reply)) - return 0; + nmap = xcb_get_pointer_mapping_map_length(reply); + if (nmap <= 0) + { + free(reply); + return EINA_FALSE; + } - tmp = xcb_get_pointer_mapping_map(reply); + if (map) + { + uint8_t *tmp; + int i = 0; - for (i = 0; i < nmap; i++) - map[i] = tmp[i]; + tmp = xcb_get_pointer_mapping_map(reply); + for (i = 0; i < nmap; i++) + map[i] = tmp[i]; + } - return 1; -} /* ecore_x_pointer_mapping_get */ + free(reply); + return EINA_TRUE; +} -EAPI Eina_Bool -ecore_x_pointer_grab(Ecore_X_Window window) +EAPI Eina_Bool +ecore_x_pointer_grab(Ecore_X_Window win) { xcb_grab_pointer_cookie_t cookie; xcb_grab_pointer_reply_t *reply; + uint16_t mask; + Eina_Bool ret = EINA_FALSE; - cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, window, - XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_ENTER_WINDOW | - XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_POINTER_MOTION, - XCB_GRAB_MODE_ASYNC, - XCB_GRAB_MODE_ASYNC, - XCB_NONE, XCB_NONE, - XCB_CURRENT_TIME); + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + mask = (XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | + XCB_EVENT_MASK_POINTER_MOTION); + + cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, win, mask, + XCB_GRAB_MODE_ASYNC, + XCB_GRAB_MODE_ASYNC, + XCB_NONE, XCB_NONE, XCB_CURRENT_TIME); reply = xcb_grab_pointer_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - return 0; + if (!reply) return EINA_FALSE; - free(reply); + ret = (reply->status == XCB_GRAB_STATUS_SUCCESS) ? EINA_TRUE : EINA_FALSE; - return 1; -} /* ecore_x_pointer_grab */ + free(reply); + return ret; +} -EAPI Eina_Bool -ecore_x_pointer_confine_grab(Ecore_X_Window window) +EAPI Eina_Bool +ecore_x_pointer_confine_grab(Ecore_X_Window win) { xcb_grab_pointer_cookie_t cookie; xcb_grab_pointer_reply_t *reply; + uint16_t mask; + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, window, - XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_ENTER_WINDOW | - XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_POINTER_MOTION, - XCB_GRAB_MODE_ASYNC, - XCB_GRAB_MODE_ASYNC, - window, XCB_NONE, - XCB_CURRENT_TIME); + mask = (XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | + XCB_EVENT_MASK_POINTER_MOTION); + + cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, win, mask, + XCB_GRAB_MODE_ASYNC, + XCB_GRAB_MODE_ASYNC, + win, XCB_NONE, XCB_CURRENT_TIME); reply = xcb_grab_pointer_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - return 0; + if (!reply) return EINA_FALSE; - free(reply); + ret = (reply->status == XCB_GRAB_STATUS_SUCCESS) ? EINA_TRUE : EINA_FALSE; - return 1; -} /* ecore_x_pointer_confine_grab */ + free(reply); + return ret; +} -EAPI void -ecore_x_pointer_ungrab(void) +EAPI void +ecore_x_pointer_ungrab(void) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + xcb_ungrab_pointer(_ecore_xcb_conn, XCB_CURRENT_TIME); -} /* ecore_x_pointer_ungrab */ +} -EAPI Eina_Bool -ecore_x_pointer_warp(Ecore_X_Window window, - int x, - int y) +EAPI Eina_Bool +ecore_x_pointer_warp(Ecore_X_Window win, int x, int y) { - xcb_warp_pointer(_ecore_xcb_conn, XCB_NONE, window, 0, 0, 0, 0, x, y); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return 1; -} /* ecore_x_pointer_warp */ + xcb_warp_pointer(_ecore_xcb_conn, XCB_NONE, win, 0, 0, 0, 0, x, y); + return EINA_TRUE; +} -EAPI Eina_Bool -ecore_x_keyboard_grab(Ecore_X_Window window) +/** + * Invoke the standard system beep to alert users + * + * @param percent The volume at which the bell rings. Must be in the range + * [-100,+100]. If percent >= 0, the final volume will be: + * base - [(base * percent) / 100] + percent + * Otherwise, it's calculated as: + * base + [(base * percent) / 100] + * where @c base is the bell's base volume as set by XChangeKeyboardControl(3). + * + * @returns EINA_TRUE on success, EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_bell(int percent) { - xcb_grab_keyboard_cookie_t cookie; - xcb_grab_keyboard_reply_t *reply; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; - cookie = xcb_grab_keyboard_unchecked(_ecore_xcb_conn, 0, window, - XCB_CURRENT_TIME, - XCB_GRAB_MODE_ASYNC, - XCB_GRAB_MODE_ASYNC); - reply = xcb_grab_keyboard_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - free(reply); + // FIXME: Use unchecked version after development is ironed out + cookie = xcb_bell_checked(_ecore_xcb_conn, percent); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } - return 1; -} /* ecore_x_keyboard_grab */ + return EINA_TRUE; +} -EAPI void -ecore_x_keyboard_ungrab(void) +EAPI void +ecore_x_display_size_get(Ecore_X_Display *dsp, int *w, int *h) { - xcb_ungrab_keyboard(_ecore_xcb_conn, XCB_CURRENT_TIME); -} /* ecore_x_keyboard_ungrab */ + xcb_screen_t *screen; -EAPI void -ecore_x_grab(void) -{ - _ecore_xcb_grab_count++; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (_ecore_xcb_grab_count == 1) - xcb_grab_server(_ecore_xcb_conn); -} /* ecore_x_grab */ + /* grab the default screen */ + screen = xcb_setup_roots_iterator(xcb_get_setup(dsp)).data; + if (w) *w = screen->width_in_pixels; + if (h) *h = screen->height_in_pixels; +} -EAPI void -ecore_x_ungrab(void) +EAPI unsigned long +ecore_x_display_black_pixel_get(Ecore_X_Display *dsp) { - _ecore_xcb_grab_count--; - if (_ecore_xcb_grab_count < 0) - _ecore_xcb_grab_count = 0; + xcb_screen_t *screen; - if (_ecore_xcb_grab_count == 0) - { - xcb_ungrab_server(_ecore_xcb_conn); - free(xcb_get_input_focus_reply(_ecore_xcb_conn, xcb_get_input_focus(_ecore_xcb_conn), NULL)); - } -} /* ecore_x_ungrab */ - -int _ecore_window_grabs_num = 0; -Ecore_X_Window *_ecore_window_grabs = NULL; -Eina_Bool (*_ecore_window_grab_replay_func)(void *data, int event_type, void *event); -void *_ecore_window_grab_replay_data; - -EAPI void -ecore_x_passive_grab_replay_func_set(Eina_Bool (*func)(void *data, - int event_type, - void *event), - void *data) -{ - _ecore_window_grab_replay_func = func; - _ecore_window_grab_replay_data = data; -} /* ecore_x_passive_grab_replay_func_set */ - -EAPI void -ecore_x_window_button_grab(Ecore_X_Window window, - int button, - Ecore_X_Event_Mask event_mask, - int mod, - int any_mod) -{ - int i; - uint16_t m; - uint16_t locks[8]; - uint16_t ev; - - m = _ecore_xcb_event_modifier(mod); - if (any_mod) - m = XCB_BUTTON_MASK_ANY; - - locks[0] = 0; - locks[1] = ECORE_X_LOCK_CAPS; - locks[2] = ECORE_X_LOCK_NUM; - locks[3] = ECORE_X_LOCK_SCROLL; - locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; - locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; - locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; - locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; - ev = event_mask; - for (i = 0; i < 8; i++) - xcb_grab_button(_ecore_xcb_conn, 0, window, ev, - XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, - XCB_NONE, XCB_NONE, button, m | locks[i]); - _ecore_window_grabs_num++; - _ecore_window_grabs = realloc(_ecore_window_grabs, - _ecore_window_grabs_num * sizeof(Ecore_X_Window)); - _ecore_window_grabs[_ecore_window_grabs_num - 1] = window; -} /* ecore_x_window_button_grab */ - -void -_ecore_x_sync_magic_send(int val, - Ecore_X_Window swindow) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* grab the default screen */ + screen = xcb_setup_roots_iterator(xcb_get_setup(dsp)).data; + return screen->black_pixel; +} + +EAPI unsigned long +ecore_x_display_white_pixel_get(Ecore_X_Display *dsp) { - xcb_client_message_event_t ev; + xcb_screen_t *screen; - ev.response_type = XCB_CLIENT_MESSAGE | 0x80; - ev.format = 32; - ev.window = _ecore_xcb_private_window; - ev.type = 27777; - ev.data.data32[0] = 0x7162534; - ev.data.data32[1] = 0x10000000 + val; - ev.data.data32[2] = swindow; - - xcb_send_event(_ecore_xcb_conn, 0, _ecore_xcb_private_window, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -} /* _ecore_x_sync_magic_send */ - -void -_ecore_x_window_grab_remove(Ecore_X_Window window) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* grab the default screen */ + screen = xcb_setup_roots_iterator(xcb_get_setup(dsp)).data; + return screen->white_pixel; +} + +EAPI void +ecore_x_pointer_last_xy_get(int *x, int *y) { - int i, shuffle = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (_ecore_window_grabs_num > 0) - { - for (i = 0; i < _ecore_window_grabs_num; i++) - { - if (shuffle) - _ecore_window_grabs[i - 1] = _ecore_window_grabs[i]; + if (x) *x = _ecore_xcb_event_last_root_x; + if (y) *y = _ecore_xcb_event_last_root_y; +} - if ((!shuffle) && (_ecore_window_grabs[i] == window)) - shuffle = 1; - } - if (shuffle) - { - _ecore_window_grabs_num--; - _ecore_window_grabs = realloc(_ecore_window_grabs, - _ecore_window_grabs_num * sizeof(Ecore_X_Window)); - } - } -} /* _ecore_x_window_grab_remove */ +EAPI void +ecore_x_focus_reset(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_POINTER_ROOT, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + XCB_CURRENT_TIME); +} -EAPI void -ecore_x_window_button_ungrab(Ecore_X_Window window, - int button, - int mod, - int any_mod) +EAPI void +ecore_x_events_allow_all(void) { - int i; - uint16_t m; - uint16_t locks[8]; - - m = _ecore_xcb_event_modifier(mod); - if (any_mod) - m = XCB_BUTTON_MASK_ANY; - - locks[0] = 0; - locks[1] = ECORE_X_LOCK_CAPS; - locks[2] = ECORE_X_LOCK_NUM; - locks[3] = ECORE_X_LOCK_SCROLL; - locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; - locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; - locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; - locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; - for (i = 0; i < 8; i++) - xcb_ungrab_button(_ecore_xcb_conn, button, window, m | locks[i]); - _ecore_x_sync_magic_send(1, window); -} /* ecore_x_window_button_ungrab */ - -int _ecore_key_grabs_num = 0; -Ecore_X_Window *_ecore_key_grabs = NULL; - -EAPI void -ecore_x_window_key_grab(Ecore_X_Window window, - const char *key, - int mod, - int any_mod) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xcb_allow_events(_ecore_xcb_conn, XCB_ALLOW_ASYNC_BOTH, XCB_CURRENT_TIME); +} + +/** + * Kill a specific client + * + * You can kill a specific client owning window @p win + * + * @param win Window of the client to be killed + */ +EAPI void +ecore_x_kill(Ecore_X_Window win) { - xcb_keycode_t keycode = 0; - uint16_t m; - uint16_t locks[8]; - int i; - - if (!strncmp(key, "Keycode-", 8)) - keycode = atoi(key + 8); - - /* FIXME: TODO... */ - -/* else */ -/* { */ -/* KeySym keysym; */ - -/* keysym = XStringToKeysym(key); */ -/* if (keysym == NoSymbol) return; */ -/* keycode = XKeysymToKeycode(_ecore_xcb_conn, XStringToKeysym(key)); */ -/* } */ - if (keycode == 0) - return; - - m = _ecore_xcb_event_modifier(mod); - if (any_mod) - m = XCB_BUTTON_MASK_ANY; - - locks[0] = 0; - locks[1] = ECORE_X_LOCK_CAPS; - locks[2] = ECORE_X_LOCK_NUM; - locks[3] = ECORE_X_LOCK_SCROLL; - locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; - locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; - locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; - locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; - for (i = 0; i < 8; i++) - xcb_grab_key(_ecore_xcb_conn, 1, window, m | locks[i], keycode, - XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); - _ecore_key_grabs_num++; - _ecore_key_grabs = realloc(_ecore_key_grabs, - _ecore_key_grabs_num * sizeof(Ecore_X_Window)); - _ecore_key_grabs[_ecore_key_grabs_num - 1] = window; -} /* ecore_x_window_key_grab */ - -void -_ecore_x_key_grab_remove(Ecore_X_Window window) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xcb_kill_client(_ecore_xcb_conn, win); +} + +/** + * Kill all clients with subwindows under a given window. + * + * You can kill all clients connected to the X server by using + * @ref ecore_x_window_root_list to get a list of root windows, and + * then passing each root window to this function. + * + * @param root The window whose children will be killed. + */ +EAPI void +ecore_x_killall(Ecore_X_Window root) { - int i, shuffle = 0; + int screens = 0, i = 0; - if (_ecore_key_grabs_num > 0) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_grab(); + + screens = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem; + + /* Traverse window tree starting from root, and drag each + * before the firing squad */ + for (i = 0; i < screens; ++i) { - for (i = 0; i < _ecore_key_grabs_num; i++) - { - if (shuffle) - _ecore_key_grabs[i - 1] = _ecore_key_grabs[i]; + xcb_query_tree_cookie_t cookie; + xcb_query_tree_reply_t *reply; - if ((!shuffle) && (_ecore_key_grabs[i] == window)) - shuffle = 1; - } - if (shuffle) + cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, root); + reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) { - _ecore_key_grabs_num--; - _ecore_key_grabs = realloc(_ecore_key_grabs, - _ecore_key_grabs_num * sizeof(Ecore_X_Window)); + xcb_window_t *wins = NULL; + int tree_c_len, j = 0; + + wins = xcb_query_tree_children(reply); + tree_c_len = xcb_query_tree_children_length(reply); + for (j = 0; j < tree_c_len; j++) + xcb_kill_client(_ecore_xcb_conn, wins[j]); + free(reply); } } -} /* _ecore_x_key_grab_remove */ -EAPI void -ecore_x_window_key_ungrab(Ecore_X_Window window, - const char *key, - int mod, - int any_mod) -{ - xcb_keycode_t keycode = 0; - uint16_t m; - uint16_t locks[8]; - int i; - - if (!strncmp(key, "Keycode-", 8)) - keycode = atoi(key + 8); - - /* FIXME: todo... */ - -/* else */ -/* { */ -/* KeySym keysym; */ - -/* keysym = XStringToKeysym(key); */ -/* if (keysym == NoSymbol) return; */ -/* keycode = XKeysymToKeycode(_ecore_xcb_conn, XStringToKeysym(key)); */ -/* } */ - if (keycode == 0) - return; - - m = _ecore_xcb_event_modifier(mod); - if (any_mod) - m = XCB_BUTTON_MASK_ANY; - - locks[0] = 0; - locks[1] = ECORE_X_LOCK_CAPS; - locks[2] = ECORE_X_LOCK_NUM; - locks[3] = ECORE_X_LOCK_SCROLL; - locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; - locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; - locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; - locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; - for (i = 0; i < 8; i++) - xcb_ungrab_key(_ecore_xcb_conn, keycode, window, m | locks[i]); - _ecore_x_sync_magic_send(2, window); -} /* ecore_x_window_key_ungrab */ + ecore_x_ungrab(); + ecore_x_sync(); // needed +} /** - * Send client message with given type and format 32. + * Return the screen DPI * - * @param window The window the message is sent to. - * @param type The client message type. - * @param mask The client message mask. - * @param d0 The client message data item 1 - * @param d1 The client message data item 2 - * @param d2 The client message data item 3 - * @param d3 The client message data item 4 - * @param d4 The client message data item 5 + * This is a simplistic call to get DPI. It does not account for differing + * DPI in the x amd y axes nor does it accoutn for multihead or xinerama and + * xrander where different parts of the screen may have differen DPI etc. * - * @return !0 on success. + * @return the general screen DPI (dots/pixels per inch). */ -EAPI Eina_Bool -ecore_x_client_message32_send(Ecore_X_Window window, - Ecore_X_Atom type, - Ecore_X_Event_Mask mask, - long d0, - long d1, - long d2, - long d3, - long d4) +EAPI int +ecore_x_dpi_get(void) { - xcb_client_message_event_t ev; - - ev.response_type = XCB_CLIENT_MESSAGE | 0x80; - ev.format = 32; - ev.window = window; - ev.type = type; - ev.data.data32[0] = d0; - ev.data.data32[1] = d1; - ev.data.data32[2] = d2; - ev.data.data32[3] = d3; - ev.data.data32[4] = d4; + uint16_t mw = 0, w = 0; - xcb_send_event(_ecore_xcb_conn, 0, window, mask, (const char *)&ev); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return 1; -} /* ecore_x_client_message32_send */ + mw = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_millimeters; + if (mw <= 0) return 75; + w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; + return ((((w * 254) / mw) + 5) / 10); +} /** - * Send client message with given type and format 8. + * @defgroup Ecore_X_Display_Attr_Group X Display Attributes * - * @param window The window the message is sent to. - * @param type The client message type. - * @param data Data to be sent. - * @param len Number of data bytes, max 20. - * - * @return !0 on success. + * Functions that set and retrieve X display attributes. */ -EAPI Eina_Bool -ecore_x_client_message8_send(Ecore_X_Window window, - Ecore_X_Atom type, - const void *data, - int len) + +/** + * Retrieves the Ecore_X_Display handle used for the current X connection. + * @return The current X display. + * @ingroup Ecore_X_Display_Attr_Group + */ +EAPI Ecore_X_Display * +ecore_x_display_get(void) { - xcb_client_message_event_t ev; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - ev.response_type = XCB_CLIENT_MESSAGE | 0x80; - ev.format = 8; - ev.window = window; - ev.type = type; - if (len > 20) - len = 20; + return (Ecore_X_Display *)_ecore_xcb_conn; +} - memcpy(ev.data.data8, data, len); - memset(ev.data.data8 + len, 0, 20 - len); +/** + * Retrieves the X display file descriptor. + * @return The current X display file descriptor. + * @ingroup Ecore_X_Display_Attr_Group + */ +EAPI int +ecore_x_fd_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return xcb_get_file_descriptor(_ecore_xcb_conn); +} - xcb_send_event(_ecore_xcb_conn, 0, window, XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +EAPI void +ecore_x_passive_grab_replay_func_set(Eina_Bool (*func) (void *data, int type, void *event), void *data) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return 1; -} /* ecore_x_client_message8_send */ + _ecore_xcb_window_grab_replay_func = func; + _ecore_xcb_window_grab_replay_data = data; +} -/* FIXME: round trip */ -EAPI Eina_Bool -ecore_x_mouse_move_send(Ecore_X_Window window, - int x, - int y) +/** + * Retrieves the size of an Ecore_X_Screen. + * @param screen the handle to the screen to query. + * @param w where to return the width. May be NULL. Returns 0 on errors. + * @param h where to return the height. May be NULL. Returns 0 on errors. + * @ingroup Ecore_X_Display_Attr_Group + * @see ecore_x_default_screen_get() + * + * @since 1.1 + */ +EAPI void +ecore_x_screen_size_get(const Ecore_X_Screen *screen, int *w, int *h) { - xcb_motion_notify_event_t ev; - xcb_get_geometry_cookie_t cookie_geom; - xcb_translate_coordinates_cookie_t cookie_trans; - xcb_get_geometry_reply_t *reply_geom; - xcb_translate_coordinates_reply_t *reply_trans; - - cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window); - reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL); - if (!reply_geom) - return 0; - - cookie_trans = xcb_translate_coordinates_unchecked(_ecore_xcb_conn, window, reply_geom->root, x, y); - reply_trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie_trans, NULL); - if (!reply_trans) - { - free(reply_geom); - return 0; - } + xcb_screen_t *s; - ev.response_type = XCB_MOTION_NOTIFY; - ev.detail = 0; - ev.time = _ecore_xcb_event_last_time; - ev.root = reply_geom->root; - ev.event = window; - ev.child = window; - ev.root_x = reply_trans->dst_x; - ev.root_y = reply_trans->dst_y; - ev.event_x = x; - ev.event_y = y; - ev.state = 0; - ev.same_screen = 1; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (w) *w = 0; + if (h) *h = 0; + if (!(s = (xcb_screen_t *)screen)) return; + if (w) *w = s->width_in_pixels; + if (h) *h = s->height_in_pixels; +} - xcb_send_event(_ecore_xcb_conn, 1, window, XCB_EVENT_MASK_POINTER_MOTION, (const char *)&ev); +EAPI int +ecore_x_screen_count_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - free(reply_geom); - free(reply_trans); + return xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); +} - return 1; -} /* ecore_x_mouse_move_send */ +EAPI unsigned int +ecore_x_visual_id_get(Ecore_X_Visual visual) +{ + return ((xcb_visualtype_t *)visual)->visual_id; +} -/* FIXME: round trip */ -EAPI Eina_Bool -ecore_x_mouse_down_send(Ecore_X_Window window, - int x, - int y, - int button) +/** + * Sets the timeout for a double and triple clicks to be flagged. + * + * This sets the time between clicks before the double_click flag is + * set in a button down event. If 3 clicks occur within double this + * time, the triple_click flag is also set. + * + * @param t The time in seconds + * @ingroup Ecore_X_Display_Attr_Group + */ +EAPI void +ecore_x_double_click_time_set(double t) { - xcb_button_press_event_t ev; - xcb_get_geometry_cookie_t cookie_geom; - xcb_translate_coordinates_cookie_t cookie_trans; - xcb_get_geometry_reply_t *reply_geom; - xcb_translate_coordinates_reply_t *reply_trans; - - cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window); - reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL); - if (!reply_geom) - return 0; - - cookie_trans = xcb_translate_coordinates_unchecked(_ecore_xcb_conn, window, reply_geom->root, x, y); - reply_trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie_trans, NULL); - if (!reply_trans) - { - free(reply_geom); - return 0; - } + if (t < 0.0) t = 0.0; + _ecore_xcb_double_click_time = t; +} - ev.response_type = XCB_BUTTON_PRESS; - ev.detail = button; - ev.time = _ecore_xcb_event_last_time; - ev.root = reply_geom->root; - ev.event = window; - ev.child = window; - ev.root_x = reply_trans->dst_x; - ev.root_y = reply_trans->dst_y; - ev.event_x = x; - ev.event_y = y; - ev.state = 1 << button; - ev.same_screen = 1; +/** + * Retrieves the double and triple click flag timeout. + * + * See @ref ecore_x_double_click_time_set for more information. + * + * @return The timeout for double clicks in seconds. + * @ingroup Ecore_X_Display_Attr_Group + */ +EAPI double +ecore_x_double_click_time_get(void) +{ + return _ecore_xcb_double_click_time; +} + +/* local function prototypes */ +static int +_ecore_xcb_shutdown(Eina_Bool close_display) +{ + if (--_ecore_xcb_init_count != 0) return _ecore_xcb_init_count; + if (!_ecore_xcb_conn) return _ecore_xcb_init_count; - xcb_send_event(_ecore_xcb_conn, 1, window, XCB_EVENT_MASK_BUTTON_PRESS, (const char *)&ev); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - free(reply_geom); - free(reply_trans); + /* shutdown keymap */ + _ecore_xcb_keymap_shutdown(); - return 1; -} /* ecore_x_mouse_down_send */ + /* shutdown events */ + _ecore_xcb_events_shutdown(); -/* FIXME: round trip */ -EAPI Eina_Bool -ecore_x_mouse_up_send(Ecore_X_Window window, - int x, - int y, - int button) -{ - xcb_button_release_event_t ev; - xcb_get_geometry_cookie_t cookie_geom; - xcb_translate_coordinates_cookie_t cookie_trans; - xcb_get_geometry_reply_t *reply_geom; - xcb_translate_coordinates_reply_t *reply_trans; - - cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window); - reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL); - if (!reply_geom) - return 0; - - cookie_trans = xcb_translate_coordinates_unchecked(_ecore_xcb_conn, window, reply_geom->root, x, y); - reply_trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie_trans, NULL); - if (!reply_trans) - { - free(reply_geom); - return 0; - } + /* shutdown selection */ + _ecore_xcb_selection_shutdown(); - ev.response_type = XCB_BUTTON_RELEASE; - ev.detail = button; - ev.time = _ecore_xcb_event_last_time; - ev.root = reply_geom->root; - ev.event = window; - ev.child = window; - ev.root_x = reply_trans->dst_x; - ev.root_y = reply_trans->dst_y; - ev.event_x = x; - ev.event_y = y; - ev.state = 0; - ev.same_screen = 1; + /* shutdown netwm */ + ecore_x_netwm_shutdown(); - xcb_send_event(_ecore_xcb_conn, 1, window, XCB_EVENT_MASK_BUTTON_RELEASE, (const char *)&ev); + /* shutdown dnd */ + _ecore_xcb_dnd_shutdown(); - free(reply_geom); - free(reply_trans); +#ifdef ECORE_XCB_XINPUT + _ecore_xcb_input_shutdown(); +#endif - return 1; -} /* ecore_x_mouse_up_send */ + if (_ecore_xcb_fd_handler) + ecore_main_fd_handler_del(_ecore_xcb_fd_handler); -EAPI void -ecore_x_focus_reset(void) -{ - xcb_set_input_focus(_ecore_xcb_conn, - (uint8_t)XCB_INPUT_FOCUS_POINTER_ROOT, - XCB_INPUT_FOCUS_POINTER_ROOT, - XCB_CURRENT_TIME); -} /* ecore_x_focus_reset */ + /* disconnect from display server */ + if (close_display) + xcb_disconnect(_ecore_xcb_conn); + else + close(xcb_get_file_descriptor(_ecore_xcb_conn)); -EAPI void -ecore_x_events_allow_all(void) -{ - xcb_allow_events(_ecore_xcb_conn, XCB_ALLOW_ASYNC_BOTH, XCB_CURRENT_TIME); -} /* ecore_x_events_allow_all */ + /* shutdown ecore_event */ + ecore_event_shutdown(); -EAPI void -ecore_x_pointer_last_xy_get(int *x, - int *y) -{ - if (x) - *x = _ecore_xcb_event_last_root_x; + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; - if (y) - *y = _ecore_xcb_event_last_root_y; -} /* ecore_x_pointer_last_xy_get */ + /* shutdown ecore */ + ecore_shutdown(); -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ + /* shutdown eina */ +// eina_shutdown(); -static int -_ecore_xcb_event_modifier(unsigned int state) + return _ecore_xcb_init_count; +} + +static Eina_Bool +_ecore_xcb_fd_handle(void *data, Ecore_Fd_Handler *hdlr __UNUSED__) { - int xmodifiers = 0; + xcb_connection_t *conn; + xcb_generic_event_t *ev = NULL; - if (state & ECORE_EVENT_MODIFIER_SHIFT) - xmodifiers |= ECORE_X_MODIFIER_SHIFT; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (state & ECORE_EVENT_MODIFIER_CTRL) - xmodifiers |= ECORE_X_MODIFIER_CTRL; + conn = (xcb_connection_t *)data; - if (state & ECORE_EVENT_MODIFIER_ALT) - xmodifiers |= ECORE_X_MODIFIER_ALT; + if (_ecore_xcb_event_buffered) + { + _ecore_xcb_events_handle(_ecore_xcb_event_buffered); + _ecore_xcb_event_buffered = NULL; + } - if (state & ECORE_EVENT_MODIFIER_WIN) - xmodifiers |= ECORE_X_MODIFIER_WIN; + while ((ev = xcb_poll_for_event(conn))) + { + // Event type 0 is an error if we don't use the xcb_*_checked funcs + if (xcb_connection_has_error(_ecore_xcb_conn)) + { + xcb_generic_error_t *err; - if (state & ECORE_EVENT_LOCK_SCROLL) - xmodifiers |= ECORE_X_LOCK_SCROLL; + err = (xcb_generic_error_t *)ev; + _ecore_xcb_io_error_handle(err); + } + else + _ecore_xcb_events_handle(ev); - if (state & ECORE_EVENT_LOCK_NUM) - xmodifiers |= ECORE_X_LOCK_NUM; + free(ev); + } - if (state & ECORE_EVENT_LOCK_CAPS) - xmodifiers |= ECORE_X_LOCK_CAPS; + return ECORE_CALLBACK_RENEW; +} - return xmodifiers; -} /* _ecore_xcb_event_modifier */ +static Eina_Bool +_ecore_xcb_fd_handle_buff(void *data, Ecore_Fd_Handler *hdlr __UNUSED__) +{ + xcb_connection_t *conn; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + conn = (xcb_connection_t *)data; + _ecore_xcb_event_buffered = xcb_poll_for_event(conn); + if (_ecore_xcb_event_buffered) return ECORE_CALLBACK_RENEW; + + return ECORE_CALLBACK_CANCEL; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_atoms.c b/src/lib/ecore_x/xcb/ecore_xcb_atoms.c new file mode 100644 index 0000000..882c17d --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_atoms.c @@ -0,0 +1,397 @@ +#include "ecore_xcb_private.h" +#include "ecore_x_atoms_decl.h" + +/* NB: Increment if you add new atoms */ +#define ECORE_X_ATOMS_COUNT 199 + +typedef struct _Xcb_Atom Xcb_Atom; +struct _Xcb_Atom +{ + const char *name; + Ecore_X_Atom *atom; +}; + +/* local function prototypes */ + +/* local variables */ +static xcb_intern_atom_cookie_t cookies[ECORE_X_ATOMS_COUNT]; +static Xcb_Atom atoms[] = +{ + { "ATOM", &ECORE_X_ATOM_ATOM }, + { "CARDINAL", &ECORE_X_ATOM_CARDINAL }, + { "COMPOUND_TEXT", &ECORE_X_ATOM_COMPOUND_TEXT }, + { "FILE_NAME", &ECORE_X_ATOM_FILE_NAME }, + { "STRING", &ECORE_X_ATOM_STRING }, + { "TEXT", &ECORE_X_ATOM_TEXT }, + { "UTF8_STRING", &ECORE_X_ATOM_UTF8_STRING }, + { "WINDOW", &ECORE_X_ATOM_WINDOW }, + { "PIXMAP", &ECORE_X_ATOM_PIXMAP }, + { "VISUALID", &ECORE_X_ATOM_VISUALID }, + + { "JXSelectionWindowProperty", &ECORE_X_ATOM_SELECTION_PROP_XDND }, + { "XdndSelection", &ECORE_X_ATOM_SELECTION_XDND }, + { "XdndAware", &ECORE_X_ATOM_XDND_AWARE }, + { "XdndEnter", &ECORE_X_ATOM_XDND_ENTER }, + { "XdndTypeList", &ECORE_X_ATOM_XDND_TYPE_LIST }, + { "XdndPosition", &ECORE_X_ATOM_XDND_POSITION }, + { "XdndActionCopy", &ECORE_X_ATOM_XDND_ACTION_COPY }, + { "XdndActionMove", &ECORE_X_ATOM_XDND_ACTION_MOVE }, + { "XdndActionPrivate", &ECORE_X_ATOM_XDND_ACTION_PRIVATE }, + { "XdndActionAsk", &ECORE_X_ATOM_XDND_ACTION_ASK }, + { "XdndActionList", &ECORE_X_ATOM_XDND_ACTION_LIST }, + { "XdndActionLink", &ECORE_X_ATOM_XDND_ACTION_LINK }, + { "XdndActionDescription", &ECORE_X_ATOM_XDND_ACTION_DESCRIPTION }, + { "XdndProxy", &ECORE_X_ATOM_XDND_PROXY }, + { "XdndStatus", &ECORE_X_ATOM_XDND_STATUS }, + { "XdndLeave", &ECORE_X_ATOM_XDND_LEAVE }, + { "XdndDrop", &ECORE_X_ATOM_XDND_DROP }, + { "XdndFinished", &ECORE_X_ATOM_XDND_FINISHED }, + + { "XdndActionCopy", &ECORE_X_DND_ACTION_COPY }, + { "XdndActionMove", &ECORE_X_DND_ACTION_MOVE }, + { "XdndActionLink", &ECORE_X_DND_ACTION_LINK }, + { "XdndActionAsk", &ECORE_X_DND_ACTION_ASK }, + { "XdndActionPrivate", &ECORE_X_DND_ACTION_PRIVATE }, + + { "_E_FRAME_SIZE", &ECORE_X_ATOM_E_FRAME_SIZE }, + + { "_WIN_LAYER", &ECORE_X_ATOM_WIN_LAYER }, + + { "WM_NAME", &ECORE_X_ATOM_WM_NAME }, + { "WM_ICON_NAME", &ECORE_X_ATOM_WM_ICON_NAME }, + { "WM_NORMAL_HINTS", &ECORE_X_ATOM_WM_NORMAL_HINTS }, + { "WM_SIZE_HINTS", &ECORE_X_ATOM_WM_SIZE_HINTS }, + { "WM_HINTS", &ECORE_X_ATOM_WM_HINTS }, + { "WM_CLASS", &ECORE_X_ATOM_WM_CLASS }, + { "WM_TRANSIENT_FOR", &ECORE_X_ATOM_WM_TRANSIENT_FOR }, + { "WM_PROTOCOLS", &ECORE_X_ATOM_WM_PROTOCOLS }, + { "WM_COLORMAP_WINDOWS", &ECORE_X_ATOM_WM_COLORMAP_WINDOWS }, + { "WM_COMMAND", &ECORE_X_ATOM_WM_COMMAND }, + { "WM_CLIENT_MACHINE", &ECORE_X_ATOM_WM_CLIENT_MACHINE }, + + { "WM_STATE", &ECORE_X_ATOM_WM_STATE }, + { "WM_ICON_SIZE", &ECORE_X_ATOM_WM_ICON_SIZE }, + + { "WM_CHANGE_STATE", &ECORE_X_ATOM_WM_CHANGE_STATE }, + + { "WM_TAKE_FOCUS", &ECORE_X_ATOM_WM_TAKE_FOCUS }, + { "WM_SAVE_YOURSELF", &ECORE_X_ATOM_WM_SAVE_YOURSELF }, + { "WM_DELETE_WINDOW", &ECORE_X_ATOM_WM_DELETE_WINDOW }, + + { "WM_COLORMAP_NOTIFY", &ECORE_X_ATOM_WM_COLORMAP_NOTIFY }, + + { "SM_CLIENT_ID", &ECORE_X_ATOM_SM_CLIENT_ID }, + { "WM_CLIENT_LEADER", &ECORE_X_ATOM_WM_CLIENT_LEADER }, + { "WM_WINDOW_ROLE", &ECORE_X_ATOM_WM_WINDOW_ROLE }, + + { "_MOTIF_WM_HINTS", &ECORE_X_ATOM_MOTIF_WM_HINTS }, + + { "_NET_SUPPORTED", &ECORE_X_ATOM_NET_SUPPORTED }, + { "_NET_CLIENT_LIST", &ECORE_X_ATOM_NET_CLIENT_LIST }, + { "_NET_CLIENT_LIST_STACKING", &ECORE_X_ATOM_NET_CLIENT_LIST_STACKING }, + { "_NET_NUMBER_OF_DESKTOPS", &ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS }, + { "_NET_DESKTOP_GEOMETRY", &ECORE_X_ATOM_NET_DESKTOP_GEOMETRY }, + { "_NET_DESKTOP_VIEWPORT", &ECORE_X_ATOM_NET_DESKTOP_VIEWPORT }, + { "_NET_CURRENT_DESKTOP", &ECORE_X_ATOM_NET_CURRENT_DESKTOP }, + { "_NET_DESKTOP_NAMES", &ECORE_X_ATOM_NET_DESKTOP_NAMES }, + { "_NET_ACTIVE_WINDOW", &ECORE_X_ATOM_NET_ACTIVE_WINDOW }, + { "_NET_WORKAREA", &ECORE_X_ATOM_NET_WORKAREA }, + { "_NET_SUPPORTING_WM_CHECK", &ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK }, + { "_NET_VIRTUAL_ROOTS", &ECORE_X_ATOM_NET_VIRTUAL_ROOTS }, + { "_NET_DESKTOP_LAYOUT", &ECORE_X_ATOM_NET_DESKTOP_LAYOUT }, + { "_NET_SHOWING_DESKTOP", &ECORE_X_ATOM_NET_SHOWING_DESKTOP }, + + { "_NET_CLOSE_WINDOW", &ECORE_X_ATOM_NET_CLOSE_WINDOW }, + { "_NET_MOVERESIZE_WINDOW", &ECORE_X_ATOM_NET_MOVERESIZE_WINDOW }, + { "_NET_WM_MOVERESIZE", &ECORE_X_ATOM_NET_WM_MOVERESIZE }, + { "_NET_RESTACK_WINDOW", &ECORE_X_ATOM_NET_RESTACK_WINDOW }, + + { "_NET_REQUEST_FRAME_EXTENTS", &ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS }, + + { "_NET_WM_NAME", &ECORE_X_ATOM_NET_WM_NAME }, + { "_NET_WM_VISIBLE_NAME", &ECORE_X_ATOM_NET_WM_VISIBLE_NAME }, + { "_NET_WM_ICON_NAME", &ECORE_X_ATOM_NET_WM_ICON_NAME }, + { "_NET_WM_VISIBLE_ICON_NAME", &ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME }, + { "_NET_WM_DESKTOP", &ECORE_X_ATOM_NET_WM_DESKTOP }, + + { "_NET_WM_WINDOW_TYPE", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE }, + { "_NET_WM_WINDOW_TYPE_DESKTOP", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP }, + { "_NET_WM_WINDOW_TYPE_DOCK", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK }, + { "_NET_WM_WINDOW_TYPE_TOOLBAR", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR }, + { "_NET_WM_WINDOW_TYPE_MENU", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU }, + { "_NET_WM_WINDOW_TYPE_UTILITY", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY }, + { "_NET_WM_WINDOW_TYPE_SPLASH", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH }, + { "_NET_WM_WINDOW_TYPE_DIALOG", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG }, + { "_NET_WM_WINDOW_TYPE_NORMAL", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL }, + { "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", + &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU }, + { "_NET_WM_WINDOW_TYPE_POPUP_MENU", + &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU }, + { "_NET_WM_WINDOW_TYPE_TOOLTIP", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP }, + { "_NET_WM_WINDOW_TYPE_NOTIFICATION", + &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION }, + { "_NET_WM_WINDOW_TYPE_COMBO", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO }, + { "_NET_WM_WINDOW_TYPE_DND", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND }, + + { "_NET_WM_STATE", &ECORE_X_ATOM_NET_WM_STATE }, + { "_NET_WM_STATE_MODAL", &ECORE_X_ATOM_NET_WM_STATE_MODAL }, + { "_NET_WM_STATE_STICKY", &ECORE_X_ATOM_NET_WM_STATE_STICKY }, + { "_NET_WM_STATE_MAXIMIZED_VERT", + &ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT }, + { "_NET_WM_STATE_MAXIMIZED_HORZ", + &ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ }, + { "_NET_WM_STATE_SHADED", &ECORE_X_ATOM_NET_WM_STATE_SHADED }, + { "_NET_WM_STATE_SKIP_TASKBAR", &ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR }, + { "_NET_WM_STATE_SKIP_PAGER", &ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER }, + { "_NET_WM_STATE_HIDDEN", &ECORE_X_ATOM_NET_WM_STATE_HIDDEN }, + { "_NET_WM_STATE_FULLSCREEN", &ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN }, + { "_NET_WM_STATE_ABOVE", &ECORE_X_ATOM_NET_WM_STATE_ABOVE }, + { "_NET_WM_STATE_BELOW", &ECORE_X_ATOM_NET_WM_STATE_BELOW }, + { "_NET_WM_STATE_DEMANDS_ATTENTION", + &ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION }, + + { "_NET_WM_ALLOWED_ACTIONS", &ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS }, + { "_NET_WM_ACTION_MOVE", &ECORE_X_ATOM_NET_WM_ACTION_MOVE }, + { "_NET_WM_ACTION_RESIZE", &ECORE_X_ATOM_NET_WM_ACTION_RESIZE }, + { "_NET_WM_ACTION_MINIMIZE", &ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE }, + { "_NET_WM_ACTION_SHADE", &ECORE_X_ATOM_NET_WM_ACTION_SHADE }, + { "_NET_WM_ACTION_STICK", &ECORE_X_ATOM_NET_WM_ACTION_STICK }, + { "_NET_WM_ACTION_MAXIMIZE_HORZ", + &ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ }, + { "_NET_WM_ACTION_MAXIMIZE_VERT", + &ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT }, + { "_NET_WM_ACTION_FULLSCREEN", &ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN }, + { "_NET_WM_ACTION_CHANGE_DESKTOP", + &ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP }, + { "_NET_WM_ACTION_CLOSE", &ECORE_X_ATOM_NET_WM_ACTION_CLOSE }, + { "_NET_WM_ACTION_ABOVE", &ECORE_X_ATOM_NET_WM_ACTION_ABOVE }, + { "_NET_WM_ACTION_BELOW", &ECORE_X_ATOM_NET_WM_ACTION_BELOW }, + + { "_NET_WM_STRUT", &ECORE_X_ATOM_NET_WM_STRUT }, + { "_NET_WM_STRUT_PARTIAL", &ECORE_X_ATOM_NET_WM_STRUT_PARTIAL }, + { "_NET_WM_ICON_GEOMETRY", &ECORE_X_ATOM_NET_WM_ICON_GEOMETRY }, + { "_NET_WM_ICON", &ECORE_X_ATOM_NET_WM_ICON }, + { "_NET_WM_PID", &ECORE_X_ATOM_NET_WM_PID }, + { "_NET_WM_HANDLED_ICONS", &ECORE_X_ATOM_NET_WM_HANDLED_ICONS }, + { "_NET_WM_USER_TIME", &ECORE_X_ATOM_NET_WM_USER_TIME }, + { "_NET_STARTUP_ID", &ECORE_X_ATOM_NET_STARTUP_ID }, + { "_NET_FRAME_EXTENTS", &ECORE_X_ATOM_NET_FRAME_EXTENTS }, + + { "_NET_WM_PING", &ECORE_X_ATOM_NET_WM_PING }, + { "_NET_WM_SYNC_REQUEST", &ECORE_X_ATOM_NET_WM_SYNC_REQUEST }, + { "_NET_WM_SYNC_REQUEST_COUNTER", + &ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER }, + + { "_NET_WM_WINDOW_OPACITY", &ECORE_X_ATOM_NET_WM_WINDOW_OPACITY }, + { "_NET_WM_WINDOW_SHADOW", &ECORE_X_ATOM_NET_WM_WINDOW_SHADOW }, + { "_NET_WM_WINDOW_SHADE", &ECORE_X_ATOM_NET_WM_WINDOW_SHADE }, + + { "TARGETS", &ECORE_X_ATOM_SELECTION_TARGETS }, + { "CLIPBOARD", &ECORE_X_ATOM_SELECTION_CLIPBOARD }, + { "PRIMARY", &ECORE_X_ATOM_SELECTION_PRIMARY }, + { "SECONDARY", &ECORE_X_ATOM_SELECTION_SECONDARY }, + { "_ECORE_SELECTION_PRIMARY", &ECORE_X_ATOM_SELECTION_PROP_PRIMARY }, + { "_ECORE_SELECTION_SECONDARY", &ECORE_X_ATOM_SELECTION_PROP_SECONDARY }, + { "_ECORE_SELECTION_CLIPBOARD", &ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD }, + + { "_E_VIRTUAL_KEYBOARD", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD }, + { "_E_VIRTUAL_KEYBOARD_STATE", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE }, + { "_E_VIRTUAL_KEYBOARD_ON", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON }, + { "_E_VIRTUAL_KEYBOARD_OFF", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF }, + { "_E_VIRTUAL_KEYBOARD_ALPHA", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA }, + { "_E_VIRTUAL_KEYBOARD_NUMERIC", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC }, + { "_E_VIRTUAL_KEYBOARD_PIN", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN }, + { "_E_VIRTUAL_KEYBOARD_PHONE_NUMBER", + &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER }, + { "_E_VIRTUAL_KEYBOARD_HEX", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX }, + { "_E_VIRTUAL_KEYBOARD_TERMINAL", + &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL }, + { "_E_VIRTUAL_KEYBOARD_PASSWORD", + &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD }, + { "_E_VIRTUAL_KEYBOARD_IP", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP }, + { "_E_VIRTUAL_KEYBOARD_HOST", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST }, + { "_E_VIRTUAL_KEYBOARD_FILE", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE }, + { "_E_VIRTUAL_KEYBOARD_URL", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL }, + { "_E_VIRTUAL_KEYBOARD_KEYPAD", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD }, + { "_E_VIRTUAL_KEYBOARD_J2ME", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME }, + + { "_E_ILLUME_ZONE", &ECORE_X_ATOM_E_ILLUME_ZONE }, + { "_E_ILLUME_ZONE_LIST", &ECORE_X_ATOM_E_ILLUME_ZONE_LIST }, + { "_E_ILLUME_CONFORMANT", &ECORE_X_ATOM_E_ILLUME_CONFORMANT }, + { "_E_ILLUME_MODE", &ECORE_X_ATOM_E_ILLUME_MODE }, + { "_E_ILLUME_MODE_SINGLE", &ECORE_X_ATOM_E_ILLUME_MODE_SINGLE }, + { "_E_ILLUME_MODE_DUAL_TOP", &ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP }, + { "_E_ILLUME_MODE_DUAL_LEFT", &ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT }, + { "_E_ILLUME_FOCUS_BACK", &ECORE_X_ATOM_E_ILLUME_FOCUS_BACK }, + { "_E_ILLUME_FOCUS_FORWARD", &ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD }, + { "_E_ILLUME_FOCUS_HOME", &ECORE_X_ATOM_E_ILLUME_FOCUS_HOME }, + { "_E_ILLUME_CLOSE", &ECORE_X_ATOM_E_ILLUME_CLOSE }, + { "_E_ILLUME_HOME_NEW", &ECORE_X_ATOM_E_ILLUME_HOME_NEW }, + { "_E_ILLUME_HOME_DEL", &ECORE_X_ATOM_E_ILLUME_HOME_DEL }, + { "_E_ILLUME_DRAG", &ECORE_X_ATOM_E_ILLUME_DRAG }, + { "_E_ILLUME_DRAG_LOCKED", &ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED }, + { "_E_ILLUME_DRAG_START", &ECORE_X_ATOM_E_ILLUME_DRAG_START }, + { "_E_ILLUME_DRAG_END", &ECORE_X_ATOM_E_ILLUME_DRAG_END }, + { "_E_ILLUME_INDICATOR_GEOMETRY", + &ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY }, + { "_E_ILLUME_SOFTKEY_GEOMETRY", &ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY }, + { "_E_ILLUME_KEYBOARD_GEOMETRY", &ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY }, + { "_E_ILLUME_QUICKPANEL", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL }, + { "_E_ILLUME_QUICKPANEL_STATE", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE }, + { "_E_ILLUME_QUICKPANEL_STATE_TOGGLE", + &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE_TOGGLE }, + { "_E_ILLUME_QUICKPANEL_ON", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON }, + { "_E_ILLUME_QUICKPANEL_OFF", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF }, + { "_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR", + &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR }, + { "_E_ILLUME_QUICKPANEL_PRIORITY_MINOR", + &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR }, + { "_E_ILLUME_QUICKPANEL_ZONE", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE }, + { "_E_ILLUME_QUICKPANEL_POSITION_UPDATE", + &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_POSITION_UPDATE }, + + { "_E_COMP_SYNC_COUNTER", &ECORE_X_ATOM_E_COMP_SYNC_COUNTER }, + { "_E_COMP_SYNC_DRAW_DONE", &ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE }, + { "_E_COMP_SYNC_SUPPORTED", &ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED }, + { "_E_COMP_SYNC_BEGIN", &ECORE_X_ATOM_E_COMP_SYNC_BEGIN }, + { "_E_COMP_SYNC_END", &ECORE_X_ATOM_E_COMP_SYNC_END }, + { "_E_COMP_SYNC_CANCEL", &ECORE_X_ATOM_E_COMP_SYNC_CANCEL }, + + { "_E_COMP_FLUSH", &ECORE_X_ATOM_E_COMP_FLUSH }, + { "_E_COMP_DUMP", &ECORE_X_ATOM_E_COMP_DUMP }, + { "_E_COMP_PIXMAP", &ECORE_X_ATOM_E_COMP_PIXMAP } +}; + +void +_ecore_xcb_atoms_init(void) +{ + int i = 0, num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + num = (sizeof(atoms) / sizeof(Xcb_Atom)); + for (i = 0; i < num; i++) + { + cookies[i] = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, + strlen(atoms[i].name), atoms[i].name); + } +} + +void +_ecore_xcb_atoms_finalize(void) +{ + int i = 0, num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + num = (sizeof(atoms) / sizeof(Xcb_Atom)); + for (i = 0; i < num; i++) + { + xcb_intern_atom_reply_t *reply = NULL; + + if (!(reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], 0))) + continue; + *(atoms[i].atom) = reply->atom; + free(reply); + } +} + +/** + * @defgroup Ecore_X_Atom_Group XCB Atom Functions + * + * Functions that operate on atoms + */ + +/** + * Retrieves the atom value associated to a name. + * + * @param name Unused. + * @return Associated atom value. + * + * Retrieves the atom value associated to a name. The reply is the + * returned value of the function ecore_xcb_intern_atom_reply(). If + * @p reply is @c NULL, the NULL atom is returned. Otherwise, the atom + * associated to the name is returned. + * + * To use this function, you must call before, and in order, + * ecore_x_atom_get_prefetch(), which sends the InternAtom request, + * then ecore_x_atom_get_fetch(), which gets the reply. + * + * @ingroup Ecore_X_Atom_Group + */ +EAPI Ecore_X_Atom +ecore_x_atom_get(const char *name) +{ + xcb_intern_atom_cookie_t cookie; + xcb_intern_atom_reply_t *reply; + Ecore_X_Atom a; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(name), name); + reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return XCB_ATOM_NONE; + a = reply->atom; + free(reply); + return a; +} + +/** + * Retrieves the name of the given atom. + * + * @param atom + * @return The name of the atom. + * + * @ingroup Ecore_X_Atom_Group + */ +EAPI char * +ecore_x_atom_name_get(Ecore_X_Atom atom) +{ + xcb_get_atom_name_cookie_t cookie; + xcb_get_atom_name_reply_t *reply; + char *name; + int len = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, atom); + reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + len = xcb_get_atom_name_name_length(reply); + name = (char *)malloc(sizeof(char) * (len + 1)); + if (!name) + { + free(reply); + return NULL; + } + memcpy(name, xcb_get_atom_name_name(reply), len); + name[len] = '\0'; + + return name; +} + +EAPI void +ecore_x_atoms_get(const char **names, int num, Ecore_X_Atom *atoms) +{ + xcb_intern_atom_cookie_t cookies[num]; + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + for (i = 0; i < num; i++) + { + cookies[i] = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, + strlen(names[i]), names[i]); + } + for (i = 0; i < num; i++) + { + xcb_intern_atom_reply_t *reply = NULL; + + if (!(reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], 0))) + continue; + atoms[i] = reply->atom; + free(reply); + } +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_composite.c b/src/lib/ecore_x/xcb/ecore_xcb_composite.c index bf7b9aa..2d36a8b 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_composite.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_composite.c @@ -1,67 +1,241 @@ #include "ecore_xcb_private.h" +#ifdef ECORE_XCB_COMPOSITE +# include +#endif + +/* local variables */ +static Eina_Bool _composite_avail = EINA_FALSE; + +void +_ecore_xcb_composite_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_COMPOSITE + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_composite_id); +#endif +} + +void +_ecore_xcb_composite_finalize(void) +{ +#ifdef ECORE_XCB_COMPOSITE + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_COMPOSITE + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_composite_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_composite_query_version_cookie_t cookie; + xcb_composite_query_version_reply_t *reply; + + cookie = + xcb_composite_query_version_unchecked(_ecore_xcb_conn, + XCB_COMPOSITE_MAJOR_VERSION, + XCB_COMPOSITE_MINOR_VERSION); + reply = + xcb_composite_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { +// if ((reply->major_version >= XCB_COMPOSITE_MAJOR_VERSION) && + if (reply->minor_version >= XCB_COMPOSITE_MINOR_VERSION) + { +# ifdef ECORE_XCB_RENDER + if (_ecore_xcb_render_avail_get()) + { +# ifdef ECORE_XCB_XFIXES + if (_ecore_xcb_xfixes_avail_get()) + _composite_avail = EINA_TRUE; +# endif + } +# endif + } + + free(reply); + } + } +#endif +} /** * @defgroup Ecore_X_Composite_Group X Composite Extension Functions - * - * Functions related to the X Composite extension. + * + * Functions related to the X Composite Extension */ +/** + * Return whether the Composite Extension is available + * + * @return EINA_TRUE is the Composite Extension is available, EINA_FALSE if not + * + * @ingroup Ecore_X_Composite_Group + */ +EAPI Eina_Bool +ecore_x_composite_query(void) +{ + return _composite_avail; +} + +EAPI void +ecore_x_composite_redirect_window(Ecore_X_Window win, Ecore_X_Composite_Update_Type type) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + #ifdef ECORE_XCB_COMPOSITE -static uint8_t _composite_available = 0; -static xcb_composite_query_version_cookie_t _ecore_xcb_composite_init_cookie; -#endif /* ECORE_XCB_COMPOSITE */ + uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; -/* To avoid round trips, the initialization is separated in 2 - functions: _ecore_xcb_composite_init and - _ecore_xcb_composite_init_finalize. The first one gets the cookies and - the second one gets the replies. */ + switch (type) + { + case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: + update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + break; + case ECORE_X_COMPOSITE_UPDATE_MANUAL: + update = XCB_COMPOSITE_REDIRECT_MANUAL; + break; + } + xcb_composite_redirect_window(_ecore_xcb_conn, win, update); +#endif +} -void -_ecore_x_composite_init(const xcb_query_extension_reply_t *reply) +EAPI void +ecore_x_composite_redirect_subwindows(Ecore_X_Window win, Ecore_X_Composite_Update_Type type) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + #ifdef ECORE_XCB_COMPOSITE - if (reply && reply->present) - _ecore_xcb_composite_init_cookie = xcb_composite_query_version_unchecked(_ecore_xcb_conn, XCB_COMPOSITE_MAJOR_VERSION, XCB_COMPOSITE_MINOR_VERSION); + uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; -#endif /* ECORE_XCB_COMPOSITE */ -} /* _ecore_x_composite_init */ + switch (type) + { + case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: + update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + break; + case ECORE_X_COMPOSITE_UPDATE_MANUAL: + update = XCB_COMPOSITE_REDIRECT_MANUAL; + break; + } + xcb_composite_redirect_subwindows(_ecore_xcb_conn, win, update); +#endif +} -void -_ecore_x_composite_init_finalize(void) +EAPI void +ecore_x_composite_unredirect_window(Ecore_X_Window win, Ecore_X_Composite_Update_Type type) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + #ifdef ECORE_XCB_COMPOSITE - xcb_composite_query_version_reply_t *reply; + uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - reply = xcb_composite_query_version_reply(_ecore_xcb_conn, - _ecore_xcb_composite_init_cookie, - NULL); - if (reply) + switch (type) { - if ((reply->major_version == XCB_COMPOSITE_MAJOR_VERSION) && - (reply->minor_version >= XCB_COMPOSITE_MINOR_VERSION)) - _composite_available = 1; + case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: + update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + break; + case ECORE_X_COMPOSITE_UPDATE_MANUAL: + update = XCB_COMPOSITE_REDIRECT_MANUAL; + break; + } + xcb_composite_unredirect_window(_ecore_xcb_conn, win, update); +#endif +} + +EAPI void +ecore_x_composite_unredirect_subwindows(Ecore_X_Window win, Ecore_X_Composite_Update_Type type) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_COMPOSITE + uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - free(reply); + switch (type) + { + case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: + update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + break; + case ECORE_X_COMPOSITE_UPDATE_MANUAL: + update = XCB_COMPOSITE_REDIRECT_MANUAL; + break; } + xcb_composite_unredirect_subwindows(_ecore_xcb_conn, win, update); +#endif +} -#endif /* ECORE_XCB_COMPOSITE */ -} /* _ecore_x_composite_init_finalize */ +EAPI Ecore_X_Pixmap +ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win) +{ + Ecore_X_Pixmap pmap = XCB_NONE; -/** - * Return whether the Composite Extension is available. - * @return 1 if the Composite Extension is available, 0 if not. - * - * Return 1 if the X server supports the Composite Extension version 0.4 - * or greater, 0 otherwise. - * @ingroup Ecore_X_Composite_Group - */ -EAPI Eina_Bool -ecore_x_composite_query(void) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_COMPOSITE + pmap = xcb_generate_id(_ecore_xcb_conn); + xcb_composite_name_window_pixmap(_ecore_xcb_conn, win, pmap); +#endif + + return pmap; +} + +EAPI void +ecore_x_composite_window_events_disable(Ecore_X_Window win) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + ecore_x_window_shape_input_rectangle_set(win, -1, -1, 1, 1); +#else + return; + win = 0; +#endif +} + +EAPI void +ecore_x_composite_window_events_enable(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + ecore_x_window_shape_input_rectangle_set(win, 0, 0, 65535, 65535); +#else + return; + win = 0; +#endif +} + +EAPI Ecore_X_Window +ecore_x_composite_render_window_enable(Ecore_X_Window root) +{ + Ecore_X_Window win = 0; +#ifdef ECORE_XCB_COMPOSITE + xcb_composite_get_overlay_window_cookie_t cookie; + xcb_composite_get_overlay_window_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + #ifdef ECORE_XCB_COMPOSITE - return _composite_available; -#else /* ifdef ECORE_XCB_COMPOSITE */ - return 0; -#endif /* ECORE_XCB_COMPOSITE */ -} /* ecore_x_composite_query */ + cookie = xcb_composite_get_overlay_window(_ecore_xcb_conn, root); + reply = + xcb_composite_get_overlay_window_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return win; + + win = reply->overlay_win; + free(reply); + + ecore_x_composite_window_events_disable(win); +#endif + + return win; +} +EAPI void +ecore_x_composite_render_window_disable(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_COMPOSITE + xcb_composite_release_overlay_window(_ecore_xcb_conn, win); +#endif +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_cursor.c b/src/lib/ecore_x/xcb/ecore_xcb_cursor.c index 2895d0b..f71d595 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_cursor.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_cursor.c @@ -1,274 +1,364 @@ #include "ecore_xcb_private.h" -#include -#include +# include +# include +#ifdef ECORE_XCB_CURSOR +# include +# include +#endif -extern int _ecore_xcb_xcursor; +/* local function prototypes */ +static xcb_image_t *_ecore_xcb_cursor_image_create(int w, int h, int *pixels); +static Ecore_X_Cursor _ecore_xcb_cursor_image_load_cursor(Ecore_X_Window win, int w, int h, int hot_x, int hot_y, int *pixels, xcb_image_t *img); +#ifdef ECORE_XCB_CURSOR +static Ecore_X_Cursor _ecore_xcb_cursor_image_load_argb_cursor(Ecore_X_Window win, int w, int h, int hot_x, int hot_y, xcb_image_t *img); +static xcb_render_pictforminfo_t *_ecore_xcb_cursor_find_image_format(void); +#endif -EAPI Eina_Bool -ecore_x_cursor_color_supported_get(void) -{ - return _ecore_xcb_xcursor; -} /* ecore_x_cursor_color_supported_get */ - -EAPI Ecore_X_Cursor -ecore_x_cursor_new(Ecore_X_Window window, - int *pixels, - int w, - int h, - int hot_x, - int hot_y) +/* local variables */ +#ifdef ECORE_XCB_CURSOR +static xcb_render_pictforminfo_t *_ecore_xcb_cursor_format = NULL; +#endif +static int _ecore_xcb_cursor_size = 0; +static Eina_Bool _ecore_xcb_cursor = EINA_FALSE; + +void +_ecore_xcb_cursor_init(void) { - Ecore_X_Cursor cursor = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_CURSOR - if (_ecore_x_xcursor) - { - Cursor c; - XcursorImage *xci; + /* NB: noop */ +#endif +} - xci = XcursorImageCreate(w, h); - if (xci) - { - int i; - - xci->xhot = hot_x; - xci->yhot = hot_y; - xci->delay = 0; - for (i = 0; i < (w * h); i++) - { -// int r, g, b, a; -// -// a = (pixels[i] >> 24) & 0xff; -// r = (((pixels[i] >> 16) & 0xff) * a) / 0xff; -// g = (((pixels[i] >> 8 ) & 0xff) * a) / 0xff; -// b = (((pixels[i] ) & 0xff) * a) / 0xff; - xci->pixels[i] = pixels[i]; -// (a << 24) | (r << 16) | (g << 8) | (b); - } - c = XcursorImageLoadCursor(_ecore_x_disp, xci); - XcursorImageDestroy(xci); - return c; - } - } - else -#endif /* ECORE_XCB_CURSOR */ - { - const uint32_t dither[2][2] = - { - {0, 2}, - {3, 1} - }; - Ecore_X_Drawable draw; - Ecore_X_Pixmap pixmap; - Ecore_X_Pixmap mask; - Ecore_X_GC gc; - xcb_image_t *image; - uint32_t *pix; - uint8_t fr; - uint8_t fg; - uint8_t fb; - uint8_t br; - uint8_t bg; - uint8_t bb; - uint32_t brightest = 0; - uint32_t darkest = 255 * 3; - uint16_t x; - uint16_t y; - - draw = window; - pixmap = xcb_generate_id(_ecore_xcb_conn); - xcb_create_pixmap(_ecore_xcb_conn, - 1, pixmap, draw, - 1, 1); - mask = xcb_generate_id(_ecore_xcb_conn); - xcb_create_pixmap(_ecore_xcb_conn, - 1, mask, draw, - 1, 1); - - image = xcb_image_create_native(_ecore_xcb_conn, w, h, - XCB_IMAGE_FORMAT_Z_PIXMAP, - 32, NULL, ~0, NULL); - image->data = malloc(image->size); - - fr = 0x00; fg = 0x00; fb = 0x00; - br = 0xff; bg = 0xff; bb = 0xff; - pix = (uint32_t *)pixels; - for (y = 0; y < h; y++) - { - for (x = 0; x < w; x++) - { - uint8_t r, g, b, a; - - a = (pix[0] >> 24) & 0xff; - r = (pix[0] >> 16) & 0xff; - g = (pix[0] >> 8) & 0xff; - b = (pix[0]) & 0xff; - if (a > 0) - { - if ((uint32_t)(r + g + b) > brightest) - { - brightest = r + g + b; - br = r; - bg = g; - bb = b; - } - - if ((uint32_t)(r + g + b) < darkest) - { - darkest = r + g + b; - fr = r; - fg = g; - fb = b; - } - } - - pix++; - } - } - - pix = (uint32_t *)pixels; - for (y = 0; y < h; y++) - { - for (x = 0; x < w; x++) - { - uint32_t v; - uint8_t r, g, b; - int32_t d1, d2; - - r = (pix[0] >> 16) & 0xff; - g = (pix[0] >> 8) & 0xff; - b = (pix[0]) & 0xff; - d1 = - ((r - fr) * (r - fr)) + - ((g - fg) * (g - fg)) + - ((b - fb) * (b - fb)); - d2 = - ((r - br) * (r - br)) + - ((g - bg) * (g - bg)) + - ((b - bb) * (b - bb)); - if (d1 + d2) - { - v = (((d2 * 255) / (d1 + d2)) * 5) / 256; - if (v > dither[x & 0x1][y & 0x1]) - v = 1; - else - v = 0; - } - else - { - v = 0; - } - - xcb_image_put_pixel(image, x, y, v); - pix++; - } - } - draw = pixmap; - gc = xcb_generate_id(_ecore_xcb_conn); - xcb_create_gc(_ecore_xcb_conn, gc, draw, 0, NULL); - xcb_image_put(_ecore_xcb_conn, draw, gc, image, 0, 0, 0); - xcb_free_gc(_ecore_xcb_conn, gc); - - pix = (uint32_t *)pixels; - for (y = 0; y < h; y++) - { - for (x = 0; x < w; x++) - { - uint32_t v; - - v = (((pix[0] >> 24) & 0xff) * 5) / 256; - if (v > dither[x & 0x1][y & 0x1]) - v = 1; - else - v = 0; - - xcb_image_put_pixel(image, x, y, v); - pix++; - } - } - draw = mask; - gc = xcb_generate_id(_ecore_xcb_conn); - xcb_create_gc (_ecore_xcb_conn, gc, draw, 0, NULL); - xcb_image_put(_ecore_xcb_conn, draw, gc, image, 0, 0, 0); - xcb_free_gc(_ecore_xcb_conn, gc); - - free(image->data); - image->data = NULL; - xcb_image_destroy(image); - - cursor = xcb_generate_id(_ecore_xcb_conn); - xcb_create_cursor (_ecore_xcb_conn, cursor, - pixmap, mask, - fr << 8 | fr, - fg << 8 | fg, - fb << 8 | fb, - br << 8 | br, - bg << 8 | bg, - bb << 8 | bb, - hot_x, - hot_y); - xcb_free_pixmap(_ecore_xcb_conn, pixmap); - xcb_free_pixmap(_ecore_xcb_conn, mask); - - return cursor; - } - - return 0; -} /* ecore_x_cursor_new */ - -EAPI void -ecore_x_cursor_free(Ecore_X_Cursor cursor) +void +_ecore_xcb_cursor_finalize(void) { - xcb_free_cursor(_ecore_xcb_conn, cursor); -} /* ecore_x_cursor_free */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_CURSOR + _ecore_xcb_cursor = _ecore_xcb_render_argb_get(); +#endif +} /* * Returns the cursor for the given shape. * Note that the return value must not be freed with * ecore_x_cursor_free()! */ -EAPI Ecore_X_Cursor -ecore_x_cursor_shape_get(int shape) +EAPI Ecore_X_Cursor +ecore_x_cursor_shape_get(int shape) { - Ecore_X_Cursor cursor; + Ecore_X_Cursor cursor = 0; xcb_font_t font; - /* Shapes are defined in Ecore_X_Cursor.h */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + font = xcb_generate_id(_ecore_xcb_conn); xcb_open_font(_ecore_xcb_conn, font, strlen("cursor"), "cursor"); cursor = xcb_generate_id(_ecore_xcb_conn); - xcb_create_glyph_cursor (_ecore_xcb_conn, - cursor, - font, - font, - shape, - shape + 1, - 0, 0, 0, - 65535, 65535, 65535); - + xcb_create_glyph_cursor(_ecore_xcb_conn, cursor, font, font, + shape, shape + 1, 0, 0, 0, 65535, 65535, 65535); xcb_close_font(_ecore_xcb_conn, font); return cursor; -} /* ecore_x_cursor_shape_get */ +} + +EAPI void +ecore_x_cursor_free(Ecore_X_Cursor cursor) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xcb_free_cursor(_ecore_xcb_conn, cursor); +} -EAPI void -ecore_x_cursor_size_set(int size) +EAPI Eina_Bool +ecore_x_cursor_color_supported_get(void) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_cursor; +} + +EAPI Ecore_X_Cursor +ecore_x_cursor_new(Ecore_X_Window win, int *pixels, int w, int h, int hot_x, int hot_y) +{ + Ecore_X_Cursor cursor = 0; + xcb_image_t *img; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (_ecore_xcb_cursor) // argb + { + if ((img = _ecore_xcb_cursor_image_create(w, h, pixels))) + { #ifdef ECORE_XCB_CURSOR - XcursorSetDefaultSize(_ecore_x_disp, size); -#else /* ifdef ECORE_XCB_CURSOR */ - size = 0; -#endif /* ECORE_XCB_CURSOR */ -} /* ecore_x_cursor_size_set */ - -EAPI int -ecore_x_cursor_size_get(void) + cursor = + _ecore_xcb_cursor_image_load_argb_cursor(win, w, h, + hot_x, hot_y, img); +#else + cursor = + _ecore_xcb_cursor_image_load_cursor(win, w, h, + hot_x, hot_y, pixels, img); +#endif + } + else + DBG("Failed to create new cursor image"); + } + else + { + if ((img = _ecore_xcb_cursor_image_create(w, h, pixels))) + { + cursor = + _ecore_xcb_cursor_image_load_cursor(win, w, h, + hot_x, hot_y, pixels, img); + } + else + DBG("Failed to create new cursor image"); + } + + if (cursor) + { + uint32_t mask, list; + + mask = XCB_CW_CURSOR; + list = cursor; + xcb_change_window_attributes(_ecore_xcb_conn, win, mask, &list); + } + + return cursor; +} + +EAPI void +ecore_x_cursor_size_set(int size) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + // NB: size_set only needed for non-argb cursors + _ecore_xcb_cursor_size = size; +} + +EAPI int +ecore_x_cursor_size_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_cursor_size; +} + +/* local functions */ +static xcb_image_t * +_ecore_xcb_cursor_image_create(int w, int h, int *pixels) { + // NB: May be able to use shm here, but the image NEEDS to be in + // native format + if (_ecore_xcb_cursor) + { #ifdef ECORE_XCB_CURSOR - return XcursorGetDefaultSize(_ecore_x_disp); -#else /* ifdef ECORE_XCB_CURSOR */ - return 0; -#endif /* ECORE_XCB_CURSOR */ -} /* ecore_x_cursor_size_get */ + return xcb_image_create_native(_ecore_xcb_conn, w, h, + XCB_IMAGE_FORMAT_Z_PIXMAP, + 32, pixels, (w * h * sizeof(int)), // 32 + (uint8_t *)pixels); +#else + return xcb_image_create_native(_ecore_xcb_conn, w, h, + XCB_IMAGE_FORMAT_Z_PIXMAP, + 1, pixels, (w * h * sizeof(int)), // 32 + (uint8_t *)pixels); +#endif + } + else + { + return xcb_image_create_native(_ecore_xcb_conn, w, h, + XCB_IMAGE_FORMAT_Z_PIXMAP, 1, + NULL, ~0, NULL); + } +} + +static Ecore_X_Cursor +_ecore_xcb_cursor_image_load_cursor(Ecore_X_Window win, int w, int h, int hot_x, int hot_y, int *pixels, xcb_image_t *img) +{ + xcb_pixmap_t pixmap, mask; + Ecore_X_Cursor cursor; + Ecore_X_GC gc; + uint32_t *pix; + uint8_t fr = 0x00, fg = 0x00, fb = 0x00; + uint8_t br = 0xff, bg = 0xff, bb = 0xff; + uint32_t brightest = 0, darkest = 255 * 3; + uint16_t x, y; + const uint32_t dither[2][2] = + { + {0, 2}, + {3, 1} + }; + + pixmap = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, 1, pixmap, win, w, h); + + mask = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, 1, mask, win, w, h); + + img->data = malloc(img->size); + + pix = (uint32_t *)pixels; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + uint8_t r, g, b, a; + + a = (pix[0] >> 24) & 0xff; + r = (pix[0] >> 16) & 0xff; + g = (pix[0] >> 8) & 0xff; + b = (pix[0]) & 0xff; + if (a > 0) + { + if ((uint32_t)(r + g + b) > brightest) + { + brightest = r + g + b; + br = r; + bg = g; + bb = b; + } + + if ((uint32_t)(r + g + b) < darkest) + { + darkest = r + g + b; + fr = r; + fg = g; + fb = b; + } + } + pix++; + } + } + + pix = (uint32_t *)pixels; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + uint32_t v; + uint8_t r, g, b; + int32_t d1, d2; + + r = (pix[0] >> 16) & 0xff; + g = (pix[0] >> 8) & 0xff; + b = (pix[0]) & 0xff; + d1 = + ((r - fr) * (r - fr)) + + ((g - fg) * (g - fg)) + + ((b - fb) * (b - fb)); + d2 = + ((r - br) * (r - br)) + + ((g - bg) * (g - bg)) + + ((b - bb) * (b - bb)); + if (d1 + d2) + { + v = (((d2 * 255) / (d1 + d2)) * 5) / 256; + if (v > dither[x & 0x1][y & 0x1]) + v = 1; + else + v = 0; + } + else + v = 0; + + xcb_image_put_pixel(img, x, y, v); + pix++; + } + } + + // img->depth was 1 + gc = ecore_x_gc_new(pixmap, 0, NULL); + xcb_put_image(_ecore_xcb_conn, XCB_IMAGE_FORMAT_Z_PIXMAP, + pixmap, gc, w, h, 0, 0, 0, img->depth, img->size, img->data); + ecore_x_gc_free(gc); + + pix = (uint32_t *)pixels; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + uint32_t v; + + v = (((pix[0] >> 24) & 0xff) * 5) / 256; + if (v > dither[x & 0x1][y & 0x1]) + v = 1; + else + v = 0; + + xcb_image_put_pixel(img, x, y, v); + pix++; + } + } + + // img->depth was 1 + gc = ecore_x_gc_new(mask, 0, NULL); + xcb_put_image(_ecore_xcb_conn, XCB_IMAGE_FORMAT_Z_PIXMAP, + mask, gc, w, h, 0, 0, 0, img->depth, img->size, img->data); + ecore_x_gc_free(gc); + + cursor = xcb_generate_id(_ecore_xcb_conn); + xcb_create_cursor(_ecore_xcb_conn, cursor, pixmap, mask, + fr << 8 | fr, fg << 8 | fg, fb << 8 | fb, + br << 8 | br, bg << 8 | bg, bb << 8 | bb, + hot_x, hot_y); + + xcb_free_pixmap(_ecore_xcb_conn, pixmap); + xcb_free_pixmap(_ecore_xcb_conn, mask); + + return cursor; +} + +#ifdef ECORE_XCB_CURSOR +static Ecore_X_Cursor +_ecore_xcb_cursor_image_load_argb_cursor(Ecore_X_Window win, int w, int h, int hot_x, int hot_y, xcb_image_t *img) +{ + xcb_pixmap_t pixmap; + xcb_render_picture_t pict; + Ecore_X_Cursor cursor; + Ecore_X_GC gc; + + if (!_ecore_xcb_cursor_format) + _ecore_xcb_cursor_format = _ecore_xcb_cursor_find_image_format(); + + pixmap = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, 32, pixmap, win, w, h); + + // img->depth was 32 + gc = ecore_x_gc_new(pixmap, 0, NULL); + xcb_put_image(_ecore_xcb_conn, XCB_IMAGE_FORMAT_Z_PIXMAP, + pixmap, gc, w, h, 0, 0, 0, + img->depth, img->size, img->data); + ecore_x_gc_free(gc); + + pict = xcb_generate_id(_ecore_xcb_conn); + xcb_render_create_picture(_ecore_xcb_conn, pict, pixmap, + _ecore_xcb_cursor_format->id, 0, NULL); + xcb_free_pixmap(_ecore_xcb_conn, pixmap); + + cursor = xcb_generate_id(_ecore_xcb_conn); + xcb_render_create_cursor(_ecore_xcb_conn, cursor, pict, hot_x, hot_y); + xcb_render_free_picture(_ecore_xcb_conn, pict); + + return cursor; +} + +static xcb_render_pictforminfo_t * +_ecore_xcb_cursor_find_image_format(void) +{ + const xcb_render_query_pict_formats_reply_t *reply; + xcb_render_pictforminfo_t *ret = NULL; + + reply = xcb_render_util_query_formats(_ecore_xcb_conn); + if (reply) + { + ret = xcb_render_util_find_standard_format(reply, + XCB_PICT_STANDARD_ARGB_32); +// free(reply); + } + return ret; +} +#endif diff --git a/src/lib/ecore_x/xcb/ecore_xcb_damage.c b/src/lib/ecore_x/xcb/ecore_xcb_damage.c index ab97445..899f0d4 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_damage.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_damage.c @@ -1,113 +1,122 @@ #include "ecore_xcb_private.h" +# ifdef ECORE_XCB_DAMAGE +# include +# endif -/** - * @defgroup Ecore_X_Damage_Group X Damage Extension Functions - * - * Functions related to the X Damage extension. - */ - -#ifdef ECORE_XCB_DAMAGE -static uint8_t _damage_available = 0; -static xcb_damage_query_version_cookie_t _ecore_xcb_damage_init_cookie; -#endif /* ECORE_XCB_DAMAGE */ +/* local variables */ +static Eina_Bool _damage_avail = EINA_FALSE; -/* To avoid round trips, the initialization is separated in 2 - functions: _ecore_xcb_damage_init and - _ecore_xcb_damage_init_finalize. The first one gets the cookies and - the second one gets the replies. */ +/* external variables */ +int _ecore_xcb_event_damage = -1; -void -_ecore_x_damage_init(const xcb_query_extension_reply_t *reply) +void +_ecore_xcb_damage_init(void) { -#ifdef ECORE_XCB_DAMAGE - if (reply && (reply->present)) - _ecore_xcb_damage_init_cookie = xcb_damage_query_version_unchecked(_ecore_xcb_conn, 1, 1); + LOGFN(__FILE__, __LINE__, __FUNCTION__); -#endif /* ECORE_XCB_DAMAGE */ -} /* _ecore_x_damage_init */ +#ifdef ECORE_XCB_DAMAGE + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_damage_id); +#endif +} -void -_ecore_x_damage_init_finalize(void) +void +_ecore_xcb_damage_finalize(void) { #ifdef ECORE_XCB_DAMAGE - xcb_damage_query_version_reply_t *reply; + const xcb_query_extension_reply_t *ext_reply; +#endif - reply = xcb_damage_query_version_reply(_ecore_xcb_conn, - _ecore_xcb_damage_init_cookie, - NULL); - if (reply) - { - if (reply->major_version >= 1) - _damage_available = 1; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - free(reply); +#ifdef ECORE_XCB_DAMAGE + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_damage_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_damage_query_version_cookie_t cookie; + xcb_damage_query_version_reply_t *reply; + + cookie = + xcb_damage_query_version_unchecked(_ecore_xcb_conn, + XCB_DAMAGE_MAJOR_VERSION, + XCB_DAMAGE_MINOR_VERSION); + reply = xcb_damage_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (reply->major_version >= XCB_DAMAGE_MAJOR_VERSION) + _damage_avail = EINA_TRUE; + free(reply); + } + + if (_damage_avail) + _ecore_xcb_event_damage = ext_reply->first_event; } - -#endif /* ECORE_XCB_DAMAGE */ -} /* _ecore_x_damage_init_finalize */ +#endif +} /** - * Return whether the Damage Extension is available. - * @return 1 if the Damage Extension is available, 0 if not. - * - * Return 1 if the X server supports the Damage Extension version 1.0, - * 0 otherwise. - * @ingroup Ecore_X_Damage_Group + * @defgroup Ecore_X_Damage_Group X Damage Extension Functions + * + * Functions related to the X Damage Extension. */ -EAPI Eina_Bool -ecore_x_damage_query(void) + +EAPI Eina_Bool +ecore_x_damage_query(void) { -#ifdef ECORE_XCB_DAMAGE - return _damage_available; -#else /* ifdef ECORE_XCB_DAMAGE */ - return 0; -#endif /* ECORE_XCB_DAMAGE */ -} /* ecore_x_damage_query */ + return _damage_avail; +} /** - * Creates a damage object. - * @param drawable The drawable to monotor. - * @param level The level of the damage report. - * @return The damage object. - * - * Creates a damage object to monitor changes to @p drawable, with the - * level @p level. + * Create a damage object + * + * @param drawable The drawable to monitor + * @param level The level of the damage report + * @return The damage object + * + * Creates a damage object to monitor changes to @p drawable, + * with the level @p level. + * * @ingroup Ecore_X_Damage_Group */ -EAPI Ecore_X_Damage -ecore_x_damage_new(Ecore_X_Drawable drawable, - Ecore_X_Damage_Report_Level level) +EAPI Ecore_X_Damage +ecore_x_damage_new(Ecore_X_Drawable drawable, Ecore_X_Damage_Report_Level level) { Ecore_X_Damage damage = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + #ifdef ECORE_XCB_DAMAGE damage = xcb_generate_id(_ecore_xcb_conn); xcb_damage_create(_ecore_xcb_conn, damage, drawable, level); -#endif /* ECORE_XCB_DAMAGE */ +#endif return damage; -} /* ecore_x_damage_new */ +} /** - * Destroys a damage object. - * @param damage The damage object to destroy. - * - * Destroys the damage object @p damage. + * Destroy a damage object + * + * @param The damage object to destroy + * + * Destroys the damage object @p damage + * * @ingroup Ecore_X_Damage_Group */ -EAPI void -ecore_x_damage_free(Ecore_X_Damage damage) +EAPI void +ecore_x_damage_free(Ecore_X_Damage damage) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + #ifdef ECORE_XCB_DAMAGE xcb_damage_destroy(_ecore_xcb_conn, damage); -#endif /* ECORE_XCB_DAMAGE */ -} /* ecore_x_damage_free */ +#endif +} /** - * Synchronously modifies the region. - * @param damage The damage object to destroy. - * @param repair The repair region. - * @param parts The parts region. + * Synchronously modifies the region + * + * @param damage The damage object to destroy + * @param repair The repair region + * @param parts The parts region * * Synchronously modifies the regions in the following manner: * If @p repair is @c XCB_NONE: @@ -117,15 +126,15 @@ ecore_x_damage_free(Ecore_X_Damage damage) * 1) parts = damage INTERSECT repair * 2) damage = damage - parts * 3) Generate DamageNotify for remaining damage areas + * * @ingroup Ecore_X_Damage_Group */ -EAPI void -ecore_x_damage_subtract(Ecore_X_Damage damage, - Ecore_X_Region repair, - Ecore_X_Region parts) +EAPI void +ecore_x_damage_subtract(Ecore_X_Damage damage, Ecore_X_Region repair, Ecore_X_Region parts) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + #ifdef ECORE_XCB_DAMAGE xcb_damage_subtract(_ecore_xcb_conn, damage, repair, parts); -#endif /* ECORE_XCB_DAMAGE */ -} /* ecore_x_damage_subtract */ - +#endif +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_dnd.c b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c index 9e289d1..0c7d8ea 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_dnd.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c @@ -1,9 +1,29 @@ -#include - -#include "Ecore.h" #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +/* local structures */ +typedef struct _Version_Cache_Item +{ + Ecore_X_Window win; + int ver; +} Version_Cache_Item; + +/* local function prototypes */ +static Eina_Bool _ecore_xcb_dnd_converter_copy(char *target __UNUSED__, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *tprop __UNUSED__, int *count __UNUSED__); + +/* local variables */ +static int _ecore_xcb_dnd_init_count; +static Ecore_X_DND_Source *_source = NULL; +static Ecore_X_DND_Target *_target = NULL; +static Version_Cache_Item *_version_cache = NULL; +static int _version_cache_num = 0, _version_cache_alloc = 0; +static void (*_posupdatecb)(void *, Ecore_X_Xdnd_Position *); +static void *_posupdatedata; + +/* external variables */ EAPI int ECORE_X_EVENT_XDND_ENTER = 0; EAPI int ECORE_X_EVENT_XDND_POSITION = 0; EAPI int ECORE_X_EVENT_XDND_STATUS = 0; @@ -11,16 +31,15 @@ EAPI int ECORE_X_EVENT_XDND_LEAVE = 0; EAPI int ECORE_X_EVENT_XDND_DROP = 0; EAPI int ECORE_X_EVENT_XDND_FINISHED = 0; -static Ecore_X_DND_Source *_source = NULL; -static Ecore_X_DND_Target *_target = NULL; -static int _ecore_x_dnd_init_count = 0; - -void -_ecore_x_dnd_init(void) +void +_ecore_xcb_dnd_init(void) { - if (!_ecore_x_dnd_init_count) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_ecore_xcb_dnd_init_count) { _source = calloc(1, sizeof(Ecore_X_DND_Source)); + if (!_source) return; _source->version = ECORE_X_DND_VERSION; _source->win = XCB_NONE; _source->dest = XCB_NONE; @@ -28,6 +47,12 @@ _ecore_x_dnd_init(void) _source->prev.window = 0; _target = calloc(1, sizeof(Ecore_X_DND_Target)); + if (!_target) + { + free(_source); + _source = NULL; + return; + } _target->win = XCB_NONE; _target->source = XCB_NONE; _target->state = ECORE_X_DND_TARGET_IDLE; @@ -39,754 +64,577 @@ _ecore_x_dnd_init(void) ECORE_X_EVENT_XDND_DROP = ecore_event_type_new(); ECORE_X_EVENT_XDND_FINISHED = ecore_event_type_new(); } + _ecore_xcb_dnd_init_count++; +} + +void +_ecore_xcb_dnd_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - _ecore_x_dnd_init_count++; -} /* _ecore_x_dnd_init */ + _ecore_xcb_dnd_init_count--; + if (_ecore_xcb_dnd_init_count > 0) return; + if (_source) free(_source); + _source = NULL; + if (_target) free(_target); + _target = NULL; + _ecore_xcb_dnd_init_count = 0; +} -void -_ecore_x_dnd_shutdown(void) +EAPI void +ecore_x_dnd_send_status(Eina_Bool will_accept, Eina_Bool suppress, Ecore_X_Rectangle rect, Ecore_X_Atom action) { - _ecore_x_dnd_init_count--; - if (_ecore_x_dnd_init_count > 0) - return; + xcb_client_message_event_t ev; - if (_source) - free(_source); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - _source = NULL; + if (_target->state == ECORE_X_DND_TARGET_IDLE) return; - if (_target) - free(_target); + memset(&ev, 0, sizeof(xcb_client_message_event_t)); - _target = NULL; + _target->will_accept = will_accept; - _ecore_x_dnd_init_count = 0; -} /* _ecore_x_dnd_shutdown */ + ev.response_type = XCB_CLIENT_MESSAGE; + ev.type = ECORE_X_ATOM_XDND_STATUS; + ev.format = 32; + ev.window = _target->source; + ev.data.data32[0] = _target->win; + ev.data.data32[1] = 0; + if (will_accept) ev.data.data32[1] |= 0x1UL; + if (!suppress) ev.data.data32[1] |= 0x2UL; -EAPI void -ecore_x_dnd_aware_set(Ecore_X_Window window, - Eina_Bool on) -{ - Ecore_X_Atom prop_data = ECORE_X_DND_VERSION; + ev.data.data32[2] = rect.x; + ev.data.data32[2] <<= 16; + ev.data.data32[2] |= rect.y; + ev.data.data32[3] = rect.width; + ev.data.data32[3] <<= 16; + ev.data.data32[3] |= rect.height; - if (on) - ecore_x_window_prop_property_set(window, ECORE_X_ATOM_XDND_AWARE, - ECORE_X_ATOM_ATOM, 32, &prop_data, 1); - else - ecore_x_window_prop_property_del(window, ECORE_X_ATOM_XDND_AWARE); -} /* ecore_x_dnd_aware_set */ + if (will_accept) + ev.data.data32[4] = action; + else + ev.data.data32[4] = XCB_NONE; + _target->accepted_action = action; -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - */ -EAPI void -ecore_x_dnd_version_get_prefetch(Ecore_X_Window window) + xcb_send_event(_ecore_xcb_conn, 0, _target->source, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +} + +EAPI Eina_Bool +ecore_x_dnd_drop(void) { - xcb_get_property_cookie_t cookie; + xcb_client_message_event_t ev; + Eina_Bool status = EINA_FALSE; - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root, - ECORE_X_ATOM_XDND_AWARE, - ECORE_X_ATOM_ATOM, - 0, LONG_MAX); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_dnd_version_get_prefetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Gets the reply of the GetProperty request sent by ecore_x_dnd_version_get_prefetch(). - */ -EAPI void -ecore_x_dnd_version_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + memset(&ev, 0, sizeof(xcb_client_message_event_t)); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_dnd_version_get_fetch */ + if (_source->dest) + { + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = _source->dest; + ev.data.data32[0] = _source->win; + ev.data.data32[1] = 0; -/** - * Get the DnD version. - * @param window Unused. - * @return 0 on failure, the version otherwise. - * - * Get the DnD version. Returns 0 on failure, the version otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_dnd_version_get_prefetch(), which sends the GetProperty request, - * then ecore_x_dnd_version_get_fetch(), which gets the reply. - */ -EAPI int -ecore_x_dnd_version_get(Ecore_X_Window window) -{ - unsigned char *prop_data; - int num; + if (_source->will_accept) + { + ev.type = ECORE_X_ATOM_XDND_DROP; + ev.data.data32[2] = _source->time; - if (ecore_x_window_prop_property_get(window, ECORE_X_ATOM_XDND_AWARE, - ECORE_X_ATOM_ATOM, 32, &prop_data, &num)) + xcb_send_event(_ecore_xcb_conn, 0, _source->dest, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); + _source->state = ECORE_X_DND_SOURCE_DROPPED; + status = EINA_TRUE; + } + else + { + ev.type = ECORE_X_ATOM_XDND_LEAVE; + xcb_send_event(_ecore_xcb_conn, 0, _source->dest, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); + _source->state = ECORE_X_DND_SOURCE_IDLE; + } + } + else { - int version = (int)*prop_data; - free(prop_data); - return version; + ecore_x_selection_xdnd_clear(); + _source->state = ECORE_X_DND_SOURCE_IDLE; } - else - return 0; -} /* ecore_x_dnd_version_get */ -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - */ -EAPI void -ecore_x_dnd_type_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; + ecore_x_window_ignore_set(_source->win, 0); + _source->prev.window = 0; - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root, - ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, - 0, LONG_MAX); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_dnd_type_get_prefetch */ + return status; +} -/** - * Gets the reply of the GetProperty request sent by ecore_x_dnd_type_get_prefetch(). - */ -EAPI void -ecore_x_dnd_type_get_fetch(void) +EAPI void +ecore_x_dnd_aware_set(Ecore_X_Window win, Eina_Bool on) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + Ecore_X_Atom prop_data = ECORE_X_DND_VERSION; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_dnd_type_get_fetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/* FIXME: round trip (InternAtomGet request) */ + if (on) + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_AWARE, + ECORE_X_ATOM_ATOM, 32, &prop_data, 1); + else + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_AWARE); +} -/** - * Check if the type is set. - * @param window Unused. - * @param type The type to check - * @return 0 on failure, 1 otherwise. - * - * Check if the type is set. 0 on failure, 1 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_dnd_type_get_prefetch(), which sends the GetProperty request, - * then ecore_x_dnd_type_get_fetch(), which gets the reply. - */ -EAPI Eina_Bool -ecore_x_dnd_type_isset(Ecore_X_Window window, - const char *type) +EAPI int +ecore_x_dnd_version_get(Ecore_X_Window win) { - xcb_intern_atom_cookie_t cookie; - xcb_intern_atom_reply_t *reply; - Ecore_X_Atom *atoms; unsigned char *data; - int num; - int i; - uint8_t ret = 0; + int num = 0; + Version_Cache_Item *t; - cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, - strlen(type), type); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!ecore_x_window_prop_property_get(window, ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, 32, &data, &num)) + if (_source->state == ECORE_X_DND_SOURCE_DRAGGING) { - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - free(reply); + if (_version_cache) + { + int i = 0; - return ret; + for (i = 0; i < _version_cache_num; i++) + { + if (_version_cache[i].win == win) + return _version_cache[i].ver; + } + } } - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) + if (ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_AWARE, + ECORE_X_ATOM_ATOM, 32, &data, &num)) { + int version = 0; + + version = (int)*data; free(data); - return 0; + if (_source->state == ECORE_X_DND_SOURCE_DRAGGING) + { + _version_cache_num++; + if (_version_cache_num > _version_cache_alloc) + _version_cache_alloc += 16; + t = realloc(_version_cache, + _version_cache_alloc * sizeof(Version_Cache_Item)); + if (!t) return 0; + _version_cache = t; + _version_cache[_version_cache_num - 1].win = win; + _version_cache[_version_cache_num - 1].ver = version; + } + return version; } - atoms = (Ecore_X_Atom *)data; + if (_source->state == ECORE_X_DND_SOURCE_DRAGGING) + { + _version_cache_num++; + if (_version_cache_num > _version_cache_alloc) + _version_cache_alloc += 16; + t = realloc(_version_cache, + _version_cache_alloc * sizeof(Version_Cache_Item)); + if (!t) return 0; + _version_cache = t; + _version_cache[_version_cache_num - 1].win = win; + _version_cache[_version_cache_num - 1].ver = 0; + } + + return 0; +} - for (i = 0; i < num; ++i) +EAPI Eina_Bool +ecore_x_dnd_type_isset(Ecore_X_Window win, const char *type) +{ + int num = 0, i = 0; + Eina_Bool ret = EINA_FALSE; + unsigned char *data; + Ecore_X_Atom *atoms, atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, &data, &num)) + return ret; + + atom = ecore_x_atom_get(type); + atoms = (Ecore_X_Atom *)data; + for (i = 0; i < num; ++i) { - if (reply->atom == atoms[i]) + if (atom == atoms[i]) { - ret = 1; + ret = EINA_TRUE; break; } } free(data); - free(reply); - return ret; -} /* ecore_x_dnd_type_isset */ - -/* FIXME: round trip (InternAtomGet request) */ +} -/** - * Set the type. - * @param window Unused. - * @param type The type to set - * @param on 0 or non 0... - * - * Set the type. - * - * To use this function, you must call before, and in order, - * ecore_x_dnd_type_get_prefetch(), which sends the GetProperty request, - * then ecore_x_dnd_type_get_fetch(), which gets the reply. - */ -EAPI void -ecore_x_dnd_type_set(Ecore_X_Window window, - const char *type, - Eina_Bool on) +EAPI void +ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, Eina_Bool on) { - xcb_intern_atom_cookie_t cookie; - xcb_intern_atom_reply_t *reply; - Ecore_X_Atom *oldset = NULL; - Ecore_X_Atom *newset = NULL; - unsigned char *data = NULL; - unsigned char *old_data = NULL; - Ecore_X_Atom atom; - int i, j = 0, num = 0; + Ecore_X_Atom atom, *oldset = NULL, *newset = NULL; + int i = 0, j = 0, num = 0; + unsigned char *data = NULL, *old_data = NULL; - cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, - strlen(type), type); + LOGFN(__FILE__, __LINE__, __FUNCTION__); atom = ecore_x_atom_get(type); - if (!ecore_x_window_prop_property_get(window, ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, - 32, &old_data, &num)) - { - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - free(reply); - - return; - } - + ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, &old_data, &num); oldset = (Ecore_X_Atom *)old_data; - - if (on) + if (on) { - if (ecore_x_dnd_type_isset(window, type)) + if (ecore_x_dnd_type_isset(win, type)) { free(old_data); - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - free(reply); - return; } - - data = calloc(num + 1, sizeof(Ecore_X_Atom)); - if (!data) - { - free(old_data); - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - free(reply); - - return; - } - - newset = (Ecore_X_Atom *)data; - + newset = calloc(num + 1, sizeof(Ecore_X_Atom)); + if (!newset) return; + data = (unsigned char *)newset; for (i = 0; i < num; i++) - newset[i + 1] = oldset[i]; - /* prepend the new type */ - - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - { - free(old_data); - return; - } - - newset[0] = reply->atom; - free(reply); - - ecore_x_window_prop_property_set(window, - ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, - 32, data, num + 1); + newset[i + 1] = oldset[i]; + newset[0] = atom; + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, data, num + 1); } - else + else { - if (!ecore_x_dnd_type_isset(window, type)) + if (!ecore_x_dnd_type_isset(win, type)) { free(old_data); return; } - newset = calloc(num - 1, sizeof(Ecore_X_Atom)); - if (!newset) + if (!newset) { free(old_data); return; } - data = (unsigned char *)newset; for (i = 0; i < num; i++) - if (oldset[i] != atom) - newset[j++] = oldset[i]; - - ecore_x_window_prop_property_set(window, - ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, - 32, data, num - 1); + if (oldset[i] != atom) + newset[j++] = oldset[i]; + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, data, num - 1); } - free(oldset); free(newset); -} /* ecore_x_dnd_type_set */ - -/* FIXME: round trips, but I don't think we can do much, here */ +} -/** - * Set the types. - * @param window Unused. - * @param types The types to set - * @param num_types The number of types - * - * Set the types. - * - * To use this function, you must call before, and in order, - * ecore_x_dnd_type_get_prefetch(), which sends the GetProperty request, - * then ecore_x_dnd_type_get_fetch(), which gets the reply. - */ EAPI void -ecore_x_dnd_types_set(Ecore_X_Window window, - const char **types, - unsigned int num_types) +ecore_x_dnd_types_set(Ecore_X_Window win, const char **types, unsigned int num_types) { Ecore_X_Atom *newset = NULL; - void *data = NULL; - uint32_t i; + unsigned int i; + unsigned char *data = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!num_types) - { - ecore_x_window_prop_property_del(window, ECORE_X_ATOM_XDND_TYPE_LIST); - } + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_TYPE_LIST); else { - xcb_intern_atom_cookie_t *cookies; - xcb_intern_atom_reply_t *reply; - - cookies = (xcb_intern_atom_cookie_t *)malloc(sizeof(xcb_intern_atom_cookie_t)); - if (!cookies) - return; - - for (i = 0; i < num_types; i++) - cookies[i] = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, - strlen(types[i]), types[i]); - data = calloc(num_types, sizeof(Ecore_X_Atom)); - if (!data) - { - for (i = 0; i < num_types; i++) - { - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], NULL); - if (reply) - free(reply); - } - free(cookies); - return; - } + newset = calloc(num_types, sizeof(Ecore_X_Atom)); + if (!newset) return; - newset = data; + data = (unsigned char *)newset; for (i = 0; i < num_types; i++) { - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], NULL); - if (reply) - { - newset[i] = reply->atom; - free(reply); - } - else - newset[i] = XCB_NONE; + newset[i] = ecore_x_atom_get(types[i]); + ecore_x_selection_converter_atom_add(newset[i], + _ecore_xcb_dnd_converter_copy); } - free(cookies); - ecore_x_window_prop_property_set(window, ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, 32, data, num_types); - free(data); + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, data, + num_types); + free(newset); } -} /* ecore_x_dnd_types_set */ +} -Ecore_X_DND_Source * -_ecore_x_dnd_source_get(void) +EAPI void +ecore_x_dnd_actions_set(Ecore_X_Window win, Ecore_X_Atom *actions, unsigned int num_actions) { - return _source; -} /* _ecore_x_dnd_source_get */ + unsigned int i; + unsigned char *data = NULL; -Ecore_X_DND_Target * -_ecore_x_dnd_target_get(void) -{ - return _target; -} /* _ecore_x_dnd_target_get */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!num_actions) + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_ACTION_LIST); + else + { + data = (unsigned char *)actions; + for (i = 0; i < num_actions; i++) + ecore_x_selection_converter_atom_add(actions[i], + _ecore_xcb_dnd_converter_copy); + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_ACTION_LIST, + ECORE_X_ATOM_ATOM, 32, data, + num_actions); + } +} /** - * Sends the GetProperty request. - * @param source Window whose properties are requested. + * The DND position update cb is called Ecore_X sends a DND position to a + * client. + * + * It essentially mirrors some of the data sent in the position message. + * Generally this cb should be set just before position update is called. + * Please note well you need to look after your own data pointer if someone + * trashes you position update cb set. + * + * It is considered good form to clear this when the dnd event finishes. + * + * @param cb Callback to updated each time ecore_x sends a position update. + * @param data User data. */ EAPI void -ecore_x_dnd_begin_prefetch(Ecore_X_Window source) +ecore_x_dnd_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *data), const void *data) { - xcb_get_property_cookie_t cookie; + _posupdatecb = cb; + _posupdatedata = (void *)data; +} - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - source ? source : ((xcb_screen_t *)_ecore_xcb_screen)->root, - ECORE_X_ATOM_XDND_AWARE, - ECORE_X_ATOM_ATOM, - 0, LONG_MAX); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_dnd_begin_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_dnd_begin_prefetch(). - */ -EAPI void -ecore_x_dnd_begin_fetch(void) +EAPI Eina_Bool +ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_dnd_begin_fetch */ + if (!ecore_x_dnd_version_get(source)) return EINA_FALSE; -/* FIXME: round trip */ + /* Take ownership of XdndSelection */ + if (!ecore_x_selection_xdnd_set(source, data, size)) return EINA_FALSE; -/** - * Begins the DnD. - * @param source Unused. - * @param data The data. - * @param size The size of the data. - * @return 0 on failure, 1 otherwise. - * - * Begins the DnD. Returns 0 on failure, 1 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_dnd_begin_prefetch(), which sends the GetProperty request, - * then ecore_x_dnd_begin_fetch(), which gets the reply. - */ -EAPI Eina_Bool -ecore_x_dnd_begin(Ecore_X_Window source, - unsigned char *data, - int size) -{ - ecore_x_selection_xdnd_prefetch(); - if (!ecore_x_dnd_version_get(source)) + if (_version_cache) { - ecore_x_selection_xdnd_fetch(); - return 0; + free(_version_cache); + _version_cache = NULL; + _version_cache_num = 0; + _version_cache_alloc = 0; } - /* Take ownership of XdndSelection */ - ecore_x_selection_xdnd_prefetch(); - ecore_x_selection_xdnd_fetch(); - if (!ecore_x_selection_xdnd_set(source, data, size)) - return 0; + ecore_x_window_shadow_tree_flush(); _source->win = source; ecore_x_window_ignore_set(_source->win, 1); _source->state = ECORE_X_DND_SOURCE_DRAGGING; - _source->time = _ecore_xcb_event_last_time; + _source->time = _ecore_xcb_events_last_time_get(); _source->prev.window = 0; - /* Default Accepted Action: ask */ - _source->action = ECORE_X_ATOM_XDND_ACTION_COPY; + /* Default Accepted Action: move */ + _source->action = ECORE_X_ATOM_XDND_ACTION_MOVE; _source->accepted_action = XCB_NONE; - return 1; -} /* ecore_x_dnd_begin */ - -EAPI Eina_Bool -ecore_x_dnd_drop(void) -{ - uint8_t status = 0; - - if (_source->dest) - { - xcb_client_message_event_t ev; - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = _source->dest; - - if (_source->will_accept) - { - ev.type = ECORE_X_ATOM_XDND_DROP; - ev.data.data32[0] = _source->win; - ev.data.data32[1] = 0; - ev.data.data32[2] = _source->time; - xcb_send_event(_ecore_xcb_conn, 0, _source->dest, 0, (const char *)&ev); - _source->state = ECORE_X_DND_SOURCE_DROPPED; - status = 1; - } - else - { - ev.type = ECORE_X_ATOM_XDND_LEAVE; - ev.data.data32[0] = _source->win; - ev.data.data32[1] = 0; - xcb_send_event(_ecore_xcb_conn, 0, _source->dest, 0, (const char *)&ev); - _source->state = ECORE_X_DND_SOURCE_IDLE; - } - } - else - { - /* Dropping on nothing */ - ecore_x_selection_xdnd_clear(); - _source->state = ECORE_X_DND_SOURCE_IDLE; - } - - ecore_x_window_ignore_set(_source->win, 0); - - _source->prev.window = 0; _source->dest = XCB_NONE; - return status; -} /* ecore_x_dnd_drop */ + return EINA_TRUE; +} -EAPI void -ecore_x_dnd_send_status(Eina_Bool will_accept, - Eina_Bool suppress, - Ecore_X_Rectangle rectangle, - Ecore_X_Atom action) +EAPI void +ecore_x_dnd_send_finished(void) { xcb_client_message_event_t ev; - if (_target->state == ECORE_X_DND_TARGET_IDLE) - return; - - _target->will_accept = will_accept; - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = _target->source; - ev.type = ECORE_X_ATOM_XDND_STATUS; - - ev.data.data32[0] = _target->win; - ev.data.data32[1] = 0; - if (will_accept) - ev.data.data32[1] |= 0x1UL; - - if (!suppress) - ev.data.data32[1] |= 0x2UL; - - /* Set rectangle information */ - ev.data.data32[2] = rectangle.x; - ev.data.data32[2] <<= 16; - ev.data.data32[2] |= rectangle.y; - ev.data.data32[3] = rectangle.width; - ev.data.data32[3] <<= 16; - ev.data.data32[3] |= rectangle.height; - - if (will_accept) - { - ev.data.data32[4] = action; - _target->accepted_action = action; - } - else - { - ev.data.data32[4] = XCB_NONE; - _target->accepted_action = action; - } - - xcb_send_event(_ecore_xcb_conn, 0, _target->source, 0, (const char *)&ev); -} /* ecore_x_dnd_send_status */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -EAPI void -ecore_x_dnd_send_finished(void) -{ - xcb_client_message_event_t ev; + if (_target->state == ECORE_X_DND_TARGET_IDLE) return; - if (_target->state == ECORE_X_DND_TARGET_IDLE) - return; + memset(&ev, 0, sizeof(xcb_client_message_event_t)); ev.response_type = XCB_CLIENT_MESSAGE; ev.format = 32; - ev.window = _target->source; ev.type = ECORE_X_ATOM_XDND_FINISHED; - + ev.window = _target->source; ev.data.data32[0] = _target->win; ev.data.data32[1] = 0; ev.data.data32[2] = 0; - if (_target->will_accept) + if (_target->will_accept) { ev.data.data32[1] |= 0x1UL; ev.data.data32[2] = _target->accepted_action; } - xcb_send_event(_ecore_xcb_conn, 0, _target->source, 0, (const char *)&ev); - + xcb_send_event(_ecore_xcb_conn, 0, _target->source, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); _target->state = ECORE_X_DND_TARGET_IDLE; -} /* ecore_x_dnd_send_finished */ +} -void -ecore_x_dnd_source_action_set(Ecore_X_Atom action) +EAPI void +ecore_x_dnd_source_action_set(Ecore_X_Atom action) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + _source->action = action; if (_source->prev.window) - _ecore_x_dnd_drag(_source->prev.window, _source->prev.x, _source->prev.y); -} /* ecore_x_dnd_source_action_set */ + _ecore_xcb_dnd_drag(_source->prev.window, + _source->prev.x, _source->prev.y); +} -Ecore_X_Atom -ecore_x_dnd_source_action_get(void) +Ecore_X_DND_Source * +_ecore_xcb_dnd_source_get(void) { - return _source->action; -} /* ecore_x_dnd_source_action_get */ + return _source; +} + +Ecore_X_DND_Target * +_ecore_xcb_dnd_target_get(void) +{ + return _target; +} -void -_ecore_x_dnd_drag(Ecore_X_Window root, - int x, - int y) +void +_ecore_xcb_dnd_drag(Ecore_X_Window root, int x, int y) { xcb_client_message_event_t ev; - Ecore_X_Window win; - Ecore_X_Window *skip; - int num; + Ecore_X_Window win, *skip; + Ecore_X_Xdnd_Position pos; + int num = 0; + + if (_source->state != ECORE_X_DND_SOURCE_DRAGGING) return; - if (_source->state != ECORE_X_DND_SOURCE_DRAGGING) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); ev.response_type = XCB_CLIENT_MESSAGE; ev.format = 32; - /* Attempt to find a DND-capable window under the cursor */ skip = ecore_x_window_ignore_list(&num); -// win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num); win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num); - while (win) - { - xcb_query_tree_cookie_t cookie_tree; - xcb_query_tree_reply_t *reply_tree; + while ((win) && !(ecore_x_dnd_version_get(win))) + win = ecore_x_window_shadow_parent_get(root, win); - ecore_x_dnd_version_get_prefetch(win); - cookie_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, win); - - ecore_x_dnd_version_get_fetch(); - /* We found the correct window ? */ - if (ecore_x_dnd_version_get(win)) - { - reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL); - if (reply_tree) - free(reply_tree); - - break; - } - - reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL); - if (reply_tree) - { - win = reply_tree->parent; - free(reply_tree); - } - } - - /* Send XdndLeave to current destination window if we have left it */ - if ((_source->dest) && (win != _source->dest)) + if ((_source->dest) && (win != _source->dest)) { ev.window = _source->dest; ev.type = ECORE_X_ATOM_XDND_LEAVE; ev.data.data32[0] = _source->win; ev.data.data32[1] = 0; - xcb_send_event(_ecore_xcb_conn, 0, _source->dest, 0, (const char *)&ev); + xcb_send_event(_ecore_xcb_conn, 0, _source->dest, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); _source->suppress = 0; } - if (win) + if (win) { - int16_t x1; - int16_t x2; - int16_t y1; - int16_t y2; + int x1, x2, y1, y2; - ecore_x_dnd_version_get_prefetch(win); - ecore_x_dnd_type_get_prefetch(_source->win); - - ecore_x_dnd_version_get_fetch(); - if (!ecore_x_dnd_version_get(win)) - { - ecore_x_dnd_type_get_fetch(); - return; - } - - _source->version = MIN(ECORE_X_DND_VERSION, + _source->version = MIN(ECORE_X_DND_VERSION, ecore_x_dnd_version_get(win)); - if (win != _source->dest) + if (win != _source->dest) { + int i = 0; unsigned char *data; Ecore_X_Atom *types; - int num; - int i; - - ecore_x_dnd_type_get_fetch(); - if (!ecore_x_window_prop_property_get(_source->win, - ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, - 32, &data, &num)) - return; + ecore_x_window_prop_property_get(_source->win, + ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, + &data, &num); types = (Ecore_X_Atom *)data; - - /* Entered new window, send XdndEnter */ ev.window = win; ev.type = ECORE_X_ATOM_XDND_ENTER; ev.data.data32[0] = _source->win; ev.data.data32[1] = 0; if (num > 3) - ev.data.data32[1] |= 0x1UL; + ev.data.data32[1] |= 0x1UL; else - ev.data.data32[1] &= 0xfffffffeUL; - + ev.data.data32[1] &= 0xfffffffeUL; ev.data.data32[1] |= ((unsigned long)_source->version) << 24; for (i = 2; i < 5; i++) - ev.data.data32[i] = 0; + ev.data.data32[i] = 0; for (i = 0; i < MIN(num, 3); ++i) - ev.data.data32[i + 2] = types[i]; + ev.data.data32[i + 2] = types[i]; free(data); - xcb_send_event(_ecore_xcb_conn, 0, win, 0, (const char *)&ev); + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); _source->await_status = 0; _source->will_accept = 0; } - else - ecore_x_dnd_type_get_fetch(); - /* Determine if we're still in the rectangle from the last status */ x1 = _source->rectangle.x; x2 = _source->rectangle.x + _source->rectangle.width; y1 = _source->rectangle.y; y2 = _source->rectangle.y + _source->rectangle.height; - if ((!_source->await_status) || - (!_source->suppress) || - ((x < x1) || (x > x2) || (y < y1) || (y > y2))) + if ((!_source->await_status) || (!_source->suppress) || + ((x < x1) || (x > x2) || (y < y1) || (y > y2))) { ev.window = win; ev.type = ECORE_X_ATOM_XDND_POSITION; ev.data.data32[0] = _source->win; - ev.data.data32[1] = 0; /* Reserved */ + ev.data.data32[1] = 0; ev.data.data32[2] = ((x << 16) & 0xffff0000) | (y & 0xffff); - ev.data.data32[3] = _source->time; /* Version 1 */ - ev.data.data32[4] = _source->action; /* Version 2, Needs to be pre-set */ - xcb_send_event(_ecore_xcb_conn, 0, win, 0, (const char *)&ev); + ev.data.data32[3] = _source->time; + ev.data.data32[4] = _source->action; + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); _source->await_status = 1; } } + if (_posupdatecb) + { + pos.position.x = x; + pos.position.y = y; + pos.win = win; + pos.prev = _source->dest; + _posupdatecb(_posupdatedata, &pos); + } + _source->prev.x = x; _source->prev.y = y; _source->prev.window = root; _source->dest = win; -} /* _ecore_x_dnd_drag */ +} + +EAPI Ecore_X_Atom +ecore_x_dnd_source_action_get(void) +{ + return _source->action; +} + +/* local functions */ +static Eina_Bool +_ecore_xcb_dnd_converter_copy(char *target __UNUSED__, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *tprop __UNUSED__, int *count __UNUSED__) +{ + Ecore_Xcb_Textproperty text_prop; + Ecore_Xcb_Encoding_Style style = XcbTextStyle; + char *mystr; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if ((!data) || (!size)) return EINA_FALSE; + + mystr = calloc(1, size + 1); + if (!mystr) return EINA_FALSE; + + memcpy(mystr, data, size); + if (_ecore_xcb_mb_textlist_to_textproperty(&mystr, 1, style, &text_prop)) + { + int len; + + len = strlen((char *)text_prop.value) + 1; + if (!(*data_ret = malloc(len))) + { + free(mystr); + return EINA_FALSE; + } + memcpy(*data_ret, text_prop.value, len); + *size_ret = len; + free(text_prop.value); + free(mystr); + return EINA_TRUE; + } + else + { + free(mystr); + return EINA_FALSE; + } +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_dpms.c b/src/lib/ecore_x/xcb/ecore_xcb_dpms.c index 1bc0f49..2cf45b7 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_dpms.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_dpms.c @@ -1,450 +1,307 @@ #include "ecore_xcb_private.h" +#ifdef ECORE_XCB_DAMAGE +# include +#endif -/** - * @defgroup Ecore_X_DPMS_Group X DPMS Extension Functions - * - * Functions related to the X DPMS extension. - */ +/* local variables */ +static Eina_Bool _dpms_avail = EINA_FALSE; -#ifdef ECORE_XCB_DPMS -static int _dpms_available = 0; -static xcb_dpms_get_version_cookie_t _ecore_xcb_dpms_init_cookie; -#endif /* ECORE_XCB_DPMS */ - -/* To avoid round trips, the initialization is separated in 2 - functions: _ecore_xcb_dpms_init and - _ecore_xcb_dpms_init_finalize. The first one gets the cookies and - the second one gets the replies. */ - -void -_ecore_x_dpms_init(const xcb_query_extension_reply_t *reply) +void +_ecore_xcb_dpms_init(void) { -#ifdef ECORE_XCB_DPMS - if (reply && (reply->present)) - _ecore_xcb_dpms_init_cookie = xcb_dpms_get_version_unchecked(_ecore_xcb_conn, 0, 0); + LOGFN(__FILE__, __LINE__, __FUNCTION__); -#endif /* ECORE_XCB_DPMS */ -} /* _ecore_x_dpms_init */ +#ifdef ECORE_XCB_DPMS + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_dpms_id); +#endif +} -void -_ecore_x_dpms_init_finalize(void) +void +_ecore_xcb_dpms_finalize(void) { #ifdef ECORE_XCB_DPMS - xcb_dpms_get_version_reply_t *reply; + const xcb_query_extension_reply_t *ext_reply; +#endif - reply = xcb_dpms_get_version_reply(_ecore_xcb_conn, - _ecore_xcb_dpms_init_cookie, NULL); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (reply) +#ifdef ECORE_XCB_DPMS + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_dpms_id); + if ((ext_reply) && (ext_reply->present)) { - if (reply->server_major_version >= 1) - _dpms_available = 1; - - free(reply); + xcb_dpms_get_version_cookie_t cookie; + xcb_dpms_get_version_reply_t *reply; + + cookie = + xcb_dpms_get_version_unchecked(_ecore_xcb_conn, + XCB_DPMS_MAJOR_VERSION, + XCB_DPMS_MINOR_VERSION); + reply = xcb_dpms_get_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (reply->server_major_version >= 1) + _dpms_avail = EINA_TRUE; + free(reply); + } } - -#endif /* ECORE_XCB_DPMS */ -} /* _ecore_x_dpms_init_finalize */ +#endif +} /** - * Checks if the DPMS extension is available or not. - * @return @c 1 if the DPMS extension is available, @c 0 otherwise. - * - * Return 1 if the X server supports the DPMS Extension version 1.0, - * 0 otherwise. - * @ingroup Ecore_X_DPMS_Group - */ -EAPI Eina_Bool -ecore_x_dpms_query(void) -{ -#ifdef ECORE_XCB_DPMS - return _dpms_available; -#else /* ifdef ECORE_XCB_DPMS */ - return 0; -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_query */ - -/** - * Sends the DPMSCapable request. - * @ingroup Ecore_X_DPMS_Group + * @defgroup Ecore_X_DPMS_Group X DPMS Extension Functions + * + * Functions related to the X DPMS Extension */ -EAPI void -ecore_x_dpms_capable_get_prefetch(void) -{ -#ifdef ECORE_XCB_DPMS - xcb_dpms_capable_cookie_t cookie; - - cookie = xcb_dpms_capable_unchecked(_ecore_xcb_conn); - _ecore_xcb_cookie_cache(cookie.sequence); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_capable_get_prefetch */ /** - * Gets the reply of the DPMSCapable request sent by ecore_x_dpms_capable_get_prefetch(). + * Checks if the DPMS extension is available or not. + * + * @return @c EINA_TRUE if the DPMS extension is available, + * @c EINA_FALSE otherwise. + * + * Return EINA_TRUE if the X server supports the DPMS Extension version 1.0, + * EINA_FALSE otherwise. + * * @ingroup Ecore_X_DPMS_Group */ -EAPI void -ecore_x_dpms_capable_get_fetch(void) +EAPI Eina_Bool +ecore_x_dpms_query(void) { -#ifdef ECORE_XCB_DPMS - xcb_dpms_capable_cookie_t cookie; - xcb_dpms_capable_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_dpms_capable_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_capable_get_fetch */ + return _dpms_avail; +} /** * Checks if the X server is capable of DPMS. * @return @c 1 if the X server is capable of DPMS, @c 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_dpms_capable_get_prefetch(), which sends the DPMSCapable request, - * then ecore_x_dpms_capable_get_fetch(), which gets the reply. * @ingroup Ecore_X_DPMS_Group */ -EAPI Eina_Bool -ecore_x_dpms_capable_get(void) +EAPI Eina_Bool +ecore_x_dpms_capable_get(void) { - int capable = 0; + int ret = EINA_FALSE; #ifdef ECORE_XCB_DPMS + xcb_dpms_capable_cookie_t cookie; xcb_dpms_capable_reply_t *reply; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - capable = reply->capable; -#endif /* ECORE_XCB_DPMS */ + if (!_dpms_avail) return EINA_FALSE; - return capable; -} /* ecore_x_dpms_capable_get */ - -/** - * Sends the DPMSInfo request. - * @ingroup Ecore_X_DPMS_Group - */ -EAPI void -ecore_x_dpms_enable_get_prefetch(void) -{ #ifdef ECORE_XCB_DPMS - xcb_dpms_info_cookie_t cookie; + cookie = xcb_dpms_capable_unchecked(_ecore_xcb_conn); + reply = xcb_dpms_capable_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = reply->capable; + free(reply); + } +#endif - cookie = xcb_dpms_info_unchecked(_ecore_xcb_conn); - _ecore_xcb_cookie_cache(cookie.sequence); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_enable_get_prefetch */ + return ret; +} /** - * Gets the reply of the DPMSInfo request sent by ecore_x_dpms_enable_get_prefetch(). + * Checks the DPMS state of the display. + * @return @c EINA_TRUE if DPMS is enabled, @c EINA_FALSE otherwise. * @ingroup Ecore_X_DPMS_Group */ -EAPI void -ecore_x_dpms_enable_get_fetch(void) +EAPI Eina_Bool +ecore_x_dpms_enabled_get(void) { + int ret = EINA_FALSE; #ifdef ECORE_XCB_DPMS xcb_dpms_info_cookie_t cookie; xcb_dpms_info_reply_t *reply; +#endif - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_dpms_info_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_enable_get_fetch */ - -/** - * Checks the DPMS state of the display. - * @return @c 1 if DPMS is enabled, @c 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_dpms_enapable_get_prefetch(), which sends the DPMSInfo request, - * then ecore_x_dpms_enapable_get_fetch(), which gets the reply. - * @ingroup Ecore_X_DPMS_Group - */ -EAPI int -ecore_x_dpms_enable_get(void) -{ - int enable = 0; -#ifdef ECORE_XCB_DPMS - xcb_dpms_info_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + if (!_dpms_avail) return EINA_FALSE; - enable = reply->state; -#endif /* ECORE_XCB_DPMS */ +#ifdef ECORE_XCB_DPMS + cookie = xcb_dpms_info_unchecked(_ecore_xcb_conn); + reply = xcb_dpms_info_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + if (reply->state) ret = EINA_TRUE; + free(reply); +#endif - return enable; -} /* ecore_x_dpms_enable_get */ + return ret; +} /** * Sets the DPMS state of the display. * @param enabled @c 0 to disable DPMS characteristics of the server, enable it otherwise. * @ingroup Ecore_X_DPMS_Group */ -EAPI void -ecore_x_dpms_enabled_set(int enabled) +EAPI void +ecore_x_dpms_enabled_set(int enabled) { -#ifdef ECORE_XCB_DPMS - if (enabled) - xcb_dpms_enable(_ecore_xcb_conn); - else - xcb_dpms_disable(_ecore_xcb_conn); + LOGFN(__FILE__, __LINE__, __FUNCTION__); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_enabled_set */ + if (!_dpms_avail) return; + +#ifdef ECORE_XCB_DPMS + if (enabled) + xcb_dpms_enable(_ecore_xcb_conn); + else + xcb_dpms_disable(_ecore_xcb_conn); +#endif +} /** - * Sets the timeouts. The values are in unit of seconds. + * Gets the timeouts. The values are in unit of seconds. * @param standby Amount of time of inactivity before standby mode will be invoked. * @param suspend Amount of time of inactivity before the screen is placed into suspend mode. * @param off Amount of time of inactivity before the monitor is shut off. - * @return Returns always 1. * @ingroup Ecore_X_DPMS_Group */ -EAPI Eina_Bool -ecore_x_dpms_timeouts_set(unsigned int standby, - unsigned int suspend, - unsigned int off) +EAPI void +ecore_x_dpms_timeouts_get(unsigned int *standby, unsigned int *suspend, unsigned int *off) { #ifdef ECORE_XCB_DPMS - xcb_dpms_set_timeouts(_ecore_xcb_conn, standby, suspend, off); -#endif /* ECORE_XCB_DPMS */ + xcb_dpms_get_timeouts_cookie_t cookie; + xcb_dpms_get_timeouts_reply_t *reply; +#endif - return 1; -} /* ecore_x_dpms_timeouts_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Sends the DPMSGetTimeouts request. - * @ingroup Ecore_X_DPMS_Group - */ -EAPI void -ecore_x_dpms_timeouts_get_prefetch(void) -{ -#ifdef ECORE_XCB_DPMS - xcb_dpms_get_timeouts_cookie_t cookie; + if (standby) *standby = 0; + if (suspend) *suspend = 0; + if (off) *off = 0; - cookie = xcb_dpms_get_timeouts_unchecked(_ecore_xcb_conn); - _ecore_xcb_cookie_cache(cookie.sequence); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_timeouts_get_prefetch */ + if (!_dpms_avail) return; -/** - * Gets the reply of the DPMSGetTimeouts request sent by ecore_x_dpms_timeouts_get_prefetch(). - * @ingroup Ecore_X_DPMS_Group - */ -EAPI void -ecore_x_dpms_timeouts_get_fetch(void) -{ #ifdef ECORE_XCB_DPMS - xcb_dpms_get_timeouts_cookie_t cookie; - xcb_dpms_get_timeouts_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); + cookie = xcb_dpms_get_timeouts_unchecked(_ecore_xcb_conn); reply = xcb_dpms_get_timeouts_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_timeouts_get_fetch */ + if (!reply) return; + if (standby) *standby = reply->standby_timeout; + if (suspend) *suspend = reply->suspend_timeout; + if (off) *off = reply->off_timeout; + free(reply); +#endif +} /** - * Gets the timeouts. The values are in unit of seconds. + * Sets the timeouts. The values are in unit of seconds. * @param standby Amount of time of inactivity before standby mode will be invoked. * @param suspend Amount of time of inactivity before the screen is placed into suspend mode. * @param off Amount of time of inactivity before the monitor is shut off. * @ingroup Ecore_X_DPMS_Group */ -EAPI void -ecore_x_dpms_timeouts_get(unsigned int *standby, - unsigned int *suspend, - unsigned int *off) +EAPI Eina_Bool +ecore_x_dpms_timeouts_set(unsigned int standby, unsigned int suspend, unsigned int off) { -#ifdef ECORE_XCB_DPMS - xcb_dpms_get_timeouts_reply_t *reply; - - reply = _ecore_xcb_reply_get(); - if (reply) - { - if (standby) - *standby = reply->standby_timeout; - - if (suspend) - *suspend = reply->suspend_timeout; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (off) - *off = 0; - } - else -#endif /* ECORE_XCB_DPMS */ - { - if (standby) - *standby = 0; + if (!_dpms_avail) return EINA_FALSE; - if (suspend) - *suspend = 0; +#ifdef ECORE_XCB_DPMS + xcb_dpms_set_timeouts(_ecore_xcb_conn, standby, suspend, off); + return EINA_TRUE; +#endif - if (off) - *off = 0; - } -} /* ecore_x_dpms_timeouts_get */ + return EINA_FALSE; +} /** * Returns the amount of time of inactivity before standby mode is invoked. * @return The standby timeout value. - * - * To use this function, you must call before, and in order, - * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request, - * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply. * @ingroup Ecore_X_DPMS_Group */ -EAPI unsigned int -ecore_x_dpms_timeout_standby_get(void) +EAPI unsigned int +ecore_x_dpms_timeout_standby_get(void) { - int standby = 0; -#ifdef ECORE_XCB_DPMS - xcb_dpms_get_timeouts_reply_t *reply; + unsigned int standby = 0; - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; - - standby = reply->standby_timeout; -#endif /* ECORE_XCB_DPMS */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_dpms_timeouts_get(&standby, NULL, NULL); return standby; -} /* ecore_x_dpms_timeout_standby_get */ +} /** * Returns the amount of time of inactivity before the second level of * power saving is invoked. * @return The suspend timeout value. - * - * To use this function, you must call before, and in order, - * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request, - * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply. * @ingroup Ecore_X_DPMS_Group */ -EAPI unsigned int -ecore_x_dpms_timeout_suspend_get(void) +EAPI unsigned int +ecore_x_dpms_timeout_suspend_get(void) { - int suspend = 0; -#ifdef ECORE_XCB_DPMS - xcb_dpms_get_timeouts_reply_t *reply; - - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + unsigned int suspend = 0; - suspend = reply->suspend_timeout; -#endif /* ECORE_XCB_DPMS */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_dpms_timeouts_get(NULL, &suspend, NULL); return suspend; -} /* ecore_x_dpms_timeout_suspend_get */ +} /** * Returns the amount of time of inactivity before the third and final * level of power saving is invoked. * @return The off timeout value. - * - * To use this function, you must call before, and in order, - * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request, - * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply. * @ingroup Ecore_X_DPMS_Group */ -EAPI unsigned int -ecore_x_dpms_timeout_off_get(void) +EAPI unsigned int +ecore_x_dpms_timeout_off_get(void) { - int off = 0; -#ifdef ECORE_XCB_DPMS - xcb_dpms_get_timeouts_reply_t *reply; - - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + unsigned int off = 0; - off = reply->off_timeout; -#endif /* ECORE_XCB_DPMS */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_dpms_timeouts_get(NULL, NULL, &off); return off; -} /* ecore_x_dpms_timeout_off_get */ +} /** * Sets the standby timeout (in unit of seconds). * @param new_standby Amount of time of inactivity before standby mode will be invoked. - * - * To use this function, you must call before, and in order, - * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request, - * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply. * @ingroup Ecore_X_DPMS_Group */ -EAPI void -ecore_x_dpms_timeout_standby_set(unsigned int new_standby) +EAPI void +ecore_x_dpms_timeout_standby_set(unsigned int new_timeout) { -#ifdef ECORE_XCB_DPMS - xcb_dpms_get_timeouts_reply_t *reply; + unsigned int standby = 0, suspend = 0, off = 0; - reply = _ecore_xcb_reply_get(); - if (!reply) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - xcb_dpms_set_timeouts(_ecore_xcb_conn, - new_standby, - reply->suspend_timeout, - reply->off_timeout); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_timeout_standby_set */ + ecore_x_dpms_timeouts_get(&standby, &suspend, &off); + ecore_x_dpms_timeouts_set(new_timeout, suspend, off); +} /** * Sets the suspend timeout (in unit of seconds). * @param suspend Amount of time of inactivity before the screen is placed into suspend mode. - * - * To use this function, you must call before, and in order, - * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request, - * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply. * @ingroup Ecore_X_DPMS_Group */ -EAPI void -ecore_x_dpms_timeout_suspend_set(unsigned int new_suspend) +EAPI void +ecore_x_dpms_timeout_suspend_set(unsigned int new_timeout) { -#ifdef ECORE_XCB_DPMS - xcb_dpms_get_timeouts_reply_t *reply; + unsigned int standby = 0, suspend = 0, off = 0; - reply = _ecore_xcb_reply_get(); - if (!reply) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - xcb_dpms_set_timeouts(_ecore_xcb_conn, - reply->standby_timeout, - new_suspend, - reply->off_timeout); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_timeout_suspend_set */ + ecore_x_dpms_timeouts_get(&standby, &suspend, &off); + ecore_x_dpms_timeouts_set(standby, new_timeout, off); +} /** * Sets the off timeout (in unit of seconds). * @param off Amount of time of inactivity before the monitor is shut off. - * - * To use this function, you must call before, and in order, - * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request, - * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply. * @ingroup Ecore_X_DPMS_Group */ -EAPI void -ecore_x_dpms_timeout_off_set(unsigned int new_off) +EAPI void +ecore_x_dpms_timeout_off_set(unsigned int new_timeout) { -#ifdef ECORE_XCB_DPMS - xcb_dpms_get_timeouts_reply_t *reply; - - reply = _ecore_xcb_reply_get(); - if (!reply) - return; + unsigned int standby = 0, suspend = 0, off = 0; - xcb_dpms_set_timeouts(_ecore_xcb_conn, - reply->standby_timeout, - reply->suspend_timeout, - new_off); -#endif /* ECORE_XCB_DPMS */ -} /* ecore_x_dpms_timeout_off_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_dpms_timeouts_get(&standby, &suspend, &off); + ecore_x_dpms_timeouts_set(standby, suspend, new_timeout); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_drawable.c b/src/lib/ecore_x/xcb/ecore_xcb_drawable.c index 55a55e5..6d8da79 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_drawable.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_drawable.c @@ -1,5 +1,4 @@ #include "ecore_xcb_private.h" -#include /** * @defgroup Ecore_X_Drawable_Group X Drawable Functions @@ -8,149 +7,102 @@ */ /** - * Sends the GetGeometry request. - * @param drawable Drawable whose characteristics are sought. - * @ingroup Ecore_X_Drawable_Group + * Fill the specified rectangle on a drawable. + * @param d The given drawable. + * @param gc The graphic context that controls the fill rules. + * @param x The X coordinate of the top-left corner of the rectangle. + * @param y The Y coordinate of the top-left corner of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. */ -EAPI void -ecore_x_drawable_geometry_get_prefetch(Ecore_X_Drawable drawable) +EAPI void +ecore_x_drawable_rectangle_fill(Ecore_X_Drawable draw, Ecore_X_GC gc, int x, int y, int w, int h) { - xcb_get_geometry_cookie_t cookie; + xcb_rectangle_t rect; - cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, drawable); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_drawable_geometry_get_prefetch */ - -/** - * Gets the reply of the GetGeometry request sent by ecore_x_atom_get_prefetch(). - * @ingroup Ecore_X_Drawable_Group - */ -EAPI void -ecore_x_drawable_geometry_get_fetch(void) -{ - xcb_get_geometry_cookie_t cookie; - xcb_get_geometry_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_drawable_geometry_get_fetch */ + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_poly_fill_rectangle(_ecore_xcb_conn, draw, gc, 1, + (const xcb_rectangle_t *)&rect); +} /** * Retrieves the geometry of the given drawable. - * @param drawable Unused. - * @param x Pointer to an integer into which the X position is to be stored. - * @param y Pointer to an integer into which the Y position is to be stored. - * @param width Pointer to an integer into which the width is to be stored. - * @param height Pointer to an integer into which the height is to be stored. - * - * To use this function, you must call before, and in order, - * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request, - * then ecore_x_drawable_geometry_get_fetch(), which gets the reply. + * @param d The given drawable. + * @param x Pointer to an integer into which the X position is to be stored. + * @param y Pointer to an integer into which the Y position is to be stored. + * @param w Pointer to an integer into which the width is to be stored. + * @param h Pointer to an integer into which the height is to be stored. * @ingroup Ecore_X_Drawable_Group */ -EAPI void -ecore_x_drawable_geometry_get(Ecore_X_Drawable drawable __UNUSED__, - int *x, - int *y, - int *width, - int *height) +EAPI void +ecore_x_drawable_geometry_get(Ecore_X_Drawable draw, int *x, int *y, int *w, int *h) { + xcb_get_geometry_cookie_t cookie; xcb_get_geometry_reply_t *reply; - reply = _ecore_xcb_reply_get(); - if (!reply) - { - if (x) - *x = 0; - - if (y) - *y = 0; - - if (width) - *width = 0; - - if (height) - *height = 0; - - return; - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (x) - *x = reply->x; - - if (y) - *y = reply->y; - - if (width) - *width = reply->width; - - if (height) - *height = reply->height; -} /* ecore_x_drawable_geometry_get */ + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, draw); + reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + if (x) *x = reply->x; + if (y) *y = reply->y; + if (w) *w = (int)reply->width; + if (h) *h = (int)reply->height; + free(reply); +} /** * Retrieves the width of the border of the given drawable. - * @param drawable Unused. - * @return The border width of the given drawable. - * - * To use this function, you must call before, and in order, - * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request, - * then ecore_x_drawable_geometry_get_fetch(), which gets the reply. + * @param d The given drawable. + * @return The border width of the given drawable. * @ingroup Ecore_X_Drawable_Group */ -EAPI int -ecore_x_drawable_border_width_get(Ecore_X_Drawable drawable __UNUSED__) +EAPI int +ecore_x_drawable_border_width_get(Ecore_X_Drawable d) { + xcb_get_geometry_cookie_t cookie; xcb_get_geometry_reply_t *reply; + int ret = 0; - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return reply->border_width; -} /* ecore_x_drawable_border_width_get */ + cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, d); + reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + ret = (int)reply->border_width; + free(reply); + return ret; +} /** * Retrieves the depth of the given drawable. - * @param drawable Unused. - * @return The depth of the given drawable. - * - * To use this function, you must call before, and in order, - * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request, - * then ecore_x_drawable_geometry_get_fetch(), which gets the reply. + * @param d The given drawable. + * @return The depth of the given drawable. * @ingroup Ecore_X_Drawable_Group */ -EAPI int -ecore_x_drawable_depth_get(Ecore_X_Drawable drawable __UNUSED__) +EAPI int +ecore_x_drawable_depth_get(Ecore_X_Drawable d) { + xcb_get_geometry_cookie_t cookie; xcb_get_geometry_reply_t *reply; + int ret = 0; - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; - - return reply->depth; -} /* ecore_x_drawable_depth_get */ - -/** - * Fill the specified rectangle on a drawable. - * @param d The given drawable. - * @param gc The graphic context that controls the fill rules. - * @param x The X coordinate of the top-left corner of the rectangle. - * @param y The Y coordinate of the top-left corner of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. - */ -EAPI void -ecore_x_drawable_rectangle_fill(Ecore_X_Drawable d, Ecore_X_GC gc, int x, int y, int width, int height) -{ - xcb_rectangle_t rectangle; - - rectangle.x = x; - rectangle.y = y; - rectangle.width = width; - rectangle.height = height; - xcb_poly_fill_rectangle(_ecore_xcb_conn, d, gc, 1, &rectangle); -} /* ecore_x_drawable_rectangle_fill */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, d); + reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + ret = (int)reply->depth; + free(reply); + return ret; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_e.c b/src/lib/ecore_x/xcb/ecore_xcb_e.c index c33eb8f..a75bb55 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_e.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_e.c @@ -1,25 +1,1000 @@ -/* - * OLD E hints - */ - #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" -EAPI void -ecore_x_e_frame_size_set(Ecore_X_Window window, - int fl, - int fr, - int ft, - int fb) +/* local function prototypes */ +static Ecore_X_Atom _ecore_xcb_e_vkbd_atom_get(Ecore_X_Virtual_Keyboard_State state); +static Ecore_X_Virtual_Keyboard_State _ecore_xcb_e_vkbd_state_get(Ecore_X_Atom atom); +static Ecore_X_Atom _ecore_xcb_e_quickpanel_atom_get(Ecore_X_Illume_Quickpanel_State state); +static Ecore_X_Illume_Quickpanel_State _ecore_xcb_e_quickpanel_state_get(Ecore_X_Atom atom); +static Ecore_X_Atom _ecore_xcb_e_illume_atom_get(Ecore_X_Illume_Mode mode); +static Ecore_X_Illume_Mode _ecore_xcb_e_illume_mode_get(Ecore_X_Atom atom); + +EAPI void +ecore_x_e_init(void) +{ + +} + +EAPI void +ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window root, Ecore_X_Window win) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE; + ev.data.data32[0] = win; + ev.data.data32[1] = 0; + ev.data.data32[2] = 0; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +} + +EAPI void +ecore_x_e_comp_sync_draw_size_done_send(Ecore_X_Window root, Ecore_X_Window win, int w, int h) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE; + ev.data.data32[0] = win; + ev.data.data32[1] = 1; + ev.data.data32[2] = w; + ev.data.data32[3] = h; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +} + +EAPI void +ecore_x_e_comp_sync_counter_set(Ecore_X_Window win, Ecore_X_Sync_Counter counter) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (counter) + ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_COMP_SYNC_COUNTER, + ECORE_X_ATOM_CARDINAL, &counter, 1); + else + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_COMP_SYNC_COUNTER); +} + +EAPI Ecore_X_Sync_Counter +ecore_x_e_comp_sync_counter_get(Ecore_X_Window win) +{ + Ecore_X_Sync_Counter counter = 0; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ret = ecore_x_window_prop_xid_get(win, ECORE_X_ATOM_E_COMP_SYNC_COUNTER, + ECORE_X_ATOM_CARDINAL, &counter, 1); + if (ret != 1) return 0; + return counter; +} + +EAPI Eina_Bool +ecore_x_e_comp_sync_supported_get(Ecore_X_Window root) +{ + Ecore_X_Window win, win2; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + ret = + ecore_x_window_prop_xid_get(root, ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + if ((ret == 1) && (win)) + { + ret = + ecore_x_window_prop_xid_get(win, ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win2, 1); + if ((ret == 1) && (win2 == win)) + return EINA_TRUE; + } + return EINA_FALSE; +} + +EAPI void +ecore_x_e_comp_sync_supported_set(Ecore_X_Window root, Eina_Bool enabled) +{ + Ecore_X_Window win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + if (enabled) + { + win = ecore_x_window_new(root, 1, 2, 3, 4); + ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + ecore_x_window_prop_xid_set(root, ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + } + else + { + int ret = 0; + + ret = ecore_x_window_prop_xid_get(root, + ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + if ((ret == 1) && (win)) + { + ecore_x_window_prop_property_del(root, + ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED); + ecore_x_window_free(win); + } + } +} + +EAPI void +ecore_x_e_comp_sync_begin_send(Ecore_X_Window win) +{ +// xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_COMP_SYNC_BEGIN, + XCB_EVENT_MASK_NO_EVENT, win, 0, 0, 0, 0); + + /* memset(&ev, 0, sizeof(xcb_client_message_event_t)); */ + + /* ev.response_type = XCB_CLIENT_MESSAGE; */ + /* ev.format = 32; */ + /* ev.window = win; */ + /* ev.type = ECORE_X_ATOM_E_COMP_SYNC_BEGIN; */ + /* ev.data.data32[0] = win; */ + /* ev.data.data32[1] = 0; */ + /* ev.data.data32[2] = 0; */ + /* ev.data.data32[3] = 0; */ + /* ev.data.data32[4] = 0; */ + + /* xcb_send_event(_ecore_xcb_conn, 0, win, */ + /* XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); */ +} + +EAPI void +ecore_x_e_comp_sync_end_send(Ecore_X_Window win) +{ +// xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_COMP_SYNC_END, + XCB_EVENT_MASK_NO_EVENT, win, 0, 0, 0, 0); + + /* memset(&ev, 0, sizeof(xcb_client_message_event_t)); */ + + /* ev.response_type = XCB_CLIENT_MESSAGE; */ + /* ev.format = 32; */ + /* ev.window = win; */ + /* ev.type = ECORE_X_ATOM_E_COMP_SYNC_END; */ + /* ev.data.data32[0] = win; */ + /* ev.data.data32[1] = 0; */ + /* ev.data.data32[2] = 0; */ + /* ev.data.data32[3] = 0; */ + /* ev.data.data32[4] = 0; */ + + /* xcb_send_event(_ecore_xcb_conn, 0, win, */ + /* XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); */ +} + +EAPI void +ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win) +{ +// xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_COMP_SYNC_CANCEL, + XCB_EVENT_MASK_NO_EVENT, win, 0, 0, 0, 0); + + /* memset(&ev, 0, sizeof(xcb_client_message_event_t)); */ + + /* ev.response_type = XCB_CLIENT_MESSAGE; */ + /* ev.format = 32; */ + /* ev.window = win; */ + /* ev.type = ECORE_X_ATOM_E_COMP_SYNC_CANCEL; */ + /* ev.data.data32[0] = win; */ + /* ev.data.data32[1] = 0; */ + /* ev.data.data32[2] = 0; */ + /* ev.data.data32[3] = 0; */ + /* ev.data.data32[4] = 0; */ + + /* xcb_send_event(_ecore_xcb_conn, 0, win, */ + /* XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); */ +} + +EAPI void +ecore_x_e_comp_flush_send(Ecore_X_Window win) +{ +// xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_COMP_FLUSH, + XCB_EVENT_MASK_NO_EVENT, win, 0, 0, 0, 0); + + /* memset(&ev, 0, sizeof(xcb_client_message_event_t)); */ + + /* ev.response_type = XCB_CLIENT_MESSAGE; */ + /* ev.format = 32; */ + /* ev.window = win; */ + /* ev.type = ECORE_X_ATOM_E_COMP_FLUSH; */ + /* ev.data.data32[0] = win; */ + /* ev.data.data32[1] = 0; */ + /* ev.data.data32[2] = 0; */ + /* ev.data.data32[3] = 0; */ + /* ev.data.data32[4] = 0; */ + + /* xcb_send_event(_ecore_xcb_conn, 0, win, */ + /* XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); */ +} + +EAPI void +ecore_x_e_comp_dump_send(Ecore_X_Window win) +{ +// xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_COMP_DUMP, + XCB_EVENT_MASK_NO_EVENT, win, 0, 0, 0, 0); + + /* memset(&ev, 0, sizeof(xcb_client_message_event_t)); */ + + /* ev.response_type = XCB_CLIENT_MESSAGE; */ + /* ev.format = 32; */ + /* ev.window = win; */ + /* ev.type = ECORE_X_ATOM_E_COMP_DUMP; */ + /* ev.data.data32[0] = win; */ + /* ev.data.data32[1] = 0; */ + /* ev.data.data32[2] = 0; */ + /* ev.data.data32[3] = 0; */ + /* ev.data.data32[4] = 0; */ + + /* xcb_send_event(_ecore_xcb_conn, 0, win, */ + /* XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); */ +} + +EAPI void +ecore_x_e_comp_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pixmap) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (pixmap) + ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_COMP_PIXMAP, + ECORE_X_ATOM_PIXMAP, &pixmap, 1); + else + ecore_x_window_prop_property_del(win, pixmap); +} + +EAPI Ecore_X_Pixmap +ecore_x_e_comp_pixmap_get(Ecore_X_Window win) +{ + Ecore_X_Pixmap pixmap = 0; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ret = ecore_x_window_prop_xid_get(win, ECORE_X_ATOM_E_COMP_PIXMAP, + ECORE_X_ATOM_PIXMAP, &pixmap, 1); + if (ret != 1) return 0; + return pixmap; +} + +EAPI void +ecore_x_e_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb) { uint32_t frames[4]; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + frames[0] = fl; frames[1] = fr; frames[2] = ft; frames[3] = fb; - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_E_FRAME_SIZE, ECORE_X_ATOM_CARDINAL, 32, - 4, (const void *)frames); -} /* ecore_x_e_frame_size_set */ + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_FRAME_SIZE, frames, 4); +} + +EAPI Ecore_X_Virtual_Keyboard_State +ecore_x_e_virtual_keyboard_state_get(Ecore_X_Window win) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_atom_get(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE, + &atom, 1)) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN; + + return _ecore_xcb_e_vkbd_state_get(atom); +} + +EAPI void +ecore_x_e_virtual_keyboard_state_set(Ecore_X_Window win, Ecore_X_Virtual_Keyboard_State state) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + atom = _ecore_xcb_e_vkbd_atom_get(state); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE, + &atom, 1); +} + +EAPI void +ecore_x_e_virtual_keyboard_state_send(Ecore_X_Window win, Ecore_X_Virtual_Keyboard_State state) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_xcb_e_vkbd_atom_get(state), + 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_virtual_keyboard_set(Ecore_X_Window win, unsigned int is_keyboard) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD, + &is_keyboard, 1); +} + +EAPI Eina_Bool +ecore_x_e_virtual_keyboard_get(Ecore_X_Window win) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD, + &val, 1)) + return EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +EAPI int +ecore_x_e_illume_quickpanel_priority_major_get(Ecore_X_Window win) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR, + &val, 1)) + return 0; + + return val; +} + +EAPI void +ecore_x_e_illume_quickpanel_priority_major_set(Ecore_X_Window win, unsigned int priority) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_card32_set(win, + ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR, + &priority, 1); +} + +EAPI int +ecore_x_e_illume_quickpanel_priority_minor_get(Ecore_X_Window win) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR, + &val, 1)) + return 0; + + return val; +} + +EAPI void +ecore_x_e_illume_quickpanel_priority_minor_set(Ecore_X_Window win, unsigned int priority) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_card32_set(win, + ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR, + &priority, 1); +} + +EAPI void +ecore_x_e_illume_quickpanel_zone_set(Ecore_X_Window win, unsigned int zone) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE, + &zone, 1); +} + +EAPI int +ecore_x_e_illume_quickpanel_zone_get(Ecore_X_Window win) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE, + &val, 1)) + return 0; + + return val; +} + +EAPI void +ecore_x_e_illume_quickpanel_position_update_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, + ECORE_X_ATOM_E_ILLUME_QUICKPANEL_POSITION_UPDATE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 1, 0, 0, 0, 0); +} + +EAPI Eina_Bool +ecore_x_e_illume_conformant_get(Ecore_X_Window win) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_CONFORMANT, + &val, 1)) + return EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_x_e_illume_conformant_set(Ecore_X_Window win, unsigned int is_conformant) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_CONFORMANT, + &is_conformant, 1); +} + +EAPI void +ecore_x_e_illume_softkey_geometry_set(Ecore_X_Window win, int x, int y, int w, int h) +{ + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + geom[0] = x; + geom[1] = y; + geom[2] = w; + geom[3] = h; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY, + geom, 4); +} + +EAPI Eina_Bool +ecore_x_e_illume_softkey_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h) +{ + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + + if (ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY, + geom, 4) != 4) + return EINA_FALSE; + + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +EAPI void +ecore_x_e_illume_indicator_geometry_set(Ecore_X_Window win, int x, int y, int w, int h) +{ + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + geom[0] = x; + geom[1] = y; + geom[2] = w; + geom[3] = h; + ecore_x_window_prop_card32_set(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY, + geom, 4); +} + +EAPI Eina_Bool +ecore_x_e_illume_indicator_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h) +{ + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + + if (ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY, + geom, 4) != 4) + return EINA_FALSE; + + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +EAPI void +ecore_x_e_illume_keyboard_geometry_set(Ecore_X_Window win, int x, int y, int w, int h) +{ + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + geom[0] = x; + geom[1] = y; + geom[2] = w; + geom[3] = h; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY, + geom, 4); +} + +EAPI Eina_Bool +ecore_x_e_illume_keyboard_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h) +{ + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + + if (ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY, + geom, 4) != 4) + return EINA_FALSE; + + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +EAPI void +ecore_x_e_illume_quickpanel_set(Ecore_X_Window win, unsigned int is_quickpanel) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL, + &is_quickpanel, 1); +} + +EAPI Eina_Bool +ecore_x_e_illume_quickpanel_get(Ecore_X_Window win) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL, + &val, 1)) + return EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_x_e_illume_quickpanel_state_set(Ecore_X_Window win, Ecore_X_Illume_Quickpanel_State state) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + atom = _ecore_xcb_e_quickpanel_atom_get(state); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Quickpanel_State +ecore_x_e_illume_quickpanel_state_get(Ecore_X_Window win) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_atom_get(win, + ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE, + &atom, 1)) + return ECORE_X_ILLUME_QUICKPANEL_STATE_UNKNOWN; + + return _ecore_xcb_e_quickpanel_state_get(atom); +} + +EAPI void +ecore_x_e_illume_quickpanel_state_send(Ecore_X_Window win, Ecore_X_Illume_Quickpanel_State state) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_xcb_e_quickpanel_atom_get(state), + 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_quickpanel_state_toggle(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, + ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE_TOGGLE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 0, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_mode_set(Ecore_X_Window win, Ecore_X_Illume_Mode mode) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + atom = _ecore_xcb_e_illume_atom_get(mode); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_MODE, &atom, 1); +} + +EAPI Ecore_X_Illume_Mode +ecore_x_e_illume_mode_get(Ecore_X_Window win) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_atom_get(win, ECORE_X_ATOM_E_ILLUME_MODE, &atom, 1)) + return ECORE_X_ILLUME_MODE_UNKNOWN; + + return _ecore_xcb_e_illume_mode_get(atom); +} + +EAPI void +ecore_x_e_illume_mode_send(Ecore_X_Window win, Ecore_X_Illume_Mode mode) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_MODE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_xcb_e_illume_atom_get(mode), + 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_focus_back_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_FOCUS_BACK, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 1, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_focus_forward_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 1, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_focus_home_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_FOCUS_HOME, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 1, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_close_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_CLOSE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 1, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_home_new_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_HOME_NEW, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 1, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_home_del_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_HOME_DEL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 1, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_drag_set(Ecore_X_Window win, unsigned int drag) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_DRAG, &drag, 1); +} + +EAPI void +ecore_x_e_illume_drag_locked_set(Ecore_X_Window win, unsigned int is_locked) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED, + &is_locked, 1); +} + +EAPI Eina_Bool +ecore_x_e_illume_drag_locked_get(Ecore_X_Window win) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED, + &val, 1)) + return EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_e_illume_drag_get(Ecore_X_Window win) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_DRAG, &val, 1)) + return EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_x_e_illume_drag_start_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_DRAG_START, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 1, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_drag_end_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_DRAG_END, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + 1, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_zone_set(Ecore_X_Window win, Ecore_X_Window zone) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_window_set(win, ECORE_X_ATOM_E_ILLUME_ZONE, &zone, 1); +} + +EAPI Ecore_X_Window +ecore_x_e_illume_zone_get(Ecore_X_Window win) +{ + Ecore_X_Window zone; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_window_get(win, ECORE_X_ATOM_E_ILLUME_ZONE, + &zone, 1)) + return 0; + + return zone; +} + +EAPI void +ecore_x_e_illume_zone_list_set(Ecore_X_Window win, Ecore_X_Window *zones, unsigned int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_window_set(win, ECORE_X_ATOM_E_ILLUME_ZONE_LIST, + zones, num); +} + +/* local functions */ +static Ecore_X_Atom +_ecore_xcb_e_vkbd_atom_get(Ecore_X_Virtual_Keyboard_State state) +{ + switch (state) + { + case ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_ON: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_IP: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_HOST: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_FILE: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_URL: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_KEYPAD: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD; + case ECORE_X_VIRTUAL_KEYBOARD_STATE_J2ME: + return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME; + default: + break; + } + return 0; +} + +static Ecore_X_Virtual_Keyboard_State +_ecore_xcb_e_vkbd_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_ON; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_IP; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_HOST; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_FILE; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_URL; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_KEYPAD; + if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_J2ME; + + return ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN; +} + +static Ecore_X_Atom +_ecore_xcb_e_quickpanel_atom_get(Ecore_X_Illume_Quickpanel_State state) +{ + switch (state) + { + case ECORE_X_ILLUME_QUICKPANEL_STATE_ON: + return ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON; + case ECORE_X_ILLUME_QUICKPANEL_STATE_OFF: + return ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF; + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Quickpanel_State +_ecore_xcb_e_quickpanel_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON) + return ECORE_X_ILLUME_QUICKPANEL_STATE_ON; + if (atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF) + return ECORE_X_ILLUME_QUICKPANEL_STATE_OFF; + + return ECORE_X_ILLUME_QUICKPANEL_STATE_UNKNOWN; +} + +static Ecore_X_Atom +_ecore_xcb_e_illume_atom_get(Ecore_X_Illume_Mode mode) +{ + switch (mode) + { + case ECORE_X_ILLUME_MODE_SINGLE: + return ECORE_X_ATOM_E_ILLUME_MODE_SINGLE; + case ECORE_X_ILLUME_MODE_DUAL_TOP: + return ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP; + case ECORE_X_ILLUME_MODE_DUAL_LEFT: + return ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT; + default: + break; + } + return ECORE_X_ILLUME_MODE_UNKNOWN; +} + +static Ecore_X_Illume_Mode +_ecore_xcb_e_illume_mode_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_MODE_SINGLE) + return ECORE_X_ILLUME_MODE_SINGLE; + if (atom == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP) + return ECORE_X_ILLUME_MODE_DUAL_TOP; + if (atom == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT) + return ECORE_X_ILLUME_MODE_DUAL_LEFT; + return ECORE_X_ILLUME_MODE_UNKNOWN; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_error.c b/src/lib/ecore_x/xcb/ecore_xcb_error.c new file mode 100644 index 0000000..c58c13c --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_error.c @@ -0,0 +1,95 @@ +#include "ecore_xcb_private.h" +#include + +/* local variables */ +static void (*_error_func)(void *data) = NULL; +static void *_error_data = NULL; +static void (*_io_error_func)(void *data) = NULL; +static void *_io_error_data = NULL; +static int _error_request_code = 0; +static int _error_code = 0; + +/** + * Set the error handler. + * @param func The error handler function + * @param data The data to be passed to the handler function + * + * Set the X error handler function + */ +EAPI void +ecore_x_error_handler_set(void (*func)(void *data), const void *data) +{ + _error_func = func; + _error_data = (void *)data; +} + +/** + * Set the I/O error handler. + * @param func The I/O error handler function + * @param data The data to be passed to the handler function + * + * Set the X I/O error handler function + */ +EAPI void +ecore_x_io_error_handler_set(void (*func)(void *data), const void *data) +{ + _io_error_func = func; + _io_error_data = (void *)data; +} + +/** + * Get the request code that caused the error. + * @return The request code causing the X error + * + * Return the X request code that caused the last X error + */ +EAPI int +ecore_x_error_request_get(void) +{ + return _error_request_code; +} + +/** + * Get the error code from the error. + * @return The error code from the X error + * + * Return the error code from the last X error + */ +EAPI int +ecore_x_error_code_get(void) +{ + return _error_code; +} + +int +_ecore_xcb_error_handle(xcb_generic_error_t *err) +{ + WRN("Got Error:"); + WRN("\tEvent: %s", xcb_event_get_request_label(err->major_code)); + WRN("\tError: %s", xcb_event_get_error_label(err->error_code)); + if (err->error_code == XCB_EVENT_ERROR_BAD_VALUE) + WRN("\tBad Value: %d", ((xcb_value_error_t *)err)->bad_value); + else if (err->error_code == XCB_EVENT_ERROR_BAD_WINDOW) + WRN("\tBad Window: %d", ((xcb_window_error_t *)err)->bad_value); + + _error_request_code = err->sequence; + _error_code = err->error_code; + if (_error_func) + _error_func(_error_data); + + return 0; +} + +int +_ecore_xcb_io_error_handle(xcb_generic_error_t *err) +{ + CRIT("IO Error:"); + CRIT("\tRequest: %d", err->sequence); + CRIT("\tCode: %d", err->error_code); + if (_io_error_func) + _io_error_func(_io_error_data); + else + exit(-1); + + return 0; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_events.c b/src/lib/ecore_x/xcb/ecore_xcb_events.c index 0f39591..f84e893 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_events.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_events.c @@ -1,962 +1,843 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include -#include -#include - -#include -#include - #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" - -/** OpenBSD does not define CODESET - * FIXME ?? - */ +//#include "Ecore_X_Atoms.h" +#include +#include +#include +# ifdef ECORE_XCB_DAMAGE +# include +# endif +# ifdef ECORE_XCB_RANDR +# include +# endif +# ifdef ECORE_XCB_SCREENSAVER +# include +# endif +# ifdef ECORE_XCB_SYNC +# include +# endif +# ifdef ECORE_XCB_XFIXES +# include +# endif #ifndef CODESET -#define CODESET "INVALID" -#endif /* ifndef CODESET */ - -static Ecore_X_Window _ecore_xcb_mouse_down_last_window = 0; -static Ecore_X_Window _ecore_xcb_mouse_down_last_last_window = 0; -static Ecore_X_Window _ecore_xcb_mouse_down_last_event_window = 0; -static Ecore_X_Window _ecore_xcb_mouse_down_last_last_event_window = 0; +# define CODESET "INVALID" +#endif + +/* local function prototypes */ +static void _ecore_xcb_event_handle_any_event(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_key_press(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_key_release(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_button_press(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_button_release(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_motion_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_enter_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_leave_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_focus_in(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_focus_out(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_expose(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_graphics_exposure(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_visibility_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_create_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_destroy_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_map_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_selection_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_client_message(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event); +#ifdef ECORE_XCB_SHAPE +static void _ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event); +#endif +static void _ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event __UNUSED__); +static void _ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_input_event(xcb_generic_event_t *event); + +static void _ecore_xcb_event_key_press(xcb_generic_event_t *event); +static void _ecore_xcb_event_key_release(xcb_generic_event_t *event); +//static void _ecore_xcb_event_mouse_move(uint16_t timestamp, uint16_t modifiers, int16_t x, int16_t y, int16_t root_x, int16_t root_y, xcb_window_t event_win, xcb_window_t win, xcb_window_t root_win, uint8_t same_screen, int dev, double radx, double rady, double pressure, double angle, int16_t mx, int16_t my, int16_t mrx, int16_t mry); +static void _ecore_xcb_event_mouse_move_free(void *data __UNUSED__, void *event); +//static Ecore_Event_Mouse_Button *_ecore_xcb_event_mouse_button(int event, uint16_t timestamp, uint16_t modifiers, xcb_button_t buttons, int16_t x, int16_t y, int16_t root_x, int16_t root_y, xcb_window_t event_win, xcb_window_t win, xcb_window_t root_win, uint8_t same_screen, int dev, double radx, double rady, double pressure, double angle, int16_t mx, int16_t my, int16_t mrx, int16_t mry); +static Ecore_X_Event_Mode _ecore_xcb_event_mode_get(uint8_t mode); +static Ecore_X_Event_Detail _ecore_xcb_event_detail_get(uint8_t detail); +static void _ecore_xcb_event_xdnd_enter_free(void *data __UNUSED__, void *event); +static void _ecore_xcb_event_selection_notify_free(void *data __UNUSED__, void *event); +static void _ecore_xcb_event_generic_event_free(void *data, void *event); + +/* local variables */ +static Ecore_X_Time _ecore_xcb_event_last_time; +static Eina_Bool _ecore_xcb_event_last_mouse_move = EINA_FALSE; +static Ecore_Event *_ecore_xcb_event_last_mouse_move_event = NULL; +static Ecore_X_Window _ecore_xcb_event_last_window = 0; static Ecore_X_Time _ecore_xcb_mouse_down_last_time = 0; static Ecore_X_Time _ecore_xcb_mouse_down_last_last_time = 0; -static int _ecore_xcb_mouse_up_count = 0; -static int _ecore_xcb_mouse_down_did_triple = 0; -static int _ecore_xcb_last_event_mouse_move = 0; -static Ecore_Event *_ecore_xcb_last_event_mouse_move_event = NULL; - -static void -_ecore_x_event_free_mouse_move(void *data __UNUSED__, void *ev) +static Ecore_X_Window _ecore_xcb_mouse_down_last_win = 0; +static Ecore_X_Window _ecore_xcb_mouse_down_last_last_win = 0; +static Ecore_X_Window _ecore_xcb_mouse_down_last_event_win = 0; +static Ecore_X_Window _ecore_xcb_mouse_down_last_last_event_win = 0; +static Eina_Bool _ecore_xcb_mouse_down_did_double = EINA_FALSE; +static Eina_Bool _ecore_xcb_mouse_down_did_triple = EINA_FALSE; + +/* public variables */ +int16_t _ecore_xcb_event_last_root_x = 0; +int16_t _ecore_xcb_event_last_root_y = 0; + +EAPI int ECORE_X_EVENT_ANY = 0; +EAPI int ECORE_X_EVENT_MOUSE_IN = 0; +EAPI int ECORE_X_EVENT_MOUSE_OUT = 0; +EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0; +EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0; +EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0; +EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0; +EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0; +EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0; +EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0; +EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0; +EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0; +EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0; +EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0; +EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0; +EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0; +EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0; +EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0; +EAPI int ECORE_X_EVENT_WINDOW_STACK = 0; +EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0; +EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0; +EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0; +EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0; +EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0; +EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0; +EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0; +EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0; +EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0; +EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0; +EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0; +EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0; +EAPI int ECORE_X_EVENT_SYNC_ALARM = 0; +EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0; +EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0; +EAPI int ECORE_X_EVENT_RANDR_CRTC_CHANGE = 0; +EAPI int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = 0; +EAPI int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = 0; +EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0; +EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0; +EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0; +EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0; +EAPI int ECORE_X_EVENT_PING = 0; +EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0; +EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0; +EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0; +EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0; +EAPI int ECORE_X_EVENT_GENERIC = 0; + +void +_ecore_xcb_events_init(void) { - Ecore_Event_Mouse_Move *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - e = ev; - if (_ecore_xcb_last_event_mouse_move) + if (!ECORE_X_EVENT_ANY) { - _ecore_xcb_last_event_mouse_move_event = NULL; - _ecore_xcb_last_event_mouse_move = 0; + ECORE_X_EVENT_ANY = ecore_event_type_new(); + ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new(); + ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new(); + ECORE_X_EVENT_MAPPING_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new(); + ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new(); + ECORE_X_EVENT_SCREENSAVER_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new(); + ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new(); + ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_RANDR_CRTC_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_PING = ecore_event_type_new(); + ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new(); + ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new(); + ECORE_X_EVENT_GENERIC = ecore_event_type_new(); } +} - free(e); -} /* _ecore_x_event_free_mouse_move */ +void +_ecore_xcb_events_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + if (_ecore_xcb_event_last_mouse_move_event) + { + ecore_event_del(_ecore_xcb_event_last_mouse_move_event); + _ecore_xcb_event_last_mouse_move_event = NULL; + } +} -/* FIXME: roundtrip */ -EAPI void -ecore_x_event_mask_set(Ecore_X_Window window, - Ecore_X_Event_Mask mask) +void +_ecore_xcb_events_handle(xcb_generic_event_t *ev) { - xcb_get_window_attributes_cookie_t cookie; - xcb_get_window_attributes_reply_t *reply; - uint32_t value_list; + uint8_t response = 0; - if (!window) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window); - reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - return; + /* strip highest bit (set if event is generated) */ + response = (ev->response_type & ~0x80); + if (response == 0) + { + xcb_generic_error_t *err; - value_list = mask | reply->your_event_mask; - xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list); - free(reply); -} /* ecore_x_event_mask_set */ + err = (xcb_generic_error_t *)ev; + + /* NB: There is no way to check access of destroyed windows, + * so trap those cases and ignore. We also ignore BadValue from + * xcb_grab/ungrab_button (happens when we are using any_mod) + * and a few others */ + if (err->error_code == XCB_EVENT_ERROR_BAD_WINDOW) return; + else if (err->error_code == XCB_EVENT_ERROR_BAD_MATCH) + { + if ((err->major_code == XCB_SET_INPUT_FOCUS) || + (err->major_code == XCB_CONFIGURE_WINDOW)) + return; + } + else if (err->error_code == XCB_EVENT_ERROR_BAD_VALUE) + { + if ((err->major_code == XCB_KILL_CLIENT) || + (err->major_code == XCB_GRAB_BUTTON) || + (err->major_code == XCB_UNGRAB_BUTTON)) + return; + } + + /* WRN("Got Event Error:"); */ + /* WRN("\tMajor Code: %d", err->major_code); */ + /* WRN("\tMinor Code: %d", err->minor_code); */ + /* WRN("\tRequest: %s", xcb_event_get_request_label(err->major_code)); */ + /* WRN("\tError: %s", xcb_event_get_error_label(err->error_code)); */ + /* if (err->error_code == XCB_EVENT_ERROR_BAD_VALUE) */ + /* WRN("\tValue: %d", ((xcb_value_error_t *)err)->bad_value); */ + /* else if (err->error_code == XCB_EVENT_ERROR_BAD_MATCH) */ + /* WRN("\tMatch: %d", ((xcb_match_error_t *)err)->bad_value); */ + + /* if (err->major_code == XCB_SEND_EVENT) */ + /* { */ + /* WRN("\tSend Event Error"); */ + /* WRN("\t\tSeq: %d", ev->sequence); */ + /* WRN("\t\tFull Seq: %d", ev->full_sequence); */ + /* WRN("\t\tType: %d", ev->response_type); */ + /* } */ + /* if (err->major_code == 148) */ + /* { */ + /* printf("GOT 148 Error\n"); */ + /* } */ + return; + } -/* FIXME: roundtrip */ -EAPI void -ecore_x_event_mask_unset(Ecore_X_Window window, - Ecore_X_Event_Mask mask) + _ecore_xcb_event_handle_any_event(ev); + + if (response == XCB_KEY_PRESS) + _ecore_xcb_event_handle_key_press(ev); + else if (response == XCB_KEY_RELEASE) + _ecore_xcb_event_handle_key_release(ev); + else if (response == XCB_BUTTON_PRESS) + _ecore_xcb_event_handle_button_press(ev); + else if (response == XCB_BUTTON_RELEASE) + _ecore_xcb_event_handle_button_release(ev); + else if (response == XCB_MOTION_NOTIFY) + _ecore_xcb_event_handle_motion_notify(ev); + else if (response == XCB_ENTER_NOTIFY) + _ecore_xcb_event_handle_enter_notify(ev); + else if (response == XCB_LEAVE_NOTIFY) + _ecore_xcb_event_handle_leave_notify(ev); + else if (response == XCB_KEYMAP_NOTIFY) + _ecore_xcb_event_handle_keymap_notify(ev); + else if (response == XCB_FOCUS_IN) + _ecore_xcb_event_handle_focus_in(ev); + else if (response == XCB_FOCUS_OUT) + _ecore_xcb_event_handle_focus_out(ev); + else if (response == XCB_EXPOSE) + _ecore_xcb_event_handle_expose(ev); + else if (response == XCB_GRAPHICS_EXPOSURE) + _ecore_xcb_event_handle_graphics_exposure(ev); + else if (response == XCB_VISIBILITY_NOTIFY) + _ecore_xcb_event_handle_visibility_notify(ev); + else if (response == XCB_CREATE_NOTIFY) + _ecore_xcb_event_handle_create_notify(ev); + else if (response == XCB_DESTROY_NOTIFY) + _ecore_xcb_event_handle_destroy_notify(ev); + else if (response == XCB_MAP_NOTIFY) + _ecore_xcb_event_handle_map_notify(ev); + else if (response == XCB_UNMAP_NOTIFY) + _ecore_xcb_event_handle_unmap_notify(ev); + else if (response == XCB_MAP_REQUEST) + _ecore_xcb_event_handle_map_request(ev); + else if (response == XCB_REPARENT_NOTIFY) + _ecore_xcb_event_handle_reparent_notify(ev); + else if (response == XCB_CONFIGURE_NOTIFY) + _ecore_xcb_event_handle_configure_notify(ev); + else if (response == XCB_CONFIGURE_REQUEST) + _ecore_xcb_event_handle_configure_request(ev); + else if (response == XCB_GRAVITY_NOTIFY) + _ecore_xcb_event_handle_gravity_notify(ev); + else if (response == XCB_RESIZE_REQUEST) + _ecore_xcb_event_handle_resize_request(ev); + else if (response == XCB_CIRCULATE_NOTIFY) + _ecore_xcb_event_handle_circulate_notify(ev); + else if (response == XCB_CIRCULATE_REQUEST) + _ecore_xcb_event_handle_circulate_request(ev); + else if (response == XCB_PROPERTY_NOTIFY) + _ecore_xcb_event_handle_property_notify(ev); + else if (response == XCB_SELECTION_CLEAR) + _ecore_xcb_event_handle_selection_clear(ev); + else if (response == XCB_SELECTION_REQUEST) + _ecore_xcb_event_handle_selection_request(ev); + else if (response == XCB_SELECTION_NOTIFY) + _ecore_xcb_event_handle_selection_notify(ev); + else if (response == XCB_COLORMAP_NOTIFY) + _ecore_xcb_event_handle_colormap_notify(ev); + else if (response == XCB_CLIENT_MESSAGE) + _ecore_xcb_event_handle_client_message(ev); + else if (response == XCB_MAPPING_NOTIFY) + _ecore_xcb_event_handle_mapping_notify(ev); + else if (response == 35) /* GenericEvent == 35 */ + _ecore_xcb_event_handle_generic_event(ev); +#ifdef ECORE_XCB_DAMAGE + else if ((_ecore_xcb_event_damage >= 0) && + (response == _ecore_xcb_event_damage + XCB_DAMAGE_NOTIFY)) + _ecore_xcb_event_handle_damage_notify(ev); +#endif +#ifdef ECORE_XCB_RANDR + else if ((_ecore_xcb_event_randr >= 0) && + (response == + _ecore_xcb_event_randr + XCB_RANDR_SCREEN_CHANGE_NOTIFY)) + _ecore_xcb_event_handle_randr_change(ev); + else if ((_ecore_xcb_event_randr >= 0) && + (response == (_ecore_xcb_event_randr + XCB_RANDR_NOTIFY))) + _ecore_xcb_event_handle_randr_notify(ev); +#endif +#ifdef ECORE_XCB_SCREENSAVER + else if ((_ecore_xcb_event_screensaver >= 0) && + (response == + _ecore_xcb_event_screensaver + XCB_SCREENSAVER_NOTIFY)) + _ecore_xcb_event_handle_screensaver_notify(ev); +#endif +#ifdef ECORE_XCB_SHAPE + else if ((_ecore_xcb_event_shape >= 0) && + (response == _ecore_xcb_event_shape + XCB_SHAPE_NOTIFY)) + _ecore_xcb_event_handle_shape_change(ev); +#endif +#ifdef ECORE_XCB_SYNC + else if ((_ecore_xcb_event_sync >= 0) && + (response == (_ecore_xcb_event_sync + XCB_SYNC_COUNTER_NOTIFY))) + _ecore_xcb_event_handle_sync_counter(ev); + else if ((_ecore_xcb_event_sync >= 0) && + (response == (_ecore_xcb_event_sync + XCB_SYNC_ALARM_NOTIFY))) + _ecore_xcb_event_handle_sync_alarm(ev); +#endif +#ifdef ECORE_XCB_XFIXES + else if ((_ecore_xcb_event_xfixes >= 0) && + (response == + _ecore_xcb_event_xfixes + XCB_XFIXES_SELECTION_NOTIFY)) + _ecore_xcb_event_handle_xfixes_selection_notify(ev); + else if ((_ecore_xcb_event_xfixes >= 0) && + (response == (_ecore_xcb_event_xfixes + XCB_XFIXES_CURSOR_NOTIFY))) + _ecore_xcb_event_handle_xfixes_cursor_notify(ev); +#endif +} + +Ecore_X_Time +_ecore_xcb_events_last_time_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_event_last_time; +} + +EAPI void +ecore_x_event_mask_set(Ecore_X_Window win, Ecore_X_Event_Mask mask) { xcb_get_window_attributes_cookie_t cookie; xcb_get_window_attributes_reply_t *reply; - uint32_t value_list; + uint32_t list; - if (!window) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window); + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - return; + if (!reply) return; - value_list = reply->your_event_mask & ~mask; - xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list); + list = (mask | reply->your_event_mask); free(reply); -} /* ecore_x_event_mask_unset */ + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +} -static void -_ecore_x_event_free_xdnd_enter(void *data __UNUSED__, void *ev) +EAPI void +ecore_x_event_mask_unset(Ecore_X_Window win, Ecore_X_Event_Mask mask) { - Ecore_X_Event_Xdnd_Enter *e; - int i; - - e = ev; - for (i = 0; i < e->num_types; i++) - free(e->types[i]); - free(e->types); - free(e); -} /* _ecore_x_event_free_xdnd_enter */ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + uint32_t list; -static void -_ecore_x_event_free_selection_notify(void *data __UNUSED__, void *ev) -{ - Ecore_X_Event_Selection_Notify *e; - Ecore_X_Selection_Data *sel; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - e = ev; - sel = e->data; - if (sel->free) - sel->free(sel); + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; - free(e->target); - free(e); -} /* _ecore_x_event_free_selection_notify */ + list = (reply->your_event_mask & ~mask); + free(reply); + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +} -static unsigned int -_ecore_x_event_modifiers(unsigned int state) +unsigned int +_ecore_xcb_events_modifiers_get(unsigned int state) { unsigned int modifiers = 0; - if (state & ECORE_X_MODIFIER_SHIFT) - modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (state & ECORE_X_MODIFIER_SHIFT) + modifiers |= ECORE_EVENT_MODIFIER_SHIFT; if (state & ECORE_X_MODIFIER_CTRL) - modifiers |= ECORE_EVENT_MODIFIER_CTRL; - + modifiers |= ECORE_EVENT_MODIFIER_CTRL; if (state & ECORE_X_MODIFIER_ALT) - modifiers |= ECORE_EVENT_MODIFIER_ALT; - + modifiers |= ECORE_EVENT_MODIFIER_ALT; if (state & ECORE_X_MODIFIER_WIN) - modifiers |= ECORE_EVENT_MODIFIER_WIN; - + modifiers |= ECORE_EVENT_MODIFIER_WIN; if (state & ECORE_X_LOCK_SCROLL) - modifiers |= ECORE_EVENT_LOCK_SCROLL; - - if (state & ECORE_X_LOCK_NUM) - modifiers |= ECORE_EVENT_LOCK_NUM; - + modifiers |= ECORE_EVENT_LOCK_SCROLL; if (state & ECORE_X_LOCK_CAPS) - modifiers |= ECORE_EVENT_LOCK_CAPS; + modifiers |= ECORE_EVENT_LOCK_CAPS; + if (state & ECORE_X_LOCK_NUM) + modifiers |= ECORE_EVENT_LOCK_NUM; + if (state & ECORE_X_LOCK_SHIFT) + modifiers |= ECORE_EVENT_LOCK_SHIFT; return modifiers; -} /* _ecore_x_event_modifiers */ - -static void -_ecore_mouse_move(unsigned int timestamp, unsigned int xmodifiers, - int x, int y, - int x_root, int y_root, - unsigned int event_window, - unsigned int window, - unsigned int root_win, - int same_screen) -{ - Ecore_Event_Mouse_Move *e; - Ecore_Event *event; - - e = malloc(sizeof(Ecore_Event_Mouse_Move)); - if (!e) - return; - - e->window = window; - e->root_window = root_win; - e->timestamp = timestamp; - e->same_screen = same_screen; - e->event_window = event_window; +} - e->modifiers = _ecore_x_event_modifiers(xmodifiers); - e->x = x; - e->y = y; - e->root.x = x_root; - e->root.y = y_root; - - event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _ecore_x_event_free_mouse_move, NULL); - - _ecore_xcb_event_last_time = timestamp; - _ecore_xcb_event_last_window = window; - _ecore_xcb_event_last_root_x = x_root; - _ecore_xcb_event_last_root_y = y_root; - - _ecore_xcb_last_event_mouse_move_event = event; -} /* _ecore_mouse_move */ - -static void -_ecore_key_press(int event, - xcb_generic_event_t *ev) -{ - /* - Ecore_Event_Key *e; - const char *compose = NULL; - char *tmp = NULL; - char *keyname; - char *key; - char keyname_buffer[256]; - char compose_buffer[256]; - KeySym sym; - XComposeStatus status; - int val; - - _ecore_xcb_last_event_mouse_move = 0; - keyname = XKeysymToString(XKeycodeToKeysym(xevent->display, - xevent->keycode, 0)); - if (!keyname) - { - snprintf(keyname_buffer, sizeof(keyname_buffer), "Keycode-%i", xevent->keycode); - keyname = keyname_buffer; - if (!keyname) return ; - } - - sym = 0; - key = NULL; - compose = NULL; - if (_ecore_x_ic) - { - Status mbstatus; - #ifdef X_HAVE_UTF8_STRING - val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus); - #else - val = XmbLookupString(_ecore_x_ic, (XKeyEvent *)xevent, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus); - #endif - if (mbstatus == XBufferOverflow) - { - tmp = malloc(sizeof (char) * (val + 1)); - if (!tmp) return ; - - compose = tmp; - - #ifdef X_HAVE_UTF8_STRING - val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, tmp, val, &sym, &mbstatus); - #else - val = XmbLookupString(_ecore_x_ic, (XKeyEvent *)xevent, tmp, val, &sym, &mbstatus); - #endif - if (val > 0) - { - tmp[val] = 0; - - #ifndef X_HAVE_UTF8_STRING - compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", tmp); - free(tmp); - tmp = compose; - #endif - } - else compose = NULL; - } - else - if (val > 0) - { - compose_buffer[val] = 0; - #ifdef X_HAVE_UTF8_STRING - compose = compose_buffer; - #else - compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer); - tmp = compose; - #endif - } - } - else - { - val = XLookupString(xevent, compose_buffer, sizeof(compose_buffer), &sym, &status); - if (val > 0) - { - compose_buffer[val] = 0; - compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer); - tmp = compose; - } - } - - key = XKeysymToString(sym); - if (!key) key = keyname; - if (!key) goto on_error; - - e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + (compose ? strlen(compose) : 0) + 3); - if (!e) goto on_error; - - e->keyname = (char*) (e + 1); - e->key = e->keyname + strlen(keyname) + 1; - e->compose = (compose) ? e->key + strlen(key) + 1 : NULL; - e->string = e->compose; - - strcpy((char *) e->keyname, keyname); - strcpy((char *) e->key, key); - if (compose) strcpy((char *) e->compose, compose); - - e->modifiers = _ecore_x_event_modifiers(xevent->state); - - e->timestamp = xevent->time; - e->window = xevent->subwindow ? xevent->subwindow : xevent->window; - e->event_window = xevent->window; - e->same_screen = xevent->same_screen; - e->root_window = xevent->root; - - ecore_event_add(event, e, NULL, NULL); - - _ecore_xcb_event_last_time = e->timestamp; - - on_error: - if (tmp) free(tmp); - */ -} /* _ecore_key_press */ - -static Ecore_Event_Mouse_Button * -_ecore_mouse_button(int event, - unsigned int timestamp, unsigned int xmodifiers, - unsigned int buttons, - int x, int y, - int x_root, int y_root, - unsigned int event_window, - unsigned int window, - unsigned int root_win, - int same_screen) +/* local functions */ +static void +_ecore_xcb_event_handle_any_event(xcb_generic_event_t *event) { - Ecore_Event_Mouse_Button *e; - - e = malloc(sizeof(Ecore_Event_Mouse_Button)); - if (!e) - return NULL; - - e->window = window; - e->root_window = root_win; - e->timestamp = timestamp; - e->same_screen = same_screen; - e->event_window = event_window; - - e->buttons = buttons; - e->modifiers = _ecore_x_event_modifiers(xmodifiers); - e->double_click = 0; - e->triple_click = 0; - e->x = x; - e->y = y; - e->root.x = x_root; - e->root.y = y_root; - - if (event_window == window) - { - if (((int)(timestamp - _ecore_xcb_mouse_down_last_time) <= - (int)(1000 * _ecore_xcb_double_click_time)) && - (window == _ecore_xcb_mouse_down_last_window) && - (event_window == _ecore_xcb_mouse_down_last_event_window) - ) - e->double_click = 1; - - if (((int)(timestamp - _ecore_xcb_mouse_down_last_last_time) <= - (int)(2 * 1000 * _ecore_xcb_double_click_time)) && - (window == _ecore_xcb_mouse_down_last_window) && - (window == _ecore_xcb_mouse_down_last_last_window) && - (event_window == _ecore_xcb_mouse_down_last_event_window) && - (event_window == _ecore_xcb_mouse_down_last_last_event_window) - ) - { - e->triple_click = 1; - _ecore_xcb_mouse_down_did_triple = 1; - } - else - _ecore_xcb_mouse_down_did_triple = 0; - } - - if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN - && !e->double_click - && !e->triple_click) - _ecore_xcb_mouse_up_count = 0; + xcb_generic_event_t *ev; - _ecore_xcb_event_last_time = e->timestamp; - _ecore_xcb_event_last_window = e->window; - _ecore_xcb_event_last_root_x = x_root; - _ecore_xcb_event_last_root_y = y_root; - - ecore_event_add(event, e, NULL, NULL); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return e; -} /* _ecore_mouse_button */ + ev = malloc(sizeof(xcb_generic_event_t)); + if (!ev) return; -void -_ecore_x_event_handle_any_event(xcb_generic_event_t *event) -{ - xcb_generic_event_t *ev = malloc(sizeof(xcb_generic_event_t)); memcpy(ev, event, sizeof(xcb_generic_event_t)); - ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL); -} /* _ecore_x_event_handle_any_event */ +} -/* FIXME: handle this event */ -void -_ecore_x_event_handle_key_press(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_key_press(xcb_generic_event_t *event) { - _ecore_key_press(ECORE_EVENT_KEY_DOWN, event); - - free(event); -} /* _ecore_x_event_handle_key_press */ + _ecore_xcb_event_key_press(event); +} -/* FIXME: handle this event */ -void -_ecore_x_event_handle_key_release(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_key_release(xcb_generic_event_t *event) { - _ecore_key_press(ECORE_EVENT_KEY_DOWN, event); + _ecore_xcb_event_key_release(event); +} - free(event); -} /* _ecore_x_event_handle_key_release */ - -void -_ecore_x_event_handle_button_press(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_button_press(xcb_generic_event_t *event) { xcb_button_press_event_t *ev; - int i; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_button_press_event_t *)event; - if ((ev->detail > 3) && (ev->detail < 8)) + if ((ev->detail > 3) && (ev->detail < 8)) { Ecore_Event_Mouse_Wheel *e; - e = malloc(sizeof(Ecore_Event_Mouse_Wheel)); - if (!e) - return; + if (!(e = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return; e->timestamp = ev->time; - e->modifiers = _ecore_x_event_modifiers(ev->state); - switch (ev->detail) + e->modifiers = _ecore_xcb_events_modifiers_get(ev->state); + switch (ev->detail) { - case 4: e->direction = 0; e->z = -1; break; - - case 5: e->direction = 0; e->z = 1; break; - - case 6: e->direction = 1; e->z = -1; break; - - case 7: e->direction = 1; e->z = 1; break; - - default: e->direction = 0; e->z = 0; break; - } /* switch */ - + case 4: + e->direction = 0; + e->z = -1; + break; + case 5: + e->direction = 0; + e->z = 1; + break; + case 6: + e->direction = 1; + e->z = -1; + break; + case 7: + e->direction = 1; + e->z = 1; + break; + default: + e->direction = 0; + e->z = 0; + break; + } e->x = ev->event_x; e->y = ev->event_y; e->root.x = ev->root_x; e->root.y = ev->root_y; - if (ev->child) - e->window = ev->child; + e->window = ev->child; else - e->window = ev->event; + e->window = ev->event; e->event_window = ev->event; e->same_screen = ev->same_screen; e->root_window = ev->root; + _ecore_xcb_event_last_time = e->timestamp; _ecore_xcb_event_last_window = e->window; _ecore_xcb_event_last_root_x = e->root.x; _ecore_xcb_event_last_root_y = e->root.y; + ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL); - for (i = 0; i < _ecore_window_grabs_num; i++) + + _ecore_xcb_window_grab_allow_events(ev->event, ev->child, + ECORE_EVENT_MOUSE_WHEEL, + e, ev->time); + } + else + { + Ecore_Event_Mouse_Button *e; + unsigned int child_win = 0; + + child_win = (ev->child ? ev->child : ev->event); + + _ecore_xcb_event_mouse_move(ev->time, ev->state, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y, + ev->event, child_win, + ev->root, ev->same_screen, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + + if (_ecore_xcb_mouse_down_did_triple) + { + _ecore_xcb_mouse_down_last_time = 0; + _ecore_xcb_mouse_down_last_win = 0; + _ecore_xcb_mouse_down_last_last_win = 0; + _ecore_xcb_mouse_down_last_event_win = 0; + _ecore_xcb_mouse_down_last_last_event_win = 0; + _ecore_xcb_mouse_down_last_last_time = 0; + } + + e = _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN, + ev->time, + ev->state, ev->detail, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y, ev->event, + child_win, + ev->root, ev->same_screen, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + if (e) + _ecore_xcb_window_grab_allow_events(ev->event, ev->child, + ECORE_EVENT_MOUSE_BUTTON_DOWN, + e, ev->time); + + if (child_win == ev->event) { - if ((_ecore_window_grabs[i] == ev->event) || - (_ecore_window_grabs[i] == ev->child)) + if (!_ecore_xcb_mouse_down_did_triple) { - Eina_Bool replay = EINA_FALSE; - - if (_ecore_window_grab_replay_func) - replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data, - ECORE_EVENT_MOUSE_WHEEL, - e); - - /* FIXME: xcb_key_press_event_t does not save the */ - /* connection. So I use the current one */ - if (replay) - xcb_allow_events(_ecore_xcb_conn, - XCB_ALLOW_REPLAY_POINTER, - ev->time); + _ecore_xcb_mouse_down_last_last_win = + _ecore_xcb_mouse_down_last_win; + if (ev->child) + _ecore_xcb_mouse_down_last_win = ev->child; else - xcb_allow_events(_ecore_xcb_conn, - XCB_ALLOW_ASYNC_POINTER, - ev->time); - - break; + _ecore_xcb_mouse_down_last_win = ev->event; + + _ecore_xcb_mouse_down_last_last_event_win = + _ecore_xcb_mouse_down_last_event_win; + _ecore_xcb_mouse_down_last_event_win = ev->event; + _ecore_xcb_mouse_down_last_last_time = + _ecore_xcb_mouse_down_last_time; + _ecore_xcb_mouse_down_last_time = ev->time; } } } - else - { - { - _ecore_mouse_move(ev->time, ev->state, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y, - ev->event, - (ev->child ? ev->child : ev->event), - ev->root, - ev->same_screen); - } - { - Ecore_Event_Mouse_Button *e; - Ecore_X_Window event_window; - Ecore_X_Window child_window; - - if (_ecore_xcb_mouse_down_did_triple) - { - _ecore_xcb_mouse_down_last_window = 0; - _ecore_xcb_mouse_down_last_last_window = 0; - _ecore_xcb_mouse_down_last_event_window = 0; - _ecore_xcb_mouse_down_last_last_event_window = 0; - _ecore_xcb_mouse_down_last_time = 0; - _ecore_xcb_mouse_down_last_last_time = 0; - } - - event_window = ev->child; - child_window = ev->child ? ev->child : ev->event; - - e = _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN, - ev->time, ev->state, - ev->detail, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y, - event_window, child_window, - ev->root, ev->same_screen); - - if (!e) - return; - - for (i = 0; i < _ecore_window_grabs_num; i++) - { - if ((_ecore_window_grabs[i] == ev->event) || - (_ecore_window_grabs[i] == ev->child)) - { - Eina_Bool replay = EINA_FALSE; - - if (_ecore_window_grab_replay_func) - replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data, - ECORE_EVENT_MOUSE_BUTTON_DOWN, - e); - - /* FIXME: xcb_key_press_event_t does not save the */ - /* connection. So I use the current one */ - if (replay) - xcb_allow_events(_ecore_xcb_conn, - XCB_ALLOW_REPLAY_POINTER, - ev->time); - else - xcb_allow_events(_ecore_xcb_conn, - XCB_ALLOW_ASYNC_POINTER, - ev->time); - - break; - } - } - if (child_window == event_window) - { - if (!_ecore_xcb_mouse_down_did_triple) - { - _ecore_xcb_mouse_down_last_last_window = _ecore_xcb_mouse_down_last_window; - if (ev->child) - _ecore_xcb_mouse_down_last_window = ev->child; - else - _ecore_xcb_mouse_down_last_window = ev->event; - - _ecore_xcb_mouse_down_last_last_event_window = _ecore_xcb_mouse_down_last_event_window; - _ecore_xcb_mouse_down_last_event_window = ev->event; - _ecore_xcb_mouse_down_last_last_time = _ecore_xcb_mouse_down_last_time; - _ecore_xcb_mouse_down_last_time = ev->time; - } - } - } - } - - free(event); -} /* _ecore_x_event_handle_button_press */ +} -void -_ecore_x_event_handle_button_release(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_button_release(xcb_generic_event_t *event) { xcb_button_release_event_t *ev; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_button_release_event_t *)event; - _ecore_xcb_last_event_mouse_move = 0; - /* filter out wheel buttons */ - if ((ev->detail <= 3) || (ev->detail > 7)) + if ((ev->detail <= 3) || (ev->detail > 7)) { - _ecore_mouse_move(ev->time, ev->state, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y, - ev->event, - (ev->child ? ev->child : ev->event), - ev->root, - ev->same_screen); - - _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP, - ev->time, ev->state, - ev->detail, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y, - ev->event, - (ev->child ? ev->child : ev->event), - ev->root, - ev->same_screen); + _ecore_xcb_event_mouse_move(ev->time, ev->state, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y, + ev->event, + (ev->child ? ev->child : ev->event), + ev->root, ev->same_screen, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + + _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP, ev->time, + ev->state, ev->detail, + ev->event_x, ev->event_y, ev->root_x, + ev->root_y, ev->event, + (ev->child ? ev->child : ev->event), + ev->root, ev->same_screen, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); } +} - free(event); -} /* _ecore_x_event_handle_button_release */ - -void -_ecore_x_event_handle_motion_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_motion_notify(xcb_generic_event_t *event) { xcb_motion_notify_event_t *ev; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ev = (xcb_motion_notify_event_t *)event; - if (_ecore_xcb_last_event_mouse_move) - { - ecore_event_del(_ecore_xcb_last_event_mouse_move_event); - _ecore_xcb_last_event_mouse_move = 0; - _ecore_xcb_last_event_mouse_move_event = NULL; - } - _ecore_mouse_move(ev->time, ev->state, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y, - ev->event, - (ev->child ? ev->child : ev->event), - ev->root, - ev->same_screen); + /* if (_ecore_xcb_event_last_mouse_move_event) */ + /* { */ + /* ecore_event_del(_ecore_xcb_event_last_mouse_move_event); */ + /* _ecore_xcb_event_last_mouse_move = EINA_FALSE; */ + /* _ecore_xcb_event_last_mouse_move_event = NULL; */ + /* } */ + + _ecore_xcb_event_mouse_move(ev->time, ev->state, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y, + ev->event, + (ev->child ? ev->child : ev->event), + ev->root, ev->same_screen, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + _ecore_xcb_event_last_mouse_move = EINA_TRUE; + + _ecore_xcb_dnd_drag(ev->root, ev->root_x, ev->root_y); +} + +static void +_ecore_xcb_event_handle_enter_notify(xcb_generic_event_t *event) +{ + xcb_enter_notify_event_t *ev; + Ecore_X_Event_Mouse_In *e; - _ecore_xcb_last_event_mouse_move = 1; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* Xdnd handling */ - _ecore_x_dnd_drag(ev->root, ev->root_x, ev->root_y); + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_enter_notify_event_t *)event; - free(event); -} /* _ecore_x_event_handle_motion_notify */ + _ecore_xcb_event_mouse_move(ev->time, ev->state, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y, + ev->event, + (ev->child ? ev->child : ev->event), + ev->root, ev->same_screen_focus, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Mouse_In)))) return; + + e->modifiers = _ecore_xcb_events_modifiers_get(ev->state); + e->x = ev->event_x; + e->y = ev->event_y; + e->root.x = ev->root_x; + e->root.y = ev->root_y; + if (ev->child) + e->win = ev->child; + else + e->win = ev->event; + e->event_win = ev->event; + e->same_screen = ev->same_screen_focus; + e->root_win = ev->root; + e->mode = _ecore_xcb_event_mode_get(ev->mode); + e->detail = _ecore_xcb_event_detail_get(ev->detail); + e->time = ev->time; + _ecore_xcb_event_last_time = e->time; -void -_ecore_x_event_handle_enter_notify(xcb_generic_event_t *event) -{ - xcb_enter_notify_event_t *ev; + ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL); +} - ev = (xcb_enter_notify_event_t *)event; - _ecore_xcb_last_event_mouse_move = 0; - - { - _ecore_mouse_move(ev->time, ev->state, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y, - ev->event, - (ev->child ? ev->child : ev->event), - ev->root, - ev->same_screen_focus); - } - { - Ecore_X_Event_Mouse_In *e; - - e = calloc(1, sizeof(Ecore_X_Event_Mouse_In)); - if (!e) - return; - - e->modifiers = _ecore_x_event_modifiers(ev->state); - e->x = ev->event_x; - e->y = ev->event_y; - e->root.x = ev->root_x; - e->root.y = ev->root_y; - if (ev->child) - e->win = ev->child; - else - e->win = ev->event; - - e->same_screen = ev->same_screen_focus; - e->root_win = ev->root; - e->event_win = ev->event; - switch (ev->mode) { - case XCB_NOTIFY_MODE_NORMAL: - e->mode = ECORE_X_EVENT_MODE_NORMAL; - break; - - case XCB_NOTIFY_MODE_GRAB: - e->mode = ECORE_X_EVENT_MODE_GRAB; - break; - - case XCB_NOTIFY_MODE_UNGRAB: - e->mode = ECORE_X_EVENT_MODE_UNGRAB; - break; - - default: - e->mode = ECORE_X_EVENT_MODE_NORMAL; - break; - } /* switch */ - switch (ev->detail) { - case XCB_NOTIFY_DETAIL_ANCESTOR: - e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; - break; - - case XCB_NOTIFY_DETAIL_VIRTUAL: - e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL; - break; - - case XCB_NOTIFY_DETAIL_INFERIOR: - e->detail = ECORE_X_EVENT_DETAIL_INFERIOR; - break; - - case XCB_NOTIFY_DETAIL_NONLINEAR: - e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR; - break; - - case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL: - e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; - break; - - default: - e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; - break; - } /* switch */ - e->time = ev->time; - _ecore_xcb_event_last_time = e->time; - ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL); - } - - free(event); -} /* _ecore_x_event_handle_enter_notify */ - -void -_ecore_x_event_handle_leave_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_leave_notify(xcb_generic_event_t *event) { xcb_leave_notify_event_t *ev; + Ecore_X_Event_Mouse_Out *e; - ev = (xcb_leave_notify_event_t *)event; - _ecore_xcb_last_event_mouse_move = 0; - - { - _ecore_mouse_move(ev->time, ev->state, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y, - ev->event, - (ev->child ? ev->child : ev->event), - ev->root, - ev->same_screen_focus); - } - { - Ecore_X_Event_Mouse_Out *e; - - e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out)); - if (!e) - return; - - e->modifiers = _ecore_x_event_modifiers(ev->state); - e->x = ev->event_x; - e->y = ev->event_y; - e->root.x = ev->root_x; - e->root.y = ev->root_y; - if (ev->child) - e->win = ev->child; - else - e->win = ev->event; - - e->same_screen = ev->same_screen_focus; - e->root_win = ev->root; - e->event_win = ev->event; - switch (ev->mode) { - case XCB_NOTIFY_MODE_NORMAL: - e->mode = ECORE_X_EVENT_MODE_NORMAL; - break; - - case XCB_NOTIFY_MODE_GRAB: - e->mode = ECORE_X_EVENT_MODE_GRAB; - break; - - case XCB_NOTIFY_MODE_UNGRAB: - e->mode = ECORE_X_EVENT_MODE_UNGRAB; - break; - - default: - e->mode = ECORE_X_EVENT_MODE_NORMAL; - break; - } /* switch */ - switch (ev->detail) { - case XCB_NOTIFY_DETAIL_ANCESTOR: - e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; - break; - - case XCB_NOTIFY_DETAIL_VIRTUAL: - e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL; - break; - - case XCB_NOTIFY_DETAIL_INFERIOR: - e->detail = ECORE_X_EVENT_DETAIL_INFERIOR; - break; - - case XCB_NOTIFY_DETAIL_NONLINEAR: - e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR; - break; - - case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL: - e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; - break; - - default: - e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; - break; - } /* switch */ - e->time = ev->time; - _ecore_xcb_event_last_time = e->time; - _ecore_xcb_event_last_window = e->win; - _ecore_xcb_event_last_root_x = e->root.x; - _ecore_xcb_event_last_root_y = e->root.y; - ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL); - } - - free(event); -} /* _ecore_x_event_handle_leave_notify */ - -void -_ecore_x_event_handle_focus_in(xcb_generic_event_t *event) -{ - xcb_focus_in_event_t *ev; - Ecore_X_Event_Window_Focus_In *e; - - ev = (xcb_focus_in_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In)); - if (!e) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - e->win = ev->event; - switch (ev->mode) { - case XCB_NOTIFY_MODE_NORMAL: - e->mode = ECORE_X_EVENT_MODE_NORMAL; - break; + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_enter_notify_event_t *)event; - case XCB_NOTIFY_MODE_GRAB: - e->mode = ECORE_X_EVENT_MODE_GRAB; - break; + _ecore_xcb_event_mouse_move(ev->time, ev->state, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y, + ev->event, + (ev->child ? ev->child : ev->event), + ev->root, ev->same_screen_focus, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out)))) return; + + e->modifiers = _ecore_xcb_events_modifiers_get(ev->state); + e->x = ev->event_x; + e->y = ev->event_y; + e->root.x = ev->root_x; + e->root.y = ev->root_y; + if (ev->child) + e->win = ev->child; + else + e->win = ev->event; + e->event_win = ev->event; + e->same_screen = ev->same_screen_focus; + e->root_win = ev->root; + e->mode = _ecore_xcb_event_mode_get(ev->mode); + e->detail = _ecore_xcb_event_detail_get(ev->detail); - case XCB_NOTIFY_MODE_UNGRAB: - e->mode = ECORE_X_EVENT_MODE_UNGRAB; - break; + e->time = ev->time; + _ecore_xcb_event_last_time = e->time; + _ecore_xcb_event_last_window = e->win; + _ecore_xcb_event_last_root_x = e->root.x; + _ecore_xcb_event_last_root_y = e->root.y; - case XCB_NOTIFY_MODE_WHILE_GRABBED: - e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED; - break; - } /* switch */ - switch (ev->detail) { - case XCB_NOTIFY_DETAIL_ANCESTOR: - e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; - break; + ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL); +} - case XCB_NOTIFY_DETAIL_VIRTUAL: - e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL; - break; +static void +_ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event __UNUSED__) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case XCB_NOTIFY_DETAIL_INFERIOR: - e->detail = ECORE_X_EVENT_DETAIL_INFERIOR; - break; + // FIXME: handle this event type + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +} - case XCB_NOTIFY_DETAIL_NONLINEAR: - e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR; - break; +static void +_ecore_xcb_event_handle_focus_in(xcb_generic_event_t *event) +{ + xcb_focus_in_event_t *ev; + Ecore_X_Event_Window_Focus_In *e; - case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL: - e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; - break; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case XCB_NOTIFY_DETAIL_POINTER: - e->detail = ECORE_X_EVENT_DETAIL_POINTER; - break; + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_focus_in_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In)))) return; - case XCB_NOTIFY_DETAIL_POINTER_ROOT: - e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT; - break; + e->win = ev->event; + e->mode = _ecore_xcb_event_mode_get(ev->mode); + e->detail = _ecore_xcb_event_detail_get(ev->detail); - case XCB_NOTIFY_DETAIL_NONE: - e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE; - break; - } /* switch */ e->time = _ecore_xcb_event_last_time; _ecore_xcb_event_last_time = e->time; - ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_focus_in */ + ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL); +} -void -_ecore_x_event_handle_focus_out(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_focus_out(xcb_generic_event_t *event) { xcb_focus_out_event_t *ev; Ecore_X_Event_Window_Focus_Out *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_focus_out_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out)))) return; e->win = ev->event; - switch (ev->mode) { - case XCB_NOTIFY_MODE_NORMAL: - e->mode = ECORE_X_EVENT_MODE_NORMAL; - break; - - case XCB_NOTIFY_MODE_GRAB: - e->mode = ECORE_X_EVENT_MODE_GRAB; - break; - - case XCB_NOTIFY_MODE_UNGRAB: - e->mode = ECORE_X_EVENT_MODE_UNGRAB; - break; - - case XCB_NOTIFY_MODE_WHILE_GRABBED: - e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED; - break; - } /* switch */ - switch (ev->detail) { - case XCB_NOTIFY_DETAIL_ANCESTOR: - e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; - break; - - case XCB_NOTIFY_DETAIL_VIRTUAL: - e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL; - break; - - case XCB_NOTIFY_DETAIL_INFERIOR: - e->detail = ECORE_X_EVENT_DETAIL_INFERIOR; - break; - - case XCB_NOTIFY_DETAIL_NONLINEAR: - e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR; - break; - - case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL: - e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; - break; - - case XCB_NOTIFY_DETAIL_POINTER: - e->detail = ECORE_X_EVENT_DETAIL_POINTER; - break; - - case XCB_NOTIFY_DETAIL_POINTER_ROOT: - e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT; - break; + e->mode = _ecore_xcb_event_mode_get(ev->mode); + e->detail = _ecore_xcb_event_detail_get(ev->detail); - case XCB_NOTIFY_DETAIL_NONE: - e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE; - break; - } /* switch */ e->time = _ecore_xcb_event_last_time; _ecore_xcb_event_last_time = e->time; - ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL); - - free(event); -} /* _ecore_x_event_handle_focus_out */ -void -_ecore_x_event_handle_keymap_notify(xcb_generic_event_t *event) -{ - /* FIXME: handle this event type */ - - free(event); -} /* _ecore_x_event_handle_keymap_notify */ + ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL); +} -void -_ecore_x_event_handle_expose(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_expose(xcb_generic_event_t *event) { xcb_expose_event_t *ev; Ecore_X_Event_Window_Damage *e; - ev = (xcb_expose_event_t *)event, - e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)); - if (!e) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_expose_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)))) return; e->win = ev->window; e->time = _ecore_xcb_event_last_time; @@ -965,191 +846,196 @@ _ecore_x_event_handle_expose(xcb_generic_event_t *event) e->w = ev->width; e->h = ev->height; e->count = ev->count; - ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_expose */ + ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL); +} -void -_ecore_x_event_handle_graphics_expose(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_graphics_exposure(xcb_generic_event_t *event) { xcb_graphics_exposure_event_t *ev; Ecore_X_Event_Window_Damage *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_graphics_exposure_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)))) return; e->win = ev->drawable; - e->time = _ecore_xcb_event_last_time; e->x = ev->x; e->y = ev->y; e->w = ev->width; e->h = ev->height; e->count = ev->count; - ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL); + e->time = _ecore_xcb_event_last_time; - free(event); -} /* _ecore_x_event_handle_graphics_expose */ + ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL); +} -void -_ecore_x_event_handle_visibility_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_visibility_notify(xcb_generic_event_t *event) { xcb_visibility_notify_event_t *ev; + Ecore_X_Event_Window_Visibility_Change *e; - ev = (xcb_visibility_notify_event_t *)event; - if (ev->state != XCB_VISIBILITY_PARTIALLY_OBSCURED) - { - Ecore_X_Event_Window_Visibility_Change *e; - - e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change)); - if (!e) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - e->win = ev->window; - e->time = _ecore_xcb_event_last_time; - if (ev->state == XCB_VISIBILITY_FULLY_OBSCURED) - e->fully_obscured = 1; - else - e->fully_obscured = 0; + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_visibility_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change)))) + return; - ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL); - } + e->win = ev->window; + e->time = _ecore_xcb_event_last_time; + if (ev->state == XCB_VISIBILITY_FULLY_OBSCURED) + e->fully_obscured = 1; + else + e->fully_obscured = 0; - free(event); -} /* _ecore_x_event_handle_visibility_notify */ + ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL); +} -void -_ecore_x_event_handle_create_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_create_notify(xcb_generic_event_t *event) { xcb_create_notify_event_t *ev; Ecore_X_Event_Window_Create *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_create_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Create)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Create)))) return; e->win = ev->window; + e->parent = ev->parent; if (ev->override_redirect) - e->override = 1; + e->override = 1; else - e->override = 0; - + e->override = 0; + e->x = ev->x; + e->y = ev->y; + e->w = ev->width; + e->h = ev->height; + e->border = ev->border_width; e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_create_notify */ + ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL); +} -void -_ecore_x_event_handle_destroy_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_destroy_notify(xcb_generic_event_t *event) { xcb_destroy_notify_event_t *ev; Ecore_X_Event_Window_Destroy *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_destroy_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy)))) return; e->win = ev->window; - e->time = _ecore_xcb_event_last_time; + e->event_win = ev->event; if (e->win == _ecore_xcb_event_last_window) - _ecore_xcb_event_last_window = 0; + _ecore_xcb_event_last_window = 0; + e->time = _ecore_xcb_event_last_time; ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL); +} - free(event); -} /* _ecore_x_event_handle_destroy_notify */ - -void -_ecore_x_event_handle_unmap_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event) { - xcb_unmap_notify_event_t *ev; - Ecore_X_Event_Window_Hide *e; + xcb_map_notify_event_t *ev; + Ecore_X_Event_Window_Show *e; - ev = (xcb_unmap_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Hide)); - if (!e) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_map_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Show)))) return; e->win = ev->window; + e->event_win = ev->event; e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_unmap_notify */ + ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL); +} -void -_ecore_x_event_handle_map_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event) { - xcb_map_notify_event_t *ev; - Ecore_X_Event_Window_Show *e; + xcb_unmap_notify_event_t *ev; + Ecore_X_Event_Window_Hide *e; - ev = (xcb_map_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Show)); - if (!e) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_unmap_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Hide)))) return; e->win = ev->window; + e->event_win = ev->event; e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_map_notify */ + ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL); +} -void -_ecore_x_event_handle_map_request(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_map_request(xcb_generic_event_t *event) { xcb_map_request_event_t *ev; Ecore_X_Event_Window_Show_Request *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_map_request_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request)))) return; e->win = ev->window; e->parent = ev->parent; e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_map_request */ + ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL); +} -void -_ecore_x_event_handle_reparent_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event) { xcb_reparent_notify_event_t *ev; Ecore_X_Event_Window_Reparent *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_reparent_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent)))) return; e->win = ev->window; + e->event_win = ev->event; e->parent = ev->parent; e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_reparent_notify */ + ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL); +} -void -_ecore_x_event_handle_configure_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event) { xcb_configure_notify_event_t *ev; Ecore_X_Event_Window_Configure *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_configure_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Configure)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure)))) return; e->win = ev->window; + e->event_win = ev->event; e->abovewin = ev->above_sibling; e->x = ev->x; e->y = ev->y; @@ -1158,25 +1044,27 @@ _ecore_x_event_handle_configure_notify(xcb_generic_event_t *event) e->border = ev->border_width; e->override = ev->override_redirect; /* send_event is bit 7 (0x80) of response_type */ - e->from_wm = (ev->response_type & 0x80) ? 1 : 0; + e->from_wm = ((ev->response_type & 0x80) ? 1 : 0); e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_configure_notify */ + ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL); +} -void -_ecore_x_event_handle_configure_request(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event) { xcb_configure_request_event_t *ev; Ecore_X_Event_Window_Configure_Request *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_configure_request_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request)))) + return; e->win = ev->window; + e->parent_win = ev->parent; e->abovewin = ev->sibling; e->x = ev->x; e->y = ev->y; @@ -1184,365 +1072,322 @@ _ecore_x_event_handle_configure_request(xcb_generic_event_t *event) e->h = ev->height; e->border = ev->border_width; e->value_mask = ev->value_mask; - switch (ev->stack_mode) { + switch (ev->stack_mode) + { case XCB_STACK_MODE_ABOVE: - e->detail = ECORE_X_WINDOW_STACK_ABOVE; - break; - + e->detail = ECORE_X_WINDOW_STACK_ABOVE; + break; case XCB_STACK_MODE_BELOW: - e->detail = ECORE_X_WINDOW_STACK_BELOW; - break; - + e->detail = ECORE_X_WINDOW_STACK_BELOW; + break; case XCB_STACK_MODE_TOP_IF: - e->detail = ECORE_X_WINDOW_STACK_TOP_IF; - break; - + e->detail = ECORE_X_WINDOW_STACK_TOP_IF; + break; case XCB_STACK_MODE_BOTTOM_IF: - e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF; - break; - + e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF; + break; case XCB_STACK_MODE_OPPOSITE: - e->detail = ECORE_X_WINDOW_STACK_OPPOSITE; - break; - } /* switch */ + e->detail = ECORE_X_WINDOW_STACK_OPPOSITE; + break; + } e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_configure_request */ + ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL); +} -void -_ecore_x_event_handle_gravity_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event) { - /* FIXME: handle this event type */ + xcb_gravity_notify_event_t *ev; + Ecore_X_Event_Window_Gravity *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - free(event); -} /* _ecore_x_event_handle_gravity_notify */ + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_gravity_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Gravity)))) return; -void -_ecore_x_event_handle_resize_request(xcb_generic_event_t *event) + e->win = ev->window; + e->event_win = ev->event; + e->time = _ecore_xcb_event_last_time; + + ecore_event_add(ECORE_X_EVENT_WINDOW_GRAVITY, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event) { xcb_resize_request_event_t *ev; Ecore_X_Event_Window_Resize_Request *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_resize_request_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request)))) return; e->win = ev->window; e->w = ev->width; e->h = ev->height; e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_resize_request */ + ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL); +} -void -_ecore_x_event_handle_circulate_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event) { xcb_circulate_notify_event_t *ev; Ecore_X_Event_Window_Stack *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_circulate_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Stack)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack)))) return; e->win = ev->window; e->event_win = ev->event; if (ev->place == XCB_PLACE_ON_TOP) - e->detail = ECORE_X_WINDOW_STACK_ABOVE; + e->detail = ECORE_X_WINDOW_STACK_ABOVE; else - e->detail = ECORE_X_WINDOW_STACK_BELOW; - + e->detail = ECORE_X_WINDOW_STACK_BELOW; e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_circulate_notify */ + ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL); +} -void -_ecore_x_event_handle_circulate_request(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event) { xcb_circulate_request_event_t *ev; Ecore_X_Event_Window_Stack_Request *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_circulate_request_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request)))) return; e->win = ev->window; e->parent = ev->event; if (ev->place == XCB_PLACE_ON_TOP) - e->detail = ECORE_X_WINDOW_STACK_ABOVE; + e->detail = ECORE_X_WINDOW_STACK_ABOVE; else - e->detail = ECORE_X_WINDOW_STACK_BELOW; - + e->detail = ECORE_X_WINDOW_STACK_BELOW; e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_circulate_request */ + ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL); +} -void -_ecore_x_event_handle_property_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event) { - { - xcb_property_notify_event_t *ev; - Ecore_X_Event_Window_Property *e; + xcb_property_notify_event_t *ev; + Ecore_X_Event_Window_Property *e; - ev = (xcb_property_notify_event_t *)event; - e = calloc(1,sizeof(Ecore_X_Event_Window_Property)); - if (!e) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - e->win = ev->window; - e->atom = ev->atom; - e->time = ev->time; - _ecore_xcb_event_last_time = e->time; - ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL); - } + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_property_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Property)))) return; - free(event); -} /* _ecore_x_event_handle_property_notify */ + e->win = ev->window; + e->atom = ev->atom; + e->time = ev->time; + _ecore_xcb_event_last_time = e->time; + + ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL); +} -void -_ecore_x_event_handle_selection_clear(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event) { xcb_selection_clear_event_t *ev; - Ecore_X_Selection_Intern *d; Ecore_X_Event_Selection_Clear *e; Ecore_X_Atom sel; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_selection_clear_event_t *)event; - d = _ecore_x_selection_get(ev->selection); - if (d && (ev->time > d->time)) - { - _ecore_x_selection_set(XCB_NONE, NULL, 0, - ev->selection); - } + if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Clear)))) return; - /* Generate event for app cleanup */ - e = malloc(sizeof(Ecore_X_Event_Selection_Clear)); e->win = ev->owner; - e->time = ev->time; e->atom = sel = ev->selection; if (sel == ECORE_X_ATOM_SELECTION_PRIMARY) - e->selection = ECORE_X_SELECTION_PRIMARY; + e->selection = ECORE_X_SELECTION_PRIMARY; else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY) - e->selection = ECORE_X_SELECTION_SECONDARY; + e->selection = ECORE_X_SELECTION_SECONDARY; else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD) - e->selection = ECORE_X_SELECTION_CLIPBOARD; + e->selection = ECORE_X_SELECTION_CLIPBOARD; else - e->selection = ECORE_X_SELECTION_OTHER; + e->selection = ECORE_X_SELECTION_OTHER; + e->time = ev->time; ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL); +} - free(event); -} /* _ecore_x_event_handle_selection_clear */ - -void -_ecore_x_event_handle_selection_request(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event) { xcb_selection_request_event_t *ev; Ecore_X_Event_Selection_Request *e; Ecore_X_Selection_Intern *sd; - void *data; - int len; - int typesize; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_selection_request_event_t *)event; - _ecore_xcb_last_event_mouse_move = 0; + if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Request)))) return; - /* - * Generate a selection request event. - */ - e = malloc(sizeof(Ecore_X_Event_Selection_Request)); e->owner = ev->owner; e->requestor = ev->requestor; - e->time = ev->time; e->selection = ev->selection; e->target = ev->target; e->property = ev->property; + e->time = ev->time; + ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL); - if ((sd = _ecore_x_selection_get(ev->selection)) && - (sd->win == ev->owner)) + if ((sd = _ecore_xcb_selection_get(ev->selection)) && + (sd->win == ev->owner)) { - Ecore_X_Selection_Intern *si; - - si = _ecore_x_selection_get(ev->selection); - if (si->data) + if (sd->data) { - Ecore_X_Atom property; - Ecore_X_Atom type; + Ecore_X_Atom property, type; + void *data; + int len = 0, typesize = 0; - /* Set up defaults for strings first */ type = ev->target; typesize = 8; len = sd->length; - - if (!ecore_x_selection_convert(ev->selection, ev->target, + if (!ecore_x_selection_convert(ev->selection, ev->target, &data, &len, &type, &typesize)) + property = XCB_NONE; + else { - /* Refuse selection, conversion to requested target failed */ - property = XCB_NONE; - } - else - { - /* FIXME: This does not properly handle large data transfers */ - ecore_x_window_prop_property_set(ev->requestor, - ev->property, - ev->target, - 8, data, sd->length); + ecore_x_window_prop_property_set(ev->requestor, ev->property, + type, typesize, data, len); property = ev->property; free(data); } - - ecore_x_selection_notify_send(ev->requestor, - ev->selection, - ev->target, - property, - ev->time); + ecore_x_selection_notify_send(ev->requestor, ev->selection, + ev->target, property, ev->time); } } -} /* _ecore_x_event_handle_selection_request */ +} -/* FIXME: round trip */ -void -_ecore_x_event_handle_selection_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_selection_notify(xcb_generic_event_t *event) { xcb_selection_notify_event_t *ev; Ecore_X_Event_Selection_Notify *e; unsigned char *data = NULL; Ecore_X_Atom selection; - int num_ret; - uint8_t format; + int num = 0, format = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_selection_notify_event_t *)event; selection = ev->selection; - - if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS) + if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS) { - ecore_x_window_prop_property_get_prefetch(ev->requestor, - ev->property, - ECORE_X_ATOM_ATOM); - ecore_x_window_prop_property_get_fetch(); - format = ecore_x_window_prop_property_get(ev->requestor, - ev->property, - ECORE_X_ATOM_ATOM, - 32, - &data, - &num_ret); - if (!format) - return; + format = + ecore_x_window_prop_property_get(ev->requestor, ev->property, + ECORE_X_ATOM_ATOM, 32, &data, &num); + if (!format) return; } - else + else { - ecore_x_window_prop_property_get_prefetch(ev->requestor, - ev->property, - XCB_GET_PROPERTY_TYPE_ANY); - ecore_x_window_prop_property_get_fetch(); - format = ecore_x_window_prop_property_get(ev->requestor, - ev->property, - ECORE_X_ATOM_ATOM, - 8, - &data, - &num_ret); - if (!format) - return; + format = + ecore_x_window_prop_property_get(ev->requestor, ev->property, + XCB_GET_PROPERTY_TYPE_ANY, 8, + &data, &num); + if (!format) return; } e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify)); - if (!e) - return; - + if (!e) return; e->win = ev->requestor; e->time = ev->time; e->atom = selection; - e->target = _ecore_x_selection_target_get(ev->target); + e->target = _ecore_xcb_selection_target_get(ev->target); if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) - e->selection = ECORE_X_SELECTION_PRIMARY; + e->selection = ECORE_X_SELECTION_PRIMARY; else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) - e->selection = ECORE_X_SELECTION_SECONDARY; + e->selection = ECORE_X_SELECTION_SECONDARY; else if (selection == ECORE_X_ATOM_SELECTION_XDND) - e->selection = ECORE_X_SELECTION_XDND; + e->selection = ECORE_X_SELECTION_XDND; else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) - e->selection = ECORE_X_SELECTION_CLIPBOARD; + e->selection = ECORE_X_SELECTION_CLIPBOARD; else - e->selection = ECORE_X_SELECTION_OTHER; + e->selection = ECORE_X_SELECTION_OTHER; - e->data = _ecore_x_selection_parse(e->target, data, num_ret, format); + e->data = _ecore_xcb_selection_parse(e->target, data, num, format); - ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_selection_notify, NULL); + ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, + _ecore_xcb_event_selection_notify_free, NULL); +} - free(event); -} /* _ecore_x_event_handle_selection_notify */ - -void -_ecore_x_event_handle_colormap_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event) { xcb_colormap_notify_event_t *ev; Ecore_X_Event_Window_Colormap *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; ev = (xcb_colormap_notify_event_t *)event; - e = calloc(1,sizeof(Ecore_X_Event_Window_Colormap)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Colormap)))) return; e->win = ev->window; e->cmap = ev->colormap; if (ev->state == XCB_COLORMAP_STATE_INSTALLED) - e->installed = 1; + e->installed = 1; else - e->installed = 0; - + e->installed = 0; e->time = _ecore_xcb_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL); - free(event); -} /* _ecore_x_event_handle_colormap_notify */ + ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL); +} -void -_ecore_x_event_handle_client_message(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_client_message(xcb_generic_event_t *event) { + xcb_client_message_event_t *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_client_message_event_t *)event; + /* Special client message event handling here. need to put LOTS of if */ /* checks here and generate synthetic events per special message known */ /* otherwise generate generic client message event. this would handle*/ /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */ - xcb_client_message_event_t *ev; - - ev = (xcb_client_message_event_t *)event; - if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) && - (ev->format == 32) && - (ev->data.data32[0] == (uint32_t)ECORE_X_ATOM_WM_DELETE_WINDOW)) + if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) && (ev->format == 32) && + (ev->data.data32[0] == ECORE_X_ATOM_WM_DELETE_WINDOW)) { Ecore_X_Event_Window_Delete_Request *e; - e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request)); - if (!e) - return; - + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request)))) + return; e->win = ev->window; e->time = _ecore_xcb_event_last_time; ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL); } - else if ((ev->type == ECORE_X_ATOM_NET_WM_MOVERESIZE) && - (ev->format == 32) && - /* Ignore move and resize with keyboard */ - (ev->data.data32[2] < 9)) + else if ((ev->type == ECORE_X_ATOM_NET_WM_MOVERESIZE) && + (ev->format == 32) && (ev->data.data32[2] < 9)) { Ecore_X_Event_Window_Move_Resize_Request *e; - e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request)); - if (!e) - return; - + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request)))) + return; e->win = ev->window; e->x = ev->data.data32[0]; e->y = ev->data.data32[1]; @@ -1551,150 +1396,88 @@ _ecore_x_event_handle_client_message(xcb_generic_event_t *event) e->source = ev->data.data32[4]; ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL); } - /* Xdnd Client Message Handling Begin */ - /* Message Type: XdndEnter target */ - else if (ev->type == ECORE_X_ATOM_XDND_ENTER) + else if (ev->type == ECORE_X_ATOM_XDND_ENTER) { Ecore_X_Event_Xdnd_Enter *e; Ecore_X_DND_Target *target; - uint32_t three; - - e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)); - if (!e) - return; - target = _ecore_x_dnd_target_get(); + if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)))) return; + target = _ecore_xcb_dnd_target_get(); target->state = ECORE_X_DND_TARGET_ENTERED; - - target = _ecore_x_dnd_target_get(); target->source = ev->data.data32[0]; target->win = ev->window; - target->version = ev->data.data32[1] >> 24; - if (target->version > ECORE_X_DND_VERSION) + target->version = (int)(ev->data.data32[1] >> 24); + if (target->version > ECORE_X_DND_VERSION) { - WRN("DND: Requested version %d, we only support up to %d", target->version, - ECORE_X_DND_VERSION); + WRN("DND: Requested version %d but we only support up to %d", + target->version, ECORE_X_DND_VERSION); + free(e); return; } - - /* FIXME: roud trip, but I don't know how to suppress it */ - if ((three = ev->data.data32[1] & 0x1UL)) + if (ev->data.data32[1] & 0x1UL) { - /* source supports more than 3 types, fetch property */ unsigned char *data; Ecore_X_Atom *types; - int num_ret; - int i; - uint8_t format; - - ecore_x_window_prop_property_get_prefetch(target->source, - ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM); - ecore_x_window_prop_property_get_fetch(); - format = ecore_x_window_prop_property_get(target->source, - ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, - 32, - &data, - &num_ret); - if (!format) + int num_ret = 0; + + if (!ecore_x_window_prop_property_get(target->source, + ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, + &data, &num_ret)) { - ERR("DND: Could not fetch data type list from source window, aborting."); + WRN("DND: Could not fetch data type list from source window"); + free(e); return; } - types = (Ecore_X_Atom *)data; e->types = calloc(num_ret, sizeof(char *)); - if (e->types) + if (e->types) { - xcb_get_atom_name_cookie_t *cookies; + int i = 0; - cookies = (xcb_get_atom_name_cookie_t *)malloc(sizeof(xcb_get_atom_name_cookie_t) * num_ret); - for (i = 0; i < num_ret; i++) - cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, types[i]); for (i = 0; i < num_ret; i++) - { - xcb_get_atom_name_reply_t *reply; - char *name; - - reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL); - if (reply) - { - name = (char *)malloc(sizeof (char) * (reply->name_len + 1)); - memcpy(name, - xcb_get_atom_name_name(reply), - reply->name_len); - name[reply->name_len] = '\0'; - e->types[i] = name; - free(reply); - } - } - free(cookies); + e->types[i] = ecore_x_atom_name_get(types[i]); } - e->num_types = num_ret; } - else + else { int i = 0; e->types = calloc(3, sizeof(char *)); - if (e->types) + if (e->types) { - xcb_get_atom_name_cookie_t cookies[3]; - - for (i = 0; i < 3; i++) - cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[i + 2]); - for (i = 0; i < 3; i++) + while ((i < 3) && (ev->data.data32[i + 2])) { - xcb_get_atom_name_reply_t *reply; - char *name; - - reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL); - if (reply && (ev->data.data32[i + 2])) - { - name = (char *)malloc(sizeof (char) * (reply->name_len + 1)); - memcpy(name, - xcb_get_atom_name_name(reply), - reply->name_len); - name[reply->name_len] = '\0'; - e->types[i] = name; - } - - if (reply) - free(reply); + e->types[i] = + ecore_x_atom_name_get(ev->data.data32[i + 2]); + i++; } } - e->num_types = i; } e->win = target->win; e->source = target->source; - ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_xdnd_enter, NULL); + ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, + _ecore_xcb_event_xdnd_enter_free, NULL); } - /* Message Type: XdndPosition target */ - else if (ev->type == ECORE_X_ATOM_XDND_POSITION) + else if (ev->type == ECORE_X_ATOM_XDND_POSITION) { Ecore_X_Event_Xdnd_Position *e; Ecore_X_DND_Target *target; - target = _ecore_x_dnd_target_get(); - if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || - (target->win != ev->window)) - return; - - target->pos.x = (int16_t)ev->data.data32[2] >> 16; - target->pos.y = (int16_t)ev->data.data32[2] & 0xFFFFUL; - target->action = ev->data.data32[4]; /* Version 2 */ - - target->time = (target->version >= 1) ? - ev->data.data32[3] : XCB_CURRENT_TIME; + target = _ecore_xcb_dnd_target_get(); + if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || + (target->win != ev->window)) return; + target->pos.x = ev->data.data32[2] >> 16; + target->pos.y = ev->data.data32[2] & 0xFFFFUL; + target->action = ev->data.data32[4]; + target->time = (target->version >= 1) ? + (Ecore_X_Time)ev->data.data32[3] : ecore_x_current_time_get(); e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position)); - if (!e) - return; - + if (!e) return; e->win = target->win; e->source = target->source; e->position.x = target->pos.x; @@ -1702,34 +1485,27 @@ _ecore_x_event_handle_client_message(xcb_generic_event_t *event) e->action = target->action; ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL); } - /* Message Type: XdndStatus source */ - else if (ev->type == ECORE_X_ATOM_XDND_STATUS) + else if (ev->type == ECORE_X_ATOM_XDND_STATUS) { Ecore_X_Event_Xdnd_Status *e; Ecore_X_DND_Source *source; - source = _ecore_x_dnd_source_get(); - /* Make sure source/target match */ - if ((source->win != ev->window) || - (source->dest != ev->data.data32[0])) - return; + source = _ecore_xcb_dnd_source_get(); + if ((source->win != ev->window) || + (source->dest != (Ecore_X_Window)ev->data.data32[0])) + return; source->await_status = 0; - source->will_accept = ev->data.data32[1] & 0x1UL; source->suppress = (ev->data.data32[1] & 0x2UL) ? 0 : 1; - - source->rectangle.x = (int16_t)ev->data.data32[2] >> 16; - source->rectangle.y = (int16_t)ev->data.data32[2] & 0xFFFFUL; - source->rectangle.width = (uint16_t)ev->data.data32[3] >> 16; - source->rectangle.height = (uint16_t)ev->data.data32[3] & 0xFFFFUL; - + source->rectangle.x = ev->data.data32[2] >> 16; + source->rectangle.y = ev->data.data32[2] & 0xFFFFUL; + source->rectangle.width = ev->data.data32[3] >> 16; + source->rectangle.height = ev->data.data32[3] & 0xFFFFUL; source->accepted_action = ev->data.data32[4]; e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status)); - if (!e) - return; - + if (!e) return; e->win = source->win; e->target = source->dest; e->will_accept = source->will_accept; @@ -1741,47 +1517,36 @@ _ecore_x_event_handle_client_message(xcb_generic_event_t *event) ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL); } - /* Message Type: XdndLeave target */ - /* Pretend the whole thing never happened, sort of */ - else if (ev->type == ECORE_X_ATOM_XDND_LEAVE) + else if (ev->type == ECORE_X_ATOM_XDND_LEAVE) { Ecore_X_Event_Xdnd_Leave *e; Ecore_X_DND_Target *target; - target = _ecore_x_dnd_target_get(); - if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || - (target->win != ev->window)) - return; - + target = _ecore_xcb_dnd_target_get(); + if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || + (target->win != ev->window)) + return; target->state = ECORE_X_DND_TARGET_IDLE; - e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave)); - if (!e) - return; - + if (!e) return; e->win = ev->window; - e->source = ev->data.data32[0]; + e->source = (Ecore_X_Window)ev->data.data32[0]; ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL); } - /* Message Type: XdndDrop target */ - else if (ev->type == ECORE_X_ATOM_XDND_DROP) + else if (ev->type == ECORE_X_ATOM_XDND_DROP) { Ecore_X_Event_Xdnd_Drop *e; Ecore_X_DND_Target *target; - target = _ecore_x_dnd_target_get(); - /* Match source/target */ - if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || + target = _ecore_xcb_dnd_target_get(); + if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || (target->win != ev->window)) - return; - - target->time = (target->version >= 1) ? - ev->data.data32[2] : _ecore_xcb_event_last_time; + return; + target->time = (target->version >= 1) ? + (Ecore_X_Time)ev->data.data32[2] : ecore_x_current_time_get(); e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop)); - if (!e) - return; - + if (!e) return; e->win = target->win; e->source = target->source; e->action = target->action; @@ -1789,398 +1554,910 @@ _ecore_x_event_handle_client_message(xcb_generic_event_t *event) e->position.y = target->pos.y; ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL); } - /* Message Type: XdndFinished source */ - else if (ev->type == ECORE_X_ATOM_XDND_FINISHED) + else if (ev->type == ECORE_X_ATOM_XDND_FINISHED) { Ecore_X_Event_Xdnd_Finished *e; Ecore_X_DND_Source *source; - uint8_t completed = 1; + Eina_Bool completed = EINA_TRUE; - source = _ecore_x_dnd_source_get(); - /* Match source/target */ - if ((source->win != ev->window) || - (source->dest != ev->data.data32[0])) - return; - - if ((source->version >= 5) && (ev->data.data32[1] & 0x1UL)) + source = _ecore_xcb_dnd_source_get(); + if ((source->win != ev->window) || + (source->dest != (Ecore_X_Window)ev->data.data32[0])) + return; + if ((source->version < 5) || (ev->data.data32[1] & 0x1UL)) { - /* Target successfully performed drop action */ ecore_x_selection_xdnd_clear(); source->state = ECORE_X_DND_SOURCE_IDLE; } - else + else if (source->version >= 5) { - completed = 0; + completed = EINA_FALSE; source->state = ECORE_X_DND_SOURCE_CONVERTING; - - /* FIXME: Probably need to add a timer to switch back to idle + /* FIXME: Probably need to add a timer to switch back to idle * and discard the selection data */ } - e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished)); - if (!e) - return; - + if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished)))) + return; e->win = source->win; e->target = source->dest; e->completed = completed; - if (source->version >= 5) + if (source->version >= 5) { source->accepted_action = ev->data.data32[2]; e->action = source->accepted_action; } - else + else { source->accepted_action = 0; e->action = source->action; } - ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL); } - else if (ev->type == ECORE_X_ATOM_NET_WM_STATE) + else if (ev->type == ECORE_X_ATOM_NET_WM_STATE) { Ecore_X_Event_Window_State_Request *e; - e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)); - if (!e) - return; - + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)))) + return; e->win = ev->window; if (ev->data.data32[0] == 0) - e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE; + e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE; else if (ev->data.data32[0] == 1) - e->action = ECORE_X_WINDOW_STATE_ACTION_ADD; + e->action = ECORE_X_WINDOW_STATE_ACTION_ADD; else if (ev->data.data32[0] == 2) - e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE; - else + e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE; + else { free(e); return; } - - e->state[0] = _ecore_x_netwm_state_get(ev->data.data32[1]); - if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN) + e->state[0] = _ecore_xcb_netwm_window_state_get(ev->data.data32[1]); + if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN) { - xcb_get_atom_name_reply_t *reply; - char *name; - - /* FIXME: round trip */ - reply = xcb_get_atom_name_reply(_ecore_xcb_conn, - xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[1]), - NULL); - if (reply) - { - name = (char *)malloc(sizeof (char) * (reply->name_len + 1)); - memcpy(name, - xcb_get_atom_name_name(reply), - reply->name_len); - name[reply->name_len] = '\0'; - ERR("Unknown state: %s", name); - free(name); - free(reply); - } + /* FIXME */ } - - e->state[1] = _ecore_x_netwm_state_get(ev->data.data32[2]); - if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN) + e->state[1] = _ecore_xcb_netwm_window_state_get(ev->data.data32[2]); + if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN) { - xcb_get_atom_name_reply_t *reply; - char *name; - - reply = xcb_get_atom_name_reply(_ecore_xcb_conn, - xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[2]), - NULL); - if (reply) - { - name = (char *)malloc(sizeof (char) * (reply->name_len + 1)); - memcpy(name, - xcb_get_atom_name_name(reply), - reply->name_len); - name[reply->name_len] = '\0'; - WRN("Unknown state: %s", name); - free(name); - } + /* FIXME */ } - e->source = ev->data.data32[3]; - ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL); } - else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) - && (ev->format == 32) - && (ev->data.data32[0] == XCB_WM_HINT_STATE)) + else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) && + (ev->format == 32) && (ev->data.data32[0] == XCB_WM_STATE_ICONIC)) { Ecore_X_Event_Window_State_Request *e; - e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)); - if (!e) - return; - + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)))) + return; e->win = ev->window; e->action = ECORE_X_WINDOW_STATE_ACTION_ADD; e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED; - ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL); } - else if ((ev->type == ECORE_X_ATOM_NET_WM_DESKTOP) - && (ev->format == 32)) + else if ((ev->type == ECORE_X_ATOM_NET_WM_DESKTOP) && (ev->format == 32)) { Ecore_X_Event_Desktop_Change *e; - e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change)); - if (!e) - return; - + if (!(e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change)))) + return; e->win = ev->window; e->desk = ev->data.data32[0]; e->source = ev->data.data32[1]; - ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL); } - else if ((ev->type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS)) + else if (ev->type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS) { Ecore_X_Event_Frame_Extents_Request *e; - e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request)); - if (!e) - return; - + if (!(e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request)))) + return; e->win = ev->window; - ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL); } - else if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) - && ((Ecore_X_Atom)ev->data.data32[0] == ECORE_X_ATOM_NET_WM_PING) - && (ev->format == 32)) + else if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) && + ((Ecore_X_Atom)ev->data.data32[0] == ECORE_X_ATOM_NET_WM_PING) && + (ev->format == 32)) { Ecore_X_Event_Ping *e; + Ecore_X_Window root = 0; + int count = 0; - e = calloc(1, sizeof(Ecore_X_Event_Ping)); - if (!e) - return; - + if (!(e = calloc(1, sizeof(Ecore_X_Event_Ping)))) return; e->win = ev->window; e->time = ev->data.data32[1]; e->event_win = ev->data.data32[2]; - ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL); + + count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); + if (count > 1) + root = ecore_x_window_root_get(e->win); + else + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + if (ev->window != root) + { + xcb_client_message_event_t cm; + + cm.response_type = XCB_CLIENT_MESSAGE; + cm.format = ev->format; + cm.window = root; + cm.type = ev->type; + cm.data.data32[0] = ECORE_X_ATOM_NET_WM_PING; + cm.data.data32[1] = ev->data.data32[1]; + cm.data.data32[2] = ev->window;//ev->data.data32[2]; + cm.data.data32[3] = 0; + cm.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), + (const char *)&cm); + } } - else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) && - (ev->format == 8)) + else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) && + (ev->format == 8)) { - _ecore_x_netwm_startup_info_begin(ev->window, (char *)ev->data.data8); + _ecore_xcb_netwm_startup_info_begin(ev->window, ev->data.data8[0]); } - else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) && - (ev->format == 8)) + else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) && (ev->format == 8)) { - _ecore_x_netwm_startup_info(ev->window, (char *)ev->data.data8); + _ecore_xcb_netwm_startup_info_begin(ev->window, ev->data.data8[0]); } - else if ((ev->type == 27777) - && (ev->data.data32[0] == 0x7162534) - && (ev->format == 32) - && (ev->window == _ecore_xcb_private_window)) + else if ((ev->type == 27777) && (ev->data.data32[0] == 0x7162534) && + (ev->format == 32))// && (ev->window = _private_window)) { - /* a grab sync marker */ if (ev->data.data32[1] == 0x10000001) - _ecore_x_window_grab_remove(ev->data.data32[2]); - else if (ev->data.data32[1] == 0x10000002) - _ecore_x_key_grab_remove(ev->data.data32[2]); + _ecore_xcb_window_button_grab_remove(ev->data.data32[2]); + else if (ev->data.data32[1] == 0x10000002) + _ecore_xcb_window_key_grab_remove(ev->data.data32[2]); } - else + else { Ecore_X_Event_Client_Message *e; - int i; + int i = 0; - e = calloc(1, sizeof(Ecore_X_Event_Client_Message)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Client_Message)))) + return; e->win = ev->window; e->message_type = ev->type; e->format = ev->format; for (i = 0; i < 5; i++) - e->data.l[i] = ev->data.data32[i]; - + e->data.l[i] = ev->data.data32[i]; ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL); } +} + +static void +_ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event) +{ + xcb_mapping_notify_event_t *ev; + Ecore_X_Event_Mapping_Change *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + + ev = (xcb_mapping_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change)))) return; + + _ecore_xcb_keymap_refresh(ev); + + switch (ev->request) + { + case XCB_MAPPING_MODIFIER: + e->type = ECORE_X_MAPPING_MODIFIER; + break; + case XCB_MAPPING_KEYBOARD: + e->type = ECORE_X_MAPPING_KEYBOARD; + break; + case XCB_MAPPING_POINTER: + default: + e->type = ECORE_X_MAPPING_MOUSE; + break; + } + e->keycode = ev->first_keycode; + e->num = ev->count; + + ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + +#ifdef ECORE_XCB_DAMAGE + xcb_damage_notify_event_t *ev; + Ecore_X_Event_Damage *e; + + ev = (xcb_damage_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Damage)))) return; + + e->level = ev->level; + e->drawable = ev->drawable; + e->damage = ev->damage; + e->time = ev->timestamp; + e->area.x = ev->area.x; + e->area.y = ev->area.y; + e->area.width = ev->area.width; + e->area.height = ev->area.height; + e->geometry.x = ev->geometry.x; + e->geometry.y = ev->geometry.y; + e->geometry.width = ev->geometry.width; + e->geometry.height = ev->geometry.height; - free(event); -} /* _ecore_x_event_handle_client_message */ + ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL); +#endif +} -void -_ecore_x_event_handle_mapping_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event) { - /* FIXME: handle this event type */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + +#ifdef ECORE_XCB_RANDR + xcb_randr_screen_change_notify_event_t *ev; + Ecore_X_Event_Screen_Change *e; + + ev = (xcb_randr_screen_change_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Screen_Change)))) return; + + e->win = ev->request_window; + e->root = ev->root; + e->size.width = ev->width; + e->size.height = ev->height; + e->time = ev->timestamp; + e->config_time = ev->config_timestamp; + e->size.width_mm = ev->mwidth; + e->size.height_mm = ev->mheight; + e->orientation = ev->rotation; + e->subpixel_order = ev->subpixel_order; - free(event); -} /* _ecore_x_event_handle_mapping_notify */ + ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL); +#endif +} -void -_ecore_x_event_handle_shape_change(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event) { -#ifdef ECORE_X_SHAPE - xcb_shape_notify_event_t *ev; - Ecore_X_Event_Window_Shape *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - ev = (xcb_shape_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Window_Shape)); - if (!e) - return; + _ecore_xcb_event_last_mouse_move = EINA_FALSE; - e->win = ev->affected_window; - e->time = ev->server_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL); -#endif /* ECORE_X_SHAPE */ +#ifdef ECORE_XCB_RANDR + xcb_randr_notify_event_t *ev; - free(event); -} /* _ecore_x_event_handle_shape_change */ + ev = (xcb_randr_notify_event_t *)event; + switch (ev->subCode) + { + case XCB_RANDR_NOTIFY_CRTC_CHANGE: + _ecore_xcb_event_handle_randr_crtc_change(event); + break; + case XCB_RANDR_NOTIFY_OUTPUT_CHANGE: + _ecore_xcb_event_handle_randr_output_change(event); + break; + case XCB_RANDR_NOTIFY_OUTPUT_PROPERTY: + _ecore_xcb_event_handle_randr_output_property_change(event); + break; + default: + break; + } +#endif +} -void -_ecore_x_event_handle_screensaver_notify(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event) { -#ifdef ECORE_X_SCREENSAVER + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + xcb_randr_notify_event_t *ev; + Ecore_X_Event_Randr_Crtc_Change *e; + + ev = (xcb_randr_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change)))) + return; + + e->win = ev->u.cc.window; + e->crtc = ev->u.cc.crtc; + e->mode = ev->u.cc.mode; + e->orientation = ev->u.cc.rotation; + e->geo.x = ev->u.cc.x; + e->geo.y = ev->u.cc.y; + e->geo.w = ev->u.cc.width; + e->geo.h = ev->u.cc.height; + + ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + xcb_randr_notify_event_t *ev; + Ecore_X_Event_Randr_Output_Change *e; + + ev = (xcb_randr_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change)))) + return; + + e->win = ev->u.oc.window; + e->output = ev->u.oc.output; + e->crtc = ev->u.oc.crtc; + e->mode = ev->u.oc.mode; + e->orientation = ev->u.oc.rotation; + e->connection = ev->u.oc.connection; + e->subpixel_order = ev->u.oc.subpixel_order; + + ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + xcb_randr_notify_event_t *ev; + Ecore_X_Event_Randr_Output_Property_Notify *e; + + ev = (xcb_randr_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify)))) + return; + + e->win = ev->u.op.window; + e->output = ev->u.op.output; + e->property = ev->u.op.atom; + e->time = ev->u.op.timestamp; + if (ev->u.op.status == XCB_PROPERTY_NEW_VALUE) + e->state = ECORE_X_RANDR_PROPERTY_CHANGE_ADD; + else + e->state = ECORE_X_RANDR_PROPERTY_CHANGE_DEL; + + ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + +#ifdef ECORE_XCB_SCREENSAVER xcb_screensaver_notify_event_t *ev; Ecore_X_Event_Screensaver_Notify *e; ev = (xcb_screensaver_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify)))) return; e->win = ev->window; - if (ev->state == XCB_SCREENSAVER_STATE_ON) - e->on = 1; - else - e->on = 0; - + e->on = EINA_FALSE; + if (ev->state == XCB_SCREENSAVER_STATE_ON) e->on = EINA_TRUE; e->time = ev->time; + ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL); -#endif /* ECORE_X_SCREENSAVER */ +#endif +} + +#ifdef ECORE_XCB_SHAPE +static void +_ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event) +{ + xcb_shape_notify_event_t *ev; + Ecore_X_Event_Window_Shape *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - free(event); -} /* _ecore_x_event_handle_screensaver_notify */ + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_shape_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Shape)))) return; -void -_ecore_x_event_handle_sync_counter(xcb_generic_event_t *event) + e->win = ev->affected_window; + e->time = ev->server_time; + switch (ev->shape_kind) + { + case XCB_SHAPE_SK_BOUNDING: + e->type = ECORE_X_SHAPE_BOUNDING; + break; + case XCB_SHAPE_SK_CLIP: + e->type = ECORE_X_SHAPE_CLIP; + break; + case XCB_SHAPE_SK_INPUT: + e->type = ECORE_X_SHAPE_INPUT; + break; + default: + break; + } + e->x = ev->extents_x; + e->y = ev->extents_y; + e->w = ev->extents_width; + e->h = ev->extents_height; + e->shaped = ev->shaped; + + ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL); +} +#endif + +static void +_ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event) { -#ifdef ECORE_X_SYNC + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + +#ifdef ECORE_XCB_SYNC xcb_sync_counter_notify_event_t *ev; Ecore_X_Event_Sync_Counter *e; ev = (xcb_sync_counter_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter)))) return; e->time = ev->timestamp; - ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL); -#endif /* ECORE_X_SYNC */ - free(event); -} /* _ecore_x_event_handle_sync_counter */ + ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL); +#endif +} -void -_ecore_x_event_handle_sync_alarm(xcb_generic_event_t *event) +static void +_ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event) { -#ifdef ECORE_X_SYNC + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + +#ifdef ECORE_XCB_SYNC xcb_sync_alarm_notify_event_t *ev; Ecore_X_Event_Sync_Alarm *e; ev = (xcb_sync_alarm_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm)); - if (!e) - return; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm)))) return; e->time = ev->timestamp; e->alarm = ev->alarm; + ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL); -#endif /* ECORE_X_SYNC */ +#endif +} - free(event); -} /* _ecore_x_event_handle_sync_alarm */ +static void +_ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event __UNUSED__) +{ +// xcb_xfixes_selection_notify_event_t *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +// ev = (xcb_xfixes_selection_notify_event_t *)event; -/* FIXME: round trip */ -void -_ecore_x_event_handle_randr_change(xcb_generic_event_t *event) +// FIXME: TBD +} + +static void +_ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event __UNUSED__) { -#ifdef ECORE_X_RANDR - xcb_randr_screen_change_notify_event_t *ev; - Ecore_X_Event_Screen_Change *e; + LOGFN(__FILE__, __LINE__, __FUNCTION__); +// FIXME: TBD +} - ev = (xcb_randr_screen_change_notify_event_t *)event; +static void +_ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event) +{ + xcb_ge_event_t *ev; + Ecore_X_Event_Generic *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ev = (xcb_ge_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Generic)))) + return; + + DBG("Handle Generic Event: %d", ev->event_type); + + e->cookie = ev->sequence; + /* NB: These are bugs in xcb ge_event structure. The struct should have a + * field for extension & data, but does not. + * + * XCB people have been notified of this issue */ + e->extension = ev->pad0; + /* e->data = ev->pad1; */ + + e->evtype = ev->event_type; + + /* FIXME: e->extension check may need to be against xcb_input_id + * NB: Have to test this */ + if (e->extension == _ecore_xcb_event_input) + _ecore_xcb_event_handle_input_event(event); + + ecore_event_add(ECORE_X_EVENT_GENERIC, e, + _ecore_xcb_event_generic_event_free, event); +} + +static void +_ecore_xcb_event_handle_input_event(xcb_generic_event_t *event) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_input_handle_event(event); +} + +static void +_ecore_xcb_event_key_press(xcb_generic_event_t *event) +{ + Ecore_Event_Key *e; + xcb_keysym_t sym = XCB_NO_SYMBOL; + xcb_keycode_t keycode = 0; + xcb_key_press_event_t *xevent; + char *keyname = NULL, *key = NULL; + char *compose = NULL, *tmp = NULL; + char compose_buffer[256]; + int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; - if ((ev->response_type & ~0x80) != XCB_CONFIGURE_NOTIFY) + xevent = (xcb_key_press_event_t *)event; + keycode = xevent->detail; + + sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state); + keyname = _ecore_xcb_keymap_keysym_to_string(sym); + if (!keyname) { - xcb_query_extension_reply_t *rep; + char buff[256]; + + snprintf(buff, sizeof(buff), "Keycode-%i", keycode); + keyname = buff; + } - rep = xcb_query_extension_reply(_ecore_xcb_conn, - xcb_query_extension_unchecked(_ecore_xcb_conn, - strlen("randr"), - "randr"), - NULL); + /* FIXME: Ecore_X_Ic */ + val = + _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer, + sizeof(compose_buffer), &sym); + if (val > 0) + { + compose_buffer[val] = 0; + compose = + eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer); + tmp = compose; + } - if ((!rep) || - (((ev->response_type & ~0x80) - rep->first_event) != XCB_RANDR_SCREEN_CHANGE_NOTIFY)) - WRN("ERROR: Can't update RandR config!"); + key = _ecore_xcb_keymap_keysym_to_string(sym); + if (!key) key = keyname; - if (rep) - free(rep); + e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + + (compose ? strlen(compose) : 0) + 3); + if (e) + { + e->keyname = (char *)(e + 1); + e->key = e->keyname + strlen(keyname) + 1; + + e->compose = NULL; + if (compose) e->compose = (e->key + strlen(key) + 1); + e->string = e->compose; + + strcpy((char *)e->keyname, keyname); + strcpy((char *)e->key, key); + if (compose) strcpy((char *)e->compose, compose); + + e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state); + e->timestamp = xevent->time; + e->window = xevent->child ? xevent->child : xevent->event; + e->event_window = xevent->event; + e->same_screen = xevent->same_screen; + e->root_window = xevent->root; + + ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); } + _ecore_xcb_event_last_time = xevent->time; +} + +static void +_ecore_xcb_event_key_release(xcb_generic_event_t *event) +{ + Ecore_Event_Key *e; + xcb_keysym_t sym = XCB_NO_SYMBOL; + xcb_keycode_t keycode = 0; + xcb_key_release_event_t *xevent; + char *keyname = NULL, *key = NULL; + char *compose = NULL, *tmp = NULL; + char compose_buffer[256]; + int val = 0; - e = calloc(1, sizeof(Ecore_X_Event_Screen_Change)); - if (!e) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - e->win = ev->request_window; - e->root = ev->root; - e->width = ev->width; - e->height = ev->height; - ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL); -#endif /* ECORE_X_RANDR */ + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + + xevent = (xcb_key_release_event_t *)event; + keycode = xevent->detail; + + sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state); + keyname = _ecore_xcb_keymap_keysym_to_string(sym); + if (!keyname) + { + char buff[256]; + + snprintf(buff, sizeof(buff), "Keycode-%i", keycode); + keyname = buff; + } + + /* FIXME: Ecore_X_Ic */ + val = + _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer, + sizeof(compose_buffer), &sym); + if (val > 0) + { + compose_buffer[val] = 0; + compose = + eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer); + tmp = compose; + } + + key = _ecore_xcb_keymap_keysym_to_string(sym); + if (!key) key = keyname; + + e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + + (compose ? strlen(compose) : 0) + 3); + if (e) + { + e->keyname = (char *)(e + 1); + e->key = e->keyname + strlen(keyname) + 1; + + e->compose = NULL; + if (compose) e->compose = (e->key + strlen(key) + 1); + e->string = e->compose; + + strcpy((char *)e->keyname, keyname); + strcpy((char *)e->key, key); + if (compose) strcpy((char *)e->compose, compose); - free(event); -} /* _ecore_x_event_handle_randr_change */ + e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state); + e->timestamp = xevent->time; + e->window = xevent->child ? xevent->child : xevent->event; + e->event_window = xevent->event; + e->same_screen = xevent->same_screen; + e->root_window = xevent->root; -void -_ecore_x_event_handle_fixes_selection_notify(xcb_generic_event_t *event) + ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL); + } + _ecore_xcb_event_last_time = xevent->time; +} + +void +_ecore_xcb_event_mouse_move(uint16_t timestamp, uint16_t modifiers, int16_t x, int16_t y, int16_t root_x, int16_t root_y, xcb_window_t event_win, xcb_window_t win, xcb_window_t root_win, uint8_t same_screen, int dev, double radx, double rady, double pressure, double angle, int16_t mx, int16_t my, int16_t mrx, int16_t mry) { -#ifdef ECORE_X_FIXES - /* Nothing here yet */ -#endif /* ECORE_X_FIXES */ + Ecore_Event_Mouse_Move *e; + Ecore_Event *event; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - free(event); -} /* _ecore_x_event_handle_fixes_selection_notify */ + if (!(e = malloc(sizeof(Ecore_Event_Mouse_Move)))) return; -void -_ecore_x_event_handle_damage_notify(xcb_generic_event_t *event) + e->window = win; + e->root_window = root_win; + e->timestamp = timestamp; + e->same_screen = same_screen; + e->event_window = event_win; + e->modifiers = _ecore_xcb_events_modifiers_get(modifiers); + e->x = x; + e->y = y; + e->root.x = root_x; + e->root.y = root_y; + e->multi.device = dev; + e->multi.radius = ((radx + rady) / 2); + e->multi.radius_x = radx; + e->multi.radius_y = rady; + e->multi.pressure = pressure; + e->multi.angle = angle; + e->multi.x = mx; + e->multi.y = my; + e->multi.root.x = mrx; + e->multi.root.y = mry; + + event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, + _ecore_xcb_event_mouse_move_free, NULL); + + _ecore_xcb_event_last_time = e->timestamp; + _ecore_xcb_event_last_window = e->window; + _ecore_xcb_event_last_root_x = root_x; + _ecore_xcb_event_last_root_y = root_y; + _ecore_xcb_event_last_mouse_move_event = event; +} + +static void +_ecore_xcb_event_mouse_move_free(void *data __UNUSED__, void *event) { -#ifdef ECORE_XCBDAMAGE - xcb_damage_notify_event_t *ev; - Ecore_X_Event_Damage *e; + Ecore_Event_Mouse_Move *ev; - ev = (xcb_damage_notify_event_t *)event; - e = calloc(1, sizeof(Ecore_X_Event_Damage)); - if (!e) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - e->level = ev->level; - e->drawable = ev->drawable; - e->damage = ev->damage; - /* FIXME: XCB has no 'more' member in xcb_damage_notify_event_t */ -/* e->more = ev->more; */ - e->time = ev->timestamp; - e->area.x = ev->area.x; - e->area.y = ev->area.y; - e->area.width = ev->area.width; - e->area.height = ev->area.height; - e->geometry.x = ev->geometry.x; - e->geometry.y = ev->geometry.y; - e->geometry.width = ev->geometry.width; - e->geometry.height = ev->geometry.height; + ev = event; + if (_ecore_xcb_event_last_mouse_move_event) + { + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + _ecore_xcb_event_last_mouse_move_event = NULL; + } + if (ev) free(ev); +} - ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL); -#endif /* ECORE_XCBDAMAGE */ +Ecore_Event_Mouse_Button * +_ecore_xcb_event_mouse_button(int event, uint16_t timestamp, uint16_t modifiers, xcb_button_t buttons, int16_t x, int16_t y, int16_t root_x, int16_t root_y, xcb_window_t event_win, xcb_window_t win, xcb_window_t root_win, uint8_t same_screen, int dev, double radx, double rady, double pressure, double angle, int16_t mx, int16_t my, int16_t mrx, int16_t mry) +{ + Ecore_Event_Mouse_Button *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(e = malloc(sizeof(Ecore_Event_Mouse_Button)))) return NULL; + + e->window = win; + e->root_window = root_win; + e->timestamp = timestamp; + e->same_screen = same_screen; + e->event_window = event_win; + e->buttons = buttons; + e->modifiers = _ecore_xcb_events_modifiers_get(modifiers); + e->double_click = 0; + e->triple_click = 0; + e->x = x; + e->y = y; + e->root.x = root_x; + e->root.y = root_y; + + if (event_win == win) + { + if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) + { + if (((int)(timestamp - _ecore_xcb_mouse_down_last_time) <= + (int)(1000 * _ecore_xcb_double_click_time)) && + (win == _ecore_xcb_mouse_down_last_win) && + (event_win == _ecore_xcb_mouse_down_last_event_win)) + { + e->double_click = 1; + _ecore_xcb_mouse_down_did_double = EINA_TRUE; + } + else + { + _ecore_xcb_mouse_down_did_double = EINA_FALSE; + _ecore_xcb_mouse_down_did_triple = EINA_FALSE; + } + if (((int)(timestamp - _ecore_xcb_mouse_down_last_last_time) <= + (int)(2 * 1000 * _ecore_xcb_double_click_time)) && + (win == _ecore_xcb_mouse_down_last_win) && + (win == _ecore_xcb_mouse_down_last_last_win) && + (event_win == _ecore_xcb_mouse_down_last_event_win) && + (event_win == _ecore_xcb_mouse_down_last_last_event_win)) + { + e->triple_click = 1; + _ecore_xcb_mouse_down_did_triple = EINA_TRUE; + } + else + _ecore_xcb_mouse_down_did_triple = EINA_FALSE; + } + else + { + if (_ecore_xcb_mouse_down_did_double) + e->double_click = 1; + if (_ecore_xcb_mouse_down_did_triple) + e->triple_click = 1; + } + } + + /* NB: Comment out right now because _ecore_xcb_mouse_up_count is + * only used here...nowhere else in the code */ + + /* if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && */ + /* (!e->double_click) && (!e->triple_click)) */ + /* _ecore_xcb_mouse_up_count = 0; */ - free(event); -} /* _ecore_x_event_handle_damage_notify */ + e->multi.device = dev; + e->multi.radius = ((radx + rady) / 2); + e->multi.radius_x = radx; + e->multi.radius_y = rady; + e->multi.pressure = pressure; + e->multi.angle = angle; + e->multi.x = mx; + e->multi.y = my; + e->multi.root.x = mrx; + e->multi.root.y = mry; + _ecore_xcb_event_last_time = e->timestamp; + _ecore_xcb_event_last_window = e->window; + _ecore_xcb_event_last_root_x = root_x; + _ecore_xcb_event_last_root_y = root_y; + + ecore_event_add(event, e, NULL, NULL); + + return e; +} + +static Ecore_X_Event_Mode +_ecore_xcb_event_mode_get(uint8_t mode) +{ + switch (mode) + { + case XCB_NOTIFY_MODE_NORMAL: + return ECORE_X_EVENT_MODE_NORMAL; + case XCB_NOTIFY_MODE_WHILE_GRABBED: + return ECORE_X_EVENT_MODE_WHILE_GRABBED; + case XCB_NOTIFY_MODE_GRAB: + return ECORE_X_EVENT_MODE_GRAB; + case XCB_NOTIFY_MODE_UNGRAB: + return ECORE_X_EVENT_MODE_UNGRAB; + default: + return ECORE_X_EVENT_MODE_NORMAL; + } +} + +static Ecore_X_Event_Detail +_ecore_xcb_event_detail_get(uint8_t detail) +{ + switch (detail) + { + case XCB_NOTIFY_DETAIL_ANCESTOR: + return ECORE_X_EVENT_DETAIL_ANCESTOR; + case XCB_NOTIFY_DETAIL_VIRTUAL: + return ECORE_X_EVENT_DETAIL_VIRTUAL; + case XCB_NOTIFY_DETAIL_INFERIOR: + return ECORE_X_EVENT_DETAIL_INFERIOR; + case XCB_NOTIFY_DETAIL_NONLINEAR: + return ECORE_X_EVENT_DETAIL_NON_LINEAR; + case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL: + return ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; + case XCB_NOTIFY_DETAIL_POINTER: + return ECORE_X_EVENT_DETAIL_POINTER; + case XCB_NOTIFY_DETAIL_POINTER_ROOT: + return ECORE_X_EVENT_DETAIL_POINTER_ROOT; + case XCB_NOTIFY_DETAIL_NONE: + default: + return ECORE_X_EVENT_DETAIL_ANCESTOR; + } +} + +static void +_ecore_xcb_event_xdnd_enter_free(void *data __UNUSED__, void *event) +{ + Ecore_X_Event_Xdnd_Enter *e; + int i = 0; + + e = event; + for (i = 0; i < e->num_types; i++) + free(e->types[i]); + free(e->types); + free(e); +} + +static void +_ecore_xcb_event_selection_notify_free(void *data __UNUSED__, void *event) +{ + Ecore_X_Event_Selection_Notify *e; + Ecore_X_Selection_Data *sel; + + e = event; + if (!(sel = e->data)) return; + if (sel->free) sel->free(sel); + free(e->target); + free(e); +} + +static void +_ecore_xcb_event_generic_event_free(void *data, void *event) +{ + Ecore_X_Event_Generic *e; + + e = (Ecore_X_Event_Generic *)event; + if (e->data) free(data); + free(e); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_extensions.c b/src/lib/ecore_x/xcb/ecore_xcb_extensions.c new file mode 100644 index 0000000..cd24997 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_extensions.c @@ -0,0 +1,139 @@ +#include "ecore_xcb_private.h" + +void +_ecore_xcb_extensions_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_big_requests_id); + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shm_id); + +#ifdef ECORE_XCB_SHAPE + _ecore_xcb_shape_init(); +#endif + +#ifdef ECORE_XCB_SCREENSAVER + _ecore_xcb_screensaver_init(); +#endif + +#ifdef ECORE_XCB_SYNC + _ecore_xcb_sync_init(); +#endif + +#ifdef ECORE_XCB_RANDR + _ecore_xcb_randr_init(); +#endif + +#ifdef ECORE_XCB_XFIXES + _ecore_xcb_xfixes_init(); +#endif + +#ifdef ECORE_XCB_DAMAGE + _ecore_xcb_damage_init(); +#endif + +#ifdef ECORE_XCB_RENDER + _ecore_xcb_render_init(); +#endif + +#ifdef ECORE_XCB_COMPOSITE + _ecore_xcb_composite_init(); +#endif + +#ifdef ECORE_XCB_DPMS + _ecore_xcb_dpms_init(); +#endif + +#ifdef ECORE_XCB_DPMS + _ecore_xcb_dpms_init(); +#endif + +#ifdef ECORE_XCB_CURSOR + _ecore_xcb_cursor_init(); +#endif + +#ifdef ECORE_XCB_XINERAMA + _ecore_xcb_xinerama_init(); +#endif + +#ifdef ECORE_XCB_XINPUT + _ecore_xcb_input_init(); +#endif + +#ifdef ECORE_XCB_DRI + _ecore_xcb_dri_init(); +#endif + +#ifdef ECORE_XCB_XTEST + _ecore_xcb_xtest_init(); +#endif + + xcb_prefetch_maximum_request_length(_ecore_xcb_conn); +} + +void +_ecore_xcb_extensions_finalize(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xcb_get_extension_data(_ecore_xcb_conn, &xcb_big_requests_id); + xcb_get_extension_data(_ecore_xcb_conn, &xcb_shm_id); + +#ifdef ECORE_XCB_SHAPE + _ecore_xcb_shape_finalize(); +#endif + +#ifdef ECORE_XCB_SCREENSAVER + _ecore_xcb_screensaver_finalize(); +#endif + +#ifdef ECORE_XCB_SYNC + _ecore_xcb_sync_finalize(); +#endif + +#ifdef ECORE_XCB_RANDR + _ecore_xcb_randr_finalize(); +#endif + +#ifdef ECORE_XCB_XFIXES + _ecore_xcb_xfixes_finalize(); +#endif + +#ifdef ECORE_XCB_DAMAGE + _ecore_xcb_damage_finalize(); +#endif + +#ifdef ECORE_XCB_RENDER + _ecore_xcb_render_finalize(); +#endif + +#ifdef ECORE_XCB_COMPOSITE + _ecore_xcb_composite_finalize(); +#endif + +#ifdef ECORE_XCB_DPMS + _ecore_xcb_dpms_finalize(); +#endif + +#ifdef ECORE_XCB_CURSOR + _ecore_xcb_cursor_finalize(); +#endif + +#ifdef ECORE_XCB_XINERAMA + _ecore_xcb_xinerama_finalize(); +#endif + +#ifdef ECORE_XCB_XINPUT + _ecore_xcb_input_finalize(); +#endif + +#ifdef ECORE_XCB_DRI + _ecore_xcb_dri_finalize(); +#endif + +#ifdef ECORE_XCB_XTEST + _ecore_xcb_xtest_finalize(); +#endif + + xcb_get_maximum_request_length(_ecore_xcb_conn); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_gc.c b/src/lib/ecore_x/xcb/ecore_xcb_gc.c index 4d5ce05..d7fb7e3 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_gc.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_gc.c @@ -3,42 +3,136 @@ /** * Creates a new default graphics context associated with the given * drawable. - * @param drawable Drawable to create graphics context with. If @c 0 is - * given instead, the default root window is used. + * @param draw Drawable to create graphics context with. If @c 0 is + * given instead, the default root window is used. * @param value_mask Bitmask values. * @param value_list List of values. The order of values must be the * same than the corresponding bitmaks. - * @return The new default graphics context. - * - * Creates a new default graphics context associated with @p - * drawable. The graphic context can be used with any destination - * drawable having the same root and depth as @p drawable. Use with - * other drawables results in a BadMatch error. + * @return The new default graphics context. */ -EAPI Ecore_X_GC -ecore_x_gc_new(Ecore_X_Drawable drawable, Ecore_X_GC_Value_Mask value_mask, const unsigned int *value_list) +EAPI Ecore_X_GC +ecore_x_gc_new(Ecore_X_Drawable drawable, Ecore_X_GC_Value_Mask value_mask, const unsigned int *value_list) { xcb_gcontext_t gc; + uint32_t vmask = 0; + int i = 0, mask = 0; - if (!drawable) - drawable = ((xcb_screen_t *)_ecore_xcb_screen)->root; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!drawable) drawable = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + for (i = 0, mask = 1; i <= 22; i++, mask <<= 1) + { + switch (mask & value_mask) + { + case ECORE_X_GC_VALUE_MASK_FUNCTION: + vmask |= XCB_GC_FUNCTION; + break; + case ECORE_X_GC_VALUE_MASK_PLANE_MASK: + vmask |= XCB_GC_PLANE_MASK; + break; + case ECORE_X_GC_VALUE_MASK_FOREGROUND: + vmask |= XCB_GC_FOREGROUND; + break; + case ECORE_X_GC_VALUE_MASK_BACKGROUND: + vmask |= XCB_GC_BACKGROUND; + break; + case ECORE_X_GC_VALUE_MASK_LINE_WIDTH: + vmask |= XCB_GC_LINE_WIDTH; + break; + case ECORE_X_GC_VALUE_MASK_LINE_STYLE: + vmask |= XCB_GC_LINE_STYLE; + break; + case ECORE_X_GC_VALUE_MASK_CAP_STYLE: + vmask |= XCB_GC_CAP_STYLE; + break; + case ECORE_X_GC_VALUE_MASK_JOIN_STYLE: + vmask |= XCB_GC_JOIN_STYLE; + break; + case ECORE_X_GC_VALUE_MASK_FILL_STYLE: + vmask |= XCB_GC_FILL_STYLE; + break; + case ECORE_X_GC_VALUE_MASK_FILL_RULE: + vmask |= XCB_GC_FILL_RULE; + break; + case ECORE_X_GC_VALUE_MASK_TILE: + vmask |= XCB_GC_TILE; + break; + case ECORE_X_GC_VALUE_MASK_STIPPLE: + vmask |= XCB_GC_STIPPLE; + break; + case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_X: + vmask |= XCB_GC_TILE_STIPPLE_ORIGIN_X; + break; + case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_Y: + vmask |= XCB_GC_TILE_STIPPLE_ORIGIN_Y; + break; + case ECORE_X_GC_VALUE_MASK_FONT: + vmask |= XCB_GC_FONT; + break; + case ECORE_X_GC_VALUE_MASK_SUBWINDOW_MODE: + vmask |= XCB_GC_SUBWINDOW_MODE; + break; + case ECORE_X_GC_VALUE_MASK_GRAPHICS_EXPOSURES: + vmask |= XCB_GC_GRAPHICS_EXPOSURES; + break; + case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_X: + vmask |= XCB_GC_CLIP_ORIGIN_X; + break; + case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_Y: + vmask |= XCB_GC_CLIP_ORIGIN_Y; + break; + case ECORE_X_GC_VALUE_MASK_CLIP_MASK: + vmask |= XCB_GC_CLIP_MASK; + break; + case ECORE_X_GC_VALUE_MASK_DASH_OFFSET: + vmask |= XCB_GC_DASH_OFFSET; + break; + case ECORE_X_GC_VALUE_MASK_DASH_LIST: + vmask |= XCB_GC_DASH_LIST; + break; + case ECORE_X_GC_VALUE_MASK_ARC_MODE: + vmask |= XCB_GC_ARC_MODE; + break; + } + } gc = xcb_generate_id(_ecore_xcb_conn); - xcb_create_gc(_ecore_xcb_conn, gc, drawable, value_mask, value_list); + xcb_create_gc(_ecore_xcb_conn, gc, drawable, vmask, value_list); return gc; -} /* ecore_x_gc_new */ +} /** * Deletes and frees the given graphics context. * @param gc The given graphics context. - * - * Destroyes the graphic context @p gc as well as the associated - * storage. */ -EAPI void -ecore_x_gc_free(Ecore_X_GC gc) +EAPI void +ecore_x_gc_free(Ecore_X_GC gc) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + xcb_free_gc(_ecore_xcb_conn, gc); -} /* ecore_x_gc_free */ +} + +EAPI void +ecore_x_gc_foreground_set(Ecore_X_GC gc, unsigned long foreground) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + list = foreground; + xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list); +} + +EAPI void +ecore_x_gc_background_set(Ecore_X_GC gc, unsigned long background) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + list = background; + xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_BACKGROUND, &list); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_icccm.c b/src/lib/ecore_x/xcb/ecore_xcb_icccm.c index 291e22e..6c86686 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_icccm.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_icccm.c @@ -1,1097 +1,305 @@ -/* - * Various ICCCM related functions. - * - * This is ALL the code involving anything ICCCM related, for both WM and - * client. - */ - -#include -#include -#include - -#include - #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" - -/** - * @defgroup Ecore_X_ICCCM_Group ICCCM related functions. - * - * Functions related to ICCCM. - */ - -static int _ecore_x_icccm_size_hints_get (const void *reply, - Ecore_X_Atom property, - xcb_size_hints_t *hints) -{ - uint32_t s; - - if (!hints) - return 0; - - if (!reply) - return 0; - - if ((((xcb_get_property_reply_t *)reply)->type != ECORE_X_ATOM_WM_SIZE_HINTS) && - ((((xcb_get_property_reply_t *)reply)->format != 8) || - (((xcb_get_property_reply_t *)reply)->format != 16) || - (((xcb_get_property_reply_t *)reply)->format != 32)) && - (((xcb_get_property_reply_t *)reply)->value_len < 15)) /* OldNumPropSizeElements = 15 (pre-ICCCM) */ - return 0; - - memcpy(hints, - xcb_get_property_value((xcb_get_property_reply_t *)reply), - ((xcb_get_property_reply_t *)reply)->value_len); - - s = (XCB_SIZE_HINT_US_POSITION | XCB_SIZE_HINT_US_SIZE | - XCB_SIZE_HINT_P_POSITION | XCB_SIZE_HINT_P_SIZE | - XCB_SIZE_HINT_P_MIN_SIZE | XCB_SIZE_HINT_P_MAX_SIZE | - XCB_SIZE_HINT_P_RESIZE_INC | XCB_SIZE_HINT_P_ASPECT); - - if (((xcb_get_property_reply_t *)reply)->value_len >= 18) /* NumPropSizeElements = 18 (ICCCM version 1) */ - s |= (XCB_SIZE_HINT_BASE_SIZE | XCB_SIZE_HINT_P_WIN_GRAVITY); - else - { - xcb_size_hints_set_base_size(hints, 0, 0); - xcb_size_hints_set_win_gravity(hints, 0); - } - - /* FIXME: is it necessary ? */ - /* hints->flags &= s; */ /* get rid of unwanted bits */ - - return 1; -} /* _ecore_x_icccm_size_hints_get */ - -/** - * Sets the state of a window. - * @param window The window. - * @param state The state. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_state_set(Ecore_X_Window window, - Ecore_X_Window_State_Hint state) -{ - uint32_t c[2]; - - if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) - c[0] = XCB_WM_STATE_WITHDRAWN; - else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL) - c[0] = XCB_WM_STATE_NORMAL; - else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC) - c[0] = XCB_WM_STATE_ICONIC; - - c[1] = 0; - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE, 32, - 2, c); -} /* ecore_x_icccm_state_set */ - -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_state_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_WM_STATE, - ECORE_X_ATOM_WM_STATE, - 0L, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_state_get_prefetch */ - -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_state_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_state_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_state_get_fetch */ - -/** - * Gets the state of a window. - * @param window The window. - * @return The state of the window - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_state_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_state_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI Ecore_X_Window_State_Hint -ecore_x_icccm_state_get(Ecore_X_Window window __UNUSED__) -{ - xcb_get_property_reply_t *reply; - uint8_t *prop; - Ecore_X_Window_State_Hint hint = ECORE_X_WINDOW_STATE_HINT_NONE; - - reply = _ecore_xcb_reply_get(); - if (!reply) - return hint; - - if ((reply->type == 0) || - (reply->format != 8) || - (reply->value_len != 2)) - return hint; - - prop = (uint8_t *)xcb_get_property_value(reply); - switch (prop[0]) { - case XCB_WM_STATE_WITHDRAWN: - hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; - break; - - case XCB_WM_STATE_NORMAL: - hint = ECORE_X_WINDOW_STATE_HINT_NORMAL; - break; - - case XCB_WM_STATE_ICONIC: - hint = ECORE_X_WINDOW_STATE_HINT_ICONIC; - break; - - default: - hint = ECORE_X_WINDOW_STATE_HINT_NONE; - break; - } /* switch */ - - return hint; -} /* ecore_x_icccm_state_get */ - -/** - * Sends the ClientMessage event with the DeleteWindow property. - * @param window The window. - * @param time The time. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_delete_window_send(Ecore_X_Window window, - Ecore_X_Time time) -{ - ecore_x_client_message32_send(window, ECORE_X_ATOM_WM_PROTOCOLS, - ECORE_X_EVENT_MASK_NONE, - ECORE_X_ATOM_WM_DELETE_WINDOW, - time, 0, 0, 0); -} /* ecore_x_icccm_delete_window_send */ - -/** - * Sends the ClientMessage event with the TakeFocus property. - * @param window The window. - * @param time The time. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_take_focus_send(Ecore_X_Window window, - Ecore_X_Time time) -{ - ecore_x_client_message32_send(window, ECORE_X_ATOM_WM_PROTOCOLS, - ECORE_X_EVENT_MASK_NONE, - ECORE_X_ATOM_WM_TAKE_FOCUS, - time, 0, 0, 0); -} /* ecore_x_icccm_take_focus_send */ - -/** - * Sends the ClientMessage event with the SaveYourself property. - * @param window The window. - * @param time The time. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_save_yourself_send(Ecore_X_Window window, - Ecore_X_Time time) -{ - ecore_x_client_message32_send(window, ECORE_X_ATOM_WM_PROTOCOLS, - ECORE_X_EVENT_MASK_NONE, - ECORE_X_ATOM_WM_SAVE_YOURSELF, - time, 0, 0, 0); -} /* ecore_x_icccm_save_yourself_send */ - -/** - * Sends the ConfigureNotify event with the StructureNotify property. - * @param window The window. - * @param x The X coordinate. - * @param y The Y coordinate. - * @param width The width. - * @param height The height. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_move_resize_send(Ecore_X_Window window, - int x, - int y, - int width, - int height) -{ - xcb_configure_notify_event_t ev; - - ev.response_type = XCB_CONFIGURE_NOTIFY | 0x80; - ev.pad0 = 0; - ev.sequence = 0; - ev.event = window; - ev.window = window; - ev.above_sibling = 0; - ev.x = x; - ev.y = y; - ev.width = width; - ev.height = height; - ev.border_width = 0; - ev.override_redirect = 0; - xcb_send_event(_ecore_xcb_conn, 0, window, - XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev); -} /* ecore_x_icccm_move_resize_send */ - -/** - * Sets the hints of a window. - * @param window The window. - * @param accepts_focus AcceptFocus hint - * @param initial_state Initial state flags. - * @param icon_pixmap Icon pixmap. - * @param icon_mask Icon mask. - * @param icon_window Icon window. - * @param window_group Group window. - * @param is_urgent IsUrgent flag. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_hints_set(Ecore_X_Window window, - Eina_Bool accepts_focus, - Ecore_X_Window_State_Hint initial_state, - Ecore_X_Pixmap icon_pixmap, - Ecore_X_Pixmap icon_mask, - Ecore_X_Window icon_window, - Ecore_X_Window window_group, - Eina_Bool is_urgent) -{ - xcb_wm_hints_t hints; - - memset(&hints, 0, sizeof(hints)); - xcb_wm_hints_set_input(&hints, accepts_focus); - if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) - xcb_wm_hints_set_withdrawn(&hints); - else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL) - xcb_wm_hints_set_normal(&hints); - else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC) - xcb_wm_hints_set_iconic(&hints); - - if (icon_pixmap != 0) - xcb_wm_hints_set_icon_pixmap(&hints, icon_pixmap); - - if (icon_mask != 0) - xcb_wm_hints_set_icon_mask(&hints, icon_mask); - - if (icon_window != 0) - xcb_wm_hints_set_icon_window(&hints, icon_window); - - if (window_group != 0) - xcb_wm_hints_set_window_group(&hints, window_group); - - if (is_urgent) - xcb_wm_hints_set_urgency(&hints); - - xcb_set_wm_hints(_ecore_xcb_conn, window, &hints); -} /* ecore_x_icccm_hints_set */ - -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_hints_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_WM_HINTS, - ECORE_X_ATOM_WM_HINTS, - 0L, XCB_NUM_WM_HINTS_ELEMENTS); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_hints_get_prefetch */ +#include -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_hints_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_hints_get_fetch(void) +EAPI void +ecore_x_icccm_init(void) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_hints_get_fetch */ +} /** - * Gets the hints of a window. - * @param window The window. - * @param accepts_focus AcceptFocus hint - * @param initial_state Initial state flags. - * @param icon_pixmap Icon pixmap. - * @param icon_mask Icon mask. - * @param icon_window Icon window. - * @param window_group Group window. - * @param is_urgent IsUrgent flag. - * @return 1 on success, 0 otherwise. + * Sets the WM_COMMAND property for @a win. * - * To use this function, you must call before, and in order, - * ecore_x_icccm_hints_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_hints_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group + * @param win The window. + * @param argc Number of arguments. + * @param argv Arguments. */ -EAPI Eina_Bool -ecore_x_icccm_hints_get(Ecore_X_Window window __UNUSED__, - Eina_Bool *accepts_focus, - Ecore_X_Window_State_Hint *initial_state, - Ecore_X_Pixmap *icon_pixmap, - Ecore_X_Pixmap *icon_mask, - Ecore_X_Window *icon_window, - Ecore_X_Window *window_group, - Eina_Bool *is_urgent) +EAPI void +ecore_x_icccm_command_set(Ecore_X_Window win, int argc, char **argv) { - xcb_wm_hints_t hints; - xcb_get_property_reply_t *reply; - int32_t hints_flags; - uint32_t hints_input; - int32_t hints_initial_state; - xcb_pixmap_t hints_icon_pixmap; - xcb_pixmap_t hints_icon_mask; - xcb_window_t hints_icon_window; - xcb_window_t hints_window_group; - - if (accepts_focus) - *accepts_focus = 1; - - if (initial_state) - *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; - - if (icon_pixmap) - *icon_pixmap = 0; - - if (icon_mask) - *icon_mask = 0; - - if (icon_window) - *icon_window = 0; - - if (window_group) - *window_group = 0; - - if (is_urgent) - *is_urgent = 0; - - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; - - if ((reply->type != ECORE_X_ATOM_WM_HINTS) || - (reply->value_len < (XCB_NUM_WM_HINTS_ELEMENTS - 1)) || - (reply->format != 32)) - return 0; - - memcpy(&hints, xcb_get_property_value(reply), reply->value_len); - hints_flags = hints.flags; - hints_input = hints.input; - hints_initial_state = hints.initial_state; - hints_icon_pixmap = hints.icon_pixmap; - hints_icon_mask = hints.icon_mask; - hints_icon_window = hints.icon_window; - hints_window_group = hints.window_group; - - if ((hints_flags & XCB_WM_HINT_INPUT) && (accepts_focus)) - { - if(hints_input) - *accepts_focus = 1; - else - *accepts_focus = 0; - } + void *buf; + char *b; + int nbytes, i; - if ((hints_flags & XCB_WM_HINT_STATE) && (initial_state)) - { - if (hints_initial_state == XCB_WM_STATE_WITHDRAWN) - *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; - else if (hints_initial_state == XCB_WM_STATE_NORMAL) - *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; - else if (hints_initial_state == XCB_WM_STATE_ICONIC) - *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC; - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if ((hints_flags & XCB_WM_HINT_ICON_PIXMAP) && (icon_pixmap)) - { - *icon_pixmap = hints_icon_pixmap; - } - - if ((hints_flags & XCB_WM_HINT_ICON_MASK) && (icon_mask)) - { - *icon_mask = hints_icon_mask; - } + for (i = 0, nbytes = 0; i < argc; i++) + nbytes += strlen(argv[i]) + 1; - if ((hints_flags & XCB_WM_HINT_ICON_WINDOW) && (icon_window)) - { - *icon_window = hints_icon_window; - } + buf = malloc(sizeof(char) * nbytes); + if (!buf) return; - if ((hints_flags & XCB_WM_HINT_WINDOW_GROUP) && (window_group)) + b = (char *)buf; + for (i = 0; i < argc; i++) { - if (reply->value_len < XCB_NUM_WM_HINTS_ELEMENTS) - *window_group = 0; + if (argv[i]) + { + strcpy(b, argv[i]); + b += strlen(argv[i]) + 1; + } else - *window_group = hints_window_group; - } - - if ((hints_flags & XCB_WM_HINT_X_URGENCY) && (is_urgent)) - { - *is_urgent = 1; + *b++ = '\0'; } - - return 1; -} /* ecore_x_icccm_hints_get */ - -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_size_pos_hints_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_WM_NORMAL_HINTS, - ECORE_X_ATOM_WM_SIZE_HINTS, - 0L, 18); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_size_pos_hints_get_prefetch */ - -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_size_pos_hints_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_size_pos_hints_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_size_pos_hints_get_fetch */ + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, + ECORE_X_ATOM_WM_COMMAND, ECORE_X_ATOM_STRING, 8, + nbytes, buf); + free(buf); +} /** - * Sets the hints of a window. - * @param window The window. - * @param request_pos Request position flag. - * @param gravity Gravity. - * @param min_w Minimum width. - * @param min_h Minimum height. - * @param max_w Maximum width. - * @param max_h Maximum height. - * @param base_w Base width - * @param base_h Base height - * @param step_x X step coordinate. - * @param step_y Y step coordinate. - * @param min_aspect Minimum aspect ratio. - * @param max_aspect Maximum aspect ratio. + * Get the WM_COMMAND property for @a win. + * + * Return the command of a window. String must be free'd when done with. * - * To use this function, you must call before, and in order, - * ecore_x_icccm_size_pos_hints_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_size_pos_hints_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group + * @param win The window. + * @param argc Number of arguments. + * @param argv Arguments. */ -EAPI void -ecore_x_icccm_size_pos_hints_set(Ecore_X_Window window, - Eina_Bool request_pos, - Ecore_X_Gravity gravity, - int min_w, - int min_h, - int max_w, - int max_h, - int base_w, - int base_h, - int step_x, - int step_y, - double min_aspect, - double max_aspect) +EAPI void +ecore_x_icccm_command_get(Ecore_X_Window win, int *argc, char ***argv) { - xcb_size_hints_t hint; + xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; + int len = 0; + char **v, *data, *cp, *start; + int c = 0, i = 0, j = 0; - reply = _ecore_xcb_reply_get(); - if (!reply || - (reply->type != ECORE_X_ATOM_WM_SIZE_HINTS) || - ((reply->format != 8) && - (reply->format != 16) && - (reply->format != 32)) || - (reply->value_len < 15)) - return; - - hint.flags = 0; - if (request_pos) - { - hint.flags = XCB_SIZE_HINT_US_POSITION; - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (gravity != ECORE_X_GRAVITY_NW) - { - hint.win_gravity = (uint8_t)gravity; - } + if (argc) *argc = 0; + if (argv) *argv = NULL; - if ((min_w > 0) || (min_h > 0)) - { - hint.min_width = min_w; - hint.min_height = min_h; - } - - if ((max_w > 0) || (max_h > 0)) - { - hint.max_width = max_w; - hint.max_height = max_h; - } - - if ((base_w > 0) || (base_h > 0)) - { - hint.base_width = base_w; - hint.base_height = base_h; - } + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, + ECORE_X_ATOM_WM_COMMAND, + XCB_GET_PROPERTY_TYPE_ANY, + 0, 1000000L); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; - if ((step_x > 1) || (step_y > 1)) + if ((reply->type != ECORE_X_ATOM_STRING) || (reply->format != 8)) { - hint.width_inc = step_x; - hint.height_inc = step_y; + free(reply); + return; } - if ((min_aspect > 0.0) || (max_aspect > 0.0)) + len = reply->value_len; + if (len < 1) { - xcb_size_hints_set_aspect(&hint, - (int32_t)(min_aspect * 10000), - 10000, - (int32_t)(max_aspect * 10000), - 10000); + free(reply); + return; } - xcb_set_wm_normal_hints(_ecore_xcb_conn, window, &hint); -} /* ecore_x_icccm_size_pos_hints_set */ - -/** - * Gets the hints of a window. - * @param window The window. - * @param request_pos Request position flag. - * @param gravity Gravity. - * @param min_w Minimum width. - * @param min_h Minimum height. - * @param max_w Maximum width. - * @param max_h Maximum height. - * @param base_w Base width - * @param base_h Base height - * @param step_x X step coordinate. - * @param step_y Y step coordinate. - * @param min_aspect Minimum aspect ratio. - * @param max_aspect M - * @return 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_size_pos_hints_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_size_pos_hints_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI Eina_Bool -ecore_x_icccm_size_pos_hints_get(Ecore_X_Window window __UNUSED__, - Eina_Bool *request_pos, - Ecore_X_Gravity *gravity, - int *min_w, - int *min_h, - int *max_w, - int *max_h, - int *base_w, - int *base_h, - int *step_x, - int *step_y, - double *min_aspect, - double *max_aspect) -{ - xcb_size_hints_t hint; - xcb_get_property_reply_t *reply; - uint32_t flags; - int32_t minw = 0; - int32_t minh = 0; - int32_t maxw = 32767; - int32_t maxh = 32767; - int32_t basew = -1; - int32_t baseh = -1; - int32_t stepx = -1; - int32_t stepy = -1; - double mina = 0.0; - double maxa = 0.0; - - if (request_pos) - *request_pos = 0; - - if (gravity) - *gravity = ECORE_X_GRAVITY_NW; - - if (min_w) - *min_w = minw; - - if (min_h) - *min_h = minh; - - if (max_w) - *max_w = maxw; - - if (max_h) - *max_h = maxh; - - if (base_w) - *base_w = basew; - - if (base_h) - *base_h = baseh; - - if (step_x) - *step_x = stepx; - - if (step_y) - *step_y = stepy; - - if (min_aspect) - *min_aspect = mina; - - if (max_aspect) - *max_aspect = maxa; - - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; - - if (!_ecore_x_icccm_size_hints_get(reply, ECORE_X_ATOM_WM_NORMAL_HINTS, &hint)) - return 0; + data = (char *)xcb_get_property_value(reply); + if (len && (data[len - 1] == '\0')) + len--; - flags = hint.flags; - if ((flags & XCB_SIZE_HINT_US_POSITION) || (flags & XCB_SIZE_HINT_P_POSITION)) - { - if (request_pos) - *request_pos = 1; - } + c = 1; + for (cp = (char *)data, i = len; i > 0; cp++, i--) + if (*cp == '\0') c++; - if (flags & XCB_SIZE_HINT_P_WIN_GRAVITY) + v = (char **)malloc((c + 1) * sizeof(char *)); + if (!v) { - if (gravity) - *gravity = hint.win_gravity; + free(reply); + return; } - if (flags & XCB_SIZE_HINT_P_MIN_SIZE) + start = (char *)malloc((len + 1) * sizeof(char)); + if (!start) { - minw = hint.min_width; - minh = hint.min_height; + free(reply); + free(v); + return; } - if (flags & XCB_SIZE_HINT_P_MAX_SIZE) + memcpy(start, (char *)data, len); + start[len] = '\0'; + for (cp = start, i = len + 1, j = 0; i > 0; cp++, i--) { - maxw = hint.max_width; - maxh = hint.max_height; - if (maxw < minw) - maxw = minw; - - if (maxh < minh) - maxh = minh; + if (*cp == '\0') + { + v[j] = start; + start = (cp + 1); + j++; + } } - if (flags & XCB_SIZE_HINT_BASE_SIZE) + if (c < 1) { - basew = hint.base_width; - baseh = hint.base_height; - if (basew > minw) - minw = basew; - - if (baseh > minh) - minh = baseh; + free(reply); + free(v); + return; } - if (flags & XCB_SIZE_HINT_P_RESIZE_INC) - { - stepx = hint.width_inc; - stepy = hint.height_inc; - if (stepx < 1) - stepx = 1; + if (argc) *argc = c; - if (stepy < 1) - stepy = 1; - } - - if (flags & XCB_SIZE_HINT_P_ASPECT) + if (argv) { - if (hint.min_aspect_den > 0) - mina = ((double)hint.min_aspect_num) / ((double)hint.min_aspect_den); + (*argv) = malloc(c * sizeof(char *)); + if (!*argv) + { + free(reply); + free(v); + if (argc) *argc = 0; + return; + } - if (hint.max_aspect_den > 0) - maxa = ((double)hint.max_aspect_num) / ((double)hint.max_aspect_den); + for (i = 0; i < c; i++) + { + if (v[i]) + (*argv)[i] = strdup(v[i]); + else + (*argv)[i] = strdup(""); + } } - if (min_w) - *min_w = minw; - - if (min_h) - *min_h = minh; - - if (max_w) - *max_w = maxw; - - if (max_h) - *max_h = maxh; - - if (base_w) - *base_w = basew; - - if (base_h) - *base_h = baseh; - - if (step_x) - *step_x = stepx; - - if (step_y) - *step_y = stepy; - - if (min_aspect) - *min_aspect = mina; - - if (max_aspect) - *max_aspect = maxa; - - return 1; -} /* ecore_x_icccm_size_pos_hints_get */ - -/** - * Set the title of a window - * @param window The window. - * @param title The title. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_title_set(Ecore_X_Window window, - const char *title) -{ - if (!title) - return; - - /* FIXME: to do: utf8 */ - -/* xprop.value = NULL; */ -/* #ifdef X_HAVE_UTF8_STRING */ -/* list[0] = strdup(t); */ -/* ret = */ -/* Xutf8TextListToTextProperty(_ecore_xcb_conn, list, 1, XUTF8StringStyle, */ -/* &xprop); */ -/* #else */ -/* list[0] = strdup(t); */ -/* ret = */ -/* XmbTextListToTextProperty(_ecore_xcb_conn, list, 1, XStdICCTextStyle, */ -/* &xprop); */ -/* #endif */ - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_NAME, ECORE_X_ATOM_STRING, 8, - strlen(title), title); -} /* ecore_x_icccm_title_set */ - -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_title_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_WM_NAME, - XCB_GET_PROPERTY_TYPE_ANY, - 0L, 128); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_title_get_prefetch */ - -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_title_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_title_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_title_get_fetch */ + free(reply); + free(v); +} -/** - * Gets the title of a window. - * @param window The window (Unused). - * @return The title of the window - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_title_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_title_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group - */ EAPI char * -ecore_x_icccm_title_get(Ecore_X_Window window __UNUSED__) +ecore_x_icccm_title_get(Ecore_X_Window win) { + xcb_get_property_cookie_t cookie; + xcb_get_text_property_reply_t prop; + uint8_t ret = 0; char *title = NULL; - xcb_get_property_reply_t *reply; - reply = _ecore_xcb_reply_get(); - if (!reply) - return NULL; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (reply->type == ECORE_X_ATOM_UTF8_STRING) - { - int length; + if (!win) return NULL; - /* FIXME: verify the value of length */ - length = (reply->value_len * reply->format) / 8; - title = (char *)malloc((length + 1) * sizeof(char)); - memcpy(title, xcb_get_property_value(reply), length); - title[length] = '\0'; - } - /* not in UTF8, so we convert */ - else + cookie = xcb_get_wm_name_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); + if (ret == 0) return NULL; + if (prop.name_len < 1) { - /* convert to utf8 */ - - /* FIXME: to do... */ - -/* #ifdef X_HAVE_UTF8_STRING */ -/* ret = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xprop, */ -/* &list, &num); */ -/* #else */ -/* ret = XmbTextPropertyToTextList(_ecore_xcb_conn, &xprop, */ -/* &list, &num); */ -/* #endif */ - -/* if ((ret == XLocaleNotSupported) || */ -/* (ret == XNoMemory) || (ret == XConverterNotFound)) */ -/* { */ -/* t = strdup((char *)xprop.value); */ -/* } */ -/* else if ((ret >= Success) && (num > 0)) */ -/* { */ -/* t = strdup(list[0]); */ -/* } */ -/* if (list) */ -/* XFreeStringList(list); */ -/* } */ - -/* if (xprop.value) XFree(xprop.value); */ + xcb_get_text_property_reply_wipe(&prop); + return NULL; } - return title; -} /* ecore_x_icccm_title_get */ - -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_protocol_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; + if (!(title = malloc((prop.name_len + 1) * sizeof(char *)))) + { + xcb_get_text_property_reply_wipe(&prop); + return NULL; + } + memcpy(title, prop.name, sizeof(char *) * prop.name_len); + title[prop.name_len] = '\0'; - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_WM_PROTOCOLS, - ECORE_X_ATOM_ATOM, 0, 1000000L); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_protocol_get_prefetch */ + if (prop.encoding != ECORE_X_ATOM_UTF8_STRING) + { + Ecore_Xcb_Textproperty tp; + int count = 0; + char **list = NULL; + Eina_Bool ret = EINA_FALSE; + + tp.value = strdup(title); + tp.nitems = prop.name_len; + tp.encoding = prop.encoding; +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count); +#else + ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count); +#endif + if (ret) + { + if (count > 0) + title = strdup(list[0]); -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_protocol_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_protocol_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + if (list) free(list); + } + } - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_protocol_get_fetch */ + xcb_get_text_property_reply_wipe(&prop); + return title; +} -/** - * Set or unset a wm protocol property. - * @param window The Window - * @param protocol The protocol to enable/disable - * @param on On/Off - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_protocol_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_protocol_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_protocol_set(Ecore_X_Window window, - Ecore_X_WM_Protocol protocol, - Eina_Bool on) +EAPI void +ecore_x_icccm_title_set(Ecore_X_Window win, const char *title) { - xcb_get_property_reply_t *reply; - Ecore_X_Atom *protos = NULL; - Ecore_X_Atom proto; - uint32_t protos_count = 0; - uint8_t already_set = 0; + Ecore_Xcb_Textproperty prop; + char *list[1]; + Eina_Bool ret = EINA_FALSE; - /* Check for invalid values */ - if (protocol >= ECORE_X_WM_PROTOCOL_NUM) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - proto = _ecore_xcb_atoms_wm_protocols[protocol]; + if (!title) return; - reply = _ecore_xcb_reply_get(); - if (!reply) - return; + prop.value = NULL; + list[0] = strdup(title); - if ((reply->type == ECORE_X_ATOM_ATOM) && (reply->format == 32)) - { - uint32_t i; +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle, + &prop); +#else + ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle, + &prop); +#endif - protos_count = reply->value_len / sizeof(Ecore_X_Atom); - protos = (Ecore_X_Atom *)xcb_get_property_value(reply); - for (i = 0; i < protos_count; i++) - { - if (protos[i] == proto) - { - already_set = 1; - break; - } - } - } - - if (on) - { - Ecore_X_Atom *new_protos = NULL; - - if (already_set) - return; - - new_protos = (Ecore_X_Atom *)malloc((protos_count + 1) * sizeof(Ecore_X_Atom)); - if (!new_protos) - return; - - memcpy(new_protos, protos, reply->value_len); - new_protos[protos_count] = proto; - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_PROTOCOLS, - ECORE_X_ATOM_ATOM, 32, - protos_count + 1, new_protos); - free(new_protos); - } - else + if (ret) { - uint32_t i; - - if (!already_set) - return; - - for (i = 0; i < protos_count; i++) - { - if (protos[i] == proto) - { - uint32_t j; - - for (j = i + 1; j < protos_count; j++) - protos[j - 1] = protos[j]; - if (protos_count > 1) - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_PROTOCOLS, - ECORE_X_ATOM_ATOM, 32, - protos_count - 1, protos); - else - xcb_delete_property(_ecore_xcb_conn, window, - ECORE_X_ATOM_WM_PROTOCOLS); + xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + strlen(prop.value), prop.value); - return; - } - } + if (prop.value) free(prop.value); } -} /* ecore_x_icccm_protocol_set */ + else + xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + strlen(title), title); + free(list[0]); +} /** - * Determines whether a protocol is set for a window. - * @param window The Window (Unused). - * @param protocol The protocol to query. - * @return 1 if the protocol is set, else 0. + * Get a window name & class. + * @param win The window + * @param n The name string + * @param c The class string * - * To use this function, you must call before, and in order, - * ecore_x_icccm_protocol_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_protocol_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group + * Get a window name * class */ -EAPI Eina_Bool -ecore_x_icccm_protocol_isset(Ecore_X_Window window __UNUSED__, - Ecore_X_WM_Protocol protocol) +EAPI void +ecore_x_icccm_name_class_get(Ecore_X_Window win, char **name, char **class) { - xcb_get_property_reply_t *reply; - Ecore_X_Atom *protos = NULL; - Ecore_X_Atom proto; - uint32_t i; + xcb_get_property_cookie_t cookie; + xcb_get_wm_class_reply_t prop; uint8_t ret = 0; - /* check for invalid values */ - if (protocol >= ECORE_X_WM_PROTOCOL_NUM) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - proto = _ecore_xcb_atoms_wm_protocols[protocol]; + if (name) *name = NULL; + if (class) *class = NULL; - reply = _ecore_xcb_reply_get(); - if (!reply || (reply->type != ECORE_X_ATOM_ATOM) || (reply->format != 32)) - { - return 0; - } + cookie = xcb_get_wm_class_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL); + if (ret == 0) return; - protos = (Ecore_X_Atom *)xcb_get_property_value(reply); - for (i = 0; i < reply->value_len; i++) - if (protos[i] == proto) - { - ret = 1; - break; - } + if (name) *name = strdup(prop.instance_name); + if (class) *class = strdup(prop.class_name); - return ret; -} /* ecore_x_icccm_protocol_isset */ + xcb_get_wm_class_reply_wipe(&prop); +} /** * Set a window name & class. - * @param window The window - * @param name The name string - * @param class The class string + * @param win The window + * @param n The name string + * @param c The class string * - * Set the name and class of @p window to respectively @p name and @p class. - * @ingroup Ecore_X_ICCCM_Group + * Set a window name * class */ -EAPI void -ecore_x_icccm_name_class_set(Ecore_X_Window window, - const char *name, - const char *class) +EAPI void +ecore_x_icccm_name_class_set(Ecore_X_Window win, const char *name, const char *class) { - char *class_string; - char *s; - int length_name; - int length_class; + char *class_string, *s; + int length_name, length_class; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); length_name = strlen(name); length_class = strlen(class); - class_string = (char *)malloc(sizeof(char) * (length_name + length_class + 2)); - if (!class_string) - return; + class_string = + (char *)malloc(sizeof(char) * (length_name + length_class + 2)); + if (!class_string) return; s = class_string; if (length_name) @@ -1102,907 +310,850 @@ ecore_x_icccm_name_class_set(Ecore_X_Window window, else *s++ = '\0'; - if(length_class) - strcpy(s, class); + if (length_class) + strcpy(s, class); else - *s = '\0'; + *s = '\0'; - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, ECORE_X_ATOM_WM_CLASS, ECORE_X_ATOM_STRING, 8, length_name + length_class + 2, (void *)class_string); free(class_string); -} /* ecore_x_icccm_name_class_set */ +} -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group +/** + * Specify that a window is transient for another top-level window and should be handled accordingly. + * @param win the transient window + * @param forwin the toplevel window */ -EAPI void -ecore_x_icccm_name_class_get_prefetch(Ecore_X_Window window) +EAPI void +ecore_x_icccm_transient_for_set(Ecore_X_Window win, Ecore_X_Window forwindow) { - xcb_get_property_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_WM_CLASS, - ECORE_X_ATOM_STRING, - 0, 2048L); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_name_class_get_prefetch */ + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, + ECORE_X_ATOM_WM_TRANSIENT_FOR, ECORE_X_ATOM_WINDOW, 32, + 1, (void *)&forwindow); +} -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_name_class_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group +/** + * Remove the transient_for setting from a window. + * @param The window */ -EAPI void -ecore_x_icccm_name_class_get_fetch(void) +EAPI void +ecore_x_icccm_transient_for_unset(Ecore_X_Window win) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_name_class_get_fetch */ + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_TRANSIENT_FOR); +} /** - * Get a window name and class. - * @param window The window (Unused). - * @param name The name string. - * @param class The class string. - * - * Store the name and class of @p window into respectively @p name and - * @p class. - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_name_class_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_name_class_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group + * Get the window this window is transient for, if any. + * @param win The window to check + * @return The window ID of the top-level window, or 0 if the property does not exist. */ -EAPI void -ecore_x_icccm_name_class_get(Ecore_X_Window window __UNUSED__, - char **name, - char **class) +EAPI Ecore_X_Window +ecore_x_icccm_transient_for_get(Ecore_X_Window win) { - xcb_get_property_reply_t *reply; - void *data; - char *n = NULL; - char *c = NULL; - int length; - int length_name; - int length_class; - - if (name) - *name = NULL; - - if (class) - *class = NULL; - - reply = _ecore_xcb_reply_get(); - if (!reply) - return; - - if ((reply->type != ECORE_X_ATOM_STRING) || - (reply->format != 8)) - return; - - length = reply->value_len; - data = xcb_get_property_value(reply); - /* data contains the name string and the class string */ - /* separated by the NULL character. data is not NULL-terminated */ - length_name = strlen(data); - n = (char *)malloc(sizeof(char) * (length_name + 1)); - if (!n) - return; - - length_class = length - length_name - 1; - c = (char *)malloc(sizeof(char) * (length_class + 1)); - if (!c) - { - free(n); - return; - } + Ecore_X_Window forwin = 0; + xcb_get_property_cookie_t cookie; - memcpy(n, data, length_name); - n[length_name] = '\0'; - length_class = length - length_name - 1; - data += length_name + 1; - memcpy(c, data, length_class); - c[length_class] = '\0'; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (name) - *name = n; + cookie = xcb_get_wm_transient_for_unchecked(_ecore_xcb_conn, win); + xcb_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL); - if (class) - *class = c; -} /* ecore_x_icccm_name_class_get */ + return forwin; +} -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group +/** + * Get the window role. + * @param win The window + * @return The window's role string. */ -EAPI void -ecore_x_icccm_client_machine_get_prefetch(Ecore_X_Window window) +EAPI char * +ecore_x_icccm_window_role_get(Ecore_X_Window win) { - xcb_get_property_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root, - ECORE_X_ATOM_WM_CLIENT_MACHINE, - XCB_GET_PROPERTY_TYPE_ANY, - 0L, 1000000L); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_client_machine_get_prefetch */ + return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE); +} -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_client_machine_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group +/** + * Set the window role hint. + * @param win The window + * @param role The role string */ -EAPI void -ecore_x_icccm_client_machine_get_fetch(void) +EAPI void +ecore_x_icccm_window_role_set(Ecore_X_Window win, const char *role) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_client_machine_get_fetch */ + ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE, role); +} /** - * Get a window client machine string. - * @param window The window - * @return The windows client machine string - * - * Return the client machine of a window. String must be free'd when done with. - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_client_machine_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_client_machine_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group + * Get the window's client leader. + * @param win The window + * @return The window's client leader window, or 0 if unset */ -EAPI char * -ecore_x_icccm_client_machine_get(Ecore_X_Window window) +EAPI Ecore_X_Window +ecore_x_icccm_client_leader_get(Ecore_X_Window win) { - char *name; + Ecore_X_Window leader; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER, + &leader, 1) > 0) + return leader; - name = ecore_x_window_prop_string_get(window, ECORE_X_ATOM_WM_CLIENT_MACHINE); - return name; -} /* ecore_x_icccm_client_machine_get */ + return 0; +} /** - * Sets the WM_COMMAND property for @a win. + * Set the window's client leader. + * @param win The window + * @param l The client leader window * - * @param window The window. - * @param argc Number of arguments. - * @param argv Arguments. - * @ingroup Ecore_X_ICCCM_Group + * All non-transient top-level windows created by an app other than + * the main window must have this property set to the app's main window. */ -EAPI void -ecore_x_icccm_command_set(Ecore_X_Window window, - int argc, - char **argv) +EAPI void +ecore_x_icccm_client_leader_set(Ecore_X_Window win, Ecore_X_Window leader) { - void *buf; - char *b; - int nbytes; - int i; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - for (i = 0, nbytes = 0; i < argc; i++) + ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER, + &leader, 1); +} + +EAPI Ecore_X_Window_State_Hint +ecore_x_icccm_state_get(Ecore_X_Window win) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + Ecore_X_Window_State_Hint hint = ECORE_X_WINDOW_STATE_HINT_NONE; + uint8_t *prop; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + cookie = + xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, + ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE, + 0L, 0x7fffffff); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return hint; + if ((reply->type == 0) || (reply->format != 8) || (reply->value_len != 2)) { - nbytes += strlen(argv[i]) + 1; + free(reply); + return hint; } - buf = malloc(sizeof(char) * nbytes); - if (!buf) - return; - b = (char *)buf; - for (i = 0; i < argc; i++) + prop = (uint8_t *)xcb_get_property_value(reply); + switch (prop[0]) { - if (argv[i]) - { - strcpy(b, argv[i]); - b += strlen(argv[i]) + 1; - } - else - *b++ = '\0'; + case XCB_WM_STATE_WITHDRAWN: + hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; + break; + case XCB_WM_STATE_NORMAL: + hint = ECORE_X_WINDOW_STATE_HINT_NORMAL; + break; + case XCB_WM_STATE_ICONIC: + hint = ECORE_X_WINDOW_STATE_HINT_ICONIC; + break; + default: + break; } - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_COMMAND, ECORE_X_ATOM_STRING, 8, - nbytes, buf); - free(buf); -} /* ecore_x_icccm_command_set */ -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_command_get_prefetch(Ecore_X_Window window) + free(reply); + return hint; +} + +EAPI void +ecore_x_icccm_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state) { - xcb_get_property_cookie_t cookie; + xcb_wm_hints_t hints; - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_WM_COMMAND, - XCB_GET_PROPERTY_TYPE_ANY, - 0L, 1000000L); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_command_get_prefetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_command_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_command_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + xcb_wm_hints_set_none(&hints); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_command_get_fetch */ + hints.flags = XCB_WM_HINT_STATE; -/** - * Get the WM_COMMAND property for a window. - * - * @param win The window. - * @param argc Number of arguments. - * @param argv Arguments. - * - * Return the command of @p window and store it in @p argv. @p argc - * contains the number of arguments. String must be free'd when done with. - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_command_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_command_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_command_get(Ecore_X_Window window __UNUSED__, - int *argc, - char ***argv) + if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + xcb_wm_hints_set_withdrawn(&hints); + else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL) + xcb_wm_hints_set_normal(&hints); + else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC) + xcb_wm_hints_set_iconic(&hints); + + xcb_set_wm_hints(_ecore_xcb_conn, win, &hints); +} + +EAPI void +ecore_x_icccm_delete_window_send(Ecore_X_Window win, Ecore_X_Time t) { - xcb_get_property_reply_t *reply; - char **v; - char *data; - char *cp; - char *start; - uint32_t value_len; - int c; - int i; - int j; - - if (argc) - *argc = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + ECORE_X_EVENT_MASK_NONE, + ECORE_X_ATOM_WM_DELETE_WINDOW, t, 0, 0, 0); +} + +EAPI void +ecore_x_icccm_hints_set(Ecore_X_Window win, Eina_Bool accepts_focus, Ecore_X_Window_State_Hint initial_state, Ecore_X_Pixmap icon_pixmap, Ecore_X_Pixmap icon_mask, Ecore_X_Window icon_window, Ecore_X_Window window_group, Eina_Bool is_urgent) +{ + xcb_wm_hints_t hints; - if (argv) - *argv = NULL; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return; + xcb_wm_hints_set_none(&hints); + xcb_wm_hints_set_input(&hints, accepts_focus); - if ((reply->type != ECORE_X_ATOM_STRING) || - (reply->format != 8)) - return; + if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + xcb_wm_hints_set_withdrawn(&hints); + else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL) + xcb_wm_hints_set_normal(&hints); + else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC) + xcb_wm_hints_set_iconic(&hints); - value_len = reply->value_len; - data = (char *)xcb_get_property_value(reply); - if (value_len && (data[value_len - 1] == '\0')) - value_len--; + if (icon_pixmap != 0) xcb_wm_hints_set_icon_pixmap(&hints, icon_pixmap); + if (icon_mask != 0) xcb_wm_hints_set_icon_mask(&hints, icon_mask); + if (icon_window != 0) xcb_wm_hints_set_icon_window(&hints, icon_window); + if (window_group != 0) xcb_wm_hints_set_window_group(&hints, window_group); + if (is_urgent) xcb_wm_hints_set_urgency(&hints); - c = 1; - for (cp = (char *)data, i = value_len; i > 0; cp++, i--) + xcb_set_wm_hints(_ecore_xcb_conn, win, &hints); +} + +EAPI Eina_Bool +ecore_x_icccm_hints_get(Ecore_X_Window win, Eina_Bool *accepts_focus, Ecore_X_Window_State_Hint *initial_state, Ecore_X_Pixmap *icon_pixmap, Ecore_X_Pixmap *icon_mask, Ecore_X_Window *icon_window, Ecore_X_Window *window_group, Eina_Bool *is_urgent) +{ + xcb_get_property_cookie_t cookie; + xcb_wm_hints_t hints; + uint8_t ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (accepts_focus) *accepts_focus = EINA_TRUE; + if (initial_state) *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; + if (icon_pixmap) *icon_pixmap = 0; + if (icon_mask) *icon_mask = 0; + if (icon_window) *icon_window = 0; + if (window_group) *window_group = 0; + if (is_urgent) *is_urgent = EINA_FALSE; + + xcb_wm_hints_set_none(&hints); + cookie = xcb_get_wm_hints_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); + if (!ret) return EINA_FALSE; + + if ((hints.flags & XCB_WM_HINT_INPUT) && (accepts_focus)) { - if (*cp == '\0') - c++; + if (hints.input) + *accepts_focus = EINA_TRUE; + else + *accepts_focus = EINA_FALSE; } - v = (char **)malloc((c + 1) * sizeof(char *)); - if (!v) - return; - start = (char *)malloc((value_len + 1) * sizeof(char)); - if (!start) + if ((hints.flags & XCB_WM_HINT_STATE) && (initial_state)) { - free(v); - return; + if (hints.initial_state == XCB_WM_STATE_WITHDRAWN) + *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; + else if (hints.initial_state == XCB_WM_STATE_NORMAL) + *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; + else if (hints.initial_state == XCB_WM_STATE_ICONIC) + *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC; } - memcpy (start, (char *)data, value_len); - start[value_len] = '\0'; - for (cp = start, i = value_len + 1, j = 0; i > 0; cp++, i--) { - if (*cp == '\0') - { - v[j] = start; - start = (cp + 1); - j++; - } - } + if ((hints.flags & XCB_WM_HINT_ICON_PIXMAP) && (icon_pixmap)) + *icon_pixmap = hints.icon_pixmap; + + if ((hints.flags & XCB_WM_HINT_ICON_MASK) && (icon_mask)) + *icon_mask = hints.icon_mask; + + if ((hints.flags & XCB_WM_HINT_ICON_WINDOW) && (icon_window)) + *icon_window = hints.icon_window; + + if ((hints.flags & XCB_WM_HINT_WINDOW_GROUP) && (window_group)) + *window_group = hints.window_group; + + if ((hints.flags & XCB_WM_HINT_X_URGENCY) && (is_urgent)) + *is_urgent = EINA_TRUE; + + return EINA_TRUE; +} + +/** + * Get a window icon name. + * @param win The window + * @return The windows icon name string + * + * Return the icon name of a window. String must be free'd when done with. + */ +EAPI char * +ecore_x_icccm_icon_name_get(Ecore_X_Window win) +{ + xcb_get_property_cookie_t cookie; + xcb_get_text_property_reply_t prop; + uint8_t ret = 0; + char *tmp = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (c < 1) + if (!win) return NULL; + + cookie = xcb_get_wm_icon_name_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); + if (ret == 0) return NULL; + + if (prop.name_len < 1) { - free(v); - return; + xcb_get_text_property_reply_wipe(&prop); + return NULL; } - if (argc) - *argc = c; + if (!(tmp = malloc((prop.name_len + 1) * sizeof(char *)))) + { + xcb_get_text_property_reply_wipe(&prop); + return NULL; + } + memcpy(tmp, prop.name, sizeof(char *) * prop.name_len); + tmp[prop.name_len] = '\0'; - if (argv) + if (prop.encoding != ECORE_X_ATOM_UTF8_STRING) { - (*argv) = malloc(c * sizeof(char *)); - if (!*argv) + Ecore_Xcb_Textproperty tp; + int count = 0; + char **list = NULL; + Eina_Bool ret = EINA_FALSE; + + tp.value = strdup(tmp); + tp.nitems = prop.name_len; + tp.encoding = prop.encoding; +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count); +#else + ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count); +#endif + if (ret) { - free(v); - if (argc) - *argc = 0; - - return; - } + if (count > 0) + tmp = strdup(list[0]); - for (i = 0; i < c; i++) - { - if (v[i]) - (*argv)[i] = strdup(v[i]); - else - (*argv)[i] = strdup(""); + if (list) free(list); } } - free(v); -} /* ecore_x_icccm_command_get */ + xcb_get_text_property_reply_wipe(&prop); + return tmp; +} /** * Set a window icon name. - * @param window The window. - * @param title The icon name string. + * @param win The window + * @param t The icon name string * - * Set @p window icon name. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_icon_name_set(Ecore_X_Window window, - const char *title) -{ - /* FIXME: do the UTF8 conversion... */ - -/* #ifdef X_HAVE_UTF8_STRING */ -/* list[0] = strdup(t); */ -/* ret = Xutf8TextListToTextProperty(_ecore_xcb_conn, list, 1, */ -/* XUTF8StringStyle, &xprop); */ -/* #else */ -/* list[0] = strdup(t); */ -/* ret = XmbTextListToTextProperty(_ecore_xcb_conn, list, 1, */ -/* XStdICCTextStyle, &xprop); */ -/* #endif */ - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_ICON_NAME, ECORE_X_ATOM_WM_ICON_NAME, - 8, strlen(title), title); -} /* ecore_x_icccm_icon_name_set */ - -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_icon_name_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_WM_ICON_NAME, - XCB_GET_PROPERTY_TYPE_ANY, - 0L, 128L); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_icon_name_get_prefetch */ - -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_icon_name_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group + * Set a window icon name */ -EAPI void -ecore_x_icccm_icon_name_get_fetch(void) +EAPI void +ecore_x_icccm_icon_name_set(Ecore_X_Window win, const char *name) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + Ecore_Xcb_Textproperty prop; + char *list[1]; + Eina_Bool ret = EINA_FALSE; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_icon_name_get_fetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Get a window icon name. - * @param window The window. - * @return The windows icon name string. - * - * Return the icon name of @p window. String must be free'd when done with. - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_icon_name_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_icon_name_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI char * -ecore_x_icccm_icon_name_get(Ecore_X_Window window __UNUSED__) -{ - xcb_get_property_reply_t *reply; - char *title = NULL; + if ((!win) || (!name)) return; - reply = _ecore_xcb_reply_get(); - if (!reply) - return NULL; + prop.value = NULL; + list[0] = strdup(name); - ERR("reply->bytes_afer (should be 0): %d", ((xcb_get_property_reply_t *)reply)->bytes_after); +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle, + &prop); +#else + ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle, + &prop); +#endif - if (reply->type == ECORE_X_ATOM_UTF8_STRING) + if (ret) { - int length; + xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + strlen(prop.value), prop.value); - /* FIXME: verify the value of length */ - length = reply->value_len * reply->format / 8; - title = (char *)malloc((length + 1) * sizeof(char)); - memcpy(title, xcb_get_property_value(reply), length); - title[length] = '\0'; - } - /* not in UTF8, so we convert */ - else - { - /* FIXME: do the UTF8... */ - - /* convert to utf8 */ -/* #ifdef X_HAVE_UTF8_STRING */ -/* ret = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xprop, */ -/* &list, &num); */ -/* #else */ -/* ret = XmbTextPropertyToTextList(_ecore_xcb_conn, &xprop, */ -/* &list, &num); */ -/* #endif */ - -/* if ((ret == XLocaleNotSupported) || */ -/* (ret == XNoMemory) || (ret == XConverterNotFound)) */ -/* { */ -/* t = strdup((char *)xprop.value); */ -/* } */ -/* else if (ret >= Success) */ -/* { */ -/* if ((num >= 1) && (list)) */ -/* { */ -/* t = strdup(list[0]); */ -/* } */ -/* if (list) */ -/* XFreeStringList(list); */ -/* } */ -/* } */ - -/* if (xprop.value) XFree(xprop.value); */ + if (prop.value) free(prop.value); } + else + xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + strlen(name), name); - return title; -} /* ecore_x_icccm_icon_name_get */ + free(list[0]); +} -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_colormap_window_get_prefetch(Ecore_X_Window window) +EAPI void +ecore_x_icccm_iconic_request_send(Ecore_X_Window win, Ecore_X_Window root) { - xcb_get_property_cookie_t cookie; + xcb_client_message_event_t ev; - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window ? ((xcb_screen_t *)_ecore_xcb_screen)->root : window, - ECORE_X_ATOM_WM_COLORMAP_WINDOWS, - ECORE_X_ATOM_WINDOW, - 0L, LONG_MAX); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_colormap_window_get_prefetch */ - -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_colormap_window_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_colormap_window_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_colormap_window_get_fetch */ + if (!win) return; + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_WM_CHANGE_STATE; + ev.data.data32[0] = XCB_WM_STATE_ICONIC; + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT), + (const char *)&ev); +} /** - * Add a subwindow to the list of windows that need a different colormap installed. - * @param window The toplevel window - * @param sub_window The subwindow to be added to the colormap windows list - * - * Add @p sub_window to the list of windows that need a different - * colormap installed. - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_colormap_window_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_colormap_window_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group + * Set or unset a wm protocol property. + * @param win The Window + * @param protocol The protocol to enable/disable + * @param on On/Off */ -EAPI void -ecore_x_icccm_colormap_window_set(Ecore_X_Window window, - Ecore_X_Window sub_window) +EAPI void +ecore_x_icccm_protocol_set(Ecore_X_Window win, Ecore_X_WM_Protocol protocol, Eina_Bool on) { - void *data = NULL; - xcb_get_property_reply_t *reply; - uint32_t num; + Ecore_X_Atom proto; + xcb_get_property_cookie_t cookie; + xcb_get_wm_protocols_reply_t protos; + int i = 0, count = 0, set = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return; + proto = _ecore_xcb_atoms_wm_protocol[protocol]; + cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); + if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL)) + count = 0; + else + count = protos.atoms_len; - if (window == 0) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; + for (i = 0; i < count; i++) + { + if (protos.atoms[i] == proto) + { + set = 1; + break; + } + } - reply = _ecore_xcb_reply_get(); - if (!reply || (reply->format != 32) || (reply->value_len == 0)) + if (on) { - data = calloc(1, sizeof(Ecore_X_Window)); - if (!data) + if (!set) { - if (reply) - free(reply); + Ecore_X_Atom *atoms = NULL; - return; + atoms = malloc((count + 1) * sizeof(Ecore_X_Atom)); + if (atoms) + { + for (i = 0; i < count; i++) + atoms[i] = protos.atoms[i]; + atoms[count] = proto; + xcb_set_wm_protocols(_ecore_xcb_conn, + ECORE_X_ATOM_WM_PROTOCOLS, + win, count, atoms); + free(atoms); + } } - - num = 1; } - else + else { - Ecore_X_Window *newset = NULL; - Ecore_X_Window *oldset = NULL; - uint32_t i; - - num = reply->value_len; - data = calloc(num + 1, sizeof(Ecore_X_Window)); - if (!data) - return; - - newset = (Ecore_X_Window *)data; - oldset = (Ecore_X_Window *)xcb_get_property_value(reply); - for (i = 0; i < num; ++i) + if (set) { - if (oldset[i] == sub_window) + for (i = 0; i < count; i++) { - free(newset); - return; + if (protos.atoms[i] == proto) + { + int j = 0; + + for (j = (i + 1); j < count; j++) + protos.atoms[j - 1] = protos.atoms[j]; + if (count > 1) + xcb_set_wm_protocols(_ecore_xcb_conn, + ECORE_X_ATOM_WM_PROTOCOLS, + win, count - 1, protos.atoms); + else + ecore_x_window_prop_property_del(win, + ECORE_X_ATOM_WM_PROTOCOLS); + break; + } } - - newset[i] = oldset[i]; } - - newset[num++] = sub_window; } - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_COLORMAP_WINDOWS, - ECORE_X_ATOM_WINDOW, - 32, num, data); - free(data); -} /* ecore_x_icccm_colormap_window_set */ + xcb_get_wm_protocols_reply_wipe(&protos); +} /** - * Remove a window from the list of colormap windows. - * @param window The toplevel window - * @param sub_window The window to be removed from the colormap window list. - * - * Remove @p sub_window from the list of colormap windows. - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_colormap_window_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_colormap_window_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group + * Determines whether a protocol is set for a window. + * @param win The Window + * @param protocol The protocol to query + * @return 1 if the protocol is set, else 0. */ -EAPI void -ecore_x_icccm_colormap_window_unset(Ecore_X_Window window, - Ecore_X_Window sub_window) +EAPI Eina_Bool +ecore_x_icccm_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol) { - void *data = NULL; - Ecore_X_Window *oldset = NULL; - Ecore_X_Window *newset = NULL; - xcb_get_property_reply_t *reply; - uint32_t num; - uint32_t i; - uint32_t j; - uint32_t k = 0; + Ecore_X_Atom proto; + Eina_Bool ret = EINA_FALSE; + xcb_get_property_cookie_t cookie; + xcb_get_wm_protocols_reply_t reply; + uint8_t val = 0; + unsigned int i = 0; - if (window == 0) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply || (reply->format != 32) || (reply->value_len == 0)) - return; + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE; - num = reply->value_len; - oldset = (Ecore_X_Window *)xcb_get_property_value(reply); - for (i = 0; i < num; i++) - { - if (oldset[i] == sub_window) - { - if (num == 1) - { - xcb_delete_property(_ecore_xcb_conn, window, - ECORE_X_ATOM_WM_COLORMAP_WINDOWS); - return; - } - else - { - data = calloc(num - 1, sizeof(Ecore_X_Window)); - newset = (Ecore_X_Window *)data; - for (j = 0; j < num; ++j) - if (oldset[j] != sub_window) - newset[k++] = oldset[j]; + proto = _ecore_xcb_atoms_wm_protocol[protocol]; + cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); + val = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL); + if (!val) return EINA_FALSE; - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_COLORMAP_WINDOWS, - ECORE_X_ATOM_WINDOW, - 32, k, data); - free(newset); - return; - } - } - } -} /* ecore_x_icccm_colormap_window_unset */ + for (i = 0; i < reply.atoms_len; i++) + if (reply.atoms[i] == proto) + { + ret = EINA_TRUE; + break; + } -/** - * Specify that a window is transient for another top-level window and should be handled accordingly. - * @param window The transient window - * @param forwindow The toplevel window - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_transient_for_set(Ecore_X_Window window, - Ecore_X_Window forwindow) -{ - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_TRANSIENT_FOR, ECORE_X_ATOM_WINDOW, 32, - 1, (void *)&forwindow); -} /* ecore_x_icccm_transient_for_set */ + xcb_get_wm_protocols_reply_wipe(&reply); + return ret; +} /** - * Remove the transient_for setting from a window. - * @param window The window. - * @ingroup Ecore_X_ICCCM_Group + * Set protocol atoms explicitly + * @param win The Window + * @param protos An array of protocol atoms + * @param num the number of members of the array */ -EAPI void -ecore_x_icccm_transient_for_unset(Ecore_X_Window window) +EAPI void +ecore_x_icccm_protocol_atoms_set(Ecore_X_Window win, Ecore_X_Atom *protos, int num) { - xcb_delete_property(_ecore_xcb_conn, window, ECORE_X_ATOM_WM_TRANSIENT_FOR); -} /* ecore_x_icccm_transient_for_unset */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/* - * Sends the GetProperty request. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_transient_for_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; + if (num > 0) + xcb_set_wm_protocols(_ecore_xcb_conn, ECORE_X_ATOM_WM_PROTOCOLS, + win, num, protos); + else + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_PROTOCOLS); - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_WM_TRANSIENT_FOR, - ECORE_X_ATOM_WINDOW, - 0L, 1L); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_transient_for_get_prefetch */ +} -/* - * Gets the reply of the GetProperty request sent by ecore_x_icccm_transient_for_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_transient_for_get_fetch(void) +EAPI Eina_Bool +ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, Eina_Bool *request_pos, Ecore_X_Gravity *gravity, int *min_w, int *min_h, int *max_w, int *max_h, int *base_w, int *base_h, int *step_x, int *step_y, double *min_aspect, double *max_aspect) { + xcb_size_hints_t hints; xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + uint8_t ret = 0; + int32_t minw = 0, minh = 0; + int32_t maxw = 32767, maxh = 32767; + int32_t basew = -1, baseh = -1; + int32_t stepx = -1, stepy = -1; + double mina = 0.0, maxa = 0.0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (request_pos) *request_pos = EINA_FALSE; + if (gravity) *gravity = ECORE_X_GRAVITY_NW; + if (min_w) *min_w = minw; + if (min_h) *min_h = minh; + if (max_w) *max_w = maxw; + if (max_h) *max_h = maxh; + if (base_w) *base_w = basew; + if (base_h) *base_h = baseh; + if (step_x) *step_x = stepx; + if (step_y) *step_y = stepy; + if (min_aspect) *min_aspect = mina; + if (max_aspect) *max_aspect = maxa; + + cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); + if (!ret) return EINA_FALSE; + + if ((hints.flags & XCB_SIZE_HINT_US_POSITION) || + (hints.flags & XCB_SIZE_HINT_P_POSITION)) + { + if (request_pos) *request_pos = EINA_TRUE; + } - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_transient_for_get_fetch */ + if (hints.flags & XCB_SIZE_HINT_P_WIN_GRAVITY) + { + if (gravity) *gravity = hints.win_gravity; + } -/** - * Get the window this window is transient for, if any. - * @param window The window to check (Unused). - * @return The window ID of the top-level window, or 0 if the property does not exist. - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_transient_for_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_transient_for_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI Ecore_X_Window -ecore_x_icccm_transient_for_get(Ecore_X_Window window __UNUSED__) -{ - xcb_get_property_reply_t *reply; - Ecore_X_Window forwin = 0; + if (hints.flags & XCB_SIZE_HINT_P_MIN_SIZE) + { + minw = hints.min_width; + minh = hints.min_height; + } - reply = _ecore_xcb_reply_get(); - if (!reply) - return forwin; + if (hints.flags & XCB_SIZE_HINT_P_MAX_SIZE) + { + maxw = hints.max_width; + maxh = hints.max_height; + if (maxw < minw) maxw = minw; + if (maxh < minh) maxh = minh; + } - if ((reply->format != 32) || - (reply->value_len == 0) || - (reply->type != ECORE_X_ATOM_WINDOW)) - return forwin; + if (hints.flags & XCB_SIZE_HINT_BASE_SIZE) + { + basew = hints.base_width; + baseh = hints.base_height; + if (basew > minw) minw = basew; + if (baseh > minh) minh = baseh; + } - forwin = *(Ecore_X_Window *)xcb_get_property_value(reply); + if (hints.flags & XCB_SIZE_HINT_P_RESIZE_INC) + { + stepx = hints.width_inc; + stepy = hints.height_inc; + if (stepx < 1) stepx = 1; + if (stepy < 1) stepy = 1; + } - return forwin; -} /* ecore_x_icccm_transient_for_get */ + if (hints.flags & XCB_SIZE_HINT_P_ASPECT) + { + if (hints.min_aspect_den > 0) + mina = ((double)hints.min_aspect_num) / ((double)hints.min_aspect_den); -/** - * Set the window role hint. - * @param window The window - * @param role The role string. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_window_role_set(Ecore_X_Window window, - const char *role) -{ - ecore_x_window_prop_string_set(window, ECORE_X_ATOM_WM_WINDOW_ROLE, - (char *)role); -} /* ecore_x_icccm_window_role_set */ + if (hints.max_aspect_den > 0) + maxa = ((double)hints.max_aspect_num) / ((double)hints.max_aspect_den); + } + + if (min_w) *min_w = minw; + if (min_h) *min_h = minh; + if (max_w) *max_w = maxw; + if (max_h) *max_h = maxh; + if (base_w) *base_w = basew; + if (base_h) *base_h = baseh; + if (step_x) *step_x = stepx; + if (step_y) *step_y = stepy; + if (min_aspect) *min_aspect = mina; + if (max_aspect) *max_aspect = maxa; + + return EINA_TRUE; +} -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - * @ingroup Ecore_X_ICCCM_Group - */ EAPI void -ecore_x_icccm_window_role_get_prefetch(Ecore_X_Window window) +ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, Eina_Bool request_pos, Ecore_X_Gravity gravity, int min_w, int min_h, int max_w, int max_h, int base_w, int base_h, int step_x, int step_y, double min_aspect, double max_aspect) { xcb_get_property_cookie_t cookie; + xcb_size_hints_t hints; + uint8_t ret = 0; - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root, - ECORE_X_ATOM_WM_WINDOW_ROLE, XCB_GET_PROPERTY_TYPE_ANY, - 0L, 1000000L); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_window_role_get_prefetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Gets the reply of the GetProperty request sent by ecore_x_icccm_window_role_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_window_role_get_fetch(void) + cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); + if (!ret) memset(&hints, 0, sizeof(xcb_size_hints_t)); + + hints.flags = 0; + if (request_pos) + hints.flags |= XCB_SIZE_HINT_US_POSITION; + + if (gravity != ECORE_X_GRAVITY_NW) + xcb_size_hints_set_win_gravity(&hints, gravity); + if ((min_w > 0) || (min_h > 0)) + xcb_size_hints_set_min_size(&hints, min_w, min_h); + if ((max_w > 0) || (max_h > 0)) + xcb_size_hints_set_max_size(&hints, max_w, max_h); + if ((base_w > 0) || (base_h > 0)) + xcb_size_hints_set_base_size(&hints, base_w, base_h); + if ((step_x > 1) || (step_y > 1)) + xcb_size_hints_set_resize_inc(&hints, step_x, step_y); + if ((min_aspect > 0.0) || (max_aspect > 0.0)) + xcb_size_hints_set_aspect(&hints, + (int32_t)(min_aspect * 10000), 10000, + (int32_t)(max_aspect * 10000), 10000); + + xcb_set_wm_normal_hints(_ecore_xcb_conn, win, &hints); +} + +EAPI void +ecore_x_icccm_move_resize_send(Ecore_X_Window win, int x, int y, int w, int h) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + xcb_configure_notify_event_t ev; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_window_role_get_fetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + memset(&ev, 0, sizeof(xcb_configure_notify_event_t)); + + ev.response_type = XCB_CONFIGURE_NOTIFY; + ev.event = win; + ev.window = win; + ev.above_sibling = XCB_NONE; + ev.x = x; + ev.y = y; + ev.width = w; + ev.height = h; + ev.border_width = 0; + ev.override_redirect = 0; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev); +} /** - * Get the window role. - * @param window The window. - * @return The window's role string. + * Get a window client machine string. + * @param win The window + * @return The windows client machine string * - * To use this function, you must call before, and in order, - * ecore_x_icccm_window_role_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_window_role_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group + * Return the client machine of a window. String must be free'd when done with. */ EAPI char * -ecore_x_icccm_window_role_get(Ecore_X_Window window) +ecore_x_icccm_client_machine_get(Ecore_X_Window win) { - return ecore_x_window_prop_string_get(window, ECORE_X_ATOM_WM_WINDOW_ROLE); -} /* ecore_x_icccm_window_role_get */ + xcb_get_property_cookie_t cookie; + xcb_get_text_property_reply_t prop; + uint8_t ret = 0; + char *tmp = NULL; -/** - * Set the window's client leader. - * @param window The window - * @param leader The client leader window - * - * All non-transient top-level windows created by an app other than - * the main window must have this property set to the app's main window. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_client_leader_set(Ecore_X_Window window, - Ecore_X_Window leader) -{ - ecore_x_window_prop_window_set(window, ECORE_X_ATOM_WM_CLIENT_LEADER, - &leader, 1); -} /* ecore_x_icccm_client_leader_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_client_leader_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; + cookie = xcb_get_wm_client_machine_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_client_machine_reply(_ecore_xcb_conn, cookie, &prop, NULL); + if (ret == 0) return NULL; + + tmp = malloc((prop.name_len + 1) * sizeof(char *)); + if (!tmp) + { + xcb_get_text_property_reply_wipe(&prop); + return NULL; + } + memcpy(tmp, prop.name, sizeof(char *) * prop.name_len); + tmp[prop.name_len] = '\0'; - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window, - ECORE_X_ATOM_WM_CLIENT_LEADER, - ECORE_X_ATOM_WINDOW, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_icccm_client_leader_get_prefetch */ + xcb_get_text_property_reply_wipe(&prop); -/** - * Gets the reply of the GetProperty request sent by ecore_x_icccm_client_leader_get_prefetch(). - * @ingroup Ecore_X_ICCCM_Group - */ -EAPI void -ecore_x_icccm_client_leader_get_fetch(void) + return tmp; +} + +EAPI void +ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time t) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_icccm_client_leader_get_fetch */ + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + XCB_EVENT_MASK_NO_EVENT, + ECORE_X_ATOM_WM_TAKE_FOCUS, t, 0, 0, 0); +} + +EAPI void +ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time t) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + XCB_EVENT_MASK_NO_EVENT, + ECORE_X_ATOM_WM_SAVE_YOURSELF, t, 0, 0, 0); +} /** - * Get the window's client leader. - * @param window The window - * @return The window's client leader window, or 0 if unset. - * - * To use this function, you must call before, and in order, - * ecore_x_icccm_client_leader_get_prefetch(), which sends the GetProperty request, - * then ecore_x_icccm_client_leader_get_fetch(), which gets the reply. - * @ingroup Ecore_X_ICCCM_Group + * Add a subwindow to the list of windows that need a different colormap installed. + * @param win The toplevel window + * @param subwin The subwindow to be added to the colormap windows list */ -EAPI Ecore_X_Window -ecore_x_icccm_client_leader_get(Ecore_X_Window window) +EAPI void +ecore_x_icccm_colormap_window_set(Ecore_X_Window win, Ecore_X_Window subwin) { - Ecore_X_Window leader; + int num = 0, i = 0; + unsigned char *odata = NULL, *data = NULL; + Ecore_X_Window *newset = NULL, *oldset = NULL; - if (ecore_x_window_prop_window_get(window, ECORE_X_ATOM_WM_CLIENT_LEADER, - &leader, 1) > 0) - return leader; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return 0; -} /* ecore_x_icccm_client_leader_get */ + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + ECORE_X_ATOM_WINDOW, 32, &odata, &num)) + { + if (!(newset = calloc(1, sizeof(Ecore_X_Window)))) return; + newset[0] = subwin; + num = 1; + data = (unsigned char *)newset; + } + else + { + if (!(newset = calloc(num + 1, sizeof(Ecore_X_Window)))) return; + oldset = (Ecore_X_Window *)odata; + for (i = 0; i < num; i++) + { + if (oldset[i] == subwin) + { + if (odata) free(odata); + odata = NULL; + free(newset); + return; + } + newset[i] = oldset[i]; + } + newset[num++] = subwin; + if (odata) free(odata); + data = (unsigned char *)newset; + } + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + ECORE_X_ATOM_WINDOW, 32, data, num); + free(newset); +} /** - * Send the ClientMessage event with the ChangeState property. - * @param window The window. - * @param root The root window. - * @ingroup Ecore_X_ICCCM_Group + * Remove a window from the list of colormap windows. + * @param win The toplevel window + * @param subwin The window to be removed from the colormap window list. */ -EAPI void -ecore_x_icccm_iconic_request_send(Ecore_X_Window window, - Ecore_X_Window root) +EAPI void +ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, Ecore_X_Window subwin) { - xcb_client_message_event_t ev; - - if (!window) - return; + int num = 0, i = 0, j = 0, k = 0; + unsigned char *odata = NULL, *data = NULL; + Ecore_X_Window *newset = NULL, *oldset = NULL; - if (!root) - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* send_event is bit 7 (0x80) of response_type */ - ev.response_type = XCB_CLIENT_MESSAGE | 0x80; - ev.format = 32; - ev.sequence = 0; - ev.window = window; - ev.type = ECORE_X_ATOM_WM_CHANGE_STATE; - ev.data.data32[0] = XCB_WM_STATE_ICONIC; + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + ECORE_X_ATOM_WINDOW, 32, &odata, &num)) + return; - xcb_send_event(_ecore_xcb_conn, 0, root, - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, - (const char *)&ev); -} /* ecore_x_icccm_iconic_request_send */ + oldset = (Ecore_X_Window *)odata; + for (i = 0; i < num; i++) + { + if (oldset[i] == subwin) + { + if (num == 1) + { + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS); + if (odata) free(odata); + odata = NULL; + return; + } + else + { + newset = calloc(num - 1, sizeof(Ecore_X_Window)); + data = (unsigned char *)newset; + for (j = 0; j < num; ++j) + if (oldset[j] != subwin) + newset[k++] = oldset[j]; -/* FIXME: there are older E hints, gnome hints and mwm hints and new netwm */ -/* hints. each should go in their own file/section so we know which */ -/* is which. also older kde hints too. we should try support as much */ -/* as makese sense to support */ + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + ECORE_X_ATOM_WINDOW, 32, data, k); + if (odata) free(odata); + odata = NULL; + free(newset); + return; + } + } + } + if (odata) free(odata); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_image.c b/src/lib/ecore_x/xcb/ecore_xcb_image.c new file mode 100644 index 0000000..2de3b74 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_image.c @@ -0,0 +1,670 @@ +#include "ecore_xcb_private.h" +#include +#include +#include +#include + +struct _Ecore_X_Image +{ + xcb_shm_segment_info_t shminfo; + xcb_image_t *xim; + Ecore_X_Visual vis; + int depth, w, h; + int bpl, bpp, rows; + unsigned char *data; + Eina_Bool shm : 1; +}; + +/* local function prototypes */ +static void _ecore_xcb_image_shm_check(void); +static void _ecore_xcb_image_shm_create(Ecore_X_Image *im); +static xcb_image_t *_ecore_xcb_image_create_native(int w, int h, xcb_image_format_t format, uint8_t depth, void *base, uint32_t bytes, uint8_t *data); +static xcb_format_t *_ecore_xcb_image_find_format(const xcb_setup_t *setup, uint8_t depth); + +/* local variables */ +static int _ecore_xcb_image_shm_can = -1; + +EAPI Ecore_X_Image * +ecore_x_image_new(int w, int h, Ecore_X_Visual vis, int depth) +{ + Ecore_X_Image *im; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(im = calloc(1, sizeof(Ecore_X_Image)))) return NULL; + im->w = w; + im->h = h; + im->vis = vis; + im->depth = depth; + _ecore_xcb_image_shm_check(); + im->shm = _ecore_xcb_image_shm_can; + return im; +} + +EAPI void +ecore_x_image_free(Ecore_X_Image *im) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!im) return; + if (im->shm) + { + if (im->xim) + { + xcb_shm_detach(_ecore_xcb_conn, im->shminfo.shmseg); + xcb_image_destroy(im->xim); + shmdt(im->shminfo.shmaddr); + shmctl(im->shminfo.shmid, IPC_RMID, 0); + } + } + else if (im->xim) + { + if (im->xim->data) free(im->xim->data); + im->xim->data = NULL; + xcb_image_destroy(im->xim); + } + + free(im); +} + +EAPI Eina_Bool +ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw, int x, int y, int sx, int sy, int w, int h) +{ + Eina_Bool ret = EINA_TRUE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (im->shm) + { + if (!im->xim) _ecore_xcb_image_shm_create(im); + if (!im->xim) return EINA_FALSE; + + if ((sx == 0) && (w == im->w)) + { + im->xim->data = (uint8_t *)im->data + (im->xim->stride * sy) + + (sx * im->bpp); + im->xim->width = w; + im->xim->height = h; + + ecore_x_grab(); + if (!xcb_image_shm_get(_ecore_xcb_conn, draw, im->xim, + im->shminfo, x, y, 0xffffffff)) + { + DBG("\tImage Shm Get Failed"); + ret = EINA_FALSE; + } + ecore_x_ungrab(); + ecore_x_sync(); // needed + } + else + { + Ecore_X_Image *tim; + + tim = ecore_x_image_new(w, h, im->vis, im->depth); + if (tim) + { + ret = ecore_x_image_get(tim, draw, x, y, 0, 0, w, h); + if (ret) + { + unsigned char *spixels, *pixels; + int sbpp = 0, sbpl = 0, srows = 0; + int bpp = 0, bpl = 0, rows = 0; + + spixels = + ecore_x_image_data_get(tim, &sbpl, &srows, &sbpp); + pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp); + if ((spixels) && (pixels)) + { + unsigned char *p, *sp; + int r = 0; + + p = (pixels + (sy * bpl) + (sx * bpp)); + sp = spixels; + for (r = srows; r > 0; r--) + { + memcpy(p, sp, sbpl); + p += bpl; + sp += sbpl; + } + } + } + ecore_x_image_free(tim); + } + } + } + else + { + ret = EINA_FALSE; + ecore_x_grab(); + im->xim = + xcb_image_get(_ecore_xcb_conn, draw, x, y, w, h, + 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP); + if (!im->xim) ret = EINA_FALSE; + ecore_x_ungrab(); + + if (im->xim) + { + im->data = (unsigned char *)im->xim->data; + im->bpl = im->xim->stride; + im->rows = im->xim->height; + if (im->xim->bpp <= 8) + im->bpp = 1; + else if (im->xim->bpp <= 16) + im->bpp = 2; + else + im->bpp = 4; + } + } + + return ret; +} + +EAPI void * +ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!im) return NULL; + if (!im->xim) _ecore_xcb_image_shm_create(im); + if (!im->xim) return NULL; + + if (bpl) *bpl = im->bpl; + if (rows) *rows = im->rows; + if (bpp) *bpp = im->bpp; + + return im->data; +} + +EAPI void +ecore_x_image_put(Ecore_X_Image *im, Ecore_X_Drawable draw, Ecore_X_GC gc, int x, int y, int sx, int sy, int w, int h) +{ + Ecore_X_GC tgc = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!gc) + { + uint32_t mask, values[1]; + + tgc = xcb_generate_id(_ecore_xcb_conn); + mask = XCB_GC_SUBWINDOW_MODE; + values[0] = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS; + xcb_create_gc(_ecore_xcb_conn, tgc, draw, mask, values); + gc = tgc; + } + if (!im->xim) _ecore_xcb_image_shm_create(im); + if (im->xim) + { + if (im->shm) + xcb_image_shm_put(_ecore_xcb_conn, draw, gc, im->xim, + im->shminfo, sx, sy, x, y, w, h, 0); + else + xcb_image_put(_ecore_xcb_conn, draw, gc, im->xim, sx, sy, 0); + + } + if (tgc) ecore_x_gc_free(tgc); +} + +EAPI Eina_Bool +ecore_x_image_is_argb32_get(Ecore_X_Image *im) +{ + xcb_visualtype_t *vis; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + vis = (xcb_visualtype_t *)im->vis; + if (!im->xim) _ecore_xcb_image_shm_create(im); + + if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && + (im->depth >= 24) && (vis->red_mask == 0xff0000) && + (vis->green_mask == 0x00ff00) && (vis->blue_mask == 0x0000ff)) + { +#ifdef WORDS_BIGENDIAN + if (im->xim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST) + return EINA_TRUE; +#else + if (im->xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST) + return EINA_TRUE; +#endif + } + + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_image_to_argb_convert(void *src, int sbpp, int sbpl, Ecore_X_Colormap c, Ecore_X_Visual v, int x, int y, int w, int h, unsigned int *dst, int dbpl, int dx, int dy) +{ + xcb_visualtype_t *vis; + uint32_t *cols; + int n = 0, nret = 0, i, row, mode = 0; + unsigned int pal[256], r, g, b; + enum + { + rgbnone = 0, + rgb565, + bgr565, + rgbx555, + argbx888, + abgrx888, + rgba888x, + bgra888x, + argbx666 + }; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + sbpp *= 8; + + vis = (xcb_visualtype_t *)v; + n = vis->colormap_entries; + if ((n <= 256) && + ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || + (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY))) + { + xcb_query_colors_cookie_t cookie; + xcb_query_colors_reply_t *reply; + + if (!c) + { + c = (xcb_colormap_t)((xcb_screen_t *) + _ecore_xcb_screen)->default_colormap; + } + + cols = alloca(n * sizeof(uint32_t)); + for (i = 0; i < n; i++) + cols[i] = i; + + cookie = xcb_query_colors_unchecked(_ecore_xcb_conn, c, n, cols); + reply = xcb_query_colors_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_rgb_iterator_t iter; + xcb_rgb_t *ret; + + iter = xcb_query_colors_colors_iterator(reply); + ret = xcb_query_colors_colors(reply); + if (ret) + { + for (i = 0; iter.rem; xcb_rgb_next(&iter), i++) + { + pal[i] = 0xff000000 | + ((iter.data->red >> 8) << 16) | + ((iter.data->green >> 8) << 8) | + ((iter.data->blue >> 8)); + } + nret = n; + } + free(reply); + } + } + else if ((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) + { + if ((vis->red_mask == 0x00ff0000) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x000000ff)) + mode = argbx888; + else if ((vis->red_mask == 0x000000ff) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x00ff0000)) + mode = abgrx888; + else if ((vis->red_mask == 0xff000000) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0x0000ff00)) + mode = rgba888x; + else if ((vis->red_mask == 0x0000ff00) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0xff000000)) + mode = bgra888x; + else if ((vis->red_mask == 0x0003f000) && + (vis->green_mask == 0x00000fc0) && + (vis->blue_mask == 0x0000003f)) + mode = argbx666; + else if ((vis->red_mask == 0x0000f800) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgb565; + else if ((vis->red_mask == 0x0000001f) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000f800)) + mode = bgr565; + else if ((vis->red_mask == 0x00007c00) && + (vis->green_mask == 0x000003e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgbx555; + else + return EINA_FALSE; + } + for (row = 0; row < h; row++) + { + unsigned char *s8; + unsigned short *s16; + unsigned int *s32, *dp, *de; + + dp = ((unsigned int *)(((unsigned char *)dst) + + ((dy + row) * dbpl))) + dx; + de = dp + w; + switch (sbpp) + { + case 8: + s8 = ((unsigned char *)(((unsigned char *)src) + + ((y + row) * sbpl))) + x; + if (nret > 0) + { + while (dp < de) + { + *dp = pal[*s8]; + s8++; dp++; + } + } + else + return EINA_FALSE; + break; + case 16: + s16 = ((unsigned short *)(((unsigned char *)src) + + ((y + row) * sbpl))) + x; + switch (mode) + { + case rgb565: + while (dp < de) + { + r = (*s16 & 0xf800) << 8; + g = (*s16 & 0x07e0) << 5; + b = (*s16 & 0x001f) << 3; + r |= (r >> 5) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + case bgr565: + while (dp < de) + { + r = (*s16 & 0x001f) << 19; + g = (*s16 & 0x07e0) << 5; + b = (*s16 & 0xf800) >> 8; + r |= (r >> 5) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + case rgbx555: + while (dp < de) + { + r = (*s16 & 0x7c00) << 9; + g = (*s16 & 0x03e0) << 6; + b = (*s16 & 0x001f) << 3; + r |= (r >> 5) & 0xff0000; + g |= (g >> 5) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + default: + return EINA_FALSE; + break; + } + break; + case 24: + case 32: + s32 = ((unsigned int *)(((unsigned char *)src) + + ((y + row) * sbpl))) + x; + switch (mode) + { + case argbx888: + while (dp < de) + { + *dp = 0xff000000 | *s32; + s32++; dp++; + } + break; + case abgrx888: + while (dp < de) + { + r = *s32 & 0x000000ff; + g = *s32 & 0x0000ff00; + b = *s32 & 0x00ff0000; + *dp = 0xff000000 | (r << 16) | (g) | (b >> 16); + s32++; dp++; + } + break; + case rgba888x: + while (dp < de) + { + *dp = 0xff000000 | (*s32 >> 8); + s32++; dp++; + } + break; + case bgra888x: + while (dp < de) + { + r = *s32 & 0x0000ff00; + g = *s32 & 0x00ff0000; + b = *s32 & 0xff000000; + *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24); + s32++; dp++; + } + break; + case argbx666: + while (dp < de) + { + r = (*s32 & 0x3f000) << 6; + g = (*s32 & 0x00fc0) << 4; + b = (*s32 & 0x0003f) << 2; + r |= (r >> 6) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 6); + *dp = 0xff000000 | r | g | b; + s32++; dp++; + } + break; + default: + return EINA_FALSE; + break; + } + break; + break; + default: + return EINA_FALSE; + break; + } + } + return EINA_TRUE; +} + +/* local functions */ +static void +_ecore_xcb_image_shm_check(void) +{ + xcb_shm_query_version_reply_t *reply; + xcb_shm_segment_info_t shminfo; + xcb_shm_get_image_cookie_t cookie; + xcb_shm_get_image_reply_t *ireply; + xcb_image_t *img = 0; + uint8_t depth = 0; + + if (_ecore_xcb_image_shm_can != -1) return; + + reply = + xcb_shm_query_version_reply(_ecore_xcb_conn, + xcb_shm_query_version(_ecore_xcb_conn), NULL); + if (!reply) + { + _ecore_xcb_image_shm_can = 0; + return; + } + + if ((reply->major_version < 1) || + ((reply->major_version == 1) && (reply->minor_version == 0))) + { + _ecore_xcb_image_shm_can = 0; + free(reply); + return; + } + + free(reply); + + depth = ((xcb_screen_t *)_ecore_xcb_screen)->root_depth; + + ecore_x_sync(); // needed + + img = _ecore_xcb_image_create_native(1, 1, XCB_IMAGE_FORMAT_Z_PIXMAP, + depth, NULL, ~0, NULL); + if (!img) + { + _ecore_xcb_image_shm_can = 0; + return; + } + + shminfo.shmid = + shmget(IPC_PRIVATE, img->stride * img->height, (IPC_CREAT | 0666)); + if (shminfo.shmid == (uint32_t)-1) + { + xcb_image_destroy(img); + _ecore_xcb_image_shm_can = 0; + return; + } + + shminfo.shmaddr = shmat(shminfo.shmid, 0, 0); + img->data = shminfo.shmaddr; + if (img->data == (uint8_t *)-1) + { + xcb_image_destroy(img); + _ecore_xcb_image_shm_can = 0; + return; + } + + shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn); + xcb_shm_attach(_ecore_xcb_conn, shminfo.shmseg, shminfo.shmid, 0); + + cookie = + xcb_shm_get_image(_ecore_xcb_conn, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + 0, 0, img->width, img->height, + 0xffffffff, img->format, + shminfo.shmseg, img->data - shminfo.shmaddr); + + ecore_x_sync(); // needed + + ireply = xcb_shm_get_image_reply(_ecore_xcb_conn, cookie, NULL); + if (ireply) + { + _ecore_xcb_image_shm_can = 1; + free(ireply); + } + else + _ecore_xcb_image_shm_can = 0; + + xcb_shm_detach(_ecore_xcb_conn, shminfo.shmseg); + xcb_image_destroy(img); + shmdt(shminfo.shmaddr); + shmctl(shminfo.shmid, IPC_RMID, 0); +} + +static void +_ecore_xcb_image_shm_create(Ecore_X_Image *im) +{ + im->xim = + _ecore_xcb_image_create_native(im->w, im->h, XCB_IMAGE_FORMAT_Z_PIXMAP, + im->depth, NULL, ~0, NULL); + if (!im->xim) return; + + im->shminfo.shmid = shmget(IPC_PRIVATE, im->xim->size, (IPC_CREAT | 0666)); +// shmget(IPC_PRIVATE, im->xim->stride * im->xim->height, (IPC_CREAT | 0666)); + if (im->shminfo.shmid == (uint32_t)-1) + { + xcb_image_destroy(im->xim); + return; + } + + im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0); + im->xim->data = im->shminfo.shmaddr; + if ((!im->xim->data) || (im->xim->data == (uint8_t *)-1)) + { + DBG("Shm Create No Image Data"); + xcb_image_destroy(im->xim); + shmdt(im->shminfo.shmaddr); + shmctl(im->shminfo.shmid, IPC_RMID, 0); + return; + } + + im->shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn); + xcb_shm_attach(_ecore_xcb_conn, im->shminfo.shmseg, im->shminfo.shmid, 0); + + im->data = (unsigned char *)im->xim->data; + im->bpl = im->xim->stride; + im->rows = im->xim->height; + if (im->xim->bpp <= 8) + im->bpp = 1; + else if (im->xim->bpp <= 16) + im->bpp = 2; + else + im->bpp = 4; +} + +static xcb_image_t * +_ecore_xcb_image_create_native(int w, int h, xcb_image_format_t format, uint8_t depth, void *base, uint32_t bytes, uint8_t *data) +{ + const xcb_setup_t *setup; + xcb_format_t *fmt = NULL; + xcb_image_format_t xif; + + /* NB: We cannot use xcb_image_create_native as it only creates images + * using MSB_FIRST, so this routine recreates that function and checks + * endian-ness correctly */ + setup = xcb_get_setup(_ecore_xcb_conn); + xif = format; + + if ((xif == XCB_IMAGE_FORMAT_Z_PIXMAP) && (depth == 1)) + xif = XCB_IMAGE_FORMAT_XY_PIXMAP; + + fmt = _ecore_xcb_image_find_format(setup, depth); + if (!fmt) return 0; + + switch (xif) + { + case XCB_IMAGE_FORMAT_XY_BITMAP: + if (depth != 1) return 0; + case XCB_IMAGE_FORMAT_XY_PIXMAP: + return xcb_image_create(w, h, xif, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, + setup->bitmap_format_scanline_unit, + setup->image_byte_order, + setup->bitmap_format_bit_order, + base, bytes, data); + case XCB_IMAGE_FORMAT_Z_PIXMAP: + return xcb_image_create(w, h, xif, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, + setup->bitmap_format_scanline_unit, + setup->image_byte_order, + setup->bitmap_format_bit_order, + base, bytes, data); + default: + break; + } + + return 0; +} + +static xcb_format_t * +_ecore_xcb_image_find_format(const xcb_setup_t *setup, uint8_t depth) +{ + xcb_format_t *fmt, *fmtend; + + fmt = xcb_setup_pixmap_formats(setup); + fmtend = fmt + xcb_setup_pixmap_formats_length(setup); + for (; fmt != fmtend; ++fmt) + if (fmt->depth == depth) + return fmt; + + return 0; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_input.c b/src/lib/ecore_x/xcb/ecore_xcb_input.c new file mode 100644 index 0000000..a5b2120 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_input.c @@ -0,0 +1,188 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_XINPUT +# include +# include +#endif + +/* local variables */ +static Eina_Bool _input_avail = EINA_FALSE; + +/* external variables */ +int _ecore_xcb_event_input = 0; + +void +_ecore_xcb_input_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XINPUT + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_input_id); +#endif +} + +void +_ecore_xcb_input_finalize(void) +{ +#ifdef ECORE_XCB_XINPUT + xcb_input_get_extension_version_cookie_t cookie; + xcb_input_get_extension_version_reply_t *reply; + char buff[128]; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XINPUT + cookie = + xcb_input_get_extension_version_unchecked(_ecore_xcb_conn, 127, buff); + reply = + xcb_input_get_extension_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + _input_avail = EINA_TRUE; + free(reply); + } + + if (_input_avail) + { + const xcb_query_extension_reply_t *ext_reply; + + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_input_id); + if (ext_reply) + _ecore_xcb_event_input = ext_reply->first_event; + } +#endif +} + +void +_ecore_xcb_input_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +} + +void +#ifdef ECORE_XCB_XINPUT +_ecore_xcb_input_handle_event(xcb_generic_event_t *event) +#else +_ecore_xcb_input_handle_event(xcb_generic_event_t *event __UNUSED__) +#endif +{ +#ifdef ECORE_XCB_XINPUT + xcb_ge_event_t *ev; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XINPUT + ev = (xcb_ge_event_t *)event; + switch (ev->event_type) + { + case XCB_INPUT_DEVICE_MOTION_NOTIFY: + { + xcb_input_device_motion_notify_event_t *de; + unsigned int child_win = 0; + + de = (xcb_input_device_motion_notify_event_t *)ev->pad1; + child_win = (de->child ? de->child : de->event); + _ecore_xcb_event_mouse_move(de->time, de->state, de->event_x, + de->event_y, de->root_x, de->root_y, + de->event, child_win, de->root, + de->same_screen, de->device_id, + 1, 1, 1.0, 0.0, + de->event_x, de->event_y, + de->root_x, de->root_y); + } + break; + case XCB_INPUT_DEVICE_BUTTON_PRESS: + { + xcb_input_device_button_press_event_t *de; + unsigned int child_win = 0; + + de = (xcb_input_device_button_press_event_t *)ev->pad1; + child_win = (de->child ? de->child : de->event); + _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN, + de->time, de->state, de->detail, + de->event_x, de->event_y, + de->root_x, de->root_y, de->event, + child_win, de->root, + de->same_screen, de->device_id, + 1, 1, 1.0, 0.0, + de->event_x, de->event_y, + de->root_x, de->root_y); + } + break; + case XCB_INPUT_DEVICE_BUTTON_RELEASE: + { + xcb_input_device_button_release_event_t *de; + unsigned int child_win = 0; + + de = (xcb_input_device_button_release_event_t *)ev->pad1; + child_win = (de->child ? de->child : de->event); + _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP, + de->time, de->state, de->detail, + de->event_x, de->event_y, + de->root_x, de->root_y, de->event, + child_win, de->root, + de->same_screen, de->device_id, + 1, 1, 1.0, 0.0, + de->event_x, de->event_y, + de->root_x, de->root_y); + } + break; + default: + break; + } +#endif +} + +EAPI Eina_Bool +ecore_x_input_multi_select(Ecore_X_Window win) +{ + Eina_Bool find = EINA_FALSE; +#ifdef ECORE_XCB_XINPUT + xcb_input_list_input_devices_cookie_t dcookie; + xcb_input_list_input_devices_reply_t *dreply; + xcb_input_device_info_iterator_t diter; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_input_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_XINPUT + dcookie = xcb_input_list_input_devices_unchecked(_ecore_xcb_conn); + dreply = + xcb_input_list_input_devices_reply(_ecore_xcb_conn, dcookie, NULL); + if (!dreply) return EINA_FALSE; + + diter = xcb_input_list_input_devices_devices_iterator(dreply); + while (diter.rem) + { + xcb_input_device_info_t *dev; + const xcb_input_event_class_t iclass = + { + XCB_INPUT_DEVICE_BUTTON_PRESS | + XCB_INPUT_DEVICE_BUTTON_RELEASE | + XCB_INPUT_DEVICE_MOTION_NOTIFY + }; + + dev = diter.data; + if (dev->device_use == XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_DEVICE) + { + DBG("Device %d", dev->device_id); + DBG("\tType: %d", dev->device_type); + DBG("\tNum Classes: %d", dev->num_class_info); + DBG("\tUse: %d", dev->device_use); + + /* FIXME: This may not be correct !! + * I have no extra Input Devices to test with */ + xcb_input_select_extension_event(_ecore_xcb_conn, win, 1, &iclass); + find = EINA_TRUE; + } + xcb_input_device_info_next(&diter); + } + free(dreply); +#endif + + return find; + win = 0; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_keymap.c b/src/lib/ecore_x/xcb/ecore_xcb_keymap.c new file mode 100644 index 0000000..ab7ca86 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_keymap.c @@ -0,0 +1,447 @@ +#include "ecore_xcb_private.h" +#define NEED_KEYSYM_TABLE +#define NEED_VTABLE +#include "ecore_xcb_keysym_table.h" +#include +#include + +/* local function prototypes */ +static int _ecore_xcb_keymap_mask_get(void *reply, xcb_keysym_t sym); +static xcb_keysym_t _ecore_xcb_keymap_string_to_keysym(const char *str); +static int _ecore_xcb_keymap_translate_key(xcb_keycode_t keycode, unsigned int modifiers, unsigned int *modifiers_return, xcb_keysym_t *keysym_return); +static int _ecore_xcb_keymap_translate_keysym(xcb_keysym_t keysym, unsigned int modifiers, char *buffer, int bytes); + +/* local variables */ +static xcb_key_symbols_t *_ecore_xcb_keysyms; +static int _ecore_xcb_mode_switch = 0; + +/* public variables */ +EAPI int ECORE_X_MODIFIER_SHIFT = 0; +EAPI int ECORE_X_MODIFIER_CTRL = 0; +EAPI int ECORE_X_MODIFIER_ALT = 0; +EAPI int ECORE_X_MODIFIER_WIN = 0; +EAPI int ECORE_X_LOCK_SCROLL = 0; +EAPI int ECORE_X_LOCK_NUM = 0; +EAPI int ECORE_X_LOCK_CAPS = 0; +EAPI int ECORE_X_LOCK_SHIFT = 0; + +void +_ecore_xcb_keymap_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_keysyms = xcb_key_symbols_alloc(_ecore_xcb_conn); +} + +void +_ecore_xcb_keymap_finalize(void) +{ + xcb_get_modifier_mapping_cookie_t cookie; + xcb_get_modifier_mapping_reply_t *reply; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + cookie = xcb_get_modifier_mapping_unchecked(_ecore_xcb_conn); + reply = xcb_get_modifier_mapping_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) + { + xcb_key_symbols_free(_ecore_xcb_keysyms); + return; + } + + _ecore_xcb_mode_switch = _ecore_xcb_keymap_mask_get(reply, XK_Mode_switch); + + ECORE_X_MODIFIER_SHIFT = _ecore_xcb_keymap_mask_get(reply, XK_Shift_L); + ECORE_X_MODIFIER_CTRL = _ecore_xcb_keymap_mask_get(reply, XK_Control_L); + + ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Alt_L); + if (!ECORE_X_MODIFIER_ALT) + ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Meta_L); + if (!ECORE_X_MODIFIER_ALT) + ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Super_L); + + ECORE_X_MODIFIER_WIN = _ecore_xcb_keymap_mask_get(reply, XK_Super_L); + if (!ECORE_X_MODIFIER_WIN) + ECORE_X_MODIFIER_WIN = _ecore_xcb_keymap_mask_get(reply, XK_Mode_switch); + if (!ECORE_X_MODIFIER_WIN) + ECORE_X_MODIFIER_WIN = _ecore_xcb_keymap_mask_get(reply, XK_Meta_L); + + if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT) + ECORE_X_MODIFIER_WIN = 0; + if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL) + ECORE_X_MODIFIER_ALT = 0; + + ECORE_X_LOCK_SCROLL = _ecore_xcb_keymap_mask_get(reply, XK_Scroll_Lock); + ECORE_X_LOCK_NUM = _ecore_xcb_keymap_mask_get(reply, XK_Num_Lock); + ECORE_X_LOCK_CAPS = _ecore_xcb_keymap_mask_get(reply, XK_Caps_Lock); + ECORE_X_LOCK_SHIFT = _ecore_xcb_keymap_mask_get(reply, XK_Shift_Lock); +} + +void +_ecore_xcb_keymap_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (_ecore_xcb_keysyms) xcb_key_symbols_free(_ecore_xcb_keysyms); +} + +void +_ecore_xcb_keymap_refresh(xcb_mapping_notify_event_t *event) +{ + xcb_refresh_keyboard_mapping(_ecore_xcb_keysyms, event); +} + +xcb_keysym_t +_ecore_xcb_keymap_keycode_to_keysym(xcb_keycode_t keycode, int col) +{ + xcb_keysym_t key0, key1; + + if (col & _ecore_xcb_mode_switch) + { + key0 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 4); + key1 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 5); + } + else + { + key0 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 0); + key1 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 1); + } + + if (key1 == XCB_NO_SYMBOL) + key1 = key0; + + if ((col & ECORE_X_LOCK_NUM) && + ((xcb_is_keypad_key(key1)) || (xcb_is_private_keypad_key(key1)))) + { + if ((col & XCB_MOD_MASK_SHIFT) || + ((col & XCB_MOD_MASK_LOCK) && (col & ECORE_X_LOCK_SHIFT))) + return key0; + else + return key1; + } + else if (!(col & XCB_MOD_MASK_SHIFT) && !(col & XCB_MOD_MASK_LOCK)) + return key0; + else if (!(col & XCB_MOD_MASK_SHIFT) && + (col & XCB_MOD_MASK_LOCK && (col & ECORE_X_LOCK_CAPS))) + return key1; + else if ((col & XCB_MOD_MASK_SHIFT) && + (col & XCB_MOD_MASK_LOCK) && (col & ECORE_X_LOCK_CAPS)) + return key0; + else if ((col & XCB_MOD_MASK_SHIFT) || + (col & XCB_MOD_MASK_LOCK && (col & ECORE_X_LOCK_SHIFT))) + return key1; + + return XCB_NO_SYMBOL; +} + +xcb_keycode_t * +_ecore_xcb_keymap_keysym_to_keycode(xcb_keysym_t keysym) +{ + return xcb_key_symbols_get_keycode(_ecore_xcb_keysyms, keysym); +} + +char * +_ecore_xcb_keymap_keysym_to_string(xcb_keysym_t keysym) +{ + int i = 0, n = 0, h = 0, idx = 0; + const unsigned char *entry; + unsigned char val1, val2, val3, val4; + + if (!keysym) return NULL; + if (keysym == XK_VoidSymbol) keysym = 0; + if (keysym <= 0x1fffffff) + { + val1 = (keysym >> 24); + val2 = ((keysym >> 16) & 0xff); + val3 = ((keysym >> 8) & 0xff); + val4 = (keysym & 0xff); + i = keysym % VTABLESIZE; + h = i + 1; + n = VMAXHASH; + while ((idx = hashKeysym[i])) + { + entry = &_ecore_xcb_keytable[idx]; + if ((entry[0] == val1) && (entry[1] == val2) && + (entry[2] == val3) && (entry[3] == val4)) + return ((char *)entry + 4); + if (!--n) break; + i += h; + if (i >= VTABLESIZE) i -= VTABLESIZE; + } + } + + if ((keysym >= 0x01000100) && (keysym <= 0x0110ffff)) + { + xcb_keysym_t val; + char *s = NULL; + int i = 0; + + val = (keysym & 0xffffff); + if (val & 0xff0000) + i = 10; + else + i = 6; + + if (!(s = malloc(i))) return NULL; + i--; + s[i--] = '\0'; + for (; i; i--) + { + val1 = (val & 0xf); + val >>= 4; + if (val1 < 10) + s[i] = '0' + val1; + else + s[i] = 'A' + val1 - 10; + } + s[i] = 'U'; + return s; + } + + return NULL; +} + +xcb_keycode_t +_ecore_xcb_keymap_string_to_keycode(const char *key) +{ + if (!strncmp(key, "Keycode-", 8)) + return atoi(key + 8); + else + { + xcb_keysym_t keysym = XCB_NO_SYMBOL; + xcb_keycode_t *keycodes, keycode = 0; + int i = 0; + + keysym = _ecore_xcb_keymap_string_to_keysym(key); + if (keysym == XCB_NO_SYMBOL) return XCB_NO_SYMBOL; + + keycodes = _ecore_xcb_keymap_keysym_to_keycode(keysym); + if (!keycodes) return XCB_NO_SYMBOL; + + while (keycodes[i] != XCB_NO_SYMBOL) + { + if (keycodes[i] != 0) + { + keycode = keycodes[i]; + break; + } + i++; + } + return keycode; + } +} + +int +_ecore_xcb_keymap_lookup_string(xcb_keycode_t keycode, int state, char *buffer, int bytes, xcb_keysym_t *sym) +{ + unsigned int modifiers = 0; + xcb_keysym_t keysym; + + if (!_ecore_xcb_keymap_translate_key(keycode, state, &modifiers, &keysym)) + return 0; + + if (sym) *sym = keysym; + + return _ecore_xcb_keymap_translate_keysym(keysym, state, buffer, bytes); +} + +EAPI const char * +ecore_x_keysym_string_get(int keysym) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_keymap_keysym_to_string(keysym); +} + +/* local functions */ +static int +_ecore_xcb_keymap_mask_get(void *reply, xcb_keysym_t sym) +{ + xcb_get_modifier_mapping_reply_t *rep; + xcb_keysym_t sym2; + int mask = 0; + const int masks[8] = + { + XCB_MOD_MASK_SHIFT, XCB_MOD_MASK_LOCK, XCB_MOD_MASK_CONTROL, + XCB_MOD_MASK_1, XCB_MOD_MASK_2, XCB_MOD_MASK_3, XCB_MOD_MASK_4, + XCB_MOD_MASK_5 + }; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + rep = (xcb_get_modifier_mapping_reply_t *)reply; + if ((rep) && (rep->keycodes_per_modifier > 0)) + { + int i = 0; + xcb_keycode_t *modmap; + + modmap = xcb_get_modifier_mapping_keycodes(rep); + for (i = 0; i < (8 * rep->keycodes_per_modifier); i++) + { + int j = 0; + + for (j = 0; j < 8; j++) + { + sym2 = + xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, + modmap[i], j); + if (sym2 != 0) break; + } + if (sym2 == sym) + { + mask = masks[i / rep->keycodes_per_modifier]; + break; + } + } + } + + return mask; +} + +static xcb_keysym_t +_ecore_xcb_keymap_string_to_keysym(const char *str) +{ + int i = 0, n = 0, h = 0; + unsigned long sig = 0; + const char *p = NULL; + int c = 0, idx = 0; + const unsigned char *entry; + unsigned char sig1, sig2; + long unsigned int val; + + p = str; + while ((c = *p++)) + sig = (sig << 1) + c; + + i = (sig % KTABLESIZE); + h = i + 1; + sig1 = (sig >> 8) & 0xff; + sig2 = sig & 0xff; + n = KMAXHASH; + + while ((idx = hashString[i])) + { + entry = &_ecore_xcb_keytable[idx]; + if ((entry[0] == sig1) && (entry[1] == sig2) && + !strcmp(str, (char *)entry + 6)) + { + val = ((entry[2] << 24) | (entry[3] << 16) | + (entry[4] << 8) | (entry[5])); + if (!val) val = 0xffffff; + return val; + } + if (!--n) break; + i += h; + if (i >= KTABLESIZE) i-= KTABLESIZE; + } + + if (*str == 'U') + { + val = 0; + for (p = &str[1]; *p; p++) + { + c = *p; + if (('0' <= c) && (c <= '9')) + val = (val << 4) + c - '0'; + else if (('a' <= c) && (c <= 'f')) + val = (val << 4) + c - 'a' + 10; + else if (('A' <= c) && (c <= 'F')) + val = (val << 4) + c - 'A' + 10; + else + return XCB_NO_SYMBOL; + if (val > 0x10ffff) return XCB_NO_SYMBOL; + } + if ((val < 0x20) || ((val > 0x7e) && (val < 0xa0))) + return XCB_NO_SYMBOL; + if (val < 0x100) return val; + return (val | 0x01000000); + } + + if ((strlen(str) > 2) && (str[0] == '0') && (str[1] == 'x')) + { + char *tmp = NULL; + + val = strtoul(str, &tmp, 16); + if ((val == ULONG_MAX) || ((tmp) && (*tmp != '\0'))) + return XCB_NO_SYMBOL; + else + return val; + } + + if (!strncmp(str, "XF86_", 5)) + { + long unsigned int ret; + char *tmp; + + tmp = strdup(str); + if (!tmp) return XCB_NO_SYMBOL; + memmove(&tmp[4], &tmp[5], strlen(str) - 5 + 1); + ret = _ecore_xcb_keymap_string_to_keysym(tmp); + free(tmp); + return ret; + } + + return XCB_NO_SYMBOL; +} + +static int +_ecore_xcb_keymap_translate_key(xcb_keycode_t keycode, unsigned int modifiers, unsigned int *modifiers_return, xcb_keysym_t *keysym_return) +{ + xcb_keysym_t sym; + + if (!_ecore_xcb_keysyms) return 0; + + sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, modifiers); + + if (modifiers_return) + *modifiers_return = ((XCB_MOD_MASK_SHIFT | XCB_MOD_MASK_LOCK) | + _ecore_xcb_mode_switch | ECORE_X_LOCK_NUM); + if (keysym_return) + *keysym_return = sym; + + return 1; +} + +static int +_ecore_xcb_keymap_translate_keysym(xcb_keysym_t keysym, unsigned int modifiers, char *buffer, int bytes) +{ + unsigned long hbytes = 0; + unsigned char c; + + if (!keysym) return 0; + hbytes = (keysym >> 8); + + if (!(bytes && + ((hbytes == 0) || + ((hbytes == 0xFF) && + (((keysym >= XK_BackSpace) && (keysym <= XK_Clear)) || + (keysym == XK_Return) || (keysym == XK_Escape) || + (keysym == XK_KP_Space) || (keysym == XK_KP_Tab) || + (keysym == XK_KP_Enter) || + ((keysym >= XK_KP_Multiply) && (keysym <= XK_KP_9)) || + (keysym == XK_KP_Equal) || (keysym == XK_Delete)))))) + return 0; + + if (keysym == XK_KP_Space) + c = (XK_space & 0x7F); + else if (hbytes == 0xFF) + c = (keysym & 0x7F); + else + c = (keysym & 0xFF); + + if (modifiers & ECORE_X_MODIFIER_CTRL) + { + if (((c >= '@') && (c < '\177')) || c == ' ') + c &= 0x1F; + else if (c == '2') + c = '\000'; + else if ((c >= '3') && (c <= '7')) + c -= ('3' - '\033'); + else if (c == '8') + c = '\177'; + else if (c == '/') + c = '_' & 0x1F; + } + buffer[0] = c; + return 1; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_mwm.c b/src/lib/ecore_x/xcb/ecore_xcb_mwm.c index 872bdec..9d3aa71 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_mwm.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_mwm.c @@ -1,151 +1,98 @@ -/* - * Various MWM related functions. - * - * This is ALL the code involving anything MWM related. for both WM and - * client. - */ - #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" - -/** - * @defgroup Ecore_X_MWM_Group MWM related functions. - * - * Functions related to MWM. - */ +//#include "Ecore_X_Atoms.h" -#define ECORE_X_MWM_HINTS_FUNCTIONS (1 << 0) +#define ECORE_X_MWM_HINTS_FUNCTIONS (1 << 0) #define ECORE_X_MWM_HINTS_DECORATIONS (1 << 1) -#define ECORE_X_MWM_HINTS_INPUT_MODE (1 << 2) -#define ECORE_X_MWM_HINTS_STATUS (1 << 3) +#define ECORE_X_MWM_HINTS_INPUT_MODE (1 << 2) +#define ECORE_X_MWM_HINTS_STATUS (1 << 3) typedef struct _mwmhints { uint32_t flags; uint32_t functions; uint32_t decorations; - int32_t inputmode; + int32_t inputmode; uint32_t status; -} -MWMHints; +} MWMHints; /** - * Sends the GetProperty request. - * @param window Window whose MWM hints are requested. - * @ingroup Ecore_X_MWM_Group + * @defgroup Ecore_X_MWM_Group MWM related functions. + * + * Functions related to MWM. */ -EAPI void -ecore_x_mwm_hints_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root, - ECORE_X_ATOM_MOTIF_WM_HINTS, - ECORE_X_ATOM_MOTIF_WM_HINTS, - 0, LONG_MAX); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_mwm_hints_get_prefetch */ /** - * Gets the reply of the GetProperty request sent by ecore_x_mwm_hints_get_prefetch(). + * Sets the borderless flag of a window using MWM. + * + * @param win The window. + * @param borderless The borderless flag. + * * @ingroup Ecore_X_MWM_Group */ -EAPI void -ecore_x_mwm_hints_get_fetch(void) +EAPI void +ecore_x_mwm_borderless_set(Ecore_X_Window win, Eina_Bool borderless) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + uint32_t data[5] = { 0, 0, 0, 0, 0 }; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_mwm_hints_get_fetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * To document. - * @param window Unused. - * @param fhint To document. - * @param dhint To document. - * @param ihint To document. - * @return 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_mwm_hints_get_prefetch(), which sends the GetProperty request, - * then ecore_x_mwm_hints_get_fetch(), which gets the reply. - * @ingroup Ecore_X_MWM_Group - */ -EAPI Eina_Bool -ecore_x_mwm_hints_get(Ecore_X_Window window __UNUSED__, - Ecore_X_MWM_Hint_Func *fhint, - Ecore_X_MWM_Hint_Decor *dhint, - Ecore_X_MWM_Hint_Input *ihint) + data[0] = 2; + data[2] = !borderless; + + ecore_x_window_prop_property_set(win ? win : ((xcb_screen_t *)_ecore_xcb_screen)->root, + ECORE_X_ATOM_MOTIF_WM_HINTS, + ECORE_X_ATOM_MOTIF_WM_HINTS, 32, + (void *)data, 5); +} + +EAPI Eina_Bool +ecore_x_mwm_hints_get(Ecore_X_Window win, Ecore_X_MWM_Hint_Func *fhint, Ecore_X_MWM_Hint_Decor *dhint, Ecore_X_MWM_Hint_Input *ihint) { - MWMHints *mwmhints = NULL; - int ret = 0; + xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; + MWMHints *mwmhints = NULL; + int ret = EINA_FALSE; - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if ((reply->format != 32) || - (reply->value_len == 0)) - return 0; + cookie = + xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, + ECORE_X_ATOM_MOTIF_WM_HINTS, + ECORE_X_ATOM_MOTIF_WM_HINTS, 0, LONG_MAX); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + if ((reply->format != 32) || (reply->value_len == 0)) + { + free(reply); + return EINA_FALSE; + } mwmhints = xcb_get_property_value(reply); - if (reply->value_len >= 4) + if (reply->value_len >= 4) { - if (dhint) + if (dhint) { if (mwmhints->flags & ECORE_X_MWM_HINTS_DECORATIONS) - *dhint = mwmhints->decorations; + *dhint = mwmhints->decorations; else - *dhint = ECORE_X_MWM_HINT_DECOR_ALL; + *dhint = ECORE_X_MWM_HINT_DECOR_ALL; } - - if (fhint) + if (fhint) { if (mwmhints->flags & ECORE_X_MWM_HINTS_FUNCTIONS) - *fhint = mwmhints->functions; + *fhint = mwmhints->functions; else - *fhint = ECORE_X_MWM_HINT_FUNC_ALL; + *fhint = ECORE_X_MWM_HINT_FUNC_ALL; } - - if (ihint) + if (ihint) { if (mwmhints->flags & ECORE_X_MWM_HINTS_INPUT_MODE) - *ihint = mwmhints->inputmode; + *ihint = mwmhints->inputmode; else - *ihint = ECORE_X_MWM_HINT_INPUT_MODELESS; + *ihint = ECORE_X_MWM_HINT_INPUT_MODELESS; } - - ret = 1; + ret = EINA_TRUE; } - + free(reply); return ret; -} /* ecore_x_mwm_hints_get */ - -/** - * Sets the borderless flag of a window using MWM. - * @param window The window. - * @param borderless The borderless flag. - * @ingroup Ecore_X_MWM_Group - */ -EAPI void -ecore_x_mwm_borderless_set(Ecore_X_Window window, - Eina_Bool borderless) -{ - uint32_t data[5] = {0, 0, 0, 0, 0}; - - data[0] = 2; /* just set the decorations hint! */ - data[2] = !borderless; - - if (window == 0) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_MOTIF_WM_HINTS, ECORE_X_ATOM_MOTIF_WM_HINTS, - 32, 5, data); -} /* ecore_x_mwm_borderless_set */ - +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_netwm.c b/src/lib/ecore_x/xcb/ecore_xcb_netwm.c index ff0f42b..0741504 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_netwm.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_netwm.c @@ -1,3380 +1,1338 @@ -/* - * _NET_WM... aka Extended Window Manager Hint (EWMH) functions. - */ - -#include -#include - #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" -/** - * @defgroup Ecore_X_NetWM_Group Extended Window Manager Hint (EWMH) functions - * - * Functions related to the Extended Window Manager Hint (EWMH). - */ +/* local function prototypes */ +static void _ecore_xcb_netwm_startup_info_free(void *data); +static Ecore_X_Atom _ecore_xcb_netwm_window_type_atom_get(Ecore_X_Window_Type type); +static Ecore_X_Window_Type _ecore_xcb_netwm_window_type_type_get(Ecore_X_Atom atom); +static Ecore_X_Atom _ecore_xcb_netwm_window_state_atom_get(Ecore_X_Window_State state); +static Ecore_X_Atom _ecore_xcb_netwm_action_atom_get(Ecore_X_Action action); -typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info; +/* local variables */ +static Eina_Hash *_startup_info = NULL; -struct _Ecore_X_Startup_Info +/* local structures */ +typedef struct _Ecore_Xcb_Startup_Info Ecore_Xcb_Startup_Info; +struct _Ecore_Xcb_Startup_Info { Ecore_X_Window win; + int init, size; + char *buffer; + int length; - int init; + /* sequence info fields */ + char *id, *name; + int screen; + char *bin, *icon; + int desktop, timestamp; + char *description, *wmclass; + int silent; +}; - int buffer_size; - char *buffer; +EAPI void +ecore_x_netwm_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - int length; + _startup_info = + eina_hash_string_superfast_new(_ecore_xcb_netwm_startup_info_free); +} - /* These are the sequence info fields */ - char *id; - char *name; - int screen; - char *bin; - char *icon; - int desktop; - int timestamp; - char *description; - char *wmclass; - int silent; -}; +EAPI void +ecore_x_netwm_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -#if 0 -static void _ecore_x_window_prop_string_utf8_get_prefetch(Ecore_X_Window window, Ecore_X_Atom atom); -static void _ecore_x_window_prop_string_utf8_get_fetch(void); -#endif /* if 0 */ -static void _ecore_x_window_prop_string_utf8_set(Ecore_X_Window window, Ecore_X_Atom atom, const char *str); -static char * _ecore_x_window_prop_string_utf8_get(Ecore_X_Window window, Ecore_X_Atom atom); -#if 0 /* Unused */ -static int _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info); -static int _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info, char *data); -#endif /* if 0 */ -static void _ecore_x_netwm_startup_info_free(void *data); - -/* - * Local variables - */ - -static Eina_Hash *startup_info = NULL; - -/** - * Initialize the NetWM module - */ -EAPI void -ecore_x_netwm_init(void) -{ - startup_info = eina_hash_string_superfast_new(_ecore_x_netwm_startup_info_free); -} /* ecore_x_netwm_init */ - -/** - * Shutdown the NetWM module - */ -EAPI void -ecore_x_netwm_shutdown(void) -{ - if (startup_info) - eina_hash_free(startup_info); - - startup_info = NULL; -} /* ecore_x_netwm_shutdown */ - -/** - * Set the _NET_SUPPORTING_WM_CHECK property. - * @param root The root window. - * @param check The child window. - * @param wm_name The name of the Window Manager. - * - * Set the _NET_SUPPORTING_WM_CHECK property on the @p root window to be - * the ID of the child window @p check created by the Window Manager. - * @p check also have the _NET_WM_NAME property set to the name - * @p wm_name of the Window Manager. - * - * The Window MUST call that function to indicate that a compliant - * window manager is active. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_wm_identify(Ecore_X_Window root, - Ecore_X_Window check, - const char *wm_name) -{ - ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1); - ecore_x_window_prop_window_set(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1); - _ecore_x_window_prop_string_utf8_set(check, ECORE_X_ATOM_NET_WM_NAME, wm_name); - /* This one isn't mandatory */ - _ecore_x_window_prop_string_utf8_set(root, ECORE_X_ATOM_NET_WM_NAME, wm_name); -} /* ecore_x_netwm_wm_identify */ - -/** - * Set the _NET_SUPPORTED property. - * @param root The root window. - * @param supported The supported hints. - * @param num The number of hints. - * - * Set the _NET_SUPPORTED property on the @p root window. The hints - * that the Window Manager supports are stored in @p supported. - * - * The Window Manager MUST set this property to indicate which hints - * it supports. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_supported_set(Ecore_X_Window root, - Ecore_X_Atom *supported, - int num) -{ - ecore_x_window_prop_atom_set(root, ECORE_X_ATOM_NET_SUPPORTED, supported, num); -} /* ecore_x_netwm_supported_set */ - -/** - * Sends the GetProperty request. - * @param root The root window - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_supported_get_prefetch(Ecore_X_Window root) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, root, - ECORE_X_ATOM_NET_SUPPORTED, ECORE_X_ATOM_ATOM, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_supported_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_supported_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_supported_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_supported_get_fetch */ - -/** - * Get the hints supported by the Window Manager. - * @param root The root window. - * @param supported The supported hints. - * @param num The number of atoms. - * @return 1 on success, 0 otherwise. - * - * Get the hints supported by the Window Manager. @p root is the root - * window. The hints are stored in @p supported. The number of hints - * is stored in @p num. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_supported_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_supported_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_supported_get(Ecore_X_Window root, - Ecore_X_Atom **supported, - int *num) -{ - int num_ret; - - if (num) - *num = 0UL; - - if (supported) - *supported = NULL; - - num_ret = ecore_x_window_prop_xid_list_get(root, - ECORE_X_ATOM_NET_SUPPORTED, - ECORE_X_ATOM_ATOM, - supported); - if (num_ret <= 0) - return 0; - - if (num) - *num = (uint32_t)num_ret; + if (_startup_info) eina_hash_free(_startup_info); + _startup_info = NULL; +} - return 1; -} /* ecore_x_netwm_supported_get */ - -/** - * Set the _NET_NUMBER_OF_DESKTOPS property. - * @param root The root window. - * @param n_desks The number of desktops. - * - * Set the number of desktops @p n_desks of the Window Manager by - * sending the _NET_NUMBER_OF_DESKTOPS to the @p root window. - * - * The Window Manager SHOULD set and update this property to indicate - * the number of virtual desktops. A Pager can request a change in the - * number of desktops by using that function. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desk_count_set(Ecore_X_Window root, - unsigned int n_desks) -{ - ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS, - &n_desks, 1); -} /* ecore_x_netwm_desk_count_set */ - -/** - * Set the _NET_VIRTUAL_ROOTS property. - * @param root The root window. - * @param vroots The virtual root windows. - * @param n_desks The number of desks. - * - * Set the number of virtual desktops by sending the - * _NET_VIRTUAL_ROOTS property to the @p root window. @p vroots is an - * array of window and @p n_desks is the number of windows. - * - * A Window Manager that implements virtual desktops by reparent - * client windows to a child of the root window MUST use that - * function. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desk_roots_set(Ecore_X_Window root, - Ecore_X_Window *vroots, - unsigned int n_desks) -{ - ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_VIRTUAL_ROOTS, vroots, n_desks); -} /* ecore_x_netwm_desk_roots_set */ - -/** - * Set the _NET_DESKTOP_NAMES property. - * @param root The root window. - * @param names The names of the virtual desktops. - * @param n_desks The number of virtual desktops. - * - * Set the name of each virtual desktop by sending the - * _NET_DESKTOP_NAMES to the @p root window. @p names are the names of - * the virtual desktops and @p n_desks is the number of virtual - * desktops. - * - * A Pager MAY use that function. @p n_desks may be different from the - * one passed to ecore_x_netwm_desk_count_set(). If it less or equal, - * then the desktops with high numbers are unnamed. If it is larger, - * then the excess names are considered to be reserved in case the - * number of desktops is increased. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desk_names_set(Ecore_X_Window root, - const char **names, - unsigned int n_desks) -{ - char ss[32]; - char *buf; - const char *s; - uint32_t i; - uint32_t len; - uint32_t l; +EAPI Eina_Bool +ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid) +{ + uint32_t tmp; - buf = NULL; - len = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - for (i = 0; i < n_desks; i++) - { - s = (names) ? names[i] : NULL; - if (!s) - { - /* Default to "Desk-" */ - sprintf(ss, "Desk-%d", i); - s = ss; - } + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID, &tmp, 1)) + return EINA_FALSE; - l = strlen(s) + 1; - buf = realloc(buf, len + l); - memcpy(buf + len, s, l); - len += l; - } + if (pid) *pid = tmp; - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, root, - ECORE_X_ATOM_NET_DESKTOP_NAMES, - ECORE_X_ATOM_UTF8_STRING, - 8, len, (const void *)buf); - free(buf); -} /* ecore_x_netwm_desk_names_set */ - -/** - * Set the _NET_DESKTOP_GEOMETRY property. - * @param root The root window. - * @param width The width of the desktop. - * @param height The height of the desktop. - * - * Set the common @p width and @p height of all desktops by sending - * the _NET_DESKTOP_GEOMETRY to the @p root window. - * - * This size is equal to the screen size if the Window Manager doesn't - * support large desktops, otherwise it's equal to the virtual size of - * the desktop. The Window Manager SHOULD set this property. A Pager - * can request a change in the desktop geometry by using this - * function. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desk_size_set(Ecore_X_Window root, - unsigned int width, - unsigned int height) + return EINA_TRUE; +} + +EAPI void +ecore_x_netwm_pid_set(Ecore_X_Window win, int pid) { - uint32_t size[2]; + unsigned int tmp; - size[0] = width; - size[1] = height; - ecore_x_window_prop_card32_set(root, - ECORE_X_ATOM_NET_DESKTOP_GEOMETRY, - size, 2); -} /* ecore_x_netwm_desk_size_set */ - -/** - * Set the _NET_DESKTOP_VIEWPORT property. - * @param root The root window. - * @param origins An array of paris of coordiantes. - * @param n_desks The number of virtual desktops. - * - * Set the top left corner of each desktop's viewport by sending the - * _NET_DESKTOP_VIEWPORT property to the @p root window. @p origins - * contains each pair of X coordinate and Y coordinate of the top left - * corner of each desktop's viewport. - * - * If the Window Manager does not support large desktops, the - * coordinates MUST be (0,0). A Pager can request to change the - * viewport for the current desktop by using this function. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desk_viewports_set(Ecore_X_Window root, - unsigned int *origins, - unsigned int n_desks) -{ - ecore_x_window_prop_card32_set(root, - ECORE_X_ATOM_NET_DESKTOP_VIEWPORT, - origins, 2 * n_desks); -} /* ecore_x_netwm_desk_viewports_set */ - -/** - * Set the _NET_DESKTOP_LAYOUT property. - * @param root The root window. - * @param orientation - * @param columns - * @param rows - * @param starting_corner - * - * Set the layout of virtual desktops relative to each other by - * sending the _NET_DESKTOP_LAYOUT to the @p root window. - * @p orientation defines the orientation of the virtual desktop. 0 - * means horizontal layout, 1 means vertical layout. @p columns is - * the number of desktops in the X direction and @p rows is the number - * in the Y direction. @p starting_corner is the corner containing the - * first desktop. The values for @p starting_corner are 0 (top-left), - * 1 (top-right), 2 (bottom-right) and 3 (bottom-left). - * - * When the orientation is horizontal the desktops are laid out in - * rows, with the first desktop in the specified starting corner. So a - * layout with four columns and three rows starting in - * the top-left corner looks like this: - * - * +--+--+--+--+ - * | 0| 1| 2| 3| - * +--+--+--+--+ - * | 4| 5| 6| 7| - * +--+--+--+--+ - * | 8| 9|10|11| - * +--+--+--+--+ - * - * With @p starting_corner being bottom-right, it looks like this: - * - * +--+--+--+--+ - * |11|10| 9| 8| - * +--+--+--+--+ - * | 7| 6| 5| 4| - * +--+--+--+--+ - * | 3| 2| 1| 0| - * +--+--+--+--+ - * - * When the orientation is vertical the layout with four columns and - * three rows starting in the top-left corner looks like: - * - * +--+--+--+--+ - * | 0| 3| 6| 9| - * +--+--+--+--+ - * | 1| 4| 7|10| - * +--+--+--+--+ - * | 2| 5| 8|11| - * +--+--+--+--+ - * - * With @p starting_corner being top-right, it looks like: - * - * +--+--+--+--+ - * | 9| 6| 3| 0| - * +--+--+--+--+ - * |10| 7| 4| 1| - * +--+--+--+--+ - * |11| 8| 5| 2| - * +--+--+--+--+ - * - * This function MUST be used by a Pager and NOT by the Window - * Manager. When using this function, the Pager must own a manager - * selection. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desk_layout_set(Ecore_X_Window root, - int orientation, - int columns, - int rows, - int starting_corner) -{ - uint32_t layout[4]; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - layout[0] = orientation; - layout[1] = columns; - layout[2] = rows; - layout[3] = starting_corner; - ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT, layout, 4); -} /* ecore_x_netwm_desk_layout_set */ - -/** - * Set the _NET_WORKAREA property. - * @param root The root window. - * @param areas An array of areas. - * @param n_desks The number of desks. - * - * Set the work area for each desktop by sending the _NET_WORKAREA - * property to the @p root window. An area contains the geometry (X - * and Y coordinates, width and height). These geometries are - * specified relative to the viewport on each desktop and specify an - * area that is completely contained within the viewport. @p areas - * stores these geometries. @p n_desks is the number of geometry to - * set. - * - * This function MUST be set by the Window Manager. It is used by - * desktop applications to place desktop icons appropriately. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desk_workareas_set(Ecore_X_Window root, - unsigned int *areas, - unsigned int n_desks) -{ - ecore_x_window_prop_card32_set(root, - ECORE_X_ATOM_NET_WORKAREA, - areas, 4 * n_desks); -} /* ecore_x_netwm_desk_workareas_set */ - -/** - * Set the _NET_CURRENT_DESKTOP property. - * @param root The root window. - * @param desk The index of the current desktop. - * - * Set the current desktop by sending the _NET_CURRENT_DESKTOP to the - * @p root window. @p deskmust be an integer number between 0 and the - * number of desks (set by ecore_x_netwm_desk_count_set()) -1. - * - * This function MUST be called by the Window Manager. If a Pagerwants - * to switch to naother desktop, it MUST call that function. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desk_current_set(Ecore_X_Window root, - unsigned int desk) -{ - ecore_x_window_prop_card32_set(root, - ECORE_X_ATOM_NET_CURRENT_DESKTOP, - &desk, 1); -} /* ecore_x_netwm_desk_current_set */ - -/** - * Set the _NET_SHOWING_DESKTOP property. - * @param root The root window - * @param on 0 to hide the desktop, non 0 to show it. - * - * Set or unset the desktop in a "showing mode" by sending the - * _NET_SHOWING_DESKTOP property to the @p root window. If @p on is 0, - * the windows are hidden and the desktop background is displayed and - * focused. - * - * If a Pager wants to enter or leave the mode, it MUST use this - * function. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, - Eina_Bool on) -{ - uint32_t val; - - val = (on) ? 1 : 0; - ecore_x_window_prop_card32_set(root, - ECORE_X_ATOM_NET_SHOWING_DESKTOP, - &val, 1); -} /* ecore_x_netwm_showing_desktop_set */ - -/* - * Client status - */ - -/** - * Set the _NET_CLIENT_LIST property. - * @param root The root window. - * @param p_clients An array of windows. - * @param n_clients The number of windows. - * - * Map all the X windows managed by the window manager from the oldest - * to the newest by sending the _NET_CLIENT_LIST property to the - * @p root window. The X windows are stored in @p p_clients and their - * number in @p n_clients. - * - * This function SHOULD be called by the Window Manager. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_client_list_set(Ecore_X_Window root, - Ecore_X_Window *p_clients, - unsigned int n_clients) -{ - ecore_x_window_prop_window_set(root, - ECORE_X_ATOM_NET_CLIENT_LIST, - p_clients, n_clients); -} /* ecore_x_netwm_client_list_set */ - -/** - * Set the _NET_CLIENT_LIST_STACKING property. - * @param root The root window. - * @param p_clients An array of windows. - * @param n_clients The number of windows. - * - * Stack all the X windows managed by the window manager from bottom - * to top order by sending the _NET_CLIENT_LIST_STACKING property to the - * @p root window. The X windows are stored in @p p_clients and their - * number in @p n_clients. - * - * This function SHOULD be called by the Window Manager. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root, - Ecore_X_Window *p_clients, - unsigned int n_clients) -{ - ecore_x_window_prop_window_set(root, - ECORE_X_ATOM_NET_CLIENT_LIST_STACKING, - p_clients, n_clients); -} /* ecore_x_netwm_client_list_stacking_set */ - -/** - * Set the _NET_ACTIVE_WINDOW property. - * @param root The root window. - * @param window The widow to activate. - * - * Activate @p window by sending the _NET_ACTIVE_WINDOW property to - * the @p root window. - * - * If a Client wants to activate another window, it MUST call this - * function. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_client_active_set(Ecore_X_Window root, - Ecore_X_Window window) -{ - ecore_x_window_prop_window_set(root, - ECORE_X_ATOM_NET_ACTIVE_WINDOW, - &window, 1); -} /* ecore_x_netwm_client_active_set */ - -/** - * Set the _NET_WM_NAME property. - * @param window The widow to activate. - * @param name The title name of the window. - * - * Set the title name of @p window to @p name by sending the - * _NET_WM_NAME property to @p window. - * - * The Client SHOULD set the title of @p window in UTF-8 encoding. If - * set, the Window Manager should use this in preference to WM_NAME. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_name_set(Ecore_X_Window window, - const char *name) -{ - _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_NAME, name); -} /* ecore_x_netwm_name_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_name_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_NAME, ECORE_X_ATOM_UTF8_STRING, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_name_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_name_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_name_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_name_get_fetch */ - -/** - * Get the title of a window. - * @param window The window. - * @param name The title name. - * @return Returns always 1. - * - * Retrieve the title name of @p window and store it in @p name. The - * function returns always 1. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_name_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_name_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI int -ecore_x_netwm_name_get(Ecore_X_Window window, - char **name) -{ - if (name) - *name = _ecore_x_window_prop_string_utf8_get(window, ECORE_X_ATOM_NET_WM_NAME); + tmp = pid; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_PID, &tmp, 1); +} - return 1; -} /* ecore_x_netwm_name_get */ - -/** - * Set the _NET_STARTUP_ID property. - * @param window The window. - * @param id The ID name. - * - * Set the ID @p id used for the startup sequence by sending the - * property _NET_STARTUP_ID to @p window. The ID name should be - * encoded in UTF-8. - * - * If a new value for the property is set, the Window Manager - * should update the window's status accordingly (update its virtual - * desktop, etc.). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_startup_id_set(Ecore_X_Window window, - const char *id) -{ - _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_STARTUP_ID, id); -} /* ecore_x_netwm_startup_id_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_startup_id_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_STARTUP_ID, ECORE_X_ATOM_UTF8_STRING, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_startup_id_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_startup_id_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_startup_id_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_startup_id_get_fetch */ - -/** - * Get the startup ID name of a window. - * @param window The window - * @param id The ID name - * @return Return always 1. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_startup_id_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_startup_id_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI int -ecore_x_netwm_startup_id_get(Ecore_X_Window window, - char **id) -{ - if (id) - *id = _ecore_x_window_prop_string_utf8_get(window, ECORE_X_ATOM_NET_STARTUP_ID); +EAPI Eina_Bool +ecore_x_netwm_window_type_get(Ecore_X_Window win, Ecore_X_Window_Type *type) +{ + Ecore_X_Atom *atoms; + int num = 0; - return 1; -} /* ecore_x_netwm_startup_id_get */ - -/** - * Set the _NET_WM_VISIBLE_NAME property. - * @param window The widow to activate. - * @param name The title name of the window. - * - * Set the title name of @p window to @p name by sending the - * _NET_WM_VISIBLE_NAME property to @p window, when the Window Manager - * displays a window name other than by calling - * ecore_x_netwm_name_set(). - * - * The Client SHOULD set the title of @p window in UTF-8 - * encoding. This function is used for displaying title windows like - * [xterm1], [xterm2], ... thereby allowing Pagers to display the same - * title as the Window Manager. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_visible_name_set(Ecore_X_Window window, - const char *name) -{ - _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_VISIBLE_NAME, - name); -} /* ecore_x_netwm_visible_name_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_visible_name_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_VISIBLE_NAME, ECORE_X_ATOM_UTF8_STRING, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_visible_name_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_visible_name_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_visible_name_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_visible_name_get_fetch */ - -/** - * Get the visible title of a window. - * @param window The window. - * @param name The title name. - * @return Returns always 1. - * - * Retrieve the visible title name of @p window and store it in @p name. The - * function returns always 1. - * @param window The window - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_visible_name_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_visible_name_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI int -ecore_x_netwm_visible_name_get(Ecore_X_Window window, - char **name) -{ - if (name) - *name = _ecore_x_window_prop_string_utf8_get(window, - ECORE_X_ATOM_NET_WM_VISIBLE_NAME); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return 1; -} /* ecore_x_netwm_visible_name_get */ - -/** - * Set the _NET_WM_ICON_NAME property. - * @param window The widow to activate. - * @param name The icon name of the window. - * - * Set the icon name of @p window to @p name by sending the - * _NET_WM_ICON_NAME property to @p window. - * - * The Client SHOULD set the title of @p window in UTF-8 encoding. If - * set, the Window Manager should use this in preference to WM_ICON_NAME. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_icon_name_set(Ecore_X_Window window, - const char *name) -{ - _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_ICON_NAME, - name); -} /* ecore_x_netwm_icon_name_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_icon_name_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_ICON_NAME, ECORE_X_ATOM_UTF8_STRING, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_icon_name_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_icon_name_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_icon_name_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_icon_name_get_fetch */ - -/** - * Get the icon name of a window. - * @param window The window. - * @param name The icon name. - * @return Returns always 1. - * - * Retrieve the icon name of @p window and store it in @p name. The - * function returns always 1. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_icon_name_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_icon_name_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI int -ecore_x_netwm_icon_name_get(Ecore_X_Window window, - char **name) -{ - if (name) - *name = _ecore_x_window_prop_string_utf8_get(window, - ECORE_X_ATOM_NET_WM_ICON_NAME); + num = + ecore_x_window_prop_atom_list_get(win, + ECORE_X_ATOM_NET_WM_WINDOW_TYPE, &atoms); + if ((type) && (num >= 1) && (atoms)) + *type = _ecore_xcb_netwm_window_type_type_get(atoms[0]); - return 1; -} /* ecore_x_netwm_icon_name_get */ - -/** - * Set the _NET_WM_VISIBLE_ICON_NAME property. - * @param window The widow to activate. - * @param name The title name of the window. - * - * Set the icon name of @p window to @p name by sending the - * _NET_WM_VISIBLE_ICON_NAME property to @p window, when the Window Manager - * displays a icon name other than by calling - * ecore_x_netwm_icon_name_set(). - * - * The Client SHOULD set the icon name in UTF-8 - * encoding. The Window Manager MUST use this function is it display - * an icon name other than with ecore_x_netwm_icon_name_set(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_visible_icon_name_set(Ecore_X_Window window, - const char *name) -{ - _ecore_x_window_prop_string_utf8_set(window, - ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME, - name); -} /* ecore_x_netwm_visible_icon_name_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_visible_icon_name_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME, ECORE_X_ATOM_UTF8_STRING, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_visible_icon_name_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_visible_icon_name_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_visible_icon_name_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_visible_icon_name_get_fetch */ - -/** - * Get the visible icon name of a window. - * @param window The window. - * @param name The icon name. - * @return Returns always 1. - * - * Retrieve the visible icon name of @p window and store it in - * @p name. The function returns always 1. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_visible_icon_name_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_visible_icon_name_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI int -ecore_x_netwm_visible_icon_name_get(Ecore_X_Window window, - char **name) -{ - if (name) - *name = _ecore_x_window_prop_string_utf8_get(window, - ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME); + /* if (type) */ + /* { */ + /* int i = 0; */ - return 1; -} /* ecore_x_netwm_visible_icon_name_get */ - -/** - * Set the _NET_WM_DESKTOP property. - * @param window The window. - * @param desk The desktop index. - * - * Set on which desktop the @p window is in by sending the - * _NET_WM_DESKTOP property to @p window. @p desk is the index of - * the desktop, starting from 0. To indicate that the window should - * appear on all desktops, @p desk must be equal to 0xFFFFFFFF. - * - * A Client MAY choose not to set this property, in which case the - * Window Manager SHOULD place it as it wishes. - * - * The Window Manager should honor _NET_WM_DESKTOP whenever a - * withdrawn window requests to be mapped. - * - * A Client can request a change of desktop for a non-withdrawn window - * by sending a _NET_WM_DESKTOP client message to the root window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desktop_set(Ecore_X_Window window, - unsigned int desk) -{ - ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1); -} /* ecore_x_netwm_desktop_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desktop_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_DESKTOP, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_desktop_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_desktop_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desktop_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_desktop_get_fetch */ - -/** - * Get the visible icon name of a window. - * @param window The window. - * @param desk The desktop index. - * @return 1 on success, 0 otherwise. - * - * Retrieve the desktop index in which @p window is displayed and - * store it in @p desk. If @p desk value is 0xFFFFFFFF, the window - * appears on all desktops. The function returns 1 on success, 0 - * otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_desktop_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_desktop_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_desktop_get(Ecore_X_Window window, - unsigned int *desk) -{ - int ret; - uint32_t tmp; + /* for (i = 0; i < num; i++) */ + /* { */ + /* *type = _ecore_xcb_netwm_window_type_type_get(atoms[i]); */ + /* if (*type != ECORE_X_WINDOW_TYPE_UNKNOWN) break; */ + /* } */ + /* } */ - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_DESKTOP, - &tmp, 1); - - if (desk) - *desk = tmp; - - return (ret == 1) ? 1 : 0; -} /* ecore_x_netwm_desktop_get */ - -/** - * Set the _NET_WM_STRUT property. - * @param window The window - * @param left The number of pixels at the left of the screen. - * @param right The number of pixels at the right of the screen. - * @param top The number of pixels at the top of the screen. - * @param bottom The number of pixels at the bottom of the screen. - * - * Set space at the edje of the screen by sending the _NET_WM_STRUT - * property to @p window if @p window is to reserve that space. - * @p left, @p right, @p top and @p bottom are respectively the number - * of pixels at the left, right, top and bottom of the screen. - * - * This property is deprecated and ecore_x_netwm_strut_partial_set() - * should be used instead. However, Clients MAY set this property in - * addition to _NET_WM_STRUT_PARTIAL to ensure backward compatibility - * with Window Managers supporting older versions of the - * Specification. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_strut_set(Ecore_X_Window window, - int left, - int right, - int top, - int bottom) -{ - uint32_t strut[4]; + if (atoms) free(atoms); - strut[0] = left; - strut[1] = right; - strut[2] = top; - strut[3] = bottom; - ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); -} /* ecore_x_netwm_strut_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_strut_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_STRUT, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_strut_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_strut_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_strut_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_strut_get_fetch */ - -/* - * _NET_WM_STRUT is deprecated - */ - -/** - * Get the space at the edje of the screen. - * @param window The window - * @param left The number of pixels at the left of the screen. - * @param right The number of pixels at the right of the screen. - * @param top The number of pixels at the top of the screen. - * @param bottom The number of pixels at the bottom of the screen. - * @return 1 on success, 0 otherwise. - * - * Retrieve the space at the edje of the screen if @p window is to - * reserve such space. The number of pixels at the left, right, top - * and bottom of the screen are respectively stored in @p left, - * @p right, @p top and @p bottom. This function returns 1 on success, - * 0 otherwise. - * - * This property is deprecated. See ecore_x_netwm_strut_set() for more - * informations. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_strut_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_strut_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_strut_get(Ecore_X_Window window, - int *left, - int *right, - int *top, - int *bottom) -{ - uint32_t strut[4]; - int ret = 0; + if (num >= 1) return EINA_TRUE; + return EINA_FALSE; +} + +EAPI void +ecore_x_netwm_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type) +{ + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + atom = _ecore_xcb_netwm_window_type_atom_get(type); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, &atom, 1); +} + +EAPI int +ecore_x_netwm_window_types_get(Ecore_X_Window win, Ecore_X_Window_Type **types) +{ + int num = 0, i = 0; + Ecore_X_Atom *atoms = NULL; + Ecore_X_Window_Type *atoms2 = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (types) *types = NULL; + num = + ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, + &atoms); + if ((num <= 0) || (!atoms)) + { + if (atoms) free(atoms); + return 0; + } - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); - if (ret != 4) - return 0; + atoms2 = malloc(num * sizeof(Ecore_X_Window_Type)); + if (!atoms2) + { + if (atoms) free(atoms); + return 0; + } - if (left) - *left = strut[0]; + for (i = 0; i < num; i++) + atoms2[i] = _ecore_xcb_netwm_window_type_type_get(atoms[i]); + if (atoms) free(atoms); - if (right) - *right = strut[1]; + if (types) + *types = atoms2; + else + free(atoms2); - if (top) - *top = strut[2]; + return num; +} - if (bottom) - *bottom = strut[3]; +EAPI int +ecore_x_netwm_name_get(Ecore_X_Window win, char **name) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (name) + *name = ecore_x_window_prop_string_get(win, ECORE_X_ATOM_NET_WM_NAME); return 1; -} /* ecore_x_netwm_strut_get */ - -/** - * Set the _NET_WM_STRUT_PARTIAL property. - * @param window The window - * @param left The number of pixels at the left of the screen. - * @param right The number of pixels at the right of the screen. - * @param top The number of pixels at the top of the screen. - * @param bottom The number of pixels at the bottom of the screen. - * @param left_start_y The number of pixels. - * @param left_end_y The number of pixels. - * @param right_start_y The number of pixels. - * @param right_end_y The number of pixels. - * @param top_start_x The number of pixels. - * @param top_end_x The number of pixels. - * @param bottom_start_x The number of pixels. - * @param bottom_end_x The number of pixels. - * - * Set space at the edje of the screen by sending the - * _NET_WM_STRUT_PARTIAL property to @p window if @p window is to - * reserve that space. @p left, @p right, @p top and @p bottom are - * respectively the number of pixels at the left, right, top and - * bottom of the screen. - * - * TODO: more description for that function. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_strut_partial_set(Ecore_X_Window window, - int left, - int right, - int top, - int bottom, - int left_start_y, - int left_end_y, - int right_start_y, - int right_end_y, - int top_start_x, - int top_end_x, - int bottom_start_x, - int bottom_end_x) +} + +EAPI void +ecore_x_netwm_name_set(Ecore_X_Window win, const char *name) { - unsigned int strut[12]; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - strut[0] = left; - strut[1] = right; - strut[2] = top; - strut[3] = bottom; - strut[4] = left_start_y; - strut[5] = left_end_y; - strut[6] = right_start_y; - strut[7] = right_end_y; - strut[8] = top_start_x; - strut[9] = top_end_x; - strut[10] = bottom_start_x; - strut[11] = bottom_end_x; - ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12); -} /* ecore_x_netwm_strut_partial_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_strut_partial_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_strut_partial_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_strut_partial_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_strut_partial_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_strut_partial_get_fetch */ - -/** - * Get the space at the edje of the screen of a window. - * @param window The window - * @param left The number of pixels at the left of the screen. - * @param right The number of pixels at the right of the screen. - * @param top The number of pixels at the top of the screen. - * @param bottom The number of pixels at the bottom of the screen. - * @param left_start_y The number of pixels. - * @param left_end_y The number of pixels. - * @param right_start_y The number of pixels. - * @param right_end_y The number of pixels. - * @param top_start_x The number of pixels. - * @param top_end_x The number of pixels. - * @param bottom_start_x The number of pixels. - * @param bottom_end_x The number of pixels. - * - * Retrieve the space at the edje of the screen if @p window is to - * reserve such space. The number of pixels at the left, right, top - * and bottom of the screen are respectively stored in @p left, - * @p right, @p top and @p bottom. This function returns 1 on success, - * 0 otherwise. - * - * TODO: more description for that function. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_strut_partial_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_strut_partial_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_strut_partial_get(Ecore_X_Window window, - int *left, - int *right, - int *top, - int *bottom, - int *left_start_y, - int *left_end_y, - int *right_start_y, - int *right_end_y, - int *top_start_x, - int *top_end_x, - int *bottom_start_x, - int *bottom_end_x) -{ - uint32_t strut[12]; - int ret = 0; + ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_NAME, name); +} - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12); - if (ret != 12) - return 0; +EAPI void +ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (left) - *left = strut[0]; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, + &opacity, 1); +} - if (right) - *right = strut[1]; +EAPI Eina_Bool +ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity) +{ + unsigned int tmp = 0; - if (top) - *top = strut[2]; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (bottom) - *bottom = strut[3]; + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, + &tmp, 1)) + return EINA_FALSE; - if (left_start_y) - *left_start_y = strut[4]; + if (opacity) *opacity = tmp; - if (left_end_y) - *left_end_y = strut[5]; + return EINA_TRUE; +} - if (right_start_y) - *right_start_y = strut[6]; +EAPI void +ecore_x_netwm_wm_identify(Ecore_X_Window root, Ecore_X_Window check, const char *wm_name) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (right_end_y) - *right_end_y = strut[7]; + ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, + &check, 1); + ecore_x_window_prop_window_set(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, + &check, 1); + ecore_x_window_prop_string_set(check, ECORE_X_ATOM_NET_WM_NAME, wm_name); + ecore_x_window_prop_string_set(root, ECORE_X_ATOM_NET_WM_NAME, wm_name); +} - if (top_start_x) - *top_start_x = strut[8]; +EAPI void +ecore_x_netwm_supported_set(Ecore_X_Window root, Ecore_X_Atom *supported, int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (top_end_x) - *top_end_x = strut[9]; + ecore_x_window_prop_atom_set(root, ECORE_X_ATOM_NET_SUPPORTED, + supported, num); +} - if (bottom_start_x) - *bottom_start_x = strut[10]; +EAPI Eina_Bool +ecore_x_netwm_supported_get(Ecore_X_Window root, Ecore_X_Atom **supported, int *num) +{ + int num_ret = 0; - if (bottom_end_x) - *bottom_end_x = strut[11]; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return 1; -} /* ecore_x_netwm_strut_partial_get */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_icons_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_ICON, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_icons_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_icons_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_icons_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_icons_get_fetch */ - -/** - * Retrieve hte possible icons of a window. - * @param window The window - * @param icon An array of icons. - * @param num The number of icons. - * @return 1 on success, 0 otherwise. - * - * Retrieve an array of possible icons of @p window. The icons are - * stored in @p icon and their number in @p num. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_icons_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_icons_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_icons_get(Ecore_X_Window window, - Ecore_X_Icon **icon, - int *num) -{ - uint32_t *data; - uint32_t *p; - uint32_t *src; - uint32_t icons; - uint32_t len; - uint32_t i; - int num_ret; - - if (num) - *num = 0UL; - - if (icon) - *icon = NULL; - - num_ret = ecore_x_window_prop_card32_list_get(window, - ECORE_X_ATOM_NET_WM_ICON, - &data); - if ((num_ret <= 0) || !data) - return 0; - - if (num_ret < 2) - { - free(data); - return 0; - } + if (num) *num = 0; + if (supported) *supported = NULL; - /* Check how many icons there are */ - icons = 0; - p = data; - while (p) - { - len = p[0] * p[1]; - p += (len + 2); - if ((p - data) > num_ret) - { - free(data); - return 0; - } + num_ret = + ecore_x_window_prop_atom_list_get(root, ECORE_X_ATOM_NET_SUPPORTED, + supported); + if (num_ret <= 0) return EINA_FALSE; + if (num) *num = num_ret; - icons++; + return EINA_TRUE; +} - if ((p - data) == num_ret) - p = NULL; - } - if (num) - *num = icons; +EAPI void +ecore_x_netwm_desk_count_set(Ecore_X_Window root, unsigned int n_desks) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* If the user doesn't want the icons, return */ - if (!icon) - { - free(data); - return 1; - } + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS, + &n_desks, 1); +} - /* Allocate memory */ - *icon = malloc(icons * sizeof(Ecore_X_Icon)); - if (!(*icon)) - { - free(data); - return 0; - } +EAPI void +ecore_x_netwm_desk_roots_set(Ecore_X_Window root, Ecore_X_Window *vroots, unsigned int n_desks) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* Fetch the icons */ - p = data; - for (i = 0; i < icons; i++) - { - uint32_t *ps, *pd, *pe; + ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_VIRTUAL_ROOTS, + vroots, n_desks); +} - len = p[0] * p[1]; - ((*icon)[i]).width = p[0]; - ((*icon)[i]).height = p[1]; - src = &(p[2]); - ((*icon)[i]).data = malloc(len * sizeof(uint32_t)); - if (!((*icon)[i]).data) +EAPI void +ecore_x_netwm_desk_names_set(Ecore_X_Window root, const char **names, unsigned int n_desks) +{ + char ss[32], *buf = NULL, *t = NULL; + const char *s; + uint32_t len = 0, i, l; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + for (i = 0; i < n_desks; i++) + { + s = ((names) ? names[i] : NULL); + if (!s) { - while (i) - free(((*icon)[--i]).data); - free(*icon); - free(data); - return 0; + /* Default to "Desk-" */ + sprintf(ss, "Desk-%d", i); + s = ss; } - pd = ((*icon)[i]).data; - ps = src; - pe = ps + len; - for (; ps < pe; ps++) + l = strlen(s) + 1; + t = realloc(buf, len + 1); + if (t) { - uint32_t r, g, b, a; - - a = (*ps >> 24) & 0xff; - r = (((*ps >> 16) & 0xff) * a) / 255; - g = (((*ps >> 8) & 0xff) * a) / 255; - b = (((*ps) & 0xff) * a) / 255; - *pd = (a << 24) | (r << 16) | (g << 8) | (b); - pd++; + buf = t; + memcpy(buf + len, s, l); } - p += (len + 2); + len += l; } - free(data); + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, root, + ECORE_X_ATOM_NET_DESKTOP_NAMES, + ECORE_X_ATOM_UTF8_STRING, 8, len, (const void *)buf); + free(buf); +} - return 1; -} /* ecore_x_netwm_icons_get */ - -/** - * Set the _NET_WM_ICON_GEOMETRY property. - * @param window The window. - * @param x The X coordinate of the icon. - * @param y The Y coordinate of the icon. - * @param width The width of the icon. - * @param height The height of the icon. - * - * Set the geometry of the icon of @p window by sending the - * _NET_WM_ICON_GEOMETRY property to @p window. @p x, @p y, @p width - * and @p height specify respectively the X coordinate, the Y - * coordinate, the width and the height of the icon. - * - * Stand alone tools like a taskbar or an iconbox MAY use this - * function. This functions makes possible for a Window Manager to - * display a nice animation like morphing the window into its icon. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_icon_geometry_set(Ecore_X_Window window, - int x, - int y, - int width, - int height) -{ - uint32_t geometry[4]; - - geometry[0] = (uint32_t)x; - geometry[1] = (uint32_t)y; - geometry[2] = (uint32_t)width; - geometry[3] = (uint32_t)height; - ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4); -} /* ecore_x_netwm_icon_geometry_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_icon_geometry_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_icon_geometry_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_icon_geometry_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_icon_geometry_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_icon_geometry_get_fetch */ - -/** - * Get the geometry of an icon. - * @param window The window - * @param x x - * @param x The X coordinate of the icon. - * @param y The Y coordinate of the icon. - * @param width The width of the icon. - * @param height The height of the icon. - * @return 1 on success, 0 othrwise. - * - * Retrieve the geometry of the icon of @p window. The geometry is - * stored in @p x, @p y, @p width and @p height. The function returns - * 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_icon_geometry_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_icon_geometry_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_icon_geometry_get(Ecore_X_Window window, - int *x, - int *y, - int *width, - int *height) -{ - uint32_t geometry[4]; - int ret; - - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4); - if (ret != 4) - return 0; - - if (x) - *x = geometry[0]; - - if (y) - *y = geometry[1]; - - if (width) - *width = geometry[2]; - - if (height) - *height = geometry[3]; +EAPI void +ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width, unsigned int height) +{ + uint32_t size[2]; - return 1; -} /* ecore_x_netwm_icon_geometry_get */ - -/** - * Set the _NET_WM_PID property. - * @param window The window. - * @param pid The process ID. - * - * Set the process ID of the client owning @p window by sending the - * _NET_WM_PID property to @p window. - * - * This function MAY be used by the Window Manager to kill windows - * which do not respond to the _NET_WM_PING protocol. - * - * If _NET_WM_PID is set, the ICCCM-specified property - * WM_CLIENT_MACHINE MUST also be set. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_pid_set(Ecore_X_Window window, - int pid) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + size[0] = width; + size[1] = height; + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_GEOMETRY, + size, 2); +} + +EAPI void +ecore_x_netwm_desk_viewports_set(Ecore_X_Window root, unsigned int *origins, unsigned int n_desks) { - unsigned int tmp; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - tmp = pid; - ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_PID, - &tmp, 1); -} /* ecore_x_netwm_pid_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_pid_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_PID, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_pid_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_pid_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_pid_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_pid_get_fetch */ - -/** - * Get the process ID of a client window. - * @param window The window. - * @param pid The process ID. - * @return 1 on success, 0 otherwise. - * - * Retrieve the process ID of @p window and store it in @p pid. This - * function returns 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_pid_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_pid_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_pid_get(Ecore_X_Window window, - int *pid) -{ - int ret; - uint32_t tmp; + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_VIEWPORT, + origins, (2 * n_desks)); +} - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_PID, - &tmp, 1); - if (pid) - *pid = tmp; - - return (ret == 1) ? 1 : 0; -} /* ecore_x_netwm_pid_get */ - -/** - * Set the _NET_WM_HANDLED_ICONS property. - * @param window The window. - * - * Indicate to the Window Manager that it does not need to provide - * icons for the iconified @p window by sending the - * _NET_WM_HANDLED_ICONS property to @p window. - * - * This function can be used by a Pager on one of its own toplevel - * windows (for example if the Client is a taskbar and provides - * buttons for iconified windows). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_handled_icons_set(Ecore_X_Window window) -{ - ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_HANDLED_ICONS, - NULL, 0); -} /* ecore_x_netwm_handled_icons_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_handled_icons_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_HANDLED_ICONS, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_handled_icons_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_handled_icons_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_handled_icons_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_handled_icons_get_fetch */ - -/** - * Return wheter the Client handles icons or not. - * @param window The window. - * @return 1 if icons are handled, 0 otherwise. - * - * Return whether the client handles icons or not if @p window is - * iconified. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_handled_icons_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_handled_icons_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_handled_icons_get(Ecore_X_Window window) +EAPI void +ecore_x_netwm_desk_layout_set(Ecore_X_Window root, int orientation, int columns, int rows, int starting_corner) { - int ret = 0; - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_HANDLED_ICONS, - NULL, 0); - return (ret == 0) ? 1 : 0; -} /* ecore_x_netwm_handled_icons_get */ - -/** - * Set the _NET_WM_USER_TIME property. - * @param window The window. - * @param time The last user activity time in the window. - * - * Set the XServer time at which last user activity in @p window took - * place by sending the _NET_WM_USER_TIME property to @p window. @p - * time contains that XServer time in seconds. - * - * This function allows a Window Manager to alter the focus, stacking, - * and/or placement behavior of windows when they are mapped depending - * on whether the new window was created by a user action or is a - * "pop-up" window activated by a timer or some other event. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_user_time_set(Ecore_X_Window window, - unsigned int time) -{ - ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_USER_TIME, - &time, 1); -} /* ecore_x_netwm_user_time_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_user_time_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_USER_TIME, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_user_time_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_user_time_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_user_time_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_user_time_get_fetch */ - -/** - * Get the last user activity time in the window. - * @param window The window. - * @param time The returned time. - * @return 1 on success, 0 otherwise. - * - * Return the XServer time at which last user activity in @p window - * took place. The time is stored in @p time. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_user_time_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_user_time_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_user_time_get(Ecore_X_Window window, - unsigned int *time) -{ - int ret; - uint32_t tmp; + unsigned int layout[4]; - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_USER_TIME, - &tmp, 1); - if (time) - *time = tmp; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return (ret == 1) ? 1 : 0; -} /* ecore_x_netwm_user_time_get */ + layout[0] = orientation; + layout[1] = columns; + layout[2] = rows; + layout[3] = starting_corner; + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT, + layout, 4); +} -Ecore_X_Window_State -_ecore_x_netwm_state_get(Ecore_X_Atom a) +EAPI void +ecore_x_netwm_desk_workareas_set(Ecore_X_Window root, unsigned int *areas, unsigned int n_desks) { - if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL) - return ECORE_X_WINDOW_STATE_MODAL; - else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY) - return ECORE_X_WINDOW_STATE_STICKY; - else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT) - return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT; - else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ) - return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ; - else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED) - return ECORE_X_WINDOW_STATE_SHADED; - else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR) - return ECORE_X_WINDOW_STATE_SKIP_TASKBAR; - else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER) - return ECORE_X_WINDOW_STATE_SKIP_PAGER; - else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN) - return ECORE_X_WINDOW_STATE_HIDDEN; - else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN) - return ECORE_X_WINDOW_STATE_FULLSCREEN; - else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE) - return ECORE_X_WINDOW_STATE_ABOVE; - else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW) - return ECORE_X_WINDOW_STATE_BELOW; - else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION) - return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION; - else - return ECORE_X_WINDOW_STATE_UNKNOWN; -} /* _ecore_x_netwm_state_get */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -static Ecore_X_Atom -_ecore_x_netwm_state_atom_get(Ecore_X_Window_State s) + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_WORKAREA, areas, + 4 * n_desks); +} + +EAPI void +ecore_x_netwm_desk_current_set(Ecore_X_Window root, unsigned int desk) { - switch(s) - { - case ECORE_X_WINDOW_STATE_MODAL: - return ECORE_X_ATOM_NET_WM_STATE_MODAL; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case ECORE_X_WINDOW_STATE_STICKY: - return ECORE_X_ATOM_NET_WM_STATE_STICKY; + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_CURRENT_DESKTOP, + &desk, 1); +} - case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT: - return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT; +EAPI void +ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, Eina_Bool on) +{ + unsigned int val = 0; - case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ: - return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case ECORE_X_WINDOW_STATE_SHADED: - return ECORE_X_ATOM_NET_WM_STATE_SHADED; + val = ((on) ? 1 : 0); + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, + &val, 1); +} - case ECORE_X_WINDOW_STATE_SKIP_TASKBAR: - return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR; +EAPI int +ecore_x_netwm_startup_id_get(Ecore_X_Window win, char **id) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case ECORE_X_WINDOW_STATE_SKIP_PAGER: - return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER; + if (id) + { + *id = + ecore_x_window_prop_string_get(win, ECORE_X_ATOM_NET_STARTUP_ID); + } - case ECORE_X_WINDOW_STATE_HIDDEN: - return ECORE_X_ATOM_NET_WM_STATE_HIDDEN; + return 1; +} - case ECORE_X_WINDOW_STATE_FULLSCREEN: - return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN; +EAPI void +ecore_x_netwm_startup_id_set(Ecore_X_Window win, const char *id) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case ECORE_X_WINDOW_STATE_ABOVE: - return ECORE_X_ATOM_NET_WM_STATE_ABOVE; + ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id); +} - case ECORE_X_WINDOW_STATE_BELOW: - return ECORE_X_ATOM_NET_WM_STATE_BELOW; +EAPI void +ecore_x_netwm_state_request_send(Ecore_X_Window win, Ecore_X_Window root, Ecore_X_Window_State s1, Ecore_X_Window_State s2, Eina_Bool set) +{ + xcb_client_message_event_t ev; - case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION: - return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - default: - return 0; - } /* switch */ -} /* _ecore_x_netwm_state_atom_get */ - -/** - * Set the _NET_WM_STATE property. - * @param window The window. - * @param state An array of window hints. - * @param num The number of hints. - * - * Set a list of hints describing @p window state by sending the - * _NET_WM_STATE property to @p window. The hints are stored in the - * array @p state. @p num must contain the number of hints. - * - * The Window Manager SHOULD honor _NET_WM_STATE whenever a withdrawn - * window requests to be mapped. A Client wishing to change the state - * of a window MUST send a _NET_WM_STATE client message to the root - * window. The Window Manager MUST keep this property updated to - * reflect the current state of the window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_window_state_set(Ecore_X_Window window, - Ecore_X_Window_State *state, - unsigned int num) + if (!win) return; + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_NET_WM_STATE; + ev.data.data32[0] = !!set; + ev.data.data32[1] = _ecore_xcb_netwm_window_state_atom_get(s1); + ev.data.data32[2] = _ecore_xcb_netwm_window_state_atom_get(s2); + /* 1 == normal client, if used in a pager this should be 2 */ + ev.data.data32[3] = 1; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +} + +EAPI void +ecore_x_netwm_window_state_set(Ecore_X_Window win, Ecore_X_Window_State *state, unsigned int num) { Ecore_X_Atom *set; - uint32_t i; + unsigned int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!num) + if (!num) { - ecore_x_window_prop_property_del(window, ECORE_X_ATOM_NET_WM_STATE); + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_NET_WM_STATE); return; } set = malloc(num * sizeof(Ecore_X_Atom)); - if (!set) - return; - - for (i = 0; i < num; i++) - set[i] = _ecore_x_netwm_state_atom_get(state[i]); + if (!set) return; - ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_STATE, set, num); + for (i = 0; i < num; i++) + set[i] = _ecore_xcb_netwm_window_state_atom_get(state[i]); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_STATE, set, num); free(set); -} /* ecore_x_netwm_window_state_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_window_state_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_STATE, ECORE_X_ATOM_ATOM, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_window_state_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_window_state_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_window_state_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_window_state_get_fetch */ - -/** - * Get the hints describing the window state. - * @param window The window. - * @param state The returned hins. - * @param num The number of hints. - * @return 1 on success, 0 otherwise. - * - * Retrieve the hints describing @p window state. The state is - * returned in @p state. The nummber of hints is stored in @p - * num. This function returns 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_window_state_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_window_state_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_window_state_get(Ecore_X_Window window, - Ecore_X_Window_State **state, - unsigned int *num) +} + +EAPI Eina_Bool +ecore_x_netwm_window_state_get(Ecore_X_Window win, Ecore_X_Window_State **state, unsigned int *num) { Ecore_X_Atom *atoms; - int num_ret; - int i; + int ret = 0; - if (num) - *num = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (state) - *state = NULL; + if (num) *num = 0; + if (state) *state = NULL; - num_ret = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_STATE, - &atoms); - if (num_ret <= 0) - return 0; + ret = + ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_STATE, &atoms); - if (state) + if (ret <= 0) return EINA_FALSE; + + if (state) { - *state = malloc(num_ret * sizeof(Ecore_X_Window_State)); - if (*state) - for (i = 0; i < num_ret; ++i) - (*state)[i] = _ecore_x_netwm_state_get(atoms[i]); + *state = malloc(ret * sizeof(Ecore_X_Window_State)); + if (*state) + { + int i = 0; - if (num) - *num = num_ret; + for (i = 0; i < ret; i++) + (*state)[i] = _ecore_xcb_netwm_window_state_get(atoms[i]); + if (num) *num = ret; + } } free(atoms); - return 1; -} /* ecore_x_netwm_window_state_get */ + return EINA_TRUE; +} -static Ecore_X_Window_Type -_ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom) +EAPI void +ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win) { - if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP) - return ECORE_X_WINDOW_TYPE_DESKTOP; - else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK) - return ECORE_X_WINDOW_TYPE_DOCK; - else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR) - return ECORE_X_WINDOW_TYPE_TOOLBAR; - else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU) - return ECORE_X_WINDOW_TYPE_MENU; - else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY) - return ECORE_X_WINDOW_TYPE_UTILITY; - else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH) - return ECORE_X_WINDOW_TYPE_SPLASH; - else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG) - return ECORE_X_WINDOW_TYPE_DIALOG; - else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL) - return ECORE_X_WINDOW_TYPE_NORMAL; - else - return ECORE_X_WINDOW_TYPE_UNKNOWN; -} /* _ecore_x_netwm_window_type_type_get */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -static Ecore_X_Atom -_ecore_x_netwm_window_type_atom_get(Ecore_X_Window_Type type) -{ - switch (type) - { - case ECORE_X_WINDOW_TYPE_DESKTOP: - return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP; + ecore_x_window_prop_window_set(root, + ECORE_X_ATOM_NET_ACTIVE_WINDOW, &win, 1); +} - case ECORE_X_WINDOW_TYPE_DOCK: - return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK; +EAPI void +ecore_x_netwm_client_active_request(Ecore_X_Window root, Ecore_X_Window win, int type, Ecore_X_Window current_win) +{ + xcb_client_message_event_t ev; - case ECORE_X_WINDOW_TYPE_TOOLBAR: - return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case ECORE_X_WINDOW_TYPE_MENU: - return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU; + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - case ECORE_X_WINDOW_TYPE_UTILITY: - return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY; + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_NET_ACTIVE_WINDOW; + ev.data.data32[0] = type; + ev.data.data32[1] = XCB_CURRENT_TIME; + ev.data.data32[2] = current_win; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; - case ECORE_X_WINDOW_TYPE_SPLASH: - return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH; + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +} - case ECORE_X_WINDOW_TYPE_DIALOG: - return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG; +EAPI void +ecore_x_netwm_client_list_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case ECORE_X_WINDOW_TYPE_NORMAL: - return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL; + ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST, + p_clients, n_clients); +} - default: - return 0; - } /* switch */ -} /* _ecore_x_netwm_window_type_atom_get */ - -/* - * FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR - * , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG - */ - -/** - * Set the _NET_WM_WINDOW_TYPE property. - * @param window The window. - * @param type The functional type of the window. - * - * Set the functional @p type of @p window by sending _NET_WM_WINDOW_TYPE - * property to @p window. - * - * This property SHOULD be set by the Client before mapping. This - * property SHOULD be used by the window manager in determining the - * decoration, stacking position and other behavior of the window. The - * Client SHOULD specify window types in order of preference (the first - * being most preferable). - * - * This hint is intended to replace the MOTIF hints. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_window_type_set(Ecore_X_Window window, - Ecore_X_Window_Type type) +EAPI void +ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients) { - Ecore_X_Atom atom; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST_STACKING, + p_clients, n_clients); +} - atom = _ecore_x_netwm_window_type_atom_get(type); - ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, - &atom, 1); -} /* ecore_x_netwm_window_type_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_window_type_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_WINDOW_TYPE, ECORE_X_ATOM_ATOM, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_window_type_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_window_type_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_window_type_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_window_type_get_fetch */ - -/* FIXME: Maybe return 0 on some conditions? */ - -/** - * Get the functional type of a window. - * @param window The window. - * @param type The function type of the window. - * @return 1 on success, 0 otherwise. - * - * Retrieve the functional type of @p window. The type is stored in - * @p type. This function returns 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_window_type_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_window_type_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_window_type_get(Ecore_X_Window window, - Ecore_X_Window_Type *type) +EAPI Eina_Bool +ecore_x_screen_is_composited(int screen) { - Ecore_X_Atom *atoms; - int num; - int i; + char buff[32]; + xcb_get_selection_owner_cookie_t ocookie; + xcb_get_selection_owner_reply_t *oreply; + Ecore_X_Window win; + static Ecore_X_Atom atom = XCB_NONE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (type) - *type = ECORE_X_WINDOW_TYPE_NORMAL; + snprintf(buff, sizeof(buff), "_NET_WM_CM_S%i", screen); - num = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, - &atoms); - if (num < 0) + if (atom == XCB_NONE) { - /* IMO this is not the place to mix netwm and icccm /kwo */ - /* Check if WM_TRANSIENT_FOR is set */ + xcb_intern_atom_cookie_t acookie; + xcb_intern_atom_reply_t *areply; + + acookie = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(buff), buff); + areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); + if (!areply) return EINA_FALSE; + atom = areply->atom; + free(areply); + } + if (atom == XCB_NONE) return EINA_FALSE; - /* Disable it for xcb */ + ocookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, atom); + oreply = xcb_get_selection_owner_reply(_ecore_xcb_conn, ocookie, NULL); + if (!oreply) return EINA_FALSE; + win = oreply->owner; + free(oreply); -/* if ((type) && (ecore_x_icccm_transient_for_get(window))) */ -/* *type = ECORE_X_WINDOW_TYPE_DIALOG; */ -/* return 1; */ - } + return (win != XCB_NONE) ? EINA_TRUE : EINA_FALSE; +} - if (type) +EAPI void +ecore_x_screen_is_composited_set(int screen, Ecore_X_Window win) +{ + static Ecore_X_Atom atom = XCB_NONE; + char buff[32]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + snprintf(buff, sizeof(buff), "_NET_WM_CM_S%i", screen); + if (atom == XCB_NONE) { - for (i = 0; i < num; ++i) - { - *type = _ecore_x_netwm_window_type_type_get(atoms[i]); - if (*type != ECORE_X_WINDOW_TYPE_UNKNOWN) - break; - } + xcb_intern_atom_cookie_t acookie; + xcb_intern_atom_reply_t *areply; + + acookie = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(buff), buff); + areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); + if (!areply) return; + atom = areply->atom; + free(areply); } + if (atom == XCB_NONE) return; + xcb_set_selection_owner(_ecore_xcb_conn, win, atom, + _ecore_xcb_events_last_time_get()); +} - free(atoms); +EAPI void +ecore_x_netwm_ping_send(Ecore_X_Window win) +{ +// xcb_client_message_event_t ev; - return 1; -} /* ecore_x_netwm_window_type_get */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + XCB_EVENT_MASK_NO_EVENT, + ECORE_X_ATOM_NET_WM_PING, + ecore_x_current_time_get(), win, 0, 0); + + /* ev.response_type = XCB_CLIENT_MESSAGE; */ + /* ev.format = 32; */ + /* ev.window = win; */ + /* ev.type = ECORE_X_ATOM_WM_PROTOCOLS; */ + /* ev.data.data32[0] = ECORE_X_ATOM_NET_WM_PING; */ + /* ev.data.data32[1] = ecore_x_current_time_get(); */ + /* ev.data.data32[2] = win; */ + /* ev.data.data32[3] = 0; */ + /* ev.data.data32[4] = 0; */ + + /* xcb_send_event(_ecore_xcb_conn, 0, win, */ + /* XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); */ +} -static Ecore_X_Atom -_ecore_x_netwm_action_atom_get(Ecore_X_Action action) +EAPI void +ecore_x_netwm_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb) { - switch (action) - { - case ECORE_X_ACTION_MOVE: - return ECORE_X_ATOM_NET_WM_ACTION_MOVE; + uint32_t frames[4]; - case ECORE_X_ACTION_RESIZE: - return ECORE_X_ATOM_NET_WM_ACTION_RESIZE; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case ECORE_X_ACTION_MINIMIZE: - return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE; + frames[0] = fl; + frames[1] = fr; + frames[2] = ft; + frames[3] = fb; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_FRAME_EXTENTS, + frames, 4); +} - case ECORE_X_ACTION_SHADE: - return ECORE_X_ATOM_NET_WM_ACTION_SHADE; +EAPI Eina_Bool +ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb) +{ + int ret = 0; + unsigned int frames[4]; - case ECORE_X_ACTION_STICK: - return ECORE_X_ATOM_NET_WM_ACTION_STICK; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case ECORE_X_ACTION_MAXIMIZE_HORZ: - return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ; + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_FRAME_EXTENTS, + frames, 4); + if (ret != 4) return EINA_FALSE; - case ECORE_X_ACTION_MAXIMIZE_VERT: - return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT; + if (fl) *fl = frames[0]; + if (fr) *fr = frames[1]; + if (ft) *ft = frames[2]; + if (fb) *fb = frames[3]; - case ECORE_X_ACTION_FULLSCREEN: - return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN; + return EINA_TRUE; +} - case ECORE_X_ACTION_CHANGE_DESKTOP: - return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP; +EAPI void +ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial) +{ +// xcb_client_message_event_t ev; - case ECORE_X_ACTION_CLOSE: - return ECORE_X_ATOM_NET_WM_ACTION_CLOSE; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - case ECORE_X_ACTION_ABOVE: - return ECORE_X_ATOM_NET_WM_ACTION_ABOVE; + if (!win) return; - case ECORE_X_ACTION_BELOW: - return ECORE_X_ATOM_NET_WM_ACTION_BELOW; + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + XCB_EVENT_MASK_NO_EVENT, + ECORE_X_ATOM_NET_WM_SYNC_REQUEST, + _ecore_xcb_events_last_time_get(), + serial, 0, 0); - default: - return 0; - } /* switch */ -} /* _ecore_x_netwm_action_atom_get */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_allowed_action_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, ECORE_X_ATOM_ATOM, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_allowed_action_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_allowed_action_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_allowed_action_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_allowed_action_get_fetch */ - -/* FIXME: Get complete list */ - -/** - * Check whether an action is supported by a window. - * @param window The window - * @param action The action - * @return 1 if set, 0 otherwise. - * - * Return whether the user operation @p action is supported by the - * Window Manager for @p window. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_allowed_action_isset(Ecore_X_Window window, - Ecore_X_Action action) + /* memset(&ev, 0, sizeof(xcb_client_message_event_t)); */ + + /* ev.response_type = XCB_CLIENT_MESSAGE; */ + /* ev.format = 32; */ + /* ev.window = win; */ + /* ev.type = ECORE_X_ATOM_WM_PROTOCOLS; */ + /* ev.data.data32[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST; */ + /* ev.data.data32[1] = _ecore_xcb_events_last_time_get(); */ + /* ev.data.data32[2] = serial; */ + /* ev.data.data32[3] = 0; */ + /* ev.data.data32[4] = 0; */ + + /* xcb_send_event(_ecore_xcb_conn, 0, win, */ + /* XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); */ +} + +EAPI void +ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk) { - Ecore_X_Atom *atoms; - Ecore_X_Atom atom; - int num; - int ret = 0; - int i; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - num = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, - &atoms); - if (num <= 0) - return ret; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1); +} - atom = _ecore_x_netwm_action_atom_get(action); +EAPI Eina_Bool +ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk) +{ + unsigned int tmp = 0; - for (i = 0; i < num; ++i) - { - if (atom == atoms[i]) - { - ret = 1; - break; - } - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); - free(atoms); + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP, + &tmp, 1)) + return EINA_FALSE; - return ret; -} /* ecore_x_netwm_allowed_action_isset */ - -/* FIXME: Set complete list */ -/** - * Set the _NET_WM_ALLOWED_ACTIONS property. - * @param window The window. - * @param action An array of allowed actions. - * @param num The number of actions. - * - * Set the user operations that the Window Manager supports for - * @p window by sending the _NET_WM_ALLOWED_ACTIONS property to - * @p window. @p action stores @p num actions. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_allowed_action_set(Ecore_X_Window window, - Ecore_X_Action *action, - unsigned int num) + if (desk) *desk = tmp; + + return EINA_TRUE; +} + +EAPI void +ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop) { - Ecore_X_Atom *set; - unsigned int i; + xcb_client_message_event_t ev; - if (!num) - { - ecore_x_window_prop_property_del(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS); - return; - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); - set = malloc(num * sizeof(Ecore_X_Atom)); - if (!set) - return; + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - for (i = 0; i < num; i++) - set[i] = _ecore_x_netwm_action_atom_get(action[i]); + memset(&ev, 0, sizeof(xcb_client_message_event_t)); - ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, set, num); + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_NET_WM_DESKTOP; + ev.data.data32[0] = desktop; - free(set); -} /* ecore_x_netwm_allowed_action_set */ - -/** - * Get the allowed actions supported by a window. - * @param window The window. - * @param action The returned array of the actions. - * @param num The number of actions. - * @return 1 on success, 0 otherwise. - * - * Retrieve the user operations that the Window Manager supports for - * @p window and store them in @p action. The number of actions is - * stored in @p num. This function returns 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_allowed_action_get(Ecore_X_Window window, - Ecore_X_Action **action, - unsigned int *num) + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +} + +EAPI void +ecore_x_netwm_handled_icons_set(Ecore_X_Window win) { - Ecore_X_Atom *atoms; - int num_ret; - int i; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (num) - *num = 0; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS, + NULL, 0); +} - if (action) - *action = NULL; +EAPI Eina_Bool +ecore_x_netwm_handled_icons_get(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - num_ret = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, - &atoms); - if (num_ret <= 0) - return 0; + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS, + NULL, 0)) + return EINA_FALSE; - if (action) - { - *action = malloc(num_ret * sizeof(Ecore_X_Action)); - if (*action) - for (i = 0; i < num_ret; ++i) - (*action)[i] = _ecore_x_netwm_action_atom_get(atoms[i]); + return EINA_TRUE; +} - if (num) - *num = num_ret; - } +EAPI int +ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - free(atoms); + if (name) + { + *name = + ecore_x_window_prop_string_get(win, ECORE_X_ATOM_NET_WM_ICON_NAME); + } return 1; -} /* ecore_x_netwm_allowed_action_get */ - -/** - * Set the _NET_WM_WINDOW_OPACITY property. - * @param window The window. - * @param opacity The opacity value. - * - * Set the desired opacity of @p window by sending the - * _NET_WM_WINDOW_OPACITY property to @p window. @p opacity is 0 for a - * transparent window and 0xffffffff for an opaque window. @p opacity - * must be multiplied with the original alpha value of @p window - * (which is 1 for visuals not including an alpha component) so that - * @p window content is modulated by the opacity value. - * - * Window Managers acting as compositing managers MAY take this into - * account when displaying a window. Window Managers MUST forward the - * value of this property to any enclosing frame window. This - * property MAY change while the window is mapped and the Window - * Manager MUST respect changes while the window is mapped. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_opacity_set(Ecore_X_Window window, - unsigned int opacity) -{ - uint32_t op = opacity; - ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, - &op, 1); -} /* ecore_x_netwm_opacity_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_opacity_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_opacity_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_opacity_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_opacity_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_opacity_get_fetch */ - -/** - * Get the opacity value of a window. - * @param window The window. - * @param opacity The returned opacity. - * @return 1 on success, 0 otherwise. - * - * Retriee the opacity value of @p window and store it in - * @p opacity. This function returns 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_opacity_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_opacity_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_opacity_get(Ecore_X_Window window, - unsigned int *opacity) -{ - int ret; - unsigned int tmp; +} - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, - &tmp, 1); - if (opacity) - *opacity = tmp; - - return ret == 1 ? 1 : 0; -} /* ecore_x_netwm_opacity_get */ - -/** - * Set the _NET_FRAME_EXTENTS property. - * @param window The window. - * @param fl The number of pixels of the left border of the window. - * @param fr The number of pixels of the right border of the window. - * @param ft The number of pixels of the top border of the window. - * @param fb The number of pixels of the bottom border of the window. - * - * Set the border witdh of @p window by sending the _NET_FRAME_EXTENTS - * property to @p window. @p fl, @p fr, @p ft and @p fb are respectively - * the number of pixels of the left, right, top and bottom border of - * @p window. - * - * The Window Manager MUST set _NET_FRAME_EXTENTS to the extents of - * the window's frame. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_frame_size_set(Ecore_X_Window window, - int fl, - int fr, - int ft, - int fb) +EAPI void +ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name) { - uint32_t frames[4]; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - frames[0] = fl; - frames[1] = fr; - frames[2] = ft; - frames[3] = fb; - ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4); -} /* ecore_x_netwm_frame_size_set */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_frame_size_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_FRAME_EXTENTS, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_frame_size_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_frame_size_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_frame_size_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_frame_size_get_fetch */ - -/** - * Get the frame extent of a window. - * @param window The window. - * @param fl The number of pixels of the left border of the window. - * @param fr The number of pixels of the right border of the window. - * @param ft The number of pixels of the top border of the window. - * @param fb The number of pixels of the bottom border of the window. - * @return 1 on success, 0 otherwise. - * - * Retrieve the frame extents of @p window. The number of pixels of - * the left, right, top and bottom border of @p window are - * respectively stored in @p fl, @p fr, @p ft anfd @p fb. TYhis - * function retuirns 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_frame_size_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_frame_size_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_frame_size_get(Ecore_X_Window window, - int *fl, - int *fr, - int *ft, - int *fb) + ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME, name); +} + +EAPI Eina_Bool +ecore_x_netwm_icons_get(Ecore_X_Window win, Ecore_X_Icon **icon, int *num) { - uint32_t frames[4]; - int ret = 0; + int num_ret = 0; + unsigned int i = 0, len = 0, icons = 0; + unsigned int *data, *p, *src; - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4); - if (ret != 4) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (fl) - *fl = frames[0]; + if (num) *num = 0; + if (icon) *icon = NULL; - if (fr) - *fr = frames[1]; + num_ret = + ecore_x_window_prop_card32_list_get(win, ECORE_X_ATOM_NET_WM_ICON, &data); - if (ft) - *ft = frames[2]; + if ((num_ret <= 0) || (!data)) + { + if (data) free(data); + return EINA_FALSE; + } + if (num_ret < 2) + { + if (data) free(data); + return EINA_FALSE; + } - if (fb) - *fb = frames[3]; + icons = 0; + p = data; + while (p) + { + len = (p[0] * p[1]); + p += (len + 2); + if ((p - data) > num_ret) + { + if (data) free(data); + return EINA_FALSE; + } + icons++; + if ((p - data) == num_ret) p = NULL; + } + if (num) *num = icons; + if (!icon) + { + if (data) free(data); + return EINA_TRUE; + } - return 1; -} /* ecore_x_netwm_frame_size_get */ - -/** - * Sends the GetProperty request. - * @param window The window. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_sync_counter_get_prefetch(Ecore_X_Window window) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_netwm_sync_counter_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_netwm_sync_counter_get_prefetch(). - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_sync_counter_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_netwm_sync_counter_get_fetch */ - -/** - * Get the X ID of a X Sync counter. - * @param window The window. - * @param counter The X ID of the Sync counter. - * @return 1 on success, 0 otherwise. - * - * Retrieve the X ID of the X Sync counter of @p window and store it - * in @p counter. This function returns 1 on success, 0 otherwise. - * - * To use this function, you must call before, and in order, - * ecore_x_netwm_frame_size_get_prefetch(), which sends the GetProperty request, - * then ecore_x_netwm_frame_size_get_fetch(), which gets the reply. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_netwm_sync_counter_get(Ecore_X_Window window, - Ecore_X_Sync_Counter *counter) -{ - int ret; - unsigned int tmp; + *icon = malloc(icons * sizeof(Ecore_X_Icon)); + if (!(*icon)) + { + if (data) free(data); + return EINA_FALSE; + } - ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, - &tmp, 1); + /* Fetch the icons */ + p = data; + for (i = 0; i < icons; i++) + { + unsigned int *ps, *pd, *pe; - if (counter) - *counter = tmp; + len = p[0] * p[1]; + ((*icon)[i]).width = p[0]; + ((*icon)[i]).height = p[1]; + src = &(p[2]); + ((*icon)[i]).data = malloc(len * sizeof(unsigned int)); + if (!((*icon)[i]).data) + { + while (i) + free(((*icon)[--i]).data); + free(*icon); + free(data); + return EINA_FALSE; + } - return (ret == 1) ? 1 : 0; -} /* ecore_x_netwm_sync_counter_get */ + pd = ((*icon)[i]).data; + ps = src; + pe = ps + len; + for (; ps < pe; ps++) + { + unsigned int r, g, b, a; -/** - * Send a _NET_WM_PING property event. - * @param window The window. - * - * Send a ClientMessage event from @p window with the _NET_WM_PING - * property set. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_ping_send(Ecore_X_Window window) -{ - xcb_client_message_event_t ev; + a = (*ps >> 24) & 0xff; + r = (((*ps >> 16) & 0xff) * a) / 255; + g = (((*ps >> 8) & 0xff) * a) / 255; + b = (((*ps) & 0xff) * a) / 255; + *pd = (a << 24) | (r << 16) | (g << 8) | (b); + pd++; + } + p += (len + 2); + } - if (!window) - return; + if (data) free(data); + return EINA_TRUE; +} - ev.response_type = XCB_CLIENT_MESSAGE | 0x80; - ev.format = 32; - ev.sequence = 0; - ev.window = window; - ev.type = ECORE_X_ATOM_WM_PROTOCOLS; - ev.data.data32[0] = ECORE_X_ATOM_NET_WM_PING; - ev.data.data32[1] = _ecore_xcb_event_last_time; - ev.data.data32[2] = window; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - ev.data.data32[5] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, window, XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -} /* ecore_x_netwm_ping_send */ - -/** - * Send a _NET_WM_SYNC_REQUEST property event. - * @param window The window. - * @param serial The update request number. - * - * Send a ClientMessage event from @p window with the _NET_WM_SYNC_REQUEST - * property set. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_sync_request_send(Ecore_X_Window window, - unsigned int serial) +EAPI void +ecore_x_netwm_icon_geometry_set(Ecore_X_Window win, int x, int y, int w, int h) { - xcb_client_message_event_t ev; + unsigned int geom[4]; - if (!window) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - ev.response_type = XCB_CLIENT_MESSAGE | 0x80; - ev.format = 32; - ev.window = window; - ev.type = ECORE_X_ATOM_WM_PROTOCOLS; - ev.data.data32[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST; - ev.data.data32[1] = _ecore_xcb_event_last_time; - ev.data.data32[2] = serial; - /* FIXME: imho, the following test is useless as serial is non negative */ - /* should we remove it ? */ - ev.data.data32[3] = (serial < 0) ? ~0L : 0L; - ev.data.data32[4] = 0; + geom[0] = x; + geom[1] = y; + geom[2] = w; + geom[3] = h; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, + geom, 4); +} - xcb_send_event(_ecore_xcb_conn, 0, window, 0, (const char *)&ev); -} /* ecore_x_netwm_sync_request_send */ - -/** - * Send a _NET_WM_STATE property event. - * @param window The window. - * @param root The root window. - * @param s1 The first state to alter. - * @param s2 The second state to alter. - * @param set 0 to unset the property, set it otherwise. - * - * Send a ClientMessage event from @p window to the @p root window - * with the _NET_WM_STATE property set. This change the state of a - * mapped window. @p s1 is the first state to alter. @p s2 is the - * second state to alter. If @p set value is 0, the property is - * removed (or unset), otherwise, the property is set. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_state_request_send(Ecore_X_Window window, - Ecore_X_Window root, - Ecore_X_Window_State s1, - Ecore_X_Window_State s2, - Eina_Bool set) +EAPI Eina_Bool +ecore_x_netwm_icon_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h) { - xcb_client_message_event_t ev; + int ret = 0; + unsigned int geom[4]; - if (!window) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!root) - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + ret = + ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, + geom, 4); + if (ret != 4) return EINA_FALSE; + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; - ev.response_type = XCB_CLIENT_MESSAGE | 0x80; - ev.format = 32; - ev.window = window; - ev.type = ECORE_X_ATOM_NET_WM_STATE; - ev.data.data32[0] = !!set; - ev.data.data32[1] = _ecore_x_netwm_state_atom_get(s1); - ev.data.data32[2] = _ecore_x_netwm_state_atom_get(s2); - /* 1 == normal client, if someone wants to use this - * function in a pager, this should be 2 */ - ev.data.data32[3] = 1; - ev.data.data32[4] = 0; + return EINA_TRUE; +} - xcb_send_event(_ecore_xcb_conn, 0, root, - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, - (const char *)&ev); -} /* ecore_x_netwm_state_request_send */ - -/** - * Send a _NET_WM_DESKTOP property event. - * @param window The window. - * @param root The root window. - * @param desktop The new desktop index. - * - * Send a ClientMessage event from @p window to the @p root window - * with the _NET_WM_DESKTOP property set. This change the state of a - * non-withdrawn window. @p desktop is the new desktop index to set. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI void -ecore_x_netwm_desktop_request_send(Ecore_X_Window window, - Ecore_X_Window root, - unsigned int desktop) +EAPI void +ecore_x_netwm_strut_set(Ecore_X_Window win, int l, int r, int t, int b) { - xcb_client_message_event_t ev; + unsigned int strut[4]; - if (!window) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!root) - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + strut[0] = l; + strut[1] = r; + strut[2] = t; + strut[3] = b; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); +} - ev.response_type = XCB_CLIENT_MESSAGE | 0x80; - ev.format = 32; - ev.window = window; - ev.type = ECORE_X_ATOM_NET_WM_DESKTOP; - ev.data.data32[0] = desktop; +EAPI Eina_Bool +ecore_x_netwm_strut_get(Ecore_X_Window win, int *l, int *r, int *t, int *b) +{ + unsigned int strut[4]; + int ret = 0; - xcb_send_event(_ecore_xcb_conn, 0, root, - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, - (const char *)&ev); -} /* ecore_x_netwm_desktop_request_send */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -int -_ecore_x_netwm_startup_info_begin(Ecore_X_Window window, - char *data) -{ -#if 0 - Ecore_X_Startup_Info *info; - unsigned char exists = 0; + ret = + ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); + if (ret != 4) return EINA_FALSE; - if (!startup_info) - return 0; + if (l) *l = strut[0]; + if (r) *r = strut[1]; + if (t) *t = strut[2]; + if (b) *b = strut[3]; - info = eina_hash_find(startup_info, (void *)window); - if (info) - { - exists = 1; - INF("Already got info for win: 0x%x", window); - _ecore_x_netwm_startup_info_free(info); - } + return EINA_TRUE; +} - info = calloc(1, sizeof(Ecore_X_Startup_Info)); - if (!info) - return 0; +EAPI void +ecore_x_netwm_strut_partial_set(Ecore_X_Window win, int left, int right, int top, int bottom, int left_start_y, int left_end_y, int right_start_y, int right_end_y, int top_start_x, int top_end_x, int bottom_start_x, int bottom_end_x) +{ + unsigned int strut[12]; - info->win = win; - info->length = 0; - info->buffer_size = 161; - info->buffer = calloc(info->buffer_size, sizeof(char)); - if (!info->buffer) - { - _ecore_x_netwm_startup_info_free(info); - return 0; - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); - memcpy(info->buffer, data, 20); - info->length += 20; - info->buffer[info->length] = 0; - if (exists) - eina_hash_modify(startup_info, (void *)info->win, info); - else - eina_hash_add(startup_info, (void *)info->win, info); + strut[0] = left; + strut[1] = right; + strut[2] = top; + strut[3] = bottom; + strut[4] = left_start_y; + strut[5] = left_end_y; + strut[6] = right_start_y; + strut[7] = right_end_y; + strut[8] = top_start_x; + strut[9] = top_end_x; + strut[10] = bottom_start_x; + strut[11] = bottom_end_x; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, + strut, 12); +} - if (strlen(info->buffer) != 20) - { - /* We have a '\0' in there, the message is done */ - _ecore_x_netwm_startup_info_process(info); - } +EAPI Eina_Bool +ecore_x_netwm_strut_partial_get(Ecore_X_Window win, int *left, int *right, int *top, int *bottom, int *left_start_y, int *left_end_y, int *right_start_y, int *right_end_y, int *top_start_x, int *top_end_x, int *bottom_start_x, int *bottom_end_x) +{ + unsigned int strut[12]; + int ret = 0; -#else /* if 0 */ - window = XCB_NONE; - data = NULL; -#endif /* if 0 */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return 1; -} /* _ecore_x_netwm_startup_info_begin */ + ret = + ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, + strut, 12); + if (ret != 12) return EINA_FALSE; -int -_ecore_x_netwm_startup_info(Ecore_X_Window window, - char *data) -{ -#if 0 - Ecore_X_Startup_Info *info; - char *p; + if (left) *left = strut[0]; + if (right) *right = strut[1]; + if (top) *top = strut[2]; + if (bottom) *bottom = strut[3]; + if (left_start_y) *left_start_y = strut[4]; + if (left_end_y) *left_end_y = strut[5]; + if (right_start_y) *right_start_y = strut[6]; + if (right_end_y) *right_end_y = strut[7]; + if (top_start_x) *top_start_x = strut[8]; + if (top_end_x) *top_end_x = strut[9]; + if (bottom_start_x) *bottom_start_x = strut[10]; + if (bottom_end_x) *bottom_end_x = strut[11]; - if (!startup_info) - return 0; + return EINA_TRUE; +} - info = eina_hash_find(startup_info, (void *)window); - if (!info) - return 0; +EAPI void +ecore_x_netwm_user_time_set(Ecore_X_Window win, unsigned int t) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if ((info->length + 20) > info->buffer_size) - { - info->buffer_size += 160; - info->buffer = realloc(info->buffer, info->buffer_size * sizeof(char)); - if (!info->buffer) - { - eina_hash_del(startup_info, (void *)info->win); - _ecore_x_netwm_startup_info_free(info); - return 0; - } - } + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME, &t, 1); +} - memcpy(info->buffer + info->length, data, 20); - p = info->buffer + info->length; - info->length += 20; - info->buffer[info->length] = 0; - if (strlen(p) != 20) - { - /* We have a '\0' in there, the message is done */ - _ecore_x_netwm_startup_info_process(info); - } +EAPI Eina_Bool +ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *t) +{ + unsigned int tmp; -#else /* if 0 */ - window = XCB_NONE; - data = NULL; -#endif /* if 0 */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return 1; -} /* _ecore_x_netwm_startup_info */ - -/* - * Set UTF-8 string property - */ -static void -_ecore_x_window_prop_string_utf8_set(Ecore_X_Window window, - Ecore_X_Atom atom, - const char *str) -{ - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - atom, ECORE_X_ATOM_UTF8_STRING, - 8, strlen(str), str); -} /* _ecore_x_window_prop_string_utf8_set */ - -static void -_ecore_x_window_prop_string_utf8_get_prefetch(Ecore_X_Window window, - Ecore_X_Atom atom) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window, - atom, ECORE_X_ATOM_UTF8_STRING, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* _ecore_x_window_prop_string_utf8_get_prefetch */ - -static void -_ecore_x_window_prop_string_utf8_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* _ecore_x_window_prop_string_utf8_get_fetch */ - -/* - * Get UTF-8 string property - * call _ecore_x_window_prop_string_utf8_get_prefetch() before. - */ -static char * -_ecore_x_window_prop_string_utf8_get(Ecore_X_Window window __UNUSED__, - Ecore_X_Atom atom __UNUSED__) -{ - xcb_get_property_reply_t *reply; - char *str; - int length; + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME, + &tmp, 1)) + return EINA_FALSE; - reply = _ecore_xcb_reply_get(); - if (!reply) - return NULL; + if (t) *t = tmp; - if ((reply->format != 8) || - (reply->value_len <= 0)) - return NULL; + return EINA_TRUE; +} - length = reply->value_len; - str = (char *)malloc (sizeof (char) * (length + 1)); - if (!str) - { - return NULL; - } +EAPI void +ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - memcpy(str, xcb_get_property_value(reply), length); - str[length] = '\0'; + ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME, + name); +} - return str; -} /* _ecore_x_window_prop_string_utf8_get */ +EAPI int +ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (name) + *name = ecore_x_window_prop_string_get(win, + ECORE_X_ATOM_NET_WM_VISIBLE_NAME); + return 1; +} -#if 0 /* Unused */ -/* - * Process startup info - */ -static int -_ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info) +EAPI void +ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name) { - Ecore_X_Event_Startup_Sequence *e; - int event; - char *p; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - p = strchr(info->buffer, ':'); - if (!p) - { - eina_hash_del(startup_info, (void *)info->win); - _ecore_x_netwm_startup_info_free(info); - return 0; - } + ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME, + name); +} - *p = 0; - if (!strcmp(info->buffer, "new")) - { - if (info->init) - event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE; - else - event = ECORE_X_EVENT_STARTUP_SEQUENCE_NEW; +EAPI int +ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - info->init = 1; - } - else if (!strcmp(info->buffer, "change")) - { - event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE; - } - else if (!strcmp(info->buffer, "remove")) - event = ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE; - else + if (name) { - eina_hash_del(startup_info, (void *)info->win); - _ecore_x_netwm_startup_info_free(info); - return 0; + *name = + ecore_x_window_prop_string_get(win, + ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME); } - p++; + return 1; +} - if (!_ecore_x_netwm_startup_info_parse(info, p)) - { - eina_hash_del(startup_info, (void *)info->win); - _ecore_x_netwm_startup_info_free(info); - return 0; - } +EAPI Eina_Bool +ecore_x_netwm_sync_counter_get(Ecore_X_Window win, Ecore_X_Sync_Counter *counter) +{ + unsigned int tmp; - if (info->init) - { - e = calloc(1, sizeof(Ecore_X_Event_Startup_Sequence)); - if (!e) - { - eina_hash_del(startup_info, (void *)info->win); - _ecore_x_netwm_startup_info_free(info); - return 0; - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); - e->win = info->win; - ecore_event_add(event, e, NULL, NULL); - } + if (!ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, + &tmp, 1)) + return EINA_FALSE; - if (event == ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE) - { - eina_hash_del(startup_info, (void *)info->win); - _ecore_x_netwm_startup_info_free(info); - } - else - { - /* Discard buffer */ - info->length = 0; - info->buffer[0] = 0; - } + if (counter) *counter = tmp; - return 1; -} /* _ecore_x_netwm_startup_info_process */ + return EINA_TRUE; +} -/* - * Parse startup info - */ -static int -_ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info, - char *data) +EAPI Eina_Bool +ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, Ecore_X_Action action) { - while (*data) - { - int in_quot_sing, in_quot_dbl, escaped; - char *p, *pp; - char *key; - char value[1024]; - - /* Skip space */ - while (*data == ' ') data++; - /* Get key */ - key = data; - data = strchr(key, '='); - if (!data) - return 0; - - *data = 0; - data++; - - /* Get value */ - p = data; - pp = value; - in_quot_dbl = 0; - in_quot_sing = 0; - escaped = 0; - while (*p) - { - if ((pp - value) >= 1024) - return 0; - - if (escaped) - { - *pp = *p; - pp++; - escaped = 0; - } - else if (in_quot_sing) - { - if (*p == '\\') - escaped = 1; - else if (*p == '\'') - in_quot_sing = 0; - else - { - *pp = *p; - pp++; - } - } - else if (in_quot_dbl) - { - if (*p == '\\') - escaped = 1; - else if (*p == '\"') - in_quot_dbl = 0; - else - { - *pp = *p; - pp++; - } - } - else - { - if (*p == '\\') - escaped = 1; - else if (*p == '\'') - in_quot_sing = 1; - else if (*p == '\"') - in_quot_dbl = 1; - else if (*p == ' ') - { - break; - } - else - { - *pp = *p; - pp++; - } - } - - p++; - } - if ((in_quot_dbl) || (in_quot_sing)) - return 0; + int num = 0, i = 0; + Ecore_X_Atom *atoms, atom; + Eina_Bool ret = EINA_FALSE; - data = p; - *pp = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* Parse info */ - if (!strcmp(key, "ID")) - { - if ((info->id) && (strcmp(info->id, value))) - return 0; - - info->id = strdup(value); - p = strstr(value, "_TIME"); - if (p) - { - info->timestamp = atoi(p + 5); - } - } - else if (!strcmp(key, "NAME")) - { - if (info->name) - free(info->name); + num = + ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, + &atoms); + if (num <= 0) return EINA_FALSE; - info->name = strdup(value); - } - else if (!strcmp(key, "SCREEN")) + atom = _ecore_xcb_netwm_action_atom_get(action); + for (i = 0; i < num; i++) + { + if (atoms[i] == atom) { - info->screen = atoi(value); + ret = EINA_TRUE; + break; } - else if (!strcmp(key, "BIN")) - { - if (info->bin) - free(info->bin); + } - info->bin = strdup(value); - } - else if (!strcmp(key, "ICON")) - { - if (info->icon) - free(info->icon); + if (atoms) free(atoms); + return ret; +} - info->icon = strdup(value); - } - else if (!strcmp(key, "DESKTOP")) - { - info->desktop = atoi(value); - } - else if (!strcmp(key, "TIMESTAMP")) - { - if (!info->timestamp) - info->timestamp = atoi(value); - } - else if (!strcmp(key, "DESCRIPTION")) - { - if (info->description) - free(info->description); +EAPI Eina_Bool +ecore_x_netwm_allowed_action_get(Ecore_X_Window win, Ecore_X_Action **action, unsigned int *num) +{ + Ecore_X_Atom *atoms; + int num_ret = 0; - info->description = strdup(value); - } - else if (!strcmp(key, "WMCLASS")) - { - if (info->wmclass) - free(info->wmclass); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - info->wmclass = strdup(value); - } - else if (!strcmp(key, "SILENT")) - { - info->silent = atoi(value); - } - else + if (num) *num = 0; + if (action) *action = NULL; + + num_ret = + ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, + &atoms); + if (num_ret <= 0) return EINA_FALSE; + if (action) + { + *action = malloc(num_ret * sizeof(Ecore_X_Action)); + if (*action) { - WRN("Ecore X Sequence, Unknown: %s=%s", key, value); + int i = 0; + + for (i = 0; i < num_ret; i++) + (*action)[i] = _ecore_xcb_netwm_action_atom_get(atoms[i]); } + if (num) *num = num_ret; } - if (!info->id) - return 0; - - return 1; -} /* _ecore_x_netwm_startup_info_parse */ - -#endif /* if 0 */ + free(atoms); + return EINA_TRUE; +} -/* - * Free startup info struct - */ -static void -_ecore_x_netwm_startup_info_free(void *data) +EAPI void +ecore_x_netwm_allowed_action_set(Ecore_X_Window win, Ecore_X_Action *action, unsigned int num) { - Ecore_X_Startup_Info *info; + Ecore_X_Atom *set; + unsigned int i = 0; - info = data; - if (!info) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (info->buffer) - free(info->buffer); + if (!num) + { + ecore_x_window_prop_property_del(win, + ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS); + return; + } - if (info->id) - free(info->id); + set = malloc(num * sizeof(Ecore_X_Atom)); + if (!set) return; - if (info->name) - free(info->name); + for (i = 0; i < num; i++) + set[i] = _ecore_xcb_netwm_action_atom_get(action[i]); - if (info->bin) - free(info->bin); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, + set, num); + free(set); +} - if (info->icon) - free(info->icon); +/* local functions */ +int +_ecore_xcb_netwm_startup_info_begin(Ecore_X_Window win __UNUSED__, uint8_t data __UNUSED__) +{ + // TODO: TBD + return 1; +} + +int +_ecore_xcb_netwm_startup_info(Ecore_X_Window win __UNUSED__, uint8_t data __UNUSED__) +{ + // TODO: TBD + return 1; +} - if (info->description) - free(info->description); +static void +_ecore_xcb_netwm_startup_info_free(void *data) +{ + Ecore_Xcb_Startup_Info *info; - if (info->wmclass) - free(info->wmclass); + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!(info = data)) return; + if (info->buffer) free(info->buffer); + if (info->id) free(info->id); + if (info->name) free(info->name); + if (info->bin) free(info->bin); + if (info->icon) free(info->icon); + if (info->description) free(info->description); + if (info->wmclass) free(info->wmclass); free(info); -} /* _ecore_x_netwm_startup_info_free */ - -/* - * Is screen composited? - */ - -/* FIXME: one round trip can be removed. Can we keep it ? */ - -/** - * Check whether a screen is composited or not. - * @param screen The screen index. - * - * Return 1 if @p screen is composited, 0 otherwise. - * @ingroup Ecore_X_NetWM_Group - */ -EAPI Eina_Bool -ecore_x_screen_is_composited(int screen) -{ - char buf[32]; - xcb_intern_atom_cookie_t cookie_atom; - xcb_get_selection_owner_cookie_t cookie_owner; - xcb_intern_atom_reply_t *reply_atom; - xcb_get_selection_owner_reply_t *reply_owner; - Ecore_X_Window window; - Ecore_X_Atom atom; - - snprintf(buf, sizeof(buf), "_NET_WM_CM_S%d", screen); - cookie_atom = xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, - strlen(buf), buf); - reply_atom = xcb_intern_atom_reply(_ecore_xcb_conn, cookie_atom, NULL); - if (!reply_atom) - return 0; +} - atom = reply_atom->atom; - free(reply_atom); +static Ecore_X_Atom +_ecore_xcb_netwm_window_type_atom_get(Ecore_X_Window_Type type) +{ + switch (type) + { + case ECORE_X_WINDOW_TYPE_DESKTOP: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP; + case ECORE_X_WINDOW_TYPE_DOCK: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK; + case ECORE_X_WINDOW_TYPE_TOOLBAR: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR; + case ECORE_X_WINDOW_TYPE_MENU: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU; + case ECORE_X_WINDOW_TYPE_UTILITY: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY; + case ECORE_X_WINDOW_TYPE_SPLASH: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH; + case ECORE_X_WINDOW_TYPE_DIALOG: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG; + case ECORE_X_WINDOW_TYPE_NORMAL: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL; + case ECORE_X_WINDOW_TYPE_DROPDOWN_MENU: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU; + case ECORE_X_WINDOW_TYPE_POPUP_MENU: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU; + case ECORE_X_WINDOW_TYPE_TOOLTIP: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP; + case ECORE_X_WINDOW_TYPE_NOTIFICATION: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION; + case ECORE_X_WINDOW_TYPE_COMBO: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO; + case ECORE_X_WINDOW_TYPE_DND: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND; + default: + return 0; + } +} - cookie_owner = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, atom); - reply_owner = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie_owner, NULL); - if (!reply_owner) - return 0; +static Ecore_X_Window_Type +_ecore_xcb_netwm_window_type_type_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP) + return ECORE_X_WINDOW_TYPE_DESKTOP; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK) + return ECORE_X_WINDOW_TYPE_DOCK; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR) + return ECORE_X_WINDOW_TYPE_TOOLBAR; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU) + return ECORE_X_WINDOW_TYPE_MENU; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY) + return ECORE_X_WINDOW_TYPE_UTILITY; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH) + return ECORE_X_WINDOW_TYPE_SPLASH; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG) + return ECORE_X_WINDOW_TYPE_DIALOG; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL) + return ECORE_X_WINDOW_TYPE_NORMAL; + else + return ECORE_X_WINDOW_TYPE_UNKNOWN; +} - window = reply_owner->owner; - free(reply_owner); +static Ecore_X_Atom +_ecore_xcb_netwm_window_state_atom_get(Ecore_X_Window_State state) +{ + switch (state) + { + case ECORE_X_WINDOW_STATE_MODAL: + return ECORE_X_ATOM_NET_WM_STATE_MODAL; + case ECORE_X_WINDOW_STATE_STICKY: + return ECORE_X_ATOM_NET_WM_STATE_STICKY; + case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT: + return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT; + case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ: + return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ; + case ECORE_X_WINDOW_STATE_SHADED: + return ECORE_X_ATOM_NET_WM_STATE_SHADED; + case ECORE_X_WINDOW_STATE_SKIP_TASKBAR: + return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR; + case ECORE_X_WINDOW_STATE_SKIP_PAGER: + return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER; + case ECORE_X_WINDOW_STATE_HIDDEN: + return ECORE_X_ATOM_NET_WM_STATE_HIDDEN; + case ECORE_X_WINDOW_STATE_FULLSCREEN: + return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN; + case ECORE_X_WINDOW_STATE_ABOVE: + return ECORE_X_ATOM_NET_WM_STATE_ABOVE; + case ECORE_X_WINDOW_STATE_BELOW: + return ECORE_X_ATOM_NET_WM_STATE_BELOW; + case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION: + return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION; + default: + return 0; + } +} - return window != XCB_NONE; -} /* ecore_x_screen_is_composited */ +Ecore_X_Window_State +_ecore_xcb_netwm_window_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_NET_WM_STATE_MODAL) + return ECORE_X_WINDOW_STATE_MODAL; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_STICKY) + return ECORE_X_WINDOW_STATE_STICKY; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT) + return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ) + return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_SHADED) + return ECORE_X_WINDOW_STATE_SHADED; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR) + return ECORE_X_WINDOW_STATE_SKIP_TASKBAR; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER) + return ECORE_X_WINDOW_STATE_SKIP_PAGER; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_HIDDEN) + return ECORE_X_WINDOW_STATE_HIDDEN; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN) + return ECORE_X_WINDOW_STATE_FULLSCREEN; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_ABOVE) + return ECORE_X_WINDOW_STATE_ABOVE; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_BELOW) + return ECORE_X_WINDOW_STATE_BELOW; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION) + return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION; + else + return ECORE_X_WINDOW_STATE_UNKNOWN; +} +static Ecore_X_Atom +_ecore_xcb_netwm_action_atom_get(Ecore_X_Action action) +{ + switch (action) + { + case ECORE_X_ACTION_MOVE: + return ECORE_X_ATOM_NET_WM_ACTION_MOVE; + case ECORE_X_ACTION_RESIZE: + return ECORE_X_ATOM_NET_WM_ACTION_RESIZE; + case ECORE_X_ACTION_MINIMIZE: + return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE; + case ECORE_X_ACTION_SHADE: + return ECORE_X_ATOM_NET_WM_ACTION_SHADE; + case ECORE_X_ACTION_STICK: + return ECORE_X_ATOM_NET_WM_ACTION_STICK; + case ECORE_X_ACTION_MAXIMIZE_HORZ: + return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ; + case ECORE_X_ACTION_MAXIMIZE_VERT: + return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT; + case ECORE_X_ACTION_FULLSCREEN: + return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN; + case ECORE_X_ACTION_CHANGE_DESKTOP: + return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP; + case ECORE_X_ACTION_CLOSE: + return ECORE_X_ATOM_NET_WM_ACTION_CLOSE; + case ECORE_X_ACTION_ABOVE: + return ECORE_X_ATOM_NET_WM_ACTION_ABOVE; + case ECORE_X_ACTION_BELOW: + return ECORE_X_ATOM_NET_WM_ACTION_BELOW; + default: + return 0; + } +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c b/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c index e374a7a..6a9e797 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c @@ -18,25 +18,21 @@ * @return New pixmap. * @ingroup Ecore_X_Pixmap_Group */ -EAPI Ecore_X_Pixmap -ecore_x_pixmap_new(Ecore_X_Window win, - int w, - int h, - int dep) +EAPI Ecore_X_Pixmap +ecore_x_pixmap_new(Ecore_X_Window win, int w, int h, int dep) { Ecore_X_Pixmap pmap; - if (win == 0) - win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (dep == 0) - dep = ((xcb_screen_t *)_ecore_xcb_screen)->root_depth; + if (win == 0) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + if (dep == 0) dep = ((xcb_screen_t *)_ecore_xcb_screen)->root_depth; pmap = xcb_generate_id(_ecore_xcb_conn); xcb_create_pixmap(_ecore_xcb_conn, dep, pmap, win, w, h); return pmap; -} /* ecore_x_pixmap_new */ +} /** * Deletes the reference to the given pixmap. @@ -47,11 +43,13 @@ ecore_x_pixmap_new(Ecore_X_Window win, * @param pmap The given pixmap. * @ingroup Ecore_X_Pixmap_Group */ -EAPI void -ecore_x_pixmap_free(Ecore_X_Pixmap pmap) +EAPI void +ecore_x_pixmap_free(Ecore_X_Pixmap pmap) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + xcb_free_pixmap(_ecore_xcb_conn, pmap); -} /* ecore_x_pixmap_free */ +} /** * Pastes a rectangular area of the given pixmap onto the given drawable. @@ -67,19 +65,13 @@ ecore_x_pixmap_free(Ecore_X_Pixmap pmap) * @param dy The Y position at which to paste the area on @p dest. * @ingroup Ecore_X_Pixmap_Group */ -EAPI void -ecore_x_pixmap_paste(Ecore_X_Pixmap pmap, - Ecore_X_Drawable dest, - Ecore_X_GC gc, - int sx, - int sy, - int w, - int h, - int dx, - int dy) +EAPI void +ecore_x_pixmap_paste(Ecore_X_Pixmap pmap, Ecore_X_Drawable dest, Ecore_X_GC gc, int sx, int sy, int w, int h, int dx, int dy) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + xcb_copy_area(_ecore_xcb_conn, pmap, dest, gc, sx, sy, dx, dy, w, h); -} /* ecore_x_pixmap_paste */ +} /** * Retrieves the size of the given pixmap. @@ -90,12 +82,14 @@ ecore_x_pixmap_paste(Ecore_X_Pixmap pmap, * @param h Pointer to an integer in which to store the height. * @ingroup Ecore_X_Pixmap_Group */ -EAPI void -ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h) +EAPI void +ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (pmap) - ecore_x_drawable_geometry_get(pmap, x, y, w, h); -} /* ecore_x_pixmap_geometry_get */ + ecore_x_drawable_geometry_get(pmap, x, y, w, h); +} /** * Retrieves the depth of the given pixmap. @@ -103,9 +97,10 @@ ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h) * @return The depth of the pixmap. * @ingroup Ecore_X_Pixmap_Group */ -EAPI int -ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap) +EAPI int +ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap) { - return ecore_x_drawable_depth_get(pmap); -} /* ecore_x_pixmap_depth_get */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return ecore_x_drawable_depth_get(pmap); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_private.h b/src/lib/ecore_x/xcb/ecore_xcb_private.h index 00761f1..5330de2 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_private.h +++ b/src/lib/ecore_x/xcb/ecore_xcb_private.h @@ -1,352 +1,337 @@ #ifndef __ECORE_XCB_PRIVATE_H__ -#define __ECORE_XCB_PRIVATE_H__ - -#include "config.h" - -#include - -#ifndef MAXHOSTNAMELEN -# define MAXHOSTNAMELEN 256 -#endif /* ifndef MAXHOSTNAMELEN */ - -#ifndef XK_MISCELLANY -# define XK_MISCELLANY 1 -#endif /* XK_MISCELLANY */ - -#include -#include -#include -#include -#ifdef ECORE_XCB_CURSOR -# include -#endif /* ECORE_XCB_CURSOR */ -#ifdef ECORE_XCB_DAMAGE -# include -#endif /* ECORE_XCB_DAMAGE */ -#ifdef ECORE_XCB_COMPOSITE -# include -#endif /* ECORE_XCB_COMPOSITE */ -#ifdef ECORE_XCB_DPMS -# include -#endif /* ECORE_XCB_DPMS */ -#ifdef ECORE_XCB_RANDR -# include -#endif /* ECORE_XCB_RANDR */ -#ifdef ECORE_XCB_RENDER -# include -#endif /* ECORE_XCB_RENDER */ -#ifdef ECORE_XCB_SCREENSAVER -# include -#endif /* ECORE_XCB_SCREENSAVER */ -#ifdef ECORE_XCB_SHAPE -# include -#endif /* ECORE_XCB_SHAPE */ -#ifdef ECORE_XCB_SYNC -# include -#endif /* ECORE_XCB_SYNC */ -#ifdef ECORE_XCB_XFIXES -# include -#endif /* ECORE_XCB_XFIXES */ -#ifdef ECORE_XCB_XINERAMA -# include -#endif /* ECORE_XCB_XINERAMA */ -#ifdef ECORE_XCB_XPRINT -# include -#endif /* ECORE_XCB_XPRINT */ - -#include "Ecore.h" -#include "ecore_private.h" -#include "Ecore_X.h" - -extern int _ecore_x11xcb_log_dom; - -#ifdef ECORE_XLIB_XCB_DEFAULT_LOG_COLOR -# undef ECORE_XLIB_XCB_DEFAULT_LOG_COLOR -#endif /* ifdef ECORE_XLIB_XCB_DEFAULT_LOG_COLOR */ -#define ECORE_XLIB_XCB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE - -#ifdef ERR -# undef ERR -#endif /* ifdef ERR */ -#define ERR(...) EINA_LOG_DOM_ERR(_ecore_x11xcb_log_dom, __VA_ARGS__) - -#ifdef DBG -# undef DBG -#endif /* ifdef DBG */ -#define DBG(...) EINA_LOG_DOM_DBG(_ecore_x11xcb_log_dom, __VA_ARGS__) - -#ifdef INF -# undef INF -#endif /* ifdef INF */ -#define INF(...) EINA_LOG_DOM_INFO(_ecore_x11xcb_log_dom, __VA_ARGS__) - -#ifdef WRN -# undef WRN -#endif /* ifdef WRN */ -#define WRN(...) EINA_LOG_DOM_WARN(_ecore_x11xcb_log_dom, __VA_ARGS__) - -#ifdef CRIT -# undef CRIT -#endif /* ifdef CRIT */ -#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_x11xcb_log_dom, __VA_ARGS__) - -typedef struct _Ecore_X_Selection_Intern Ecore_X_Selection_Intern; - -struct _Ecore_X_Selection_Intern +# define __ECORE_XCB_PRIVATE_H__ + +//# define LOGFNS 1 + +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif + +# include // included for close & gethostname functions + +/* generic xcb includes */ +# include +# include +# include + +/* EFL includes */ +# include "Ecore.h" +# include "Ecore_Input.h" +# include "Ecore_X.h" + +/* logging */ +extern int _ecore_xcb_log_dom; + +# ifdef ECORE_XCB_DEFAULT_LOG_COLOR +# undef ECORE_XCB_DEFAULT_LOG_COLOR +# endif +# define ECORE_XCB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE + +# ifdef ERR +# undef ERR +# endif +# define ERR(...) EINA_LOG_DOM_ERR(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef DBG +# undef DBG +# endif +# define DBG(...) EINA_LOG_DOM_DBG(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef INF +# undef INF +# endif +# define INF(...) EINA_LOG_DOM_INFO(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef WRN +# undef WRN +# endif +# define WRN(...) EINA_LOG_DOM_WARN(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef CRIT +# undef CRIT +# endif +# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef LOGFNS +# include +# define LOGFN(fl, ln, fn) printf("-ECORE-XCB: %25s: %5i - %s\n", fl, ln, fn); +# else +# define LOGFN(fl, ln, fn) +# endif + +# ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +# endif + +# ifndef MIN +# define MIN(x, y) (((x) > (y)) ? (y) : (x)) +# endif + +# ifndef MAX +# define MAX(a, b) ((a < b) ? b : a) +# endif + +/* enums */ +typedef enum _Ecore_Xcb_Encoding_Style Ecore_Xcb_Encoding_Style; + +enum _Ecore_Xcb_Encoding_Style { - Ecore_X_Window win; - Ecore_X_Atom selection; - unsigned char *data; - int length; - Ecore_X_Time time; + XcbStringStyle, + XcbCompoundTextStyle, + XcbTextStyle, + XcbStdICCTextStyle, + XcbUTF8StringStyle }; -typedef struct _Ecore_X_Selection_Converter Ecore_X_Selection_Converter; - -struct _Ecore_X_Selection_Converter -{ - Ecore_X_Atom target; - int (*convert)(char *target, void *data, int size, - void **data_ret, int *size_ret, - Ecore_X_Atom *type, int *typeseize); - Ecore_X_Selection_Converter *next; -}; - -typedef struct _Ecore_X_Selection_Parser Ecore_X_Selection_Parser; - -struct _Ecore_X_Selection_Parser -{ - char *target; - void *(*parse)(const char *target, void *data, int size, int format); - Ecore_X_Selection_Parser *next; -}; +/* structures */ +typedef struct _Ecore_X_DND_Source Ecore_X_DND_Source; +typedef struct _Ecore_X_DND_Target Ecore_X_DND_Target; +typedef struct _Ecore_X_Selection_Intern Ecore_X_Selection_Intern; +typedef struct _Ecore_X_Selection_Converter Ecore_X_Selection_Converter; +typedef struct _Ecore_X_Selection_Parser Ecore_X_Selection_Parser; +typedef struct _Ecore_Xcb_Textproperty Ecore_Xcb_Textproperty; -typedef struct _Ecore_X_DND_Source +struct _Ecore_X_DND_Source { - int version; + int version; Ecore_X_Window win, dest; - enum { - ECORE_X_DND_SOURCE_IDLE, - ECORE_X_DND_SOURCE_DRAGGING, - ECORE_X_DND_SOURCE_DROPPED, - ECORE_X_DND_SOURCE_CONVERTING - } state; - - struct - { - short x, y; - unsigned short width, height; - } rectangle; - - struct - { - Ecore_X_Window window; - int x, y; - } prev; + enum + { + ECORE_X_DND_SOURCE_IDLE, + ECORE_X_DND_SOURCE_DRAGGING, + ECORE_X_DND_SOURCE_DROPPED, + ECORE_X_DND_SOURCE_CONVERTING + } state; + + struct + { + short x, y; + unsigned short width, height; + } rectangle; + + struct + { + Ecore_X_Window window; + int x, y; + } prev; Ecore_X_Time time; Ecore_X_Atom action, accepted_action; - int will_accept; - int suppress; - - int await_status; -} Ecore_X_DND_Source; + int will_accept, suppress; + int await_status; +}; -typedef struct _Ecore_X_DND_Target +struct _Ecore_X_DND_Target { - int version; + int version; Ecore_X_Window win, source; - enum { - ECORE_X_DND_TARGET_IDLE, - ECORE_X_DND_TARGET_ENTERED - } state; + enum + { + ECORE_X_DND_TARGET_IDLE, + ECORE_X_DND_TARGET_ENTERED + } state; - struct - { - int x, y; - } pos; + struct + { + int x, y; + } pos; Ecore_X_Time time; Ecore_X_Atom action, accepted_action; + int will_accept; +}; - int will_accept; -} Ecore_X_DND_Target; +struct _Ecore_X_Selection_Intern +{ + Ecore_X_Window win; + Ecore_X_Atom selection; + unsigned char *data; + int length; + Ecore_X_Time time; +}; -extern int ECORE_X_MODIFIER_SHIFT; -extern int ECORE_X_MODIFIER_CTRL; -extern int ECORE_X_MODIFIER_ALT; -extern int ECORE_X_MODIFIER_WIN; +struct _Ecore_X_Selection_Converter +{ + Ecore_X_Atom target; + Eina_Bool (*convert) (char *target, void *data, int size, void **data_ret, + int *size_ret, Ecore_X_Atom *type, int *size_type); + Ecore_X_Selection_Converter *next; +}; -extern int ECORE_X_LOCK_SCROLL; -extern int ECORE_X_LOCK_NUM; -extern int ECORE_X_LOCK_CAPS; +struct _Ecore_X_Selection_Parser +{ + char *target; + void *(*parse) (const char *target, void *data, int size, int format); + Ecore_X_Selection_Parser *next; +}; + +struct _Ecore_Xcb_Textproperty +{ + char *value; + Ecore_X_Atom encoding; + unsigned int format, nitems; +}; +/* external variables */ extern Ecore_X_Connection *_ecore_xcb_conn; extern Ecore_X_Screen *_ecore_xcb_screen; extern double _ecore_xcb_double_click_time; -extern Ecore_X_Time _ecore_xcb_event_last_time; -extern Ecore_X_Window _ecore_xcb_event_last_window; extern int16_t _ecore_xcb_event_last_root_x; extern int16_t _ecore_xcb_event_last_root_y; -extern int _ecore_xcb_xcursor; - -extern Ecore_X_Atom _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM]; - -extern int _ecore_window_grabs_num; -extern Ecore_X_Window *_ecore_window_grabs; -extern Eina_Bool (*_ecore_window_grab_replay_func)(void *data, int event_type, void *event); -extern void *_ecore_window_grab_replay_data; - -extern Ecore_X_Window _ecore_xcb_private_window; - -void _ecore_x_error_handler_init(void); - -void _ecore_x_event_handle_any_event (xcb_generic_event_t *event); -void _ecore_x_event_handle_key_press (xcb_generic_event_t *event); -void _ecore_x_event_handle_key_release (xcb_generic_event_t *event); -void _ecore_x_event_handle_button_press (xcb_generic_event_t *event); -void _ecore_x_event_handle_button_release (xcb_generic_event_t *event); -void _ecore_x_event_handle_motion_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_enter_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_leave_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_focus_in (xcb_generic_event_t *event); -void _ecore_x_event_handle_focus_out (xcb_generic_event_t *event); -void _ecore_x_event_handle_keymap_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_expose (xcb_generic_event_t *event); -void _ecore_x_event_handle_graphics_expose (xcb_generic_event_t *event); -void _ecore_x_event_handle_visibility_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_create_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_destroy_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_unmap_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_map_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_map_request (xcb_generic_event_t *event); -void _ecore_x_event_handle_reparent_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_configure_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_configure_request (xcb_generic_event_t *event); -void _ecore_x_event_handle_gravity_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_resize_request (xcb_generic_event_t *event); -void _ecore_x_event_handle_circulate_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_circulate_request (xcb_generic_event_t *event); -void _ecore_x_event_handle_property_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_selection_clear (xcb_generic_event_t *event); -void _ecore_x_event_handle_selection_request (xcb_generic_event_t *event); -void _ecore_x_event_handle_selection_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_colormap_notify (xcb_generic_event_t *event); -void _ecore_x_event_handle_client_message (xcb_generic_event_t *event); -void _ecore_x_event_handle_mapping_notify (xcb_generic_event_t *event); -#ifdef ECORE_XCB_DAMAGE -void _ecore_x_event_handle_damage_notify (xcb_generic_event_t *event); -#endif /* ECORE_XCB_DAMAGE */ -#ifdef ECORE_XCB_RANDR -void _ecore_x_event_handle_randr_change (xcb_generic_event_t *event); -#endif /* ECORE_XCB_RANDR */ -#ifdef ECORE_XCB_SCREENSAVER -void _ecore_x_event_handle_screensaver_notify (xcb_generic_event_t *event); -#endif /* ECORE_XCB_SCREENSAVER */ -#ifdef ECORE_XCB_SHAPE -void _ecore_x_event_handle_shape_change (xcb_generic_event_t *event); -#endif /* ECORE_XCB_SHAPE */ -#ifdef ECORE_XCB_SYNC -void _ecore_x_event_handle_sync_counter (xcb_generic_event_t *event); -void _ecore_x_event_handle_sync_alarm (xcb_generic_event_t *event); -#endif /* ECORE_XCB_SYNC */ -#ifdef ECORE_XCB_FIXES -void _ecore_x_event_handle_fixes_selection_notify(xcb_generic_event_t *event); -#endif /* ECORE_XCB_FIXES */ - -/* requests / replies */ -int _ecore_x_reply_init (); -void _ecore_x_reply_shutdown (); -void _ecore_xcb_cookie_cache (unsigned int cookie); -unsigned int _ecore_xcb_cookie_get (void); -void _ecore_xcb_reply_cache (void *reply); -void * _ecore_xcb_reply_get (void); - -/* atoms */ -extern Ecore_X_Atom ECORE_X_ATOM_ATOM; -extern Ecore_X_Atom ECORE_X_ATOM_CARDINAL; -extern Ecore_X_Atom ECORE_X_ATOM_STRING; -extern Ecore_X_Atom ECORE_X_ATOM_WINDOW; -extern Ecore_X_Atom ECORE_X_ATOM_E_FRAME_SIZE; -extern Ecore_X_Atom ECORE_X_ATOM_WM_SIZE_HINTS; - -#define ECORE_X_ATOMS_COUNT 117 - -void _ecore_x_atom_init (xcb_intern_atom_cookie_t *); -void _ecore_x_atom_init_finalize (xcb_intern_atom_cookie_t *); - -/* damage */ -void _ecore_x_damage_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_damage_init_finalize (void); - -/* composite */ -void _ecore_x_composite_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_composite_init_finalize (void); - -/* from dnd */ -void _ecore_x_dnd_init (void); -void _ecore_x_dnd_shutdown (void); -Ecore_X_DND_Source * _ecore_x_dnd_source_get (void); -Ecore_X_DND_Target * _ecore_x_dnd_target_get (void); -void _ecore_x_dnd_drag (Ecore_X_Window root, - int x, - int y); - -/* dpms */ -void _ecore_x_dpms_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_dpms_init_finalize (void); - -/* netwm */ -Ecore_X_Window_State _ecore_x_netwm_state_get(Ecore_X_Atom a); -int _ecore_x_netwm_startup_info_begin(Ecore_X_Window win, char *data); -int _ecore_x_netwm_startup_info(Ecore_X_Window win, char *data); - -/* randr */ -void _ecore_x_randr_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_randr_init_finalize (void); - -/* selection */ -void _ecore_x_selection_init(void); -void _ecore_x_selection_shutdown(void); -Ecore_X_Atom _ecore_x_selection_target_atom_get(const char *target); -char * _ecore_x_selection_target_get(Ecore_X_Atom target); -Ecore_X_Selection_Intern * _ecore_x_selection_get(Ecore_X_Atom selection); -int _ecore_x_selection_set(Ecore_X_Window w, const void *data, int len, Ecore_X_Atom selection); -int _ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret); -void * _ecore_x_selection_parse(const char *target, void *data, int size, int format); - -/* screensaver */ -void _ecore_x_screensaver_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_screensaver_init_finalize (void); - -/* shape */ -void _ecore_x_shape_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_shape_init_finalize (void); - -/* sync */ -void _ecore_x_sync_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_sync_init_finalize (void); - -/* xfixes */ -void _ecore_x_xfixes_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_xfixes_init_finalize (void); - -/* xinerama */ -void _ecore_x_xinerama_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_xinerama_init_finalize (void); - -/* xprint */ -void _ecore_x_xprint_init (const xcb_query_extension_reply_t *reply); -void _ecore_x_xprint_init_finalize (void); - -/* to categorize */ -void _ecore_x_sync_magic_send(int val, Ecore_X_Window swin); -void _ecore_x_window_grab_remove(Ecore_X_Window win); -void _ecore_x_key_grab_remove(Ecore_X_Window win); - -#endif /* __ECORE_XCB_PRIVATE_H__*/ + +/* external variables for extension events */ +extern int _ecore_xcb_event_damage; +extern int _ecore_xcb_event_randr; +extern int _ecore_xcb_event_screensaver; +extern int _ecore_xcb_event_shape; +extern int _ecore_xcb_event_sync; +extern int _ecore_xcb_event_xfixes; +extern int _ecore_xcb_event_input; + +extern int ECORE_X_MODIFIER_SHIFT; +extern int ECORE_X_MODIFIER_CTRL; +extern int ECORE_X_MODIFIER_ALT; +extern int ECORE_X_MODIFIER_WIN; +extern int ECORE_X_LOCK_SCROLL; +extern int ECORE_X_LOCK_NUM; +extern int ECORE_X_LOCK_CAPS; +extern int ECORE_X_LOCK_SHIFT; + +extern Ecore_X_Atom _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_NUM]; + +extern int _ecore_xcb_button_grabs_num; +extern int _ecore_xcb_key_grabs_num; +extern Ecore_X_Window *_ecore_xcb_button_grabs; +extern Ecore_X_Window *_ecore_xcb_key_grabs; +extern Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data, int type, void *event); +extern void *_ecore_xcb_window_grab_replay_data; + +/* private function prototypes */ +void _ecore_xcb_error_handler_init(void); +void _ecore_xcb_error_handler_shutdown(void); + +void _ecore_xcb_atoms_init(void); +void _ecore_xcb_atoms_finalize(void); + +void _ecore_xcb_extensions_init(void); +void _ecore_xcb_extensions_finalize(void); + +void _ecore_xcb_shape_init(void); +void _ecore_xcb_shape_finalize(void); + +void _ecore_xcb_screensaver_init(void); +void _ecore_xcb_screensaver_finalize(void); + +void _ecore_xcb_sync_init(void); +void _ecore_xcb_sync_finalize(void); +void _ecore_xcb_sync_magic_send(int val, Ecore_X_Window win); + +void _ecore_xcb_render_init(void); +void _ecore_xcb_render_finalize(void); +Eina_Bool _ecore_xcb_render_argb_get(void); +Eina_Bool _ecore_xcb_render_anim_get(void); +Eina_Bool _ecore_xcb_render_avail_get(void); + +Eina_Bool _ecore_xcb_render_visual_supports_alpha(Ecore_X_Visual visual); +uint32_t _ecore_xcb_render_find_visual_id(int type, Eina_Bool check_alpha); +Ecore_X_Visual *_ecore_xcb_render_visual_get(int visual_id); + +void _ecore_xcb_randr_init(void); +void _ecore_xcb_randr_finalize(void); + +void _ecore_xcb_xfixes_init(void); +void _ecore_xcb_xfixes_finalize(void); +Eina_Bool _ecore_xcb_xfixes_avail_get(void); + +void _ecore_xcb_damage_init(void); +void _ecore_xcb_damage_finalize(void); + +void _ecore_xcb_composite_init(void); +void _ecore_xcb_composite_finalize(void); + +void _ecore_xcb_dpms_init(void); +void _ecore_xcb_dpms_finalize(void); + +void _ecore_xcb_cursor_init(void); +void _ecore_xcb_cursor_finalize(void); + +void _ecore_xcb_xinerama_init(void); +void _ecore_xcb_xinerama_finalize(void); + +void _ecore_xcb_dnd_init(void); +void _ecore_xcb_dnd_shutdown(void); +Ecore_X_DND_Source *_ecore_xcb_dnd_source_get(void); +Ecore_X_DND_Target *_ecore_xcb_dnd_target_get(void); +void _ecore_xcb_dnd_drag(Ecore_X_Window root, int x, int y); + +void _ecore_xcb_selection_init(void); +void _ecore_xcb_selection_shutdown(void); +void *_ecore_xcb_selection_parse(const char *target, void *data, int size, int format); +char *_ecore_xcb_selection_target_get(Ecore_X_Atom target); +Ecore_X_Selection_Intern *_ecore_xcb_selection_get(Ecore_X_Atom selection); + +# ifdef HAVE_ICONV +Eina_Bool _ecore_xcb_utf8_textlist_to_textproperty(char **list, int count, Ecore_Xcb_Encoding_Style style, Ecore_Xcb_Textproperty *ret); +# endif +Eina_Bool _ecore_xcb_mb_textlist_to_textproperty(char **list, int count, Ecore_Xcb_Encoding_Style style, Ecore_Xcb_Textproperty *ret); +Eina_Bool _ecore_xcb_textlist_to_textproperty(const char *type, char **list, int count, Ecore_Xcb_Encoding_Style style, Ecore_Xcb_Textproperty *ret); + +# ifdef HAVE_ICONV +Eina_Bool _ecore_xcb_utf8_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, char ***list_ret, int *count_ret); +# endif +Eina_Bool _ecore_xcb_mb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, char ***list_ret, int *count_ret); +Eina_Bool _ecore_xcb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, const char *type, char ***list_ret, int *count_ret); + +void _ecore_xcb_events_init(void); +void _ecore_xcb_events_shutdown(void); +void _ecore_xcb_events_handle(xcb_generic_event_t *ev); +Ecore_X_Time _ecore_xcb_events_last_time_get(void); +unsigned int _ecore_xcb_events_modifiers_get(unsigned int state); +void _ecore_xcb_event_mouse_move(uint16_t timestamp, uint16_t modifiers, int16_t x, int16_t y, int16_t root_x, int16_t root_y, xcb_window_t event_win, xcb_window_t win, xcb_window_t root_win, uint8_t same_screen, int dev, double radx, double rady, double pressure, double angle, int16_t mx, int16_t my, int16_t mrx, int16_t mry); +Ecore_Event_Mouse_Button *_ecore_xcb_event_mouse_button(int event, uint16_t timestamp, uint16_t modifiers, xcb_button_t buttons, int16_t x, int16_t y, int16_t root_x, int16_t root_y, xcb_window_t event_win, xcb_window_t win, xcb_window_t root_win, uint8_t same_screen, int dev, double radx, double rady, double pressure, double angle, int16_t mx, int16_t my, int16_t mrx, int16_t mry); + +void _ecore_xcb_keymap_init(void); +void _ecore_xcb_keymap_finalize(void); +void _ecore_xcb_keymap_shutdown(void); +void _ecore_xcb_keymap_refresh(xcb_mapping_notify_event_t *event); +xcb_keysym_t _ecore_xcb_keymap_keycode_to_keysym(xcb_keycode_t keycode, int col); +xcb_keycode_t *_ecore_xcb_keymap_keysym_to_keycode(xcb_keysym_t keysym); +char *_ecore_xcb_keymap_keysym_to_string(xcb_keysym_t keysym); +xcb_keycode_t _ecore_xcb_keymap_string_to_keycode(const char *key); +int _ecore_xcb_keymap_lookup_string(xcb_keycode_t keycode, int state, char *buffer, int bytes, xcb_keysym_t *sym); + +void _ecore_xcb_input_init(void); +void _ecore_xcb_input_finalize(void); +void _ecore_xcb_input_shutdown(void); +# ifdef ECORE_XCB_XINPUT +void _ecore_xcb_input_handle_event(xcb_generic_event_t *event); +# else +void _ecore_xcb_input_handle_event(xcb_generic_event_t *event __UNUSED__); +# endif + +void _ecore_xcb_dri_init(void); +void _ecore_xcb_dri_finalize(void); + +void _ecore_xcb_xtest_init(void); +void _ecore_xcb_xtest_finalize(void); + +Ecore_X_Window _ecore_xcb_window_root_of_screen_get(int screen); +void _ecore_xcb_window_prop_string_utf8_set(Ecore_X_Window win, Ecore_X_Atom atom, const char *str); +Ecore_X_Visual _ecore_xcb_window_visual_get(Ecore_X_Window win); +void _ecore_xcb_window_button_grab_remove(Ecore_X_Window win); +void _ecore_xcb_window_key_grab_remove(Ecore_X_Window win); +void _ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win, Ecore_X_Window child_win, int type, void *event, Ecore_X_Time timestamp); + +int _ecore_xcb_netwm_startup_info_begin(Ecore_X_Window win __UNUSED__, uint8_t data __UNUSED__); +int _ecore_xcb_netwm_startup_info(Ecore_X_Window win __UNUSED__, uint8_t data __UNUSED__); +Ecore_X_Window_State _ecore_xcb_netwm_window_state_get(Ecore_X_Atom atom); + +int _ecore_xcb_error_handle(xcb_generic_error_t *err); +int _ecore_xcb_io_error_handle(xcb_generic_error_t *err); + +#endif diff --git a/src/lib/ecore_x/xcb/ecore_xcb_randr.c b/src/lib/ecore_x/xcb/ecore_xcb_randr.c index 84806d4..9f8b297 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_randr.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_randr.c @@ -1,566 +1,2225 @@ #include "ecore_xcb_private.h" +# ifdef ECORE_XCB_RANDR +# include +# endif -/** - * @defgroup Ecore_X_RandR_Group X RandR Extension Functions - * - * Functions related to the X RandR extension. - */ +#define Ecore_X_Randr_None 0 +#define Ecore_X_Randr_Unset -1 -#ifdef ECORE_XCB_RANDR -static int _randr_available = 0; -static xcb_randr_query_version_cookie_t _ecore_xcb_randr_init_cookie; -#endif /* ECORE_XCB_RANDR */ +/* local function prototypes */ +static Eina_Bool _ecore_xcb_randr_output_validate(Ecore_X_Window root, Ecore_X_Randr_Output output); +static Eina_Bool _ecore_xcb_randr_crtc_validate(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); +static Eina_Bool _ecore_xcb_randr_root_validate(Ecore_X_Window root); +static int _ecore_xcb_randr_root_to_screen(Ecore_X_Window root); + +/* local variables */ +static Eina_Bool _randr_avail = EINA_FALSE; +static int _randr_version = -1; -/* To avoid round trips, the initialization is separated in 2 - functions: _ecore_xcb_randr_init and - _ecore_xcb_randr_init_finalize. The first one gets the cookies and - the second one gets the replies and set the atoms. */ +/* external variables */ +int _ecore_xcb_event_randr = -1; -void -_ecore_x_randr_init(const xcb_query_extension_reply_t *reply) +void +_ecore_xcb_randr_init(void) { -#ifdef ECORE_XCB_RANDR - if (reply && (reply->present)) - _ecore_xcb_randr_init_cookie = xcb_randr_query_version_unchecked(_ecore_xcb_conn, 1, 2); + LOGFN(__FILE__, __LINE__, __FUNCTION__); -#endif /* ECORE_XCB_RANDR */ -} /* _ecore_x_randr_init */ +#ifdef ECORE_XCB_RANDR + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_randr_id); +#endif +} -void -_ecore_x_randr_init_finalize(void) +void +_ecore_xcb_randr_finalize(void) { #ifdef ECORE_XCB_RANDR - xcb_randr_query_version_reply_t *reply; + const xcb_query_extension_reply_t *ext_reply; +#endif - reply = xcb_randr_query_version_reply(_ecore_xcb_conn, - _ecore_xcb_randr_init_cookie, NULL); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (reply) +#ifdef ECORE_XCB_RANDR + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_randr_id); + if ((ext_reply) && (ext_reply->present)) { - if ((reply->major_version >= 1) && - (reply->minor_version >= 1)) - _randr_available = 1; + xcb_randr_query_version_cookie_t cookie; + xcb_randr_query_version_reply_t *reply; + + cookie = + xcb_randr_query_version_unchecked(_ecore_xcb_conn, + XCB_RANDR_MAJOR_VERSION, + XCB_RANDR_MINOR_VERSION); + reply = xcb_randr_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if ((reply->major_version >= XCB_RANDR_MAJOR_VERSION) && + (reply->minor_version >= XCB_RANDR_MINOR_VERSION)) + _randr_avail = EINA_TRUE; - free(reply); - } + _randr_version = + ((reply->major_version << 16) | reply->minor_version); -#endif /* ECORE_XCB_RANDR */ -} /* _ecore_x_randr_init_finalize */ + free(reply); + } -/** - * Return whether the X server supports the RandR Extension. - * @return 1 if the X RandR Extension is available, 0 otherwise. - * - * Return 1 if the X server supports the RandR Extension version 1.1, - * 0 otherwise. - * @ingroup Ecore_X_RandR_Group - */ -EAPI Eina_Bool -ecore_x_randr_query(void) + if (_randr_avail) + _ecore_xcb_event_randr = ext_reply->first_event; + } +#endif +} + +static Eina_Bool +_ecore_xcb_randr_root_validate(Ecore_X_Window root) { #ifdef ECORE_XCB_RANDR - return _randr_available; -#else /* ifdef ECORE_XCB_RANDR */ - return 0; -#endif /* ECORE_XCB_RANDR */ -} /* ecore_x_randr_query */ + Ecore_X_Randr_Screen scr = -1; +# define RANDR_VALIDATE_ROOT(screen, root) \ + ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if ((root) && RANDR_VALIDATE_ROOT(scr, root)) + return EINA_TRUE; +#endif -static Ecore_X_Window -_xcb_randr_root_to_screen(Ecore_X_Window root) + return EINA_FALSE; +} + +static int +_ecore_xcb_randr_root_to_screen(Ecore_X_Window root) { - xcb_screen_iterator_t iter; + int count = 0, num = 0; - iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); - for (; iter.rem; xcb_screen_next(&iter)) - { - if (iter.data->root == root) - return iter.data->root; - } + count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); + for (num = 0; num < count; num++) + if (_ecore_xcb_window_root_of_screen_get(num) == root) + return num; - return XCB_NONE; -} /* _xcb_randr_root_to_screen */ + return -1; +} + +/* public functions */ -/** - * Select if the ScreenChangeNotify events will be sent. - * @param window The window. - * @param on 1 to enable, 0 to disable. - * @return 1 on success, 0 otherwise. - * - * If @p on value is @c 1, ScreenChangeNotify events - * will be sent when the screen configuration changes, either from - * this protocol extension, or due to detected external screen - * configuration changes. ScreenChangeNotify may also be sent when - * this request executes if the screen configuration has changed since - * the client connected, to avoid race conditions. - * @ingroup Ecore_X_RandR_Group - */ /* -EAPI Eina_Bool -ecore_x_randr_events_select(Ecore_X_Window window, - int on) + * @brief query whether randr is available or not + * @return EINA_TRUE, if extension is available, else EINA_FALSE + */ +EAPI Eina_Bool +ecore_x_randr_query(void) { -#ifdef ECORE_XCB_RANDR - xcb_randr_select_input(_ecore_xcb_conn, window, - on ? XCB_RANDR_SCREEN_CHANGE_NOTIFY : 0); - return 1; -#else - return 0; -#endif -}*/ + return _randr_avail; +} -/** - * Sends the GetScreenInfo request. - * @param window Window whose properties are requested. - * @ingroup Ecore_X_RandR_Group +/* + * @return version of the RandRR extension supported by the server or, + * in case RandRR extension is not available, Ecore_X_Randr_Unset (=-1). + * bit version information: 31 MAJOR 16 | 15 MINOR 0 */ -EAPI void -ecore_x_randr_get_screen_info_prefetch(Ecore_X_Window window) +EAPI int +ecore_x_randr_version_get(void) { -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, - _xcb_randr_root_to_screen(window)); - _ecore_xcb_cookie_cache(cookie.sequence); -#endif /* ECORE_XCB_RANDR */ -} /* ecore_x_randr_get_screen_info_prefetch */ + return _randr_version; +} -/** - * Gets the reply of the GetScreenInfo request sent by ecore_x_randr_get_screen_info_prefetch(). - * @ingroup Ecore_X_RandR_Group +/* + * @param root window which's primary output will be queried */ -EAPI void -ecore_x_randr_get_screen_info_fetch(void) +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root) { + int ret = Ecore_X_Randr_None; #ifdef ECORE_XCB_RANDR xcb_randr_get_screen_info_cookie_t cookie; xcb_randr_get_screen_info_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -#endif /* ECORE_XCB_RANDR */ -} /* ecore_x_randr_get_screen_info_fetch */ + if (reply) + { + ret = reply->rotations; + free(reply); + } +#endif + + return ret; +} -/** - * Get the set of rotations and reflections. - * @param root The window (Unused). - * @return The set of rotations and reflections. - * - * Get the set of rotations and reflections supported by the screen - * associated to @p window (passed to - * ecore_x_randr_get_screen_info_prefetch()). - * - * To use this function, you must call before, and in order, - * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request, - * then ecore_x_randr_get_screen_info_fetch(), which gets the reply. - * @ingroup Ecore_X_RandR_Group - */ /* -EAPI Ecore_X_Randr_Rotation -ecore_x_randr_screen_rotations_get(Ecore_X_Window root __UNUSED__) + * @param root window which's primary output will be queried + * @return the current orientation of the root window's screen primary output + */ +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root) { + int ret = Ecore_X_Randr_None; #ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; xcb_randr_get_screen_info_reply_t *reply; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return reply->rotations; -#else - return 0; +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = reply->rotation; + free(reply); + } #endif -}*/ -/** - * Get the rotation. - * @param root The window (Unused). - * @return The rotation. - * - * Get the rotation supported by the screen - * associated to @p window (passed to - * ecore_x_randr_get_screen_info_prefetch()). - * - * To use this function, you must call before, and in order, - * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request, - * then ecore_x_randr_get_screen_info_fetch(), which gets the reply. - * @ingroup Ecore_X_RandR_Group - */ + return ret; +} + /* -EAPI Ecore_X_Randr_Rotation -ecore_x_randr_screen_rotation_get(Ecore_X_Window root __UNUSED__) + * @brief sets a given screen's primary output's orientation + * @param root window which's screen's primary output will be queried + * @param orientation orientation which should be set for the root window's screen primary output + * @return EINA_TRUE if the primary output's orientation could be successfully altered + */ +EAPI Eina_Bool +ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Orientation orientation) { + int ret = EINA_FALSE; #ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; xcb_randr_get_screen_info_reply_t *reply; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return reply->rotation; -#else - return 0; +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_set_screen_config_cookie_t scookie; + xcb_randr_set_screen_config_reply_t *sreply; + + scookie = + xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, + XCB_CURRENT_TIME, + reply->config_timestamp, + reply->sizeID, orientation, + reply->rate); + sreply = + xcb_randr_set_screen_config_reply(_ecore_xcb_conn, scookie, NULL); + if (!sreply) + ret = EINA_FALSE; + else + { + ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? + EINA_TRUE : EINA_FALSE; + free(sreply); + } + free(reply); + } #endif -}*/ -/** - * Get the frame buffer sizes. - * @param root The window (Unused). - * @param num The number of sizes. - * @return The sizes. - * - * Get the list of possible frame buffer sizes (at the normal - * orientation supported by the screen associated to @p window (passed - * to ecore_x_randr_get_screen_info_prefetch()). Each size indicates - * both the linear physical size of the screen and the pixel size. - * - * To use this function, you must call before, and in order, - * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request, - * then ecore_x_randr_get_screen_info_fetch(), which gets the reply. - * @ingroup Ecore_X_RandR_Group - */ + return ret; +} + /* -EAPI Ecore_X_Screen_Size * -ecore_x_randr_screen_sizes_get(Ecore_X_Window root __UNUSED__, - int *num) + * @brief gets a screen's primary output's possible sizes + * @param root window which's primary output will be queried + * @param num number of sizes reported as supported by the screen's primary output + * @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL + */ +EAPI Ecore_X_Randr_Screen_Size_MM * +ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, int *num) { #ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; xcb_randr_get_screen_info_reply_t *reply; - xcb_randr_screen_size_t *sizes; - Ecore_X_Screen_Size *ret; - int n; - int i; - - if (num) - *num = 0; + Ecore_X_Randr_Screen_Size_MM *ret = NULL; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return NULL; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - n = xcb_randr_get_screen_info_sizes_length(reply); - ret = calloc(n, sizeof(Ecore_X_Screen_Size)); - if (!ret) - return NULL; +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int len = 0, i = 0; + xcb_randr_screen_size_t *sizes; - if (num) - *num = n; + len = xcb_randr_get_screen_info_sizes_length(reply); + sizes = xcb_randr_get_screen_info_sizes(reply); + if ((!sizes) || (len <= 0)) + { + free(reply); + return NULL; + } + if (num) *num = len; + ret = calloc(len, sizeof(Ecore_X_Randr_Screen_Size_MM)); + if (!ret) + { + free(reply); + return NULL; + } + for (i = 0; i < len; i++) + { + ret[i].width = sizes[i].width; + ret[i].height = sizes[i].height; + ret[i].width_mm = sizes[i].mwidth; + ret[i].height_mm = sizes[i].mheight; + } - sizes = xcb_randr_get_screen_info_sizes(reply); - for (i = 0; i < n; i++) - { - ret[i].width = sizes[i].width; - ret[i].height = sizes[i].height; + free(reply); } return ret; #else - if (num) - *num = 0; - return NULL; #endif -}*/ +} -/** - * Get the current frame buffer size. - * @param root The window (Unused). - * @return The active size. - * - * Get the active frame buffer size supported by the screen associated - * to @p window (passed to - * ecore_x_randr_get_screen_info_prefetch()). - * - * To use this function, you must call before, and in order, - * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request, - * then ecore_x_randr_get_screen_info_fetch(), which gets the reply. - * @ingroup Ecore_X_RandR_Group - */ /* -EAPI Ecore_X_Screen_Size -ecore_x_randr_current_screen_size_get(Ecore_X_Window root __UNUSED__) + * @brief get the current set size of a given screen's primary output + * @param root window which's primary output will be queried + * @param w the current size's width + * @param h the current size's height + * @param w_mm the current size's width in mm + * @param h_mm the current size's height in mm + * @param size_index of current set size to be used with ecore_x_randr_primary_output_size_set() + */ +EAPI void +ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm, int *size_index) { - Ecore_X_Screen_Size ret = { -1, -1 }; #ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; xcb_randr_get_screen_info_reply_t *reply; - xcb_randr_screen_size_t *sizes; - uint16_t size_index; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return ret; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - size_index = reply->sizeID; - sizes = xcb_randr_get_screen_info_sizes(reply); - if (size_index < reply->nSizes) +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) { - ret.width = sizes[size_index].mwidth; - ret.height = sizes[size_index].mheight; + int len = 0, idx = 0; + xcb_randr_screen_size_t *sizes; + + len = xcb_randr_get_screen_info_sizes_length(reply); + sizes = xcb_randr_get_screen_info_sizes(reply); + if ((!sizes) || (len <= 0)) + { + free(reply); + return; + } + idx = reply->sizeID; + if ((idx < len) && (idx >= 0)) + { + if (w) *w = sizes[idx].width; + if (h) *h = sizes[idx].height; + if (w_mm) *w_mm = sizes[idx].mwidth; + if (h_mm) *h_mm = sizes[idx].mheight; + if (size_index) *size_index = idx; + } + + free(reply); } +#endif +} +/* + * @brief sets a given screen's primary output size, but disables all other outputs at the same time + * @param root window which's primary output will be queried + * @param size_index within the list of sizes reported as supported by the root window's screen primary output + * @return EINA_TRUE on success, EINA_FALSE on failure due to e.g. invalid times + */ +EAPI Eina_Bool +ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, int size_index) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; #endif + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!((size_index >= 0) && (_ecore_xcb_randr_root_validate(root)))) + return EINA_FALSE; + + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int len = 0; + + len = xcb_randr_get_screen_info_sizes_length(reply); + if (len <= 0) + { + free(reply); + return EINA_FALSE; + } + if ((size_index < len) && (size_index >= 0)) + { + xcb_randr_set_screen_config_cookie_t scookie; + xcb_randr_set_screen_config_reply_t *sreply; + + scookie = + xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, + XCB_CURRENT_TIME, + reply->config_timestamp, + size_index, + reply->rotation, + reply->rate); + sreply = + xcb_randr_set_screen_config_reply(_ecore_xcb_conn, + scookie, NULL); + if (!sreply) + ret = EINA_FALSE; + else + { + ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? + EINA_TRUE : EINA_FALSE; + free(sreply); + } + } + + free(reply); + } +#endif return ret; -}*/ +} -/** - * Get the current refresh rate. - * @param root The window (Unused). - * @return The current refresh rate. - * - * Get the current refresh rate supported by the screen associated - * to @p window (passed to - * ecore_x_randr_get_screen_info_prefetch()). - * - * To use this function, you must call before, and in order, - * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request, - * then ecore_x_randr_get_screen_info_fetch(), which gets the reply. - * @ingroup Ecore_X_RandR_Group - */ /* -EAPI Ecore_X_Screen_Refresh_Rate -ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root __UNUSED__) + * @param root window which's primary output will be queried + * @return currently used refresh rate or - if request failed or RandRR is not available - 0.0 + */ +EAPI Ecore_X_Randr_Refresh_Rate +ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root) { - Ecore_X_Screen_Refresh_Rate ret = { -1 }; #ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; xcb_randr_get_screen_info_reply_t *reply; + Ecore_X_Randr_Refresh_Rate ret = 0.0; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return ret; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - ret.rate = reply->rate; -#endif +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_root_validate(root)) return ret; + + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = reply->rate; + free(reply); + } return ret; -}*/ +#else + return 0.0; +#endif +} -/** - * Get the refresh rates. - * @param root The window (Unused). - * @param num The number of refresh rates. - * @return The refresh rates. - * - * Get the list of refresh rates for each size supported by the screen - * associated to @p window (passed to - * ecore_x_randr_get_screen_info_prefetch()). Each element - * of 'sizes' has a corresponding element in 'refresh'. An empty list - * indicates no known rates, or a device for which refresh is not - * relevant. - * - * To use this function, you must call before, and in order, - * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request, - * then ecore_x_randr_get_screen_info_fetch(), which gets the reply. - * @ingroup Ecore_X_RandR_Group - */ /* -EAPI Ecore_X_Screen_Refresh_Rate * -ecore_x_randr_screen_refresh_rates_get(Ecore_X_Window root __UNUSED__, - int size_id __UNUSED__, - int *num) + * @param root window which's primary output will be queried + * @param size_index referencing the size to query valid refresh rates for + * @return currently used refresh rate or - if request failed or RandRR is not available - NULL + */ +EAPI Ecore_X_Randr_Refresh_Rate * +ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, int size_index, int *num) { #ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; xcb_randr_get_screen_info_reply_t *reply; - Ecore_X_Screen_Refresh_Rate *ret; - Ecore_X_Screen_Refresh_Rate *tmp; - xcb_randr_refresh_rates_iterator_t iter; - uint16_t n; + Ecore_X_Randr_Refresh_Rate *ret = NULL; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (num) - *num = 0; +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_root_validate(root)) return ret; + + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int len = 0; - reply = _ecore_xcb_reply_get(); - if (!reply) - return NULL; + len = xcb_randr_get_screen_info_rates_length(reply); + if (num) *num = len; - n = reply->nSizes; - ret = calloc(n, sizeof(Ecore_X_Screen_Refresh_Rate)); - if (!ret) - return NULL; + ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * len); + if (ret) + { + xcb_randr_refresh_rates_iterator_t iter; + int i = 0; - if (num) - *num = n; + iter = xcb_randr_get_screen_info_rates_iterator(reply); + while (i++ < size_index) + xcb_randr_refresh_rates_next(&iter); - iter = xcb_randr_get_screen_info_rates_iterator(reply); - tmp = ret; - for (; iter.rem; xcb_randr_refresh_rates_next(&iter), tmp++) - { - tmp->rate = iter.data->nRates; + memcpy(ret, xcb_randr_refresh_rates_rates(iter.data), + sizeof(Ecore_X_Randr_Refresh_Rate) * len); + } + free(reply); } return ret; #else - if (num) - *num = 0; - return NULL; #endif -}*/ - -/* FIXME: round trip. Should we remove it ? */ +} -/** - * Set the screen rotation. - * @param root The root window. - * @param rot The rotation. - * - * Set the rotation of the screen associated to @p root. - * - * Note that that function is blocking. - * @ingroup Ecore_X_RandR_Group - */ /* -EAPI void -ecore_x_randr_screen_rotation_set(Ecore_X_Window root, - Ecore_X_Randr_Rotation rot) + * @brief sets the current primary output's refresh rate + * @param root window which's primary output will be queried + * @param size_index referencing the size to be set + * @param rate the refresh rate to be set + * @return EINA_TRUE on success else EINA_FALSE + */ +EAPI Eina_Bool +ecore_x_randr_screen_primary_output_refresh_rate_set(Ecore_X_Window root, int size_index, Ecore_X_Randr_Refresh_Rate rate) { + Eina_Bool ret = EINA_FALSE; #ifdef ECORE_XCB_RANDR - xcb_randr_set_screen_config_cookie_t cookie; - xcb_randr_set_screen_config_reply_t *reply_config; + xcb_randr_get_screen_info_cookie_t cookie; xcb_randr_get_screen_info_reply_t *reply; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return; - - cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, - XCB_CURRENT_TIME, - reply->config_timestamp, - reply->sizeID, - rot, - 0); - reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL); - if (reply_config) - free(reply_config); + LOGFN(__FILE__, __LINE__, __FUNCTION__); +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_set_screen_config_cookie_t scookie; + xcb_randr_set_screen_config_reply_t *sreply; + + scookie = + xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, + XCB_CURRENT_TIME, + reply->config_timestamp, + size_index, + reply->rotation, rate); + sreply = + xcb_randr_set_screen_config_reply(_ecore_xcb_conn, + scookie, NULL); + if (!sreply) + ret = EINA_FALSE; + else + { + ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? + EINA_TRUE : EINA_FALSE; + free(sreply); + } + free(reply); + } #endif -}*/ -/* FIXME: round trip. Should we remove it ? */ + return ret; +} -/** - * Set the screen size. - * @param root The root window. - * @param size The size. - * - * Set the size of the screen associated to @p root. - * - * Note that that function is blocking. - * @ingroup Ecore_X_RandR_Group +/* + * @brief free detailed mode information. The pointer handed in will be set to + * NULL after freeing the memory. + * @param mode_info the mode information that should be freed */ +EAPI void +ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!mode_info) return; + + if (mode_info->name) free(mode_info->name); + free(mode_info); + mode_info = NULL; +} + /* -EAPI int -ecore_x_randr_screen_size_set(Ecore_X_Window root, - Ecore_X_Screen_Size size) + * @param root window which's screen should be queried + * @return Ecore_X_Randr_Ouptut_Id or - if query failed or none is set - Ecore_X_Randr_None + */ +EAPI Ecore_X_Randr_Output +ecore_x_randr_primary_output_get(Ecore_X_Window root) +{ + Ecore_X_Randr_Output ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_output_primary_cookie_t cookie; + xcb_randr_get_output_primary_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_root_validate(root)) + return Ecore_X_Randr_None; + + cookie = xcb_randr_get_output_primary_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_output_primary_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = reply->output; + free(reply); + } +#endif + return ret; +} + +EAPI Ecore_X_Randr_Mode * +ecore_x_randr_output_modes_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num, int *npreferred) { + Ecore_X_Randr_Mode *modes = NULL; #ifdef ECORE_XCB_RANDR - xcb_randr_set_screen_config_cookie_t cookie; - xcb_randr_set_screen_config_reply_t *reply_config; + xcb_randr_get_screen_info_cookie_t cookie; xcb_randr_get_screen_info_reply_t *reply; - xcb_randr_screen_size_iterator_t iter; - int size_index = -1; - int i; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - iter = xcb_randr_get_screen_info_sizes_iterator(reply); - for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++) +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) { - if ((iter.data->width = size.width) && - (iter.data->height = size.height) && - (iter.data->mwidth = size.width) && - (iter.data->mheight = size.height)) + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) { - size_index = i; - break; + if (num) *num = oreply->num_modes; + if (npreferred) *npreferred = oreply->num_preferred; + + modes = malloc(sizeof(Ecore_X_Randr_Mode) * oreply->num_modes); + if (modes) + { + xcb_randr_mode_t *rmodes; + int len = 0; + + len = xcb_randr_get_output_info_modes_length(oreply); + rmodes = xcb_randr_get_output_info_modes(oreply); + memcpy(modes, rmodes, sizeof(Ecore_X_Randr_Mode) * len); + } + free(oreply); } + free(reply); } - if (size_index == -1) - return 0; +#endif - cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, - XCB_CURRENT_TIME, - reply->config_timestamp, - size_index, - XCB_RANDR_ROTATION_ROTATE_0, - 0); - reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply_config) - return 0; + return modes; +} - free(reply_config); +/* + * @brief get detailed information for a given mode id + * @param root window which's screen's ressources are queried + * @param mode the XID which identifies the mode of interest + * @return mode's detailed information + */ +EAPI Ecore_X_Randr_Mode_Info * +ecore_x_randr_mode_info_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode) +{ + Ecore_X_Randr_Mode_Info *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif - return 1; -#else - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_root_validate(root)) return NULL; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)); + if (ret) + { + uint8_t *nbuf; + xcb_randr_mode_info_iterator_t miter; + + nbuf = xcb_randr_get_screen_resources_names(reply); + miter = xcb_randr_get_screen_resources_modes_iterator(reply); + while (miter.rem) + { + xcb_randr_mode_info_t *minfo; + + minfo = miter.data; + nbuf += minfo->name_len; + + if (minfo->id == mode) + { + ret->xid = minfo->id; + ret->width = minfo->width; + ret->height = minfo->height; + ret->dotClock = minfo->dot_clock; + ret->hSyncStart = minfo->hsync_start; + ret->hSyncEnd = minfo->hsync_end; + ret->hTotal = minfo->htotal; + ret->vSyncStart = minfo->vsync_start; + ret->vSyncEnd = minfo->vsync_end; + ret->vTotal = minfo->vtotal; + ret->modeFlags = minfo->mode_flags; + + ret->name = NULL; + ret->nameLength = minfo->name_len; + if (ret->nameLength > 0) + { + ret->name = malloc(ret->nameLength + 1); + if (ret->name) + memcpy(ret->name, nbuf, ret->nameLength + 1); + } + + break; + } + xcb_randr_mode_info_next(&miter); + } + } + + free(reply); + } +#endif + return ret; +} + +/** + * @brief gets the EDID information of an attached output if available. + * Note that this information is not to be compared using ordinary string + * comparison functions, since it includes 0-bytes. + * @param root window this information should be queried from + * @param output the XID of the output + * @param length length of the byte-array. If NULL, request will fail. + */ +EAPI unsigned char * +ecore_x_randr_output_edid_get(Ecore_X_Window root, Ecore_X_Randr_Output output, unsigned long *length) +{ + unsigned char *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_output_property_cookie_t cookie; + xcb_randr_get_output_property_reply_t *reply; + Ecore_X_Atom atom; #endif -}*/ -/* FIXME: round trip. Should we remove it ? */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if ((!length) || (!_ecore_xcb_randr_output_validate(root, output))) + return NULL; + + atom = ecore_x_atom_get("EDID"); + cookie = + xcb_randr_get_output_property_unchecked(_ecore_xcb_conn, output, atom, + XCB_GET_PROPERTY_TYPE_ANY, + 0, 100, 0, 0); + reply = + xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if ((reply->type == XCB_ATOM_INTEGER) && (reply->format == 8)) + { + if (length) *length = reply->num_items; + if ((ret = malloc(reply->num_items * sizeof(unsigned char)))) + { + memcpy(ret, xcb_randr_get_output_property_data(reply), + (reply->num_items * sizeof(unsigned char))); + } + } + free(reply); + } +#endif + return ret; +} /** - * Set the screen refresh rate. - * @param root The root window. - * @param size The size. - * @param rate The refresh rate. - * - * Set the size and the refresh rate of the screen associated to - * @p root. - * - * Note that that function is blocking. - * @ingroup Ecore_X_RandR_Group + * @brief gets the the outputs which might be used simultenously on the same + * CRTC. + * @param root window that this information should be queried for. + * @param output the output which's clones we concern + * @param num number of possible clones */ -/* -EAPI int -ecore_x_randr_screen_refresh_rate_set(Ecore_X_Window root, - Ecore_X_Screen_Size size, - Ecore_X_Screen_Refresh_Rate rate) +EAPI Ecore_X_Randr_Output * +ecore_x_randr_output_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num) { + Ecore_X_Randr_Output *outputs = NULL; #ifdef ECORE_XCB_RANDR - xcb_randr_set_screen_config_cookie_t cookie; - xcb_randr_set_screen_config_reply_t *reply_config; - xcb_randr_get_screen_info_reply_t *reply; - xcb_randr_screen_size_iterator_t iter; - int size_index = -1; - int i; + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - iter = xcb_randr_get_screen_info_sizes_iterator(reply); - for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++) +#ifdef ECORE_XCB_RANDR + if (output == Ecore_X_Randr_None) return NULL; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) { - if ((iter.data->width = size.width) && - (iter.data->height = size.height) && - (iter.data->mwidth = size.width) && - (iter.data->mheight = size.height)) + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) { - size_index = i; - break; + if (num) *num = oreply->num_clones; + + outputs = + malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_clones); + if (outputs) + { + memcpy(outputs, xcb_randr_get_output_info_clones(oreply), + sizeof(Ecore_X_Randr_Output) * oreply->num_clones); + } + free(oreply); } + free(reply); } - if (size_index == -1) - return 0; +#endif + return outputs; +} - cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, - XCB_CURRENT_TIME, - reply->config_timestamp, - size_index, - XCB_RANDR_ROTATION_ROTATE_0, - rate.rate); - reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply_config) - return 0; +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num) +{ + Ecore_X_Randr_Crtc *crtcs = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif - free(reply_config); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return 1; -#else - return 0; +#ifdef ECORE_XCB_RANDR + if (output == Ecore_X_Randr_None) return NULL; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_crtcs; + + crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); + if (crtcs) + { + memcpy(crtcs, xcb_randr_get_output_info_crtcs(oreply), + sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); + } + free(oreply); + } + free(reply); + } #endif -}*/ + return crtcs; +} +/** + * @brief gets the given output's name as reported by X + * @param root the window which's screen will be queried + * @param len length of returned c-string. + * @return name of the output as reported by X + */ +EAPI char * +ecore_x_randr_output_name_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *len) +{ + char *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (output == Ecore_X_Randr_None) return NULL; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + uint8_t *nbuf; + + nbuf = xcb_randr_get_output_info_name(oreply); + nbuf += oreply->name_len; + + if (len) *len = oreply->name_len; + if (oreply->name_len > 0) + { + ret = malloc(oreply->name_len + 1); + if (ret) + memcpy(ret, nbuf, oreply->name_len + 1); + } + + free(oreply); + } + free(reply); + } +#endif + + return ret; +} + +EAPI Ecore_X_Randr_Connection_Status +ecore_x_randr_output_connection_status_get(Ecore_X_Window root, Ecore_X_Randr_Output output) +{ + Ecore_X_Randr_Connection_Status ret = ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (output == Ecore_X_Randr_None) return ret; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + ret = oreply->connection; + free(oreply); + } + free(reply); + } +#endif + + return ret; +} + +EAPI Ecore_X_Randr_Output * +ecore_x_randr_outputs_get(Ecore_X_Window root, int *num) +{ + Ecore_X_Randr_Output *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (num) *num = reply->num_outputs; + ret = malloc(sizeof(Ecore_X_Randr_Output) * reply->num_outputs); + if (ret) + memcpy(ret, xcb_randr_get_screen_resources_outputs(reply), + sizeof(Ecore_X_Randr_Output) * reply->num_outputs); + free(reply); + } +#endif + + return ret; +} + +EAPI Ecore_X_Randr_Crtc +ecore_x_randr_output_crtc_get(Ecore_X_Window root, Ecore_X_Randr_Output output) +{ + Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (output == Ecore_X_Randr_None) return ret; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + ret = oreply->crtc; + free(oreply); + } + free(reply); + } +#endif + + return ret; +} + +/** + * @brief sets the demanded parameters for a given CRTC. Note that the CRTC is + * auto enabled in it's preferred mode, when it was disabled before. + * @param root the root window which's default display will be queried + * @param crtc the CRTC which's configuration should be altered + * @param outputs an array of outputs, that should display this CRTC's content. + * @param noutputs number of outputs in the array of outputs. + * If set to Ecore_X_Randr_Unset, current outputs and number of outputs will be used. + * If set to Ecore_X_Randr_None, CRTC will be disabled + * @param x new x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x + * corrdinate will be assumed. + * @param y new y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y + * corrdinate will be assumed. + * @param mode the new mode to be set. If Ecore_X_Randr_None is passed, the + * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is assumed. + * @param orientation the new orientation to be set. If Ecore_X_Randr_Unset is used, + * the current mode is assumed. + * @return EINA_TRUE if the configuration alteration was successful, else + * EINA_FALSE + */ +EAPI Eina_Bool +ecore_x_randr_crtc_settings_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int num, int x, int y, Ecore_X_Randr_Mode mode, Ecore_X_Randr_Orientation orientation) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_crtc_info_cookie_t ccookie; + xcb_randr_get_crtc_info_reply_t *creply; + + ccookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, + reply->config_timestamp); + creply = + xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ccookie, NULL); + if (creply) + { + xcb_randr_set_crtc_config_cookie_t scookie; + xcb_randr_set_crtc_config_reply_t *sreply; + + if ((mode == Ecore_X_Randr_None) || (num == Ecore_X_Randr_None)) + { + outputs = NULL; + num = 0; + } + else if (num == (int)Ecore_X_Randr_Unset) + { + outputs = xcb_randr_get_crtc_info_outputs(creply); + num = creply->num_outputs; + } + if ((int)mode == Ecore_X_Randr_Unset) mode = creply->mode; + if (x < 0) x = creply->x; + if (y < 0) y = creply->y; + if ((int)orientation == Ecore_X_Randr_Unset) + orientation = creply->rotation; + + scookie = + xcb_randr_set_crtc_config_unchecked(_ecore_xcb_conn, + crtc, XCB_CURRENT_TIME, + reply->config_timestamp, + x, y, mode, orientation, + num, outputs); + sreply = + xcb_randr_set_crtc_config_reply(_ecore_xcb_conn, scookie, NULL); + if (sreply) + { + ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? + EINA_TRUE : EINA_FALSE; + free(sreply); + } + free(creply); + } + free(reply); + } +#endif + + return ret; +} + +/** + * @brief sets a mode for a CRTC and the outputs attached to it + * @param root the window's screen to be queried + * @param crtc the CRTC which shall be set + * @param outputs array of outputs which have to be compatible with the mode. If + * NULL CRTC will be disabled. + * @param noutputs number of outputs in array to be used. Use + * Ecore_X_Randr_Unset (or -1) to use currently used outputs. + * @param mode XID of the mode to be set. If set to 0 the CRTC will be disabled. + * If set to -1 the call will fail. + * @return EINA_TRUE if mode setting was successful. Else EINA_FALSE + */ +EAPI Eina_Bool +ecore_x_randr_crtc_mode_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int num, Ecore_X_Randr_Mode mode) +{ + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if ((int)mode == Ecore_X_Randr_Unset) return ret; + ret = + ecore_x_randr_crtc_settings_set(root, crtc, outputs, num, + Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, + mode, Ecore_X_Randr_Unset); +#endif + + return ret; +} + +/** + * @brief Get the current set mode of a given CRTC + * @param root the window's screen to be queried + * @param crtc the CRTC which's should be queried + * @return currently set mode or - in case parameters are invalid - + * Ecore_X_Randr_Unset + */ +EAPI Ecore_X_Randr_Mode +ecore_x_randr_crtc_mode_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc) +{ + Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, + reply->config_timestamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + ret = oreply->mode; + free(oreply); + } + free(reply); + } +#endif + + return ret; +} + +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc) +{ + Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, + reply->config_timestamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + ret = oreply->rotation; + free(oreply); + } + free(reply); + } +#endif + + return ret; +} + +/* + * @brief get a CRTC's possible outputs. + * @param root the root window which's screen will be queried + * @param num number of possible outputs referenced by given CRTC + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num) +{ + Ecore_X_Randr_Output *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, + reply->config_timestamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_possible_outputs; + ret = malloc(sizeof(Ecore_X_Randr_Output) * + oreply->num_possible_outputs); + if (ret) + { + memcpy(ret, xcb_randr_get_crtc_info_possible(oreply), + sizeof(Ecore_X_Randr_Output) * + oreply->num_possible_outputs); + } + free(oreply); + } + free(reply); + } +#endif + + return ret; +} + +/* + * @brief get all known CRTCs related to a root window's screen + * @param root window which's screen's ressources are queried + * @param num number of CRTCs returned + * @return CRTC IDs + */ +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_crtcs_get(Ecore_X_Window root, int *num) +{ + Ecore_X_Randr_Crtc *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (num) *num = reply->num_crtcs; + ret = malloc(sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); + if (ret) + memcpy(ret, xcb_randr_get_screen_resources_crtcs(reply), + sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); + free(reply); + } +#endif + + return ret; +} + +/* + * @brief get a CRTC's outputs. + * @param root the root window which's screen will be queried + * @param num number of outputs referenced by given CRTC + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num) +{ + Ecore_X_Randr_Output *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, + reply->config_timestamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_outputs; + ret = malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_outputs); + if (ret) + memcpy(ret, xcb_randr_get_crtc_info_outputs(oreply), + sizeof(Ecore_X_Randr_Output) * oreply->num_outputs); + free(oreply); + } + free(reply); + } +#endif + + return ret; +} + +EAPI void +ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, + reply->config_timestamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + if (x) *x = oreply->x; + if (y) *y = oreply->y; + if (w) *w = oreply->width; + if (h) *h = oreply->height; + free(oreply); + } + free(reply); + } +#endif +} + +/** + * @brief sets a CRTC relative to another one. + * @param crtc_r1 the CRTC to be positioned. + * @param crtc_r2 the CRTC the position should be relative to + * @param position the relation between the crtcs + * @param alignment in case CRTCs size differ, aligns CRTC1 accordingly at CRTC2's + * borders + * @return EINA_TRUE if crtc could be successfully positioned. EINA_FALSE if + * repositioning failed or if position of new crtc would be out of given screen's min/max bounds. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc1, Ecore_X_Randr_Crtc crtc2, Ecore_X_Randr_Output_Policy policy, Ecore_X_Randr_Relative_Alignment alignment) +{ +#ifdef ECORE_XCB_RANDR + Eina_Rectangle r1, r2; + int w_max = 0, h_max = 0, cw = 0, ch = 0, xn = -1, yn = -1; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if ((ecore_x_randr_crtc_mode_get(root, crtc1) == 0) || + (ecore_x_randr_crtc_mode_get(root, crtc2) == 0)) + return EINA_FALSE; + + if ((!_ecore_xcb_randr_crtc_validate(root, crtc1) || + (!(crtc1 != crtc2) && (!_ecore_xcb_randr_crtc_validate(root, crtc2))))) + return EINA_FALSE; + + ecore_x_randr_crtc_geometry_get(root, crtc1, &r1.x, &r1.y, &r1.w, &r1.h); + ecore_x_randr_crtc_geometry_get(root, crtc2, &r2.x, &r2.y, &r2.w, &r2.h); + ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); + ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); + + switch (policy) + { + case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT: + xn = (r2.x + r2.w); + if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) + yn = -1; + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) + yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0))); + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) + yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0)); + break; + case ECORE_X_RANDR_OUTPUT_POLICY_LEFT: + xn = (r2.x - r1.w); + if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) + yn = -1; + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) + yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0))); + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) + yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0)); + break; + case ECORE_X_RANDR_OUTPUT_POLICY_BELOW: + yn = (r2.y + r2.h); + if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) + xn = -1; + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) + xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0))); + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) + xn = ((int)((double)cw / 2.0)); + break; + case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE: + yn = (r2.y - r1.h); + if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) + xn = -1; + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) + xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0))); + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) + xn = ((int)((double)cw / 2.0)); + break; + case ECORE_X_RANDR_OUTPUT_POLICY_CLONE: + return ecore_x_randr_crtc_pos_set(root, crtc1, r2.x, r2.y); + break; + case ECORE_X_RANDR_OUTPUT_POLICY_NONE: + break; + } + + if ((xn == r1.x) && (yn == r1.x)) return EINA_TRUE; + if (((yn + r1.h) > h_max) || ((xn + r1.w) > w_max)) + return EINA_FALSE; + + return ecore_x_randr_crtc_pos_set(root, crtc1, xn, yn); +#endif + + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, const Ecore_X_Randr_Crtc *not_moved, int num, int dx, int dy) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + Ecore_X_Randr_Crtc *crtcs = NULL, *move = NULL; + int i = 0, j = 0, k = 0, n = 0, total = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if ((num <= 0) || (!not_moved) || (!_ecore_xcb_randr_root_validate(root))) + return EINA_FALSE; + + crtcs = ecore_x_randr_crtcs_get(root, &total); + n = (total - num); + move = malloc(sizeof(Ecore_X_Randr_Crtc) * n); + if (move) + { + for (i = 0, k = 0; (i < total) && (k < n); i++) + { + for (j = 0; j < num; j++) + if (crtcs[i] == not_moved[j]) break; + if (j == num) + move[k++] = crtcs[i]; + } + ret = ecore_x_randr_move_crtcs(root, move, n, dx, dy); + free(move); + free(crtcs); + } +#endif + + return ret; +} + +/* + * @brief sets the position of given CRTC within root window's screen + * @param root the window's screen to be queried + * @param crtc the CRTC which's position within the mentioned screen is to be altered + * @param x position on the x-axis (0 == left) of the screen. if x < 0 current value will be kept. + * @param y position on the y-ayis (0 == top) of the screen. if y < 0, current value will be kept. + * @return EINA_TRUE if position could be successfully be altered. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_pos_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, int y) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + int w = 0, h = 0, nw = 0, nh = 0; + Eina_Rectangle rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + ecore_x_randr_crtc_geometry_get(root, crtc, + &rect.x, &rect.y, &rect.w, &rect.h); + ecore_x_randr_screen_current_size_get(root, &w, &h, NULL, NULL); + if (x < 0) x = rect.x; + if (y < 0) y = rect.y; + if ((x + rect.w) > w) + nw = (x + rect.w); + if ((y + rect.h) > h) + nh = (y + rect.h); + + if ((nw != 0) || (nh != 0)) + { + if (!ecore_x_randr_screen_current_size_set(root, nw, nh, 0, 0)) + return EINA_FALSE; + } + + ret = ecore_x_randr_crtc_settings_set(root, crtc, NULL, -1, x, y, -1, -1); +#endif + + return ret; +} + +/* + * @brief move given CRTCs belonging to the given root window's screen dx/dy pixels relative to their current position. The screen size will be automatically adjusted if necessary and possible. + * @param root window which's screen's resources are used + * @param crtcs list of CRTCs to be moved + * @param ncrtc number of CRTCs in array + * @param dx amount of pixels the CRTCs should be moved in x direction + * @param dy amount of pixels the CRTCs should be moved in y direction + * @return EINA_TRUE if all crtcs could be moved successfully. + */ +EAPI Eina_Bool +ecore_x_randr_move_crtcs(Ecore_X_Window root, const Ecore_X_Randr_Crtc *crtcs, int num, int dx, int dy) +{ + Eina_Bool ret = EINA_TRUE; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_root_validate(root)) return EINA_FALSE; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_get_crtc_info_reply_t *oreply[num]; + int i = 0, cw = 0, ch = 0; + int mw = 0, mh = 0, nw = 0, nh = 0; + + ecore_x_randr_screen_size_range_get(root, NULL, NULL, &mw, &mh); + ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); + nw = cw; + nh = ch; + + for (i = 0; i < num; i++) + { + xcb_randr_get_crtc_info_cookie_t ocookie; + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i], + reply->config_timestamp); + oreply[i] = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply[i]) + { + if (((oreply[i]->x + dx) < 0) || + ((oreply[i]->y + dy) < 0) || + ((oreply[i]->x + oreply[i]->width + dx) > mw) || + ((oreply[i]->y + oreply[i]->height + dy) > mh)) + { +// free(oreply[i]); + continue; + } + nw = MAX((int)(oreply[i]->x + oreply[i]->width + dx), nw); + nh = MAX((int)(oreply[i]->y + oreply[i]->height + dy), nh); +// free(oreply); + } + } + free(reply); + + if ((nw > cw) || (nh > ch)) + { + if (!ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1)) + { + for (i = 0; i < num; i++) + if (oreply[i]) free(oreply[i]); + + return EINA_FALSE; + } + } + + for (i = 0; ((i < num) && (oreply[i])); i++) + { + if (!oreply[i]) continue; + if (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1, + (oreply[i]->x + dx), + (oreply[i]->y + dy), + oreply[i]->mode, + oreply[i]->rotation)) + { + ret = EINA_FALSE; + break; + } + } + + if (i < num) + { + while (i-- >= 0) + { + if (oreply[i]) + ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1, + (oreply[i]->x - dx), + (oreply[i]->y - dy), + oreply[i]->mode, + oreply[i]->rotation); + } + } + + for (i = 0; i < num; i++) + if (oreply[i]) free(oreply[i]); + } +#endif + + return ret; +} + +/** + * @brief enable event selection. This enables basic interaction with + * output/crtc events and requires RRandR >= 1.2. + * @param win select this window's properties for RandRR events + * @param on enable/disable selecting + */ +EAPI void +ecore_x_randr_events_select(Ecore_X_Window win, Eina_Bool on) +{ +#ifdef ECORE_XCB_RANDR + uint16_t mask = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (on) + { + mask = XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE; + if (_randr_version >= ((1 << 16) | 2)) + { + mask |= (XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | + XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | + XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY); + } + } + + xcb_randr_select_input(_ecore_xcb_conn, win, mask); +#endif +} + +/** + * @brief removes unused screen space. The most upper left CRTC is set to 0x0 + * and all other CRTCs dx,dy respectively. + * @param root the window's screen which will be reset. + */ +EAPI void +ecore_x_randr_screen_reset(Ecore_X_Window root) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; + Ecore_X_Randr_Crtc *crtcs = NULL; + int total = 0, i = 0, w = 0, h = 0; + int dx = 100000, dy = 100000, num = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_root_validate(root)) return; + crtcs = ecore_x_randr_crtcs_get(root, &total); + + Ecore_X_Randr_Crtc enabled[total]; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + for (i = 0; i < total; i++) + { + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i], + reply->config_timestamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (!oreply) continue; + if ((oreply->mode <= 0) || (oreply->num_outputs == 0)) + { + free(oreply); + continue; + } + + enabled[num++] = crtcs[i]; + if ((int)(oreply->x + oreply->width) > w) + w = (oreply->x + oreply->width); + if ((int)(oreply->y + oreply->height) > h) + h = (oreply->y + oreply->height); + + if (oreply->x < dx) dx = oreply->x; + if (oreply->y < dy) dy = oreply->y; + + free(oreply); + } + free(reply); + free(crtcs); + + if ((dx > 0) || (dy > 0)) + { + if (ecore_x_randr_move_crtcs(root, enabled, num, -dx, -dy)) + { + w -= dx; + h -= dy; + } + } + + ecore_x_randr_screen_current_size_set(root, w, h, -1, -1); + } +#endif +} + +/* + * @param root window which's screen will be queried + * @param wmin minimum width the screen can be set to + * @param hmin minimum height the screen can be set to + * @param wmax maximum width the screen can be set to + * @param hmax maximum height the screen can be set to + */ +EAPI void +ecore_x_randr_screen_size_range_get(Ecore_X_Window root, int *minw, int *minh, int *maxw, int *maxh) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_size_range_cookie_t cookie; + xcb_randr_get_screen_size_range_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_size_range_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_size_range_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (minw) *minw = reply->min_width; + if (minh) *minh = reply->min_height; + if (maxw) *maxw = reply->max_width; + if (maxh) *maxh = reply->max_height; + free(reply); + } +#endif +} + +/* + * @param w width of screen in px + * @param h height of screen in px + */ +EAPI void +ecore_x_randr_screen_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; + Ecore_X_Randr_Screen scr; +# define RANDR_VALIDATE_ROOT(screen, root) \ + ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!RANDR_VALIDATE_ROOT(scr, root)) return; + + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int len = 0, idx = 0; + xcb_randr_screen_size_t *sizes; + + len = xcb_randr_get_screen_info_sizes_length(reply); + sizes = xcb_randr_get_screen_info_sizes(reply); + if ((!sizes) || (len <= 0)) + { + free(reply); + return; + } + idx = reply->sizeID; + if ((idx < len) && (idx >= 0)) + { + if (w) *w = sizes[idx].width; + if (h) *h = sizes[idx].height; + if (w_mm) *w_mm = sizes[idx].mwidth; + if (h_mm) *h_mm = sizes[idx].mheight; + } + free(reply); + } +#endif +} + +/* + * @param root window which's screen's size should be set. If invalid (e.g. NULL) no action is taken. + * @param w width in px the screen should be set to. If out of valid boundaries, current value is assumed. + * @param h height in px the screen should be set to. If out of valid boundaries, current value is assumed. + * @param w_mm width in mm the screen should be set to. If 0, current aspect is assumed. + * @param h_mm height in mm the screen should be set to. If 0, current aspect is assumed. + * @return EINA_TRUE if request was successfully sent or screen is already in + * requested size, EINA_FALSE if parameters are invalid + */ +EAPI Eina_Bool +ecore_x_randr_screen_current_size_set(Ecore_X_Window root, int w, int h, int w_mm, int h_mm) +{ + Eina_Bool ret = EINA_TRUE; +#ifdef ECORE_XCB_RANDR + Ecore_X_Randr_Screen scr; + int wc = 0, hc = 0, w_mm_c = 0, h_mm_c = 0; + int mw = 0, mh = 0, xw = 0, xh = 0; +# define RANDR_VALIDATE_ROOT(screen, root) \ + ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (!RANDR_VALIDATE_ROOT(scr, root)) return EINA_FALSE; + ecore_x_randr_screen_current_size_get(root, &wc, &hc, &w_mm_c, &h_mm_c); + if ((w == wc) && (h == hc) && (w_mm == w_mm_c) && (h_mm == h_mm_c)) + return EINA_TRUE; + ecore_x_randr_screen_size_range_get(root, &mw, &mh, &xw, &xh); + if (((w != 1) && ((w < mw) || (w > xw))) || + ((h != -1) && ((h < mh) || (h > xh)))) return EINA_FALSE; + if (w <= 0) + w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; + if (h <= 0) + h = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; + if (w_mm <= 0) + w_mm = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_millimeters; + if (h_mm <= 0) + h_mm = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_millimeters; + + xcb_randr_set_screen_size(_ecore_xcb_conn, root, w, h, w_mm, h_mm); +#endif + + return ret; +} + +/* + * @brief get the outputs, which display a certain window + * @param window window the displaying outputs shall be found for + * @param num the number of outputs displaying the window + * @return array of outputs that display a certain window. NULL if no outputs + * was found that displays the specified window. + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_window_outputs_get(Ecore_X_Window window, int *num) +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Window root; + Eina_Rectangle w_geo, c_geo; + Ecore_X_Randr_Crtc *crtcs; + Ecore_X_Randr_Mode mode; + Ecore_X_Randr_Output *outputs, *ret = NULL, *tret; + int ncrtcs, noutputs, i, nret = 0; + xcb_translate_coordinates_reply_t *trans; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (num) *num = 0; + +#ifdef ECORE_XCB_RANDR + if (_randr_version < ((1 << 16) | 2)) return NULL; + + ecore_x_window_geometry_get(window, &w_geo.x, &w_geo.y, &w_geo.w, &w_geo.h); + + root = ecore_x_window_root_get(window); + crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs); + if (!crtcs) return NULL; + + /* now get window RELATIVE to root window - thats what matters. */ + trans = + xcb_translate_coordinates_reply(_ecore_xcb_conn, + xcb_translate_coordinates(_ecore_xcb_conn, + window, root, 0, 0), + NULL); + w_geo.x = trans->dst_x; + w_geo.y = trans->dst_y; + free(trans); + + for (i = 0; i < ncrtcs; i++) + { + /* if crtc is not enabled, don't bother about it any further */ + mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]); + if (mode == Ecore_X_Randr_None) continue; + + ecore_x_randr_crtc_geometry_get(root, crtcs[i], &c_geo.x, &c_geo.y, + &c_geo.w, &c_geo.h); + if (eina_rectangles_intersect(&w_geo, &c_geo)) + { + outputs = + ecore_x_randr_crtc_outputs_get(root, crtcs[i], &noutputs); + /* The case below should be impossible, but for safety reasons + * remains */ + if (!outputs) + { + if (num) *num = 0; + free(ret); + free(crtcs); + return NULL; + } + tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output))); + if (!tret) + { + if (num) *num = 0; + free(outputs); + free(ret); + free(crtcs); + return NULL; + } + ret = tret; + memcpy(&ret[nret], outputs, + (noutputs * sizeof(Ecore_X_Randr_Output))); + nret += noutputs; + free(outputs); + } + } + free(crtcs); + + if (num) *num = nret; + return ret; + +#endif + if (num) *num = 0; + return NULL; +} + +/* + * @brief get the backlight level of the given output + * @param root window which's screen should be queried + * @param output from which the backlight level should be retrieved + * @return the backlight level + */ +EAPI double +ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, Ecore_X_Randr_Output output) +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Atom _backlight; + xcb_intern_atom_cookie_t acookie; + xcb_intern_atom_reply_t *areply; + xcb_randr_get_output_property_cookie_t cookie; + xcb_randr_get_output_property_reply_t *reply; + xcb_randr_query_output_property_cookie_t qcookie; + xcb_randr_query_output_property_reply_t *qreply; + double dvalue; + long value, max, min; + + acookie = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, + strlen("Backlight"), "Backlight"); + areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); + + if (!areply) + { + ERR("Backlight property is not suppported on this server or driver"); + return -1; + } + else + { + _backlight = areply->atom; + free(areply); + } + + if (!_ecore_xcb_randr_output_validate(root, output)) + { + ERR("Invalid output"); + return -1; + } + + cookie = + xcb_randr_get_output_property_unchecked(_ecore_xcb_conn, + output, _backlight, + XCB_ATOM_NONE, 0, 4, 0, 0); + reply = + xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) + { + WRN("Backlight not supported on this output"); + return -1; + } + + if ((reply->format != 32) || (reply->num_items != 1) || + (reply->type != XCB_ATOM_INTEGER)) + { + free(reply); + return -1; + } + + value = *((long *)xcb_randr_get_output_property_data(reply)); + free (reply); + + /* I have the current value of the backlight */ + /* Now retrieve the min and max intensities of the output */ + qcookie = + xcb_randr_query_output_property_unchecked(_ecore_xcb_conn, + output, _backlight); + qreply = + xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL); + if (qreply) + { + dvalue = -1; + if ((qreply->range) && + (xcb_randr_query_output_property_valid_values_length(qreply) == 2)) + { + int32_t *vals; + + vals = xcb_randr_query_output_property_valid_values(qreply); + /* finally convert the current value in the interval [0..1] */ + min = vals[0]; + max = vals[1]; + dvalue = ((double)(value - min)) / ((double)(max - min)); + } + free(qreply); + return dvalue; + } +#endif + return -1; +} + +/* + * @brief set the backlight level of a given output + * @param root window which's screen should be queried + * @param output that should be set + * @param level for which the backlight should be set + * @return EINA_TRUE in case of success + */ +EAPI Eina_Bool +ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, Ecore_X_Randr_Output output, double level) +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Atom _backlight; + xcb_intern_atom_cookie_t acookie; + xcb_intern_atom_reply_t *areply; + xcb_randr_query_output_property_cookie_t qcookie; + xcb_randr_query_output_property_reply_t *qreply; + + if ((level < 0) || (level > 1)) + { + ERR("Backlight level should be between 0 and 1"); + return EINA_FALSE; + } + + if (!_ecore_xcb_randr_output_validate(root, output)) + { + ERR("Wrong output value"); + return EINA_FALSE; + } + + acookie = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, + strlen("Backlight"), "Backlight"); + areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); + if (!areply) + { + WRN("Backlight property is not suppported on this server or driver"); + return EINA_FALSE; + } + else + { + _backlight = areply->atom; + free(areply); + } + + qcookie = + xcb_randr_query_output_property_unchecked(_ecore_xcb_conn, + output, _backlight); + qreply = + xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL); + if (qreply) + { + if ((qreply->range) && (qreply->length == 2)) + { + int32_t *vals; + double min, max, tmp; + long n; + + vals = xcb_randr_query_output_property_valid_values(qreply); + min = vals[0]; + max = vals[1]; + tmp = (level * (max - min)) + min; + n = tmp; + if (n > max) n = max; + if (n < min) n = min; + xcb_randr_change_output_property(_ecore_xcb_conn, output, + _backlight, XCB_ATOM_INTEGER, + 32, XCB_PROP_MODE_REPLACE, + 1, (unsigned char *)&n); + ecore_x_flush(); // needed + } + + free(qreply); + return EINA_TRUE; + } +#endif + return EINA_FALSE; +} + +/* local functions */ +static Eina_Bool +_ecore_xcb_randr_output_validate(Ecore_X_Window root, Ecore_X_Randr_Output output) +{ + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if ((output) && (_ecore_xcb_randr_root_validate(root))) + { + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; + + cookie = + xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = + xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int len = 0, i = 0; + xcb_randr_output_t *outputs; + + len = xcb_randr_get_screen_resources_outputs_length(reply); + outputs = xcb_randr_get_screen_resources_outputs(reply); + for (i = 0; i < len; i++) + { + if (outputs[i] == output) + { + ret = EINA_TRUE; + break; + } + } + free(reply); + } + } +#endif + return ret; +} + +/** + * @brief validates a CRTC for a given root window's screen. + * @param root the window which's default display will be queried + * @param crtc the CRTC to be validated. + * @return in case it is found EINA_TRUE will be returned. Else EINA_FALSE is returned. + */ +static Eina_Bool +_ecore_xcb_randr_crtc_validate(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc) +{ + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if (((int)crtc == Ecore_X_Randr_None) || ((int)crtc == Ecore_X_Randr_Unset)) + return ret; + + if ((crtc) && (_ecore_xcb_randr_root_validate(root))) + { + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; + + cookie = + xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, root); + reply = + xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int i = 0; + xcb_randr_crtc_t *crtcs; + + crtcs = xcb_randr_get_screen_resources_crtcs(reply); + for (i = 0; i < reply->num_crtcs; i++) + { + if (crtcs[i] == crtc) + { + ret = EINA_TRUE; + break; + } + } + free(reply); + } + } +#endif + + return ret; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_region.c b/src/lib/ecore_x/xcb/ecore_xcb_region.c index 369ad3b..2151cb7 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_region.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_region.c @@ -1,32 +1,11 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include - #include "ecore_xcb_private.h" +#include /* - * [x] XCreateRegion * [ ] XPolygonRegion - * [x] XSetRegion - * [x] XDestroyRegion - * - * [x] XOffsetRegion * [ ] XShrinkRegion - * * [ ] XClipBox - * [x] XIntersectRegion - * [x] XUnionRegion - * [x] XUnionRectWithRegion - * [x] XSubtractRegion * [ ] XXorRegion - * - * [x] XEmptyRegion - * [x] XEqualRegion - * - * [x] XPointInRegion - * [x] XRectInRegion */ EAPI Ecore_X_XRegion * @@ -34,44 +13,37 @@ ecore_x_xregion_new() { pixman_region16_t *region; - region = (pixman_region16_t *)malloc (sizeof (pixman_region16_t)); - if (!region) - return NULL; + region = (pixman_region16_t *)malloc(sizeof(pixman_region16_t)); + if (!region) return NULL; pixman_region_init(region); return (Ecore_X_XRegion *)region; -} /* ecore_x_xregion_new */ +} EAPI void ecore_x_xregion_free(Ecore_X_XRegion *region) { - if (!region) - return; + if (!region) return; pixman_region_fini(region); free(region); -} /* ecore_x_xregion_free */ +} EAPI Eina_Bool ecore_x_xregion_set(Ecore_X_XRegion *region, Ecore_X_GC gc) { xcb_rectangle_t *rects; pixman_box16_t *boxes; - int num; - int i; + int num = 0, i = 0; - if (!region) - return 0; + if (!region) return EINA_FALSE; - boxes = pixman_region_rectangles ((pixman_region16_t *)region, &num); - - if (!boxes || (num == 0)) - return 0; + boxes = pixman_region_rectangles((pixman_region16_t *)region, &num); + if ((!boxes) || (num == 0)) return EINA_FALSE; rects = (xcb_rectangle_t *)malloc(sizeof(xcb_rectangle_t) * num); - if (!rects) - return 0; + if (!rects) return EINA_FALSE; for (i = 0; i < num; i++) { @@ -81,83 +53,83 @@ ecore_x_xregion_set(Ecore_X_XRegion *region, Ecore_X_GC gc) rects[i].height = boxes[i].y2 - boxes[i].y1 + 1; } - xcb_set_clip_rectangles(_ecore_xcb_conn, - XCB_CLIP_ORDERING_YX_BANDED, - gc, - 0, 0, - num, - rects); - return 1; -} /* ecore_x_xregion_set */ + xcb_set_clip_rectangles(_ecore_xcb_conn, XCB_CLIP_ORDERING_YX_BANDED, + gc, 0, 0, num, rects); + + return EINA_TRUE; +} EAPI void ecore_x_xregion_translate(Ecore_X_XRegion *region, int x, int y) { - if (!region) - return; + if (!region) return; pixman_region_translate((pixman_region16_t *)region, x, y); -} /* ecore_x_xregion_translate */ +} EAPI Eina_Bool ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) { - return pixman_region_intersect((pixman_region16_t *)dst, (pixman_region16_t *)r1, (pixman_region16_t *)r2); -} /* ecore_x_xregion_intersect */ + return pixman_region_intersect((pixman_region16_t *)dst, + (pixman_region16_t *)r1, + (pixman_region16_t *)r2); +} EAPI Eina_Bool ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) { - return pixman_region_union((pixman_region16_t *)dst, (pixman_region16_t *)r1, (pixman_region16_t *)r2); -} /* ecore_x_xregion_union */ + return pixman_region_union((pixman_region16_t *)dst, + (pixman_region16_t *)r1, + (pixman_region16_t *)r2); +} EAPI Eina_Bool ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect) { - return pixman_region_union_rect((pixman_region16_t *)dst, (pixman_region16_t *)src, + return pixman_region_union_rect((pixman_region16_t *)dst, + (pixman_region16_t *)src, rect->x, rect->y, rect->width, rect->height); -} /* ecore_x_xregion_union_rect */ +} EAPI Eina_Bool ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *rm, Ecore_X_XRegion *rs) { - return pixman_region_subtract((pixman_region16_t *)dst, (pixman_region16_t *)rm, (pixman_region16_t *)rs); -} /* ecore_x_xregion_subtract */ + return pixman_region_subtract((pixman_region16_t *)dst, + (pixman_region16_t *)rm, + (pixman_region16_t *)rs); +} EAPI Eina_Bool ecore_x_xregion_is_empty(Ecore_X_XRegion *region) { - if (!region) - return 1; + if (!region) return EINA_TRUE; return !pixman_region_not_empty((pixman_region16_t *)region); -} /* ecore_x_xregion_is_empty */ +} EAPI Eina_Bool ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) { - if (!r1 || !r2) - return 0; + if ((!r1) || (!r2)) return EINA_FALSE; - return pixman_region_equal((pixman_region16_t *)r1, (pixman_region16_t *)r2); -} /* ecore_x_xregion_is_equal */ + return pixman_region_equal((pixman_region16_t *)r1, + (pixman_region16_t *)r2); +} EAPI Eina_Bool ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y) { - if (!region) - return 0; + if (!region) return EINA_FALSE; return pixman_region_contains_point((pixman_region16_t *)region, x, y, NULL); -} /* ecore_x_xregion_point_contain */ +} EAPI Eina_Bool ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect) { pixman_box16_t box; - if (!region || !rect) - return 0; + if ((!region) || (!rect)) return EINA_FALSE; box.x1 = rect->x; box.y1 = rect->y; @@ -165,5 +137,4 @@ ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect) box.y2 = rect->y + rect->height - 1; return pixman_region_contains_rectangle((pixman_region16_t *)region, &box); -} /* ecore_x_xregion_rect_contain */ - +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_render.c b/src/lib/ecore_x/xcb/ecore_xcb_render.c new file mode 100644 index 0000000..059d9a3 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_render.c @@ -0,0 +1,229 @@ +#include "ecore_xcb_private.h" +#include +#ifdef ECORE_XCB_RENDER +# include +# include +#endif + +/* local function prototypes */ +static Eina_Bool _ecore_xcb_render_parse_boolean(char *v); +static char *_ecore_xcb_render_get_resource(const char *prog __UNUSED__, const char *name __UNUSED__); + +/* local variables */ +static Eina_Bool _render_avail = EINA_FALSE; +static Eina_Bool _render_argb = EINA_FALSE; +static Eina_Bool _render_anim = EINA_FALSE; + +void +_ecore_xcb_render_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RENDER + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_render_id); +#endif +} + +void +_ecore_xcb_render_finalize(void) +{ +#ifdef ECORE_XCB_RENDER + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RENDER + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_render_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_render_query_version_cookie_t cookie; + xcb_render_query_version_reply_t *reply; + + cookie = + xcb_render_query_version_unchecked(_ecore_xcb_conn, + XCB_RENDER_MAJOR_VERSION, + XCB_RENDER_MINOR_VERSION); + reply = xcb_render_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { +// if ((reply->major_version >= XCB_RENDER_MAJOR_VERSION) && + if (reply->minor_version >= XCB_RENDER_MINOR_VERSION) + { + char *v = NULL; + + _render_avail = EINA_TRUE; + if ((reply->major_version > 0) || (reply->minor_version >= 5)) + { + _render_argb = EINA_TRUE; + v = getenv("XCURSOR_CORE"); + if (!v) + { + // TODO: check xgetdefault when xcb supports resources + v = _ecore_xcb_render_get_resource("Xcursor", "core"); + } + if ((v) && (_ecore_xcb_render_parse_boolean(v))) + _render_argb = EINA_FALSE; + } + if ((_render_argb) && + ((reply->major_version > 0) || (reply->minor_version >= 8))) + { + _render_anim = EINA_TRUE; + v = getenv("XCURSOR_ANIM"); + if (!v) + { + // TODO: check xgetdefault when xcb supports resources + v = _ecore_xcb_render_get_resource("Xcursor", "anim"); + } + if ((v) && (_ecore_xcb_render_parse_boolean(v))) + _render_anim = EINA_FALSE; + } + } + } + free(reply); + } +#endif +} + +Eina_Bool +_ecore_xcb_render_avail_get(void) +{ + return _render_avail; +} + +Eina_Bool +_ecore_xcb_render_argb_get(void) +{ + return _render_argb; +} + +Eina_Bool +_ecore_xcb_render_anim_get(void) +{ + return _render_anim; +} + +Eina_Bool +_ecore_xcb_render_visual_supports_alpha(Ecore_X_Visual visual) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RENDER + const xcb_render_query_pict_formats_reply_t *reply; + xcb_render_pictvisual_t *vis; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!visual) return EINA_FALSE; + +#ifdef ECORE_XCB_RENDER + reply = xcb_render_util_query_formats(_ecore_xcb_conn); + if (!reply) return EINA_FALSE; + + vis = + xcb_render_util_find_visual_format(reply, + ((xcb_visualtype_t *)visual)->visual_id); + if (vis) + { + xcb_render_pictforminfo_t temp; + xcb_render_pictforminfo_t *format; + + temp.id = vis->format; + format = + xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID, &temp, 0); + + if ((format->type == XCB_RENDER_PICT_TYPE_DIRECT) && + (format->direct.alpha_mask)) + ret = EINA_TRUE; + } + +#endif + + return ret; +} + +uint32_t +_ecore_xcb_render_find_visual_id(int type, Eina_Bool check_alpha) +{ +#ifdef ECORE_XCB_RENDER + const xcb_render_query_pict_formats_reply_t *reply; + xcb_render_pictvisual_t *visual = NULL; + xcb_render_pictscreen_iterator_t screens; + xcb_render_pictdepth_iterator_t depths; + xcb_render_pictvisual_iterator_t visuals; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RENDER + reply = xcb_render_util_query_formats(_ecore_xcb_conn); + if (!reply) return 0; + + for (screens = xcb_render_query_pict_formats_screens_iterator(reply); + screens.rem; xcb_render_pictscreen_next(&screens)) + { + for (depths = xcb_render_pictscreen_depths_iterator(screens.data); + depths.rem; xcb_render_pictdepth_next(&depths)) + { + for (visuals = xcb_render_pictdepth_visuals_iterator(depths.data); + visuals.rem; xcb_render_pictvisual_next(&visuals)) + { + xcb_render_pictforminfo_t temp; + xcb_render_pictforminfo_t *format; + + visual = visuals.data; + temp.id = visual->format; + + format = + xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID, + &temp, 0); + if (!format) continue; + if (format->type == type) + { + if (check_alpha) + { + if (format->direct.alpha_mask) + return visual->visual; + } + else + return visual->visual; + } + } + } + } +#endif + + return 0; +} + +/* local function prototypes */ +static Eina_Bool +_ecore_xcb_render_parse_boolean(char *v) +{ + char c; + + c = *v; + if (isupper((int)c)) + c = tolower(c); + if ((c == 't') || (c == 'y') || (c == '1')) + return EINA_TRUE; + if ((c == 'f') || (c == 'n') || (c == '0')) + return EINA_FALSE; + if (c == 'o') + { + char d; + + d = v[1]; + if (isupper((int)d)) + d = tolower(d); + if (d == 'n') return EINA_TRUE; + if (d == 'f') return EINA_FALSE; + } + return EINA_FALSE; +} + +static char * +_ecore_xcb_render_get_resource(const char *prog __UNUSED__, const char *name __UNUSED__) +{ + return NULL; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_reply.c b/src/lib/ecore_x/xcb/ecore_xcb_reply.c deleted file mode 100644 index 4f50a51..0000000 --- a/src/lib/ecore_x/xcb/ecore_xcb_reply.c +++ /dev/null @@ -1,114 +0,0 @@ -#include - -#include - -/* - * FIXME: - * - in ecore_xcb_cookie_cache, should provide better error management - * when memory allocation fails - * - Use an array instead of a list - * - Is ecore_xcb_reply_free really needed ? - * _ecore_xcb_reply_cache frees the current reply and - * _ecore_x_reply_shutdown frees the last reply to free. - * I keep it in case it is need for memory improvements, - * but its code is commented. - */ - -static Eina_List *_ecore_xcb_cookies = NULL; -static void *_ecore_xcb_reply = NULL; - -typedef struct _Ecore_Xcb_Data Ecore_Xcb_Data; - -struct _Ecore_Xcb_Data -{ - unsigned int cookie; -}; - -int -_ecore_x_reply_init () -{ - return 1; -} /* _ecore_x_reply_init */ - -void -_ecore_x_reply_shutdown () -{ - Ecore_Xcb_Data *data; - - if (_ecore_xcb_reply) - free(_ecore_xcb_reply); - - if (!_ecore_xcb_cookies) - return; - - EINA_LIST_FREE(_ecore_xcb_cookies, data) - free(data); -} /* _ecore_x_reply_shutdown */ - -void -_ecore_xcb_cookie_cache (unsigned int cookie) -{ - Ecore_Xcb_Data *data; - - if (!_ecore_xcb_cookies) - return; - - data = (Ecore_Xcb_Data *)malloc(sizeof(Ecore_Xcb_Data)); - if (!data) - return; - - data->cookie = cookie; - - _ecore_xcb_cookies = eina_list_append(_ecore_xcb_cookies, data); - if (!eina_list_data_find(_ecore_xcb_cookies, data)) - { - free(data); - return; - } -} /* _ecore_xcb_cookie_cache */ - -unsigned int -_ecore_xcb_cookie_get (void) -{ - Ecore_Xcb_Data *data; - unsigned int cookie; - - if (!_ecore_xcb_cookies) - return 0; - - data = eina_list_data_get(_ecore_xcb_cookies); - if (!data) - return 0; - - _ecore_xcb_cookies = eina_list_remove_list(_ecore_xcb_cookies, _ecore_xcb_cookies); - cookie = data->cookie; - free(data); - - return cookie; -} /* _ecore_xcb_cookie_get */ - -void -_ecore_xcb_reply_cache (void *reply) -{ - if (_ecore_xcb_reply) - free(_ecore_xcb_reply); - - _ecore_xcb_reply = reply; -} /* _ecore_xcb_reply_cache */ - -void * -_ecore_xcb_reply_get (void) -{ - return _ecore_xcb_reply; -} /* _ecore_xcb_reply_get */ - -EAPI void -ecore_xcb_reply_free() -{ -/* if (_ecore_xcb_reply) */ -/* { */ -/* free(_ecore_xcb_reply); */ -/* _ecore_xcb_reply = NULL; */ -/* } */ -} /* ecore_xcb_reply_free */ - diff --git a/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c b/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c index 3f8f0bf..7d0007b 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c @@ -1,401 +1,301 @@ #include "ecore_xcb_private.h" +# ifdef ECORE_XCB_SCREENSAVER +# include +# endif -/** - * @defgroup Ecore_X_ScreenSaver_Group X ScreenSaver extension - * - * These functions use the ScreenSaver extension of the X server - */ +/* local variables */ +static Eina_Bool _screensaver_avail = EINA_FALSE; -#ifdef ECORE_XCB_SCREENSAVER -static int _screensaver_available = 0; -static xcb_screensaver_query_version_cookie_t _ecore_xcb_screensaver_init_cookie; -#endif /* ECORE_XCB_SCREENSAVER */ - -/* To avoid round trips, the initialization is separated in 2 - functions: _ecore_xcb_screensaver_init and - _ecore_xcb_screensaver_init_finalize. The first one gets the cookies and - the second one gets the replies and set the atoms. */ +/* external variables */ +int _ecore_xcb_event_screensaver = -1; -void -_ecore_x_screensaver_init(const xcb_query_extension_reply_t *reply) +void +_ecore_xcb_screensaver_init(void) { -#ifdef ECORE_XCB_SCREENSAVER - if (reply && (reply->present)) - _ecore_xcb_screensaver_init_cookie = xcb_screensaver_query_version_unchecked(_ecore_xcb_conn, 1, 1); + LOGFN(__FILE__, __LINE__, __FUNCTION__); -#endif /* ECORE_XCB_SCREENSAVER */ -} /* _ecore_x_screensaver_init */ +#ifdef ECORE_XCB_SCREENSAVER + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); +#endif +} -void -_ecore_x_screensaver_init_finalize(void) +void +_ecore_xcb_screensaver_finalize(void) { #ifdef ECORE_XCB_SCREENSAVER - xcb_screensaver_query_version_reply_t *reply; + const xcb_query_extension_reply_t *ext_reply; +#endif - reply = xcb_screensaver_query_version_reply(_ecore_xcb_conn, - _ecore_xcb_screensaver_init_cookie, NULL); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (reply) +#ifdef ECORE_XCB_SCREENSAVER + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); + if ((ext_reply) && (ext_reply->present)) { - if ((reply->server_major_version >= 1) && - (reply->server_minor_version >= 1)) - _screensaver_available = 1; - - free(reply); + xcb_screensaver_query_version_cookie_t cookie; + xcb_screensaver_query_version_reply_t *reply; + + cookie = + xcb_screensaver_query_version_unchecked(_ecore_xcb_conn, + XCB_SCREENSAVER_MAJOR_VERSION, + XCB_SCREENSAVER_MINOR_VERSION); + reply = + xcb_screensaver_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if ((reply->server_major_version >= XCB_SCREENSAVER_MAJOR_VERSION) && + (reply->server_minor_version >= XCB_SCREENSAVER_MINOR_VERSION)) + _screensaver_avail = EINA_TRUE; + + free(reply); + } + + if (_screensaver_avail) + _ecore_xcb_event_screensaver = ext_reply->first_event; } +#endif +} -#endif /* ECORE_XCB_SCREENSAVER */ -} /* _ecore_x_screensaver_init_finalize */ - -/** - * Return whether the X server supports the ScreenSaver Extension. - * @return 1 if the X ScreenSaver Extension is available, 0 otherwise. - * - * Return 1 if the X server supports the ScreenSaver Extension version 1.0, - * 0 otherwise. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI Eina_Bool -ecore_x_screensaver_event_available_get(void) -{ - return 1; -} /* ecore_x_screensaver_event_available_get */ - -/** - * Sends the QueryInfo request. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_screensaver_idle_time_prefetch(void) -{ -#ifdef ECORE_XCB_SCREENSAVER - xcb_screensaver_query_info_cookie_t cookie; - - cookie = xcb_screensaver_query_info_unchecked(_ecore_xcb_conn, ((xcb_screen_t *)_ecore_xcb_screen)->root); - _ecore_xcb_cookie_cache(cookie.sequence); -#endif /* ECORE_XCB_SCREENSAVER */ -} /* ecore_x_screensaver_idle_time_prefetch */ - -/** - * Gets the reply of the QueryInfo request sent by ecore_x_get_screensaver_prefetch(). - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_screensaver_idle_time_fetch(void) +EAPI int +ecore_x_screensaver_idle_time_get(void) { + int ret = 0; #ifdef ECORE_XCB_SCREENSAVER xcb_screensaver_query_info_cookie_t cookie; xcb_screensaver_query_info_reply_t *reply; + Ecore_X_Window root; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); +#ifdef ECORE_XCB_SCREENSAVER + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + cookie = xcb_screensaver_query_info_unchecked(_ecore_xcb_conn, root); reply = xcb_screensaver_query_info_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -#endif /* ECORE_XCB_SCREENSAVER */ -} /* ecore_x_screensaver_idle_time_fetch */ - -/** - * Get the number of seconds since the last input was received. - * @return The number of seconds. - * - * Get the number of milliseconds since the last input was received - * from the user on any of the input devices. - * - * To use this function, you must call before, and in order, - * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request, - * then ecore_x_get_screensaver_fetch(), which gets the reply. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI int -ecore_x_screensaver_idle_time_get(void) + if (!reply) return 0; + ret = (reply->ms_until_server / 1000); + free(reply); +#endif + + return ret; +} + +EAPI void +ecore_x_screensaver_set(int timeout, int interval, int prefer_blanking, int allow_exposures) { - int idle = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + #ifdef ECORE_XCB_SCREENSAVER - xcb_screensaver_query_info_reply_t *reply; + xcb_set_screen_saver(_ecore_xcb_conn, + timeout, interval, prefer_blanking, allow_exposures); +#endif +} - reply = _ecore_xcb_reply_get(); - - if (!reply) - return 0; - - /* FIXME: check if it is ms_since_user_input or ms_until_server */ - idle = reply->ms_since_user_input / 1000; -#endif /* ECORE_XCB_SCREENSAVER */ - - return idle; -} /* ecore_x_screensaver_idle_time_get */ - -/** - * Set the parameters of the screen saver. - * @param timeout The timeout, in second. - * @param interval The interval, in seconds. - * @param blank 0 to disable screen blanking, otherwise enable it. - * @param expose Allow Expose generation event or not. - * - * Set the parameters of the screen saver. @p timeout is the timeout, - * in seconds, until the screen saver turns on. @p interval is the - * interval, in seconds, between screen saver alterations. @p blank - * specifies how to enable screen blanking. @p expose specifies the - * screen save control values. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_screensaver_set(int timeout, - int interval, - int blank, - int expose) -{ - xcb_set_screen_saver(_ecore_xcb_conn, - (int16_t)timeout, - (int16_t)interval, - (uint8_t)blank, - (uint8_t)expose); -} /* ecore_x_screensaver_set */ - -/** - * Sends the GetScreenSaver request. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_get_screensaver_prefetch(void) +EAPI void +ecore_x_screensaver_timeout_set(int timeout) { +#ifdef ECORE_XCB_SCREENSAVER xcb_get_screen_saver_cookie_t cookie; + xcb_get_screen_saver_reply_t *reply; + uint16_t pint; + uint8_t pblank, pexpo; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); +#ifdef ECORE_XCB_SCREENSAVER cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_get_screensaver_prefetch */ - -/** - * Gets the reply of the GetScreenSaver request sent by ecore_x_get_screensaver_prefetch(). - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_get_screensaver_fetch(void) + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + pint = reply->interval; + pblank = reply->prefer_blanking; + pexpo = reply->allow_exposures; + free(reply); + xcb_set_screen_saver(_ecore_xcb_conn, timeout, pint, pblank, pexpo); +#endif +} + +EAPI int +ecore_x_screensaver_timeout_get(void) { + int timeout = 0; +#ifdef ECORE_XCB_SCREENSAVER xcb_get_screen_saver_cookie_t cookie; xcb_get_screen_saver_reply_t *reply; +#endif - cookie.sequence = _ecore_xcb_cookie_get(); + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_get_screensaver_fetch */ - -/** - * Set the timeout of the screen saver. - * @param timeout The timeout to set. - * - * Set the @p timeout, in seconds, until the screen saver turns on. - * - * To use this function, you must call before, and in order, - * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request, - * then ecore_x_get_screensaver_fetch(), which gets the reply. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_screensaver_timeout_set(int timeout) -{ - xcb_get_screen_saver_reply_t *reply; + if (!reply) return 0; + timeout = reply->timeout; + free(reply); +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return; - - xcb_set_screen_saver(_ecore_xcb_conn, - (int16_t)timeout, - reply->interval, - reply->prefer_blanking, - reply->allow_exposures); -} /* ecore_x_screensaver_timeout_set */ - -/** - * Get the timeout of the screen saver. - * @return The timeout. - * - * Get the @p timeout, in seconds, until the screen saver turns on. - * - * To use this function, you must call before, and in order, - * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request, - * then ecore_x_get_screensaver_fetch(), which gets the reply. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI int -ecore_x_screensaver_timeout_get(void) -{ - xcb_get_screen_saver_reply_t *reply; + return timeout; +} - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0.0; - - return (int)reply->timeout; -} /* ecore_x_screensaver_timeout_get */ - -/** - * Set the interval of the screen saver. - * @param interval The interval to set. - * - * Set the @p interval, in seconds, between screen saver alterations. - * - * To use this function, you must call before, and in order, - * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request, - * then ecore_x_get_screensaver_fetch(), which gets the reply. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_screensaver_interval_set(int interval) +EAPI void +ecore_x_screensaver_blank_set(int blank) { +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; xcb_get_screen_saver_reply_t *reply; + uint16_t pint, pto; + uint8_t pexpo; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return; - - xcb_set_screen_saver(_ecore_xcb_conn, - reply->timeout, - (int16_t)interval, - reply->prefer_blanking, - reply->allow_exposures); -} /* ecore_x_screensaver_interval_set */ - -/** - * Get the interval of the screen saver. - * @return The interval. - * - * Get the @p interval, in seconds, between screen saver alterations. - * - * To use this function, you must call before, and in order, - * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request, - * then ecore_x_get_screensaver_fetch(), which gets the reply. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI int -ecore_x_screensaver_interval_get(void) +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + pto = reply->timeout; + pint = reply->interval; + pexpo = reply->allow_exposures; + free(reply); + xcb_set_screen_saver(_ecore_xcb_conn, pto, pint, blank, pexpo); +#endif +} + +EAPI int +ecore_x_screensaver_blank_get(void) { + int blank = 0; +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; xcb_get_screen_saver_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + blank = reply->prefer_blanking; + free(reply); +#endif + + return blank; +} - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0.0; - - return (int)reply->interval; -} /* ecore_x_screensaver_interval_get */ - -/** - * Set the screen blanking. - * @param blank The blank to set. - * - * @p blank specifies how to enable screen blanking. - * - * To use this function, you must call before, and in order, - * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request, - * then ecore_x_get_screensaver_fetch(), which gets the reply. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_screensaver_blank_set(int blank) +EAPI void +ecore_x_screensaver_expose_set(int expose) { +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; xcb_get_screen_saver_reply_t *reply; + uint16_t pint, pto; + uint8_t pblank; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return; - - xcb_set_screen_saver(_ecore_xcb_conn, - reply->timeout, - reply->interval, - (uint8_t)blank, - reply->allow_exposures); -} /* ecore_x_screensaver_blank_set */ - -/** - * Get the screen blanking. - * @return The blanking. - * - * Get the screen blanking. - * - * To use this function, you must call before, and in order, - * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request, - * then ecore_x_get_screensaver_fetch(), which gets the reply. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI int -ecore_x_screensaver_blank_get(void) +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + pto = reply->timeout; + pint = reply->interval; + pblank = reply->prefer_blanking; + free(reply); + xcb_set_screen_saver(_ecore_xcb_conn, pto, pint, pblank, expose); +#endif +} + +EAPI int +ecore_x_screensaver_expose_get(void) { + int expose = 0; +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; xcb_get_screen_saver_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + expose = reply->allow_exposures; + free(reply); +#endif + + return expose; +} - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0.0; - - return (int)reply->prefer_blanking; -} /* ecore_x_screensaver_blank_get */ - -/** - * Set the screen save control values. - * @param expose The expose to set. - * - * Set the screen save control values. - * - * To use this function, you must call before, and in order, - * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request, - * then ecore_x_get_screensaver_fetch(), which gets the reply. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_screensaver_expose_set(int expose) +EAPI void +ecore_x_screensaver_interval_set(int interval) { +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; xcb_get_screen_saver_reply_t *reply; + uint16_t pto; + uint8_t pblank, pexpose; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return; - - xcb_set_screen_saver(_ecore_xcb_conn, - reply->timeout, - reply->interval, - reply->prefer_blanking, - (uint8_t)expose); -} /* ecore_x_screensaver_expose_set */ - -/** - * Get the screen save control values. - * @return The expose. - * - * Get the screen save control values. - * - * To use this function, you must call before, and in order, - * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request, - * then ecore_x_get_screensaver_fetch(), which gets the reply. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI int -ecore_x_screensaver_expose_get(void) +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + pto = reply->timeout; + pblank = reply->prefer_blanking; + pexpose = reply->allow_exposures; + free(reply); + xcb_set_screen_saver(_ecore_xcb_conn, pto, interval, pblank, pexpose); +#endif +} + +EAPI int +ecore_x_screensaver_interval_get(void) { + int interval = 0; +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; xcb_get_screen_saver_reply_t *reply; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0.0; - - return (int)reply->allow_exposures; -} /* ecore_x_screensaver_expose_get */ - -/** - * Specifies if the Screen Saver NotifyMask event should be generated. - * @param on 0 to disable the generation of the event, otherwise enable it. - * - * Specifies if the Screen Saver NotifyMask event on the screen - * associated with drawable should be generated for this client. If - * @p on is set to @c 0, the generation is disabled, otherwise, it is - * enabled. - * @ingroup Ecore_X_ScreenSaver_Group - */ -EAPI void -ecore_x_screensaver_event_listen_set(Eina_Bool on) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + interval = reply->interval; + free(reply); +#endif + + return interval; +} + +EAPI void +ecore_x_screensaver_event_listen_set(Eina_Bool on) { #ifdef ECORE_XCB_SCREENSAVER - xcb_screensaver_select_input(_ecore_xcb_conn, - ((xcb_screen_t *)_ecore_xcb_screen)->root, - on ? XCB_SCREENSAVER_EVENT_NOTIFY_MASK : 0); -#endif /* ECORE_XCB_SCREENSAVER */ -} /* ecore_x_screensaver_event_listen_set */ + Ecore_X_Window root; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); +#ifdef ECORE_XCB_SCREENSAVER + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + if (on) + xcb_screensaver_select_input(_ecore_xcb_conn, root, + XCB_SCREENSAVER_EVENT_NOTIFY_MASK); + else + xcb_screensaver_select_input(_ecore_xcb_conn, root, 0); +#endif +} + +EAPI Eina_Bool +ecore_x_screensaver_event_available_get(void) +{ + return _screensaver_avail; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_selection.c b/src/lib/ecore_x/xcb/ecore_xcb_selection.c index ec5f664..be352ea 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_selection.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_selection.c @@ -1,63 +1,70 @@ -#include - #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" - -static Ecore_X_Selection_Intern selections[4]; -static Ecore_X_Selection_Converter *converters = NULL; -static Ecore_X_Selection_Parser *parsers = NULL; - -static Eina_Bool _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *tprop, int *); -static Eina_Bool _ecore_x_selection_data_default_free(void *data); -static void * _ecore_x_selection_parser_files(const char *target, void *data, int size, int format); -static Eina_Bool _ecore_x_selection_data_files_free(void *data); -static void * _ecore_x_selection_parser_text(const char *target, void *data, int size, int format); -static Eina_Bool _ecore_x_selection_data_text_free(void *data); -static void * _ecore_x_selection_parser_targets(const char *target, void *data, int size, int format); -static Eina_Bool _ecore_x_selection_data_targets_free(void *data); - -#define ECORE_X_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x)) - -void -_ecore_x_selection_init(void) -{ - /* Initialize global data */ - memset(selections, 0, sizeof(selections)); - - /* Initialize converters */ - ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT, - _ecore_x_selection_converter_text); -#ifdef X_HAVE_UTF8_STRING - ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING, - _ecore_x_selection_converter_text); -#endif /* ifdef X_HAVE_UTF8_STRING */ - ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT, - _ecore_x_selection_converter_text); - ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING, - _ecore_x_selection_converter_text); - - /* Initialize parsers */ - ecore_x_selection_parser_add("text/plain", - _ecore_x_selection_parser_text); - ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING, - _ecore_x_selection_parser_text); - ecore_x_selection_parser_add("text/uri-list", - _ecore_x_selection_parser_files); - ecore_x_selection_parser_add("_NETSCAPE_URL", - _ecore_x_selection_parser_files); - ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS, - _ecore_x_selection_parser_targets); -} /* _ecore_x_selection_init */ - -void -_ecore_x_selection_shutdown(void) +//#include "Ecore_X_Atoms.h" + +#define ECORE_XCB_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x)) + +/* local function prototypes */ +static Eina_Bool _ecore_xcb_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *type, int *size_type); +static void *_ecore_xcb_selection_parser_text(const char *target __UNUSED__, void *data, int size, int format __UNUSED__); +static void *_ecore_xcb_selection_parser_files(const char *target, void *data, int size, int format __UNUSED__); +static void *_ecore_xcb_selection_parser_targets(const char *target __UNUSED__, void *data, int size, int format __UNUSED__); + +//static int _ecore_xcb_selection_data_free(void *data); +static int _ecore_xcb_selection_data_text_free(void *data); +static int _ecore_xcb_selection_data_targets_free(void *data); +static int _ecore_xcb_selection_data_files_free(void *data); +static int _ecore_xcb_selection_data_default_free(void *data); +static Eina_Bool _ecore_xcb_selection_set(Ecore_X_Window win, const void *data, int size, Ecore_X_Atom selection); +static void _ecore_xcb_selection_request(Ecore_X_Window win, Ecore_X_Atom selection, const char *target); +static Ecore_X_Atom _ecore_xcb_selection_target_atom_get(const char *target); + +/* local variables */ +static Ecore_X_Selection_Intern _selections[4]; +static Ecore_X_Selection_Converter *_converters = NULL; +static Ecore_X_Selection_Parser *_parsers = NULL; + +/* local functions */ +void +_ecore_xcb_selection_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + memset(_selections, 0, sizeof(_selections)); + + /* init converters */ + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT, + _ecore_xcb_selection_converter_text); + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING, + _ecore_xcb_selection_converter_text); + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT, + _ecore_xcb_selection_converter_text); + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING, + _ecore_xcb_selection_converter_text); + + /* init parsers */ + ecore_x_selection_parser_add("text/plain", + _ecore_xcb_selection_parser_text); + ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING, + _ecore_xcb_selection_parser_text); + ecore_x_selection_parser_add("text/uri-list", + _ecore_xcb_selection_parser_files); + ecore_x_selection_parser_add("_NETSCAPE_URL", + _ecore_xcb_selection_parser_files); + ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS, + _ecore_xcb_selection_parser_targets); +} + +void +_ecore_xcb_selection_shutdown(void) { Ecore_X_Selection_Converter *cnv; Ecore_X_Selection_Parser *prs; - /* free the selection converters */ - cnv = converters; - while (cnv) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* free selection converters */ + cnv = _converters; + while (cnv) { Ecore_X_Selection_Converter *tmp; @@ -65,11 +72,11 @@ _ecore_x_selection_shutdown(void) free(cnv); cnv = tmp; } - converters = NULL; + _converters = NULL; - /* free the selection parsers */ - prs = parsers; - while (prs) + /* free parsers */ + prs = _parsers; + while (prs) { Ecore_X_Selection_Parser *tmp; @@ -78,998 +85,839 @@ _ecore_x_selection_shutdown(void) free(tmp->target); free(tmp); } - parsers = NULL; -} /* _ecore_x_selection_shutdown */ + _parsers = NULL; +} -Ecore_X_Selection_Intern * -_ecore_x_selection_get(Ecore_X_Atom selection) +/* public functions */ +EAPI void +ecore_x_selection_converter_atom_add(Ecore_X_Atom target, + Eina_Bool (*func) (char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *type, int *size_type)) { - if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) - return &selections[0]; - else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) - return &selections[1]; - else if (selection == ECORE_X_ATOM_SELECTION_XDND) - return &selections[2]; - else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) - return &selections[3]; - else - return NULL; -} /* _ecore_x_selection_get */ + Ecore_X_Selection_Converter *cnv; -/* - * Sends the GetSelectionOwner request. - */ -void -_ecore_xcb_get_selection_owner_prefetch(Ecore_X_Atom selection) -{ - xcb_get_selection_owner_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, selection); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* _ecore_xcb_get_selection_owner_prefetch */ + cnv = _converters; + if (_converters) + { + while (1) + { + if (cnv->target == target) + { + cnv->convert = func; + return; + } + if (cnv->next) + cnv = cnv->next; + else + break; + } + cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter)); + cnv = cnv->next; + } + else + { + _converters = calloc(1, sizeof(Ecore_X_Selection_Converter)); + cnv = _converters; + } + cnv->target = target; + cnv->convert = func; +} -/* - * Gets the reply of the GetSelectionOwner request sent by _ecore_xcb_get_selection_owner_prefetch(). - */ -void -_ecore_xcb_get_selection_owner_fetch(void) +EAPI void +ecore_x_selection_converter_add(char *target, + Eina_Bool (*func)(char *target, void *data, int size, void **date_ret, int *size_ret, Ecore_X_Atom *atom_ret, int *ret)) { - xcb_get_selection_owner_cookie_t cookie; - xcb_get_selection_owner_reply_t *reply; + Ecore_X_Atom atarget; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* _ecore_xcb_get_selection_owner_fetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/* - * To use this function, you must call before, and in order, - * _ecore_xcb_get_selection_owner_prefetch(), which sends the GetSelectionOwner request, - * then _ecore_xcb_get_selection_owner_fetch(), which gets the reply. - */ -int -_ecore_x_selection_set(Ecore_X_Window window, - const void *data, - int size, - Ecore_X_Atom selection) + if ((!func) || (!target)) return; + atarget = _ecore_xcb_selection_target_atom_get(target); + ecore_x_selection_converter_atom_add(atarget, func); +} + +EAPI void +ecore_x_selection_converter_del(char *target) { - xcb_get_selection_owner_reply_t *reply; - unsigned char *buf = NULL; - int in; + Ecore_X_Atom atarget; - xcb_set_selection_owner(_ecore_xcb_conn, window, selection, _ecore_xcb_event_last_time); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply || (reply->owner != window)) - return 0; + if (!target) return; + atarget = _ecore_xcb_selection_target_atom_get(target); + ecore_x_selection_converter_atom_del(atarget); +} - if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) - in = 0; - else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) - in = 1; - else if (selection == ECORE_X_ATOM_SELECTION_XDND) - in = 2; - else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) - in = 3; - else - return 0; +EAPI void +ecore_x_selection_converter_atom_del(Ecore_X_Atom target) +{ + Ecore_X_Selection_Converter *conv, *pconv = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (data) + conv = _converters; + while (conv) { - selections[in].win = window; - selections[in].selection = selection; - selections[in].length = size; - selections[in].time = _ecore_xcb_event_last_time; - - buf = malloc(size); - memcpy(buf, data, size); - selections[in].data = buf; + if (conv->target == target) + { + if (pconv) + pconv->next = conv->next; + else + _converters = conv->next; + free(conv); + return; + } + pconv = conv; + conv = conv->next; } - else +} + +EAPI void +ecore_x_selection_parser_add(const char *target, + void *(*func) (const char *target, void *data, int size, int format)) +{ + Ecore_X_Selection_Parser *prs; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!target) return; + prs = _parsers; + if (prs) { - if (selections[in].data) + while (prs->next) { - free(selections[in].data); - memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data)); + if (!strcmp(prs->target, target)) + { + prs->parse = func; + return; + } + prs = prs->next; } + prs->next = calloc(1, sizeof(Ecore_X_Selection_Parser)); + prs = prs->next; } + else + { + _parsers = calloc(1, sizeof(Ecore_X_Selection_Parser)); + prs = _parsers; + } + prs->target = strdup(target); + prs->parse = func; +} - return 1; -} /* _ecore_x_selection_set */ - -/** - * Sends the GetSelectionOwner request. - */ -EAPI void -ecore_x_selection_primary_prefetch(void) +EAPI void +ecore_x_selection_parser_del(const char *target) { - xcb_get_selection_owner_cookie_t cookie; + Ecore_X_Selection_Parser *prs, *pprs = NULL; - cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_PRIMARY); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_selection_primary_prefetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_primary_prefetch(). - */ -EAPI void -ecore_x_selection_primary_fetch(void) -{ - xcb_get_selection_owner_cookie_t cookie; - xcb_get_selection_owner_reply_t *reply; + if (!target) return; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_selection_primary_fetch */ + prs = _parsers; + while (prs) + { + if (!strcmp(prs->target, target)) + { + if (pprs) + pprs->next = prs->next; + else + _parsers = prs->next; + free(prs->target); + free(prs); + return; + } + pprs = prs; + prs = prs->next; + } +} /** * Claim ownership of the PRIMARY selection and set its data. - * @param window The window to which this selection belongs - * @param data The data associated with the selection - * @param size The size of the data buffer in bytes - * @return Returns 1 if the ownership of the selection was successfully - * claimed, or 0 if unsuccessful. - * - * To use this function, you must call before, and in order, - * ecore_x_selection_primary_prefetch(), which sends the GetSelectionOwner request, - * then ecore_x_selection_primary_fetch(), which gets the reply. + * @param w The window to which this selection belongs + * @param data The data associated with the selection + * @param size The size of the data buffer in bytes + * @return Returns 1 if the ownership of the selection was successfully + * claimed, or 0 if unsuccessful. */ -EAPI Eina_Bool -ecore_x_selection_primary_set(Ecore_X_Window window, - const void *data, - int size) +EAPI Eina_Bool +ecore_x_selection_primary_set(Ecore_X_Window win, const void *data, int size) { - return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_PRIMARY); -} /* ecore_x_selection_primary_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(win, data, size, + ECORE_X_ATOM_SELECTION_PRIMARY); +} /** * Release ownership of the primary selection * @return Returns 1 if the selection was successfully cleared, * or 0 if unsuccessful. - * - * To use this function, you must call before, and in order, - * ecore_x_selection_primary_prefetch(), which sends the GetSelectionOwner request, - * then ecore_x_selection_primary_fetch(), which gets the reply. */ -EAPI Eina_Bool -ecore_x_selection_primary_clear(void) +EAPI Eina_Bool +ecore_x_selection_primary_clear(void) { - return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_PRIMARY); -} /* ecore_x_selection_primary_clear */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Sends the GetSelectionOwner request. - */ -EAPI void -ecore_x_selection_secondary_prefetch(void) -{ - xcb_get_selection_owner_cookie_t cookie; + return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, + ECORE_X_ATOM_SELECTION_PRIMARY); +} - cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_SECONDARY); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_selection_secondary_prefetch */ - -/** - * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_secondary_prefetch(). - */ -EAPI void -ecore_x_selection_secondary_fetch(void) +EAPI void +ecore_x_selection_primary_request(Ecore_X_Window win, const char *target) { - xcb_get_selection_owner_cookie_t cookie; - xcb_get_selection_owner_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_selection_secondary_fetch */ + _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_PRIMARY, target); +} /** * Claim ownership of the SECONDARY selection and set its data. - * @param window The window to which this selection belongs - * @param data The data associated with the selection - * @param size The size of the data buffer in bytes - * @return Returns 1 if the ownership of the selection was successfully - * claimed, or 0 if unsuccessful. - * - * To use this function, you must call before, and in order, - * ecore_x_selection_secondary_prefetch(), which sends the GetSelectionOwner request, - * then ecore_x_selection_secondary_fetch(), which gets the reply. + * @param w The window to which this selection belongs + * @param data The data associated with the selection + * @param size The size of the data buffer in bytes + * @return Returns 1 if the ownership of the selection was successfully + * claimed, or 0 if unsuccessful. */ -EAPI Eina_Bool -ecore_x_selection_secondary_set(Ecore_X_Window window, - const void *data, - int size) +EAPI Eina_Bool +ecore_x_selection_secondary_set(Ecore_X_Window win, const void *data, int size) { - return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_SECONDARY); -} /* ecore_x_selection_secondary_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(win, data, size, + ECORE_X_ATOM_SELECTION_SECONDARY); +} /** * Release ownership of the secondary selection * @return Returns 1 if the selection was successfully cleared, * or 0 if unsuccessful. - * - * To use this function, you must call before, and in order, - * ecore_x_selection_secondary_prefetch(), which sends the GetSelectionOwner request, - * then ecore_x_selection_secondary_fetch(), which gets the reply. */ -EAPI Eina_Bool -ecore_x_selection_secondary_clear(void) +EAPI Eina_Bool +ecore_x_selection_secondary_clear(void) { - return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_SECONDARY); -} /* ecore_x_selection_secondary_clear */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Sends the GetSelectionOwner request. - */ -EAPI void -ecore_x_selection_xdnd_prefetch(void) -{ - xcb_get_selection_owner_cookie_t cookie; + return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, + ECORE_X_ATOM_SELECTION_SECONDARY); +} - cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_XDND); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_selection_xdnd_prefetch */ - -/** - * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_xdnd_prefetch(). - */ -EAPI void -ecore_x_selection_xdnd_fetch(void) +EAPI void +ecore_x_selection_secondary_request(Ecore_X_Window win, const char *target) { - xcb_get_selection_owner_cookie_t cookie; - xcb_get_selection_owner_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_selection_xdnd_fetch */ + _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_SECONDARY, target); +} /** * Claim ownership of the XDND selection and set its data. - * @param window The window to which this selection belongs - * @param data The data associated with the selection - * @param size The size of the data buffer in bytes - * @return Returns 1 if the ownership of the selection was successfully - * claimed, or 0 if unsuccessful. - * - * To use this function, you must call before, and in order, - * ecore_x_selection_xdnd_prefetch(), which sends the GetSelectionOwner request, - * then ecore_x_selection_xdnd_fetch(), which gets the reply. + * @param w The window to which this selection belongs + * @param data The data associated with the selection + * @param size The size of the data buffer in bytes + * @return Returns 1 if the ownership of the selection was successfully + * claimed, or 0 if unsuccessful. */ -EAPI Eina_Bool -ecore_x_selection_xdnd_set(Ecore_X_Window window, - const void *data, - int size) +EAPI Eina_Bool +ecore_x_selection_xdnd_set(Ecore_X_Window win, const void *data, int size) { - return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_XDND); -} /* ecore_x_selection_xdnd_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(win, data, size, + ECORE_X_ATOM_SELECTION_XDND); +} /** * Release ownership of the XDND selection * @return Returns 1 if the selection was successfully cleared, * or 0 if unsuccessful. - * - * To use this function, you must call before, and in order, - * ecore_x_selection_xdnd_prefetch(), which sends the GetSelectionOwner request, - * then ecore_x_selection_xdnd_fetch(), which gets the reply. */ -EAPI Eina_Bool -ecore_x_selection_xdnd_clear(void) +EAPI Eina_Bool +ecore_x_selection_xdnd_clear(void) { - return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_XDND); -} /* ecore_x_selection_xdnd_clear */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Sends the GetSelectionOwner request. - */ -EAPI void -ecore_x_selection_clipboard_prefetch(void) + return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, + ECORE_X_ATOM_SELECTION_XDND); +} + +EAPI void +ecore_x_selection_xdnd_request(Ecore_X_Window win, const char *target) { - xcb_get_selection_owner_cookie_t cookie; + Ecore_X_Atom atom; + Ecore_X_DND_Target *_target; - cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_CLIPBOARD); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_selection_clipboard_prefetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_clipboard_prefetch(). - */ -EAPI void -ecore_x_selection_clipboard_fetch(void) -{ - xcb_get_selection_owner_cookie_t cookie; - xcb_get_selection_owner_reply_t *reply; + _target = _ecore_xcb_dnd_target_get(); + atom = _ecore_xcb_selection_target_atom_get(target); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_selection_clipboard_fetch */ + xcb_convert_selection(_ecore_xcb_conn, win, ECORE_X_ATOM_SELECTION_XDND, + atom, ECORE_X_ATOM_SELECTION_PROP_XDND, _target->time); +} /** * Claim ownership of the CLIPBOARD selection and set its data. - * @param window The window to which this selection belongs - * @param data The data associated with the selection - * @param size The size of the data buffer in bytes - * @return Returns 1 if the ownership of the selection was successfully - * claimed, or 0 if unsuccessful. + * @param w The window to which this selection belongs + * @param data The data associated with the selection + * @param size The size of the data buffer in bytes + * @return Returns 1 if the ownership of the selection was successfully + * claimed, or 0 if unsuccessful. * * Get the converted data from a previous CLIPBOARD selection * request. The buffer must be freed when done with. - * - * To use this function, you must call before, and in order, - * ecore_x_selection_clipboard_prefetch(), which sends the GetSelectionOwner request, - * then ecore_x_selection_clipboard_fetch(), which gets the reply. */ -EAPI Eina_Bool -ecore_x_selection_clipboard_set(Ecore_X_Window window, - const void *data, - int size) +EAPI Eina_Bool +ecore_x_selection_clipboard_set(Ecore_X_Window win, const void *data, int size) { - return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_CLIPBOARD); -} /* ecore_x_selection_clipboard_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(win, data, size, + ECORE_X_ATOM_SELECTION_CLIPBOARD); +} /** * Release ownership of the clipboard selection * @return Returns 1 if the selection was successfully cleared, * or 0 if unsuccessful. - * - * To use this function, you must call before, and in order, - * ecore_x_selection_clipboard_prefetch(), which sends the GetSelectionOwner request, - * then ecore_x_selection_clipboard_fetch(), which gets the reply. */ -EAPI Eina_Bool -ecore_x_selection_clipboard_clear(void) +EAPI Eina_Bool +ecore_x_selection_clipboard_clear(void) { - return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_CLIPBOARD); -} /* ecore_x_selection_clipboard_clear */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, + ECORE_X_ATOM_SELECTION_CLIPBOARD); +} -/* FIXME: roundtrip if target is not handled in the tests */ -Ecore_X_Atom -_ecore_x_selection_target_atom_get(const char *target) +EAPI void +ecore_x_selection_clipboard_request(Ecore_X_Window win, const char *target) { - Ecore_X_Atom x_target = XCB_NONE; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) - x_target = ECORE_X_ATOM_TEXT; - else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) - x_target = ECORE_X_ATOM_COMPOUND_TEXT; - else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) - x_target = ECORE_X_ATOM_STRING; - else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) - x_target = ECORE_X_ATOM_UTF8_STRING; - else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME)) - x_target = ECORE_X_ATOM_FILE_NAME; - else - { - xcb_intern_atom_cookie_t cookie; - xcb_intern_atom_reply_t *reply; + _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_CLIPBOARD, target); +} - cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, - strlen(target), target); - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - return XCB_NONE; +EAPI Eina_Bool +ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret, int *size, Ecore_X_Atom *targtype, int *typesize) +{ + Ecore_X_Selection_Intern *sel; + Ecore_X_Selection_Converter *cnv; + void *data; + char *tgt_str; - x_target = reply->atom; - free(reply); - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return x_target; -} /* _ecore_x_selection_target_atom_get */ + sel = _ecore_xcb_selection_get(selection); + tgt_str = _ecore_xcb_selection_target_get(target); -/* FIXME: roundtrip if target is not handled in the tests */ -char * -_ecore_x_selection_target_get(Ecore_X_Atom target) -{ - if (target == ECORE_X_ATOM_FILE_NAME) - return strdup(ECORE_X_SELECTION_TARGET_FILENAME); - else if (target == ECORE_X_ATOM_STRING) - return strdup(ECORE_X_SELECTION_TARGET_STRING); - else if (target == ECORE_X_ATOM_UTF8_STRING) - return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING); - else if (target == ECORE_X_ATOM_TEXT) - return strdup(ECORE_X_SELECTION_TARGET_TEXT); - else + for (cnv = _converters; cnv; cnv = cnv->next) { - xcb_get_atom_name_cookie_t cookie; - xcb_get_atom_name_reply_t *reply; - char *name; - - cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, target); - reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - return NULL; - - name = (char *)malloc(sizeof(char) * (reply->length + 1)); - if (!name) + if (cnv->target == target) { - free(reply); - return NULL; - } + int r = 0; - memcpy(name, xcb_get_atom_name_name(reply), reply->length); - name[reply->length] = '\0'; - free(reply); - return name; + r = cnv->convert(tgt_str, sel->data, sel->length, &data, size, + targtype, typesize); + free(tgt_str); + if (r) + { + if (data_ret) *data_ret = data; + return r; + } + else + return EINA_FALSE; + } } -} /* _ecore_x_selection_target_get */ -static void -_ecore_x_selection_request(Ecore_X_Window window, - Ecore_X_Atom selection, - const char *target_str) + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_selection_notify_send(Ecore_X_Window requestor, Ecore_X_Atom selection, Ecore_X_Atom target, Ecore_X_Atom property, Ecore_X_Time time) { - Ecore_X_Atom target, prop; + xcb_selection_notify_event_t ev; - target = _ecore_x_selection_target_atom_get(target_str); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) - prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY; - else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) - prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY; - else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) - prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD; - else - return; + memset(&ev, 0, sizeof(xcb_selection_notify_event_t)); - xcb_convert_selection(_ecore_xcb_conn, window, - selection, target, prop, - XCB_CURRENT_TIME); -} /* _ecore_x_selection_request */ + ev.response_type = XCB_SELECTION_NOTIFY; + ev.requestor = requestor; + ev.selection = selection; + ev.target = target; + ev.property = property; + ev.time = time; -EAPI void -ecore_x_selection_primary_request(Ecore_X_Window window, - const char *target) -{ - _ecore_x_selection_request(window, ECORE_X_ATOM_SELECTION_PRIMARY, target); -} /* ecore_x_selection_primary_request */ + xcb_send_event(_ecore_xcb_conn, 0, requestor, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -EAPI void -ecore_x_selection_secondary_request(Ecore_X_Window window, - const char *target) -{ - _ecore_x_selection_request(window, ECORE_X_ATOM_SELECTION_SECONDARY, target); -} /* ecore_x_selection_secondary_request */ + return EINA_TRUE; +} -EAPI void -ecore_x_selection_xdnd_request(Ecore_X_Window window, - const char *target) +EAPI void +ecore_x_selection_owner_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Time time) { - Ecore_X_Atom atom; - Ecore_X_DND_Target *_target; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - _target = _ecore_x_dnd_target_get(); - atom = _ecore_x_selection_target_atom_get(target); - xcb_convert_selection(_ecore_xcb_conn, window, - ECORE_X_ATOM_SELECTION_XDND, atom, - ECORE_X_ATOM_SELECTION_PROP_XDND, - _target->time); -} /* ecore_x_selection_xdnd_request */ + xcb_set_selection_owner(_ecore_xcb_conn, win, atom, time); +} -EAPI void -ecore_x_selection_clipboard_request(Ecore_X_Window window, const char *target) +EAPI Ecore_X_Window +ecore_x_selection_owner_get(Ecore_X_Atom atom) { - _ecore_x_selection_request(window, ECORE_X_ATOM_SELECTION_CLIPBOARD, target); -} /* ecore_x_selection_clipboard_request */ - -EAPI void -ecore_x_selection_converter_atom_add(Ecore_X_Atom target, - Eina_Bool (*func) - (char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *ttype, - int *tsize)) + xcb_get_selection_owner_cookie_t cookie; + xcb_get_selection_owner_reply_t *reply; + Ecore_X_Window ret; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + cookie = xcb_get_selection_owner(_ecore_xcb_conn, atom); + reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + ret = reply->owner; + free(reply); + return ret; +} + +void * +_ecore_xcb_selection_parse(const char *target, void *data, int size, int format) { - Ecore_X_Selection_Converter *cnv; + Ecore_X_Selection_Parser *prs; + Ecore_X_Selection_Data *sel; - cnv = converters; - if (converters) + for (prs = _parsers; prs; prs = prs->next) { - while (1) + if (!strcmp(prs->target, target)) { - if (cnv->target == target) - { - cnv->convert = func; - return; - } - - if (cnv->next) - cnv = cnv->next; - else - break; + sel = prs->parse(target, data, size, format); + if (sel) return sel; } - - cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter)); - cnv = cnv->next; - } - else - { - converters = calloc(1, sizeof(Ecore_X_Selection_Converter)); - cnv = converters; } - cnv->target = target; - cnv->convert = func; -} /* ecore_x_selection_converter_atom_add */ - -EAPI void -ecore_x_selection_converter_add(char *target, - Eina_Bool (*func) - (char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *, - int *)) -{ - Ecore_X_Atom x_target; - - if (!func || !target) - return; + sel = calloc(1, sizeof(Ecore_X_Selection_Data)); + if (!sel) return NULL; + sel->free = _ecore_xcb_selection_data_default_free; + sel->length = size; + sel->format = format; + sel->data = data; - x_target = _ecore_x_selection_target_atom_get(target); + return sel; +} - ecore_x_selection_converter_atom_add(x_target, func); -} /* ecore_x_selection_converter_add */ +Ecore_X_Selection_Intern * +_ecore_xcb_selection_get(Ecore_X_Atom selection) +{ + if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) + return &_selections[0]; + else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) + return &_selections[1]; + else if (selection == ECORE_X_ATOM_SELECTION_XDND) + return &_selections[2]; + else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) + return &_selections[3]; + else + return NULL; +} -EAPI void -ecore_x_selection_converter_atom_del(Ecore_X_Atom target) +/* local functions */ +static Eina_Bool +_ecore_xcb_selection_set(Ecore_X_Window win, const void *data, int size, Ecore_X_Atom selection) { - Ecore_X_Selection_Converter *cnv, *prev_cnv; + xcb_get_selection_owner_cookie_t cookie; + xcb_get_selection_owner_reply_t *reply; + int in = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - prev_cnv = NULL; - cnv = converters; + xcb_set_selection_owner(_ecore_xcb_conn, win, + selection, ecore_x_current_time_get()); - while (cnv) + cookie = xcb_get_selection_owner(_ecore_xcb_conn, selection); + reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + if (reply->owner != win) { - if (cnv->target == target) - { - if (prev_cnv) - prev_cnv->next = cnv->next; - else - converters = cnv->next; /* This was the first converter */ + free(reply); + return EINA_FALSE; + } + free(reply); - free(cnv); + if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) + in = 0; + else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) + in = 1; + else if (selection == ECORE_X_ATOM_SELECTION_XDND) + in = 2; + else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) + in = 3; + else + return EINA_FALSE; - return; - } + if (data) + { + unsigned char *buff = NULL; - prev_cnv = cnv; - cnv = cnv->next; + _selections[in].win = win; + _selections[in].selection = selection; + _selections[in].length = size; + _selections[in].time = ecore_x_current_time_get(); + + buff = malloc(size); + if (!buff) return EINA_FALSE; + memcpy(buff, data, size); + _selections[in].data = buff; } -} /* ecore_x_selection_converter_atom_del */ + else if (_selections[in].data) + { + free(_selections[in].data); + memset(&_selections[in], 0, sizeof(Ecore_X_Selection_Data)); + } + + return EINA_TRUE; +} -EAPI void -ecore_x_selection_converter_del(char *target) +static void +_ecore_xcb_selection_request(Ecore_X_Window win, Ecore_X_Atom selection, const char *target) { - Ecore_X_Atom x_target; + Ecore_X_Atom atarget, prop; - if (!target) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - x_target = _ecore_x_selection_target_atom_get(target); - ecore_x_selection_converter_atom_del(x_target); -} /* ecore_x_selection_converter_del */ + if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) + prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY; + else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) + prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY; + else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) + prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD; + else + return; -EAPI Eina_Bool -ecore_x_selection_notify_send(Ecore_X_Window requestor, - Ecore_X_Atom selection, - Ecore_X_Atom target, - Ecore_X_Atom property, - Ecore_X_Time time) -{ - xcb_selection_notify_event_t ev; + atarget = _ecore_xcb_selection_target_atom_get(target); - ev.time = time; - ev.requestor = requestor; - ev.selection = selection; - ev.target = target; - ev.property = property; - /* send_event is bit 7 (0x80) of response_type */ - ev.response_type = 0x80; + xcb_convert_selection(_ecore_xcb_conn, win, selection, atarget, prop, + ecore_x_current_time_get()); +} - xcb_send_event(_ecore_xcb_conn, 0, - requestor, 0, (const char *)&ev); - return 1; -} /* ecore_x_selection_notify_send */ - -/* Locate and run conversion callback for specified selection target */ -EAPI Eina_Bool -ecore_x_selection_convert(Ecore_X_Atom selection, - Ecore_X_Atom target, - void **data_ret, - int *size, - Ecore_X_Atom *targtype, - int *typesize) +static Eina_Bool +_ecore_xcb_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *type __UNUSED__, int *size_type __UNUSED__) { - Ecore_X_Selection_Intern *sel; - Ecore_X_Selection_Converter *cnv; - void *data; - char *tgt_str; + Ecore_Xcb_Encoding_Style style; + Ecore_Xcb_Textproperty ret; + char *str; - sel = _ecore_x_selection_get(selection); - tgt_str = _ecore_x_selection_target_get(target); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - for (cnv = converters; cnv; cnv = cnv->next) - { - if (cnv->target == target) - { - int r; - r = cnv->convert(tgt_str, sel->data, sel->length, &data, size, targtype, typesize); - free(tgt_str); - if (r) - { - *data_ret = data; - return r; - } - else - return 0; - } - } + if ((!data) || (!size)) return EINA_FALSE; - /* Default, just return the data */ - *data_ret = malloc(sel->length); - memcpy(*data_ret, sel->data, sel->length); - free(tgt_str); - return 1; -} /* ecore_x_selection_convert */ - -/* TODO: We need to work out a mechanism for automatic conversion to any requested - * locale using Ecore_Txt functions */ -/* Converter for standard non-utf8 text targets */ -static Eina_Bool -_ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *targprop, int *s) -{ - /* FIXME: to do... */ - -/* XTextProperty text_prop; */ -/* char *mystr; */ -/* XICCEncodingStyle style; */ - -/* if (!data || !size) */ -/* return 0; */ - -/* if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) */ -/* style = XTextStyle; */ -/* else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) */ -/* style = XCompoundTextStyle; */ -/* else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) */ -/* style = XStringStyle; */ -/* #ifdef X_HAVE_UTF8_STRING */ -/* else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) */ -/* style = XUTF8StringStyle; */ -/* #endif */ -/* else */ -/* return 0; */ - -/* if (!(mystr = strdup(data))) */ -/* return 0; */ - -/* #ifdef X_HAVE_UTF8_STRING */ -/* if (Xutf8TextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success) */ -/* { */ -/* int bufsize = strlen((char *)text_prop.value) + 1; */ -/* *data_ret = malloc(bufsize); */ -/* memcpy(*data_ret, text_prop.value, bufsize); */ -/* *size_ret = bufsize; */ -/* XFree(text_prop.value); */ -/* free(mystr); */ -/* return 1; */ -/* } */ -/* #else */ -/* if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success) */ -/* { */ -/* int bufsize = strlen(text_prop.value) + 1; */ -/* *data_ret = malloc(bufsize); */ -/* memcpy(*data_ret, text_prop.value, bufsize); */ -/* *size_ret = bufsize; */ -/* XFree(text_prop.value); */ -/* free(mystr); */ -/* return 1; */ -/* } */ -/* #endif */ -/* else */ -/* { */ -/* free(mystr); */ -/* return 0; */ -/* } */ - - return 0; -} /* _ecore_x_selection_converter_text */ - -EAPI void -ecore_x_selection_parser_add(const char *target, - void *(*func)(const char *target, - void *data, - int size, - int format)) -{ - Ecore_X_Selection_Parser *prs; + if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) + style = XcbTextStyle; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) + style = XcbCompoundTextStyle; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) + style = XcbStringStyle; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) + style = XcbUTF8StringStyle; + else + return EINA_FALSE; - if (!target) - return; + if (!(str = strdup(data))) return EINA_FALSE; - prs = parsers; - if (parsers) +#ifdef HAVE_ICONV + if (_ecore_xcb_utf8_textlist_to_textproperty(&str, 1, style, &ret)) { - while (prs->next) - { - if (!strcmp(prs->target, target)) - { - prs->parse = func; - return; - } + int size = 0; - prs = prs->next; + size = (strlen((char *)ret.value) + 1); + *data_ret = malloc(size); + if (!*data_ret) + { + free(str); + return EINA_FALSE; } + memcpy(*data_ret, ret.value, size); + *size_ret = size; + if (ret.value) free(ret.value); + if (str) free(str); + return EINA_TRUE; + } +#else + if (_ecore_xcb_mb_textlist_to_textproperty(&str, 1, style, &ret)) + { + int size = 0; - prs->next = calloc(1, sizeof(Ecore_X_Selection_Parser)); - prs = prs->next; + size = (strlen((char *)ret.value) + 1); + *data_ret = malloc(size); + if (!*data_ret) + { + free(str); + return EINA_FALSE; + } + memcpy(*data_ret, ret.value, size); + *size_ret = size; + if (ret.value) free(ret.value); + if (str) free(str); + return EINA_TRUE; } - else +#endif + else { - parsers = calloc(1, sizeof(Ecore_X_Selection_Parser)); - prs = parsers; + if (str) free(str); + return EINA_TRUE; } + return EINA_FALSE; +} - prs->target = strdup(target); - prs->parse = func; -} /* ecore_x_selection_parser_add */ - -EAPI void -ecore_x_selection_parser_del(const char *target) +static void * +_ecore_xcb_selection_parser_text(const char *target __UNUSED__, void *data, int size, int format __UNUSED__) { - Ecore_X_Selection_Parser *prs, *prev_prs; - - if (!target) - return; - - prev_prs = NULL; - prs = parsers; - - while (prs) - { - if (!strcmp(prs->target, target)) - { - if (prev_prs) - prev_prs->next = prs->next; - else - parsers = prs->next; /* This was the first parser */ + Ecore_X_Selection_Data_Text *sel; + char *_data; - free(prs->target); - free(prs); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return; - } + if (!(_data = data)) return NULL; - prev_prs = prs; - prs = prs->next; - } -} /* ecore_x_selection_parser_del */ - -/* Locate and run conversion callback for specified selection target */ -void * -_ecore_x_selection_parse(const char *target, void *data, int size, int format) -{ - Ecore_X_Selection_Parser *prs; - Ecore_X_Selection_Data *sel; + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text)); + if (!sel) return NULL; - for (prs = parsers; prs; prs = prs->next) + if (_data[size - 1]) { - if (!strcmp(prs->target, target)) - { - sel = prs->parse(target, data, size, format); - return sel; - } + size++; + _data = realloc(_data, size); + _data[size - 1] = 0; } - - /* Default, just return the data */ - sel = calloc(1, sizeof(Ecore_X_Selection_Data)); - sel->free = _ecore_x_selection_data_default_free; - sel->length = size; - sel->format = format; - sel->data = data; + sel->text = (char *)_data; + ECORE_XCB_SELECTION_DATA(sel)->length = size; + ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TEXT; + ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_text_free; return sel; -} /* _ecore_x_selection_parse */ - -static Eina_Bool -_ecore_x_selection_data_default_free(void *data) -{ - Ecore_X_Selection_Data *sel; - - sel = data; - free(sel->data); - free(sel); - return 1; -} /* _ecore_x_selection_data_default_free */ +} static void * -_ecore_x_selection_parser_files(const char *target, void *_data, int size, int format __UNUSED__) +_ecore_xcb_selection_parser_files(const char *target, void *data, int size, int format __UNUSED__) { Ecore_X_Selection_Data_Files *sel; - char *data = _data; - int i, is; - char *tmp; + char *_data, *tmp; + int i = 0, is = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (strcmp(target, "text/uri-list") && - strcmp(target, "_NETSCAPE_URL")) - return NULL; + if ((strcmp(target, "text/uri-list")) && + (strcmp(target, "_NETSCAPE_URL"))) return NULL; + + if (!(_data = data)) return NULL; sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files)); - ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free; + if (!sel) return NULL; + + ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_files_free; - if (data[size - 1]) + if (_data[size - 1]) { - /* Isn't nul terminated */ size++; - data = realloc(data, size); - data[size - 1] = 0; + _data = realloc(_data, size); + _data[size - 1] = 0; } tmp = malloc(size); - i = 0; - is = 0; - while ((is < size) && (data[is])) + while ((is < size) && (_data[is])) { - if ((i == 0) && (data[is] == '#')) + if ((i == 0) && (_data[is] == '#')) { - for (; ((data[is]) && (data[is] != '\n')); is++) ; + for (; ((_data[is]) && (_data[is] != '\n')); is++) ; } - else + else { - if ((data[is] != '\r') && - (data[is] != '\n')) + if ((_data[is] != '\r') && (_data[is] != '\n')) + tmp[i++] = _data[is++]; + else { - tmp[i++] = data[is++]; - } - else - { - while ((data[is] == '\r') || (data[is] == '\n')) is++; + while ((_data[is] == '\r') || (_data[is] == '\n')) + is++; tmp[i] = 0; sel->num_files++; - sel->files = realloc(sel->files, sel->num_files * sizeof(char *)); + sel->files = + realloc(sel->files, sel->num_files * sizeof(char *)); sel->files[sel->num_files - 1] = strdup(tmp); tmp[0] = 0; i = 0; } } } - if (i > 0) + if (i > 0) { tmp[i] = 0; sel->num_files++; sel->files = realloc(sel->files, sel->num_files * sizeof(char *)); sel->files[sel->num_files - 1] = strdup(tmp); } + if (tmp) free(tmp); + if (_data) free(_data); + ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES; + ECORE_XCB_SELECTION_DATA(sel)->length = sel->num_files; + return ECORE_XCB_SELECTION_DATA(sel); +} - free(tmp); - free(data); +static void * +_ecore_xcb_selection_parser_targets(const char *target __UNUSED__, void *data, int size, int format __UNUSED__) +{ + Ecore_X_Selection_Data_Targets *sel; + uint32_t *targets; + xcb_get_atom_name_cookie_t *cookies; + int i = 0; - ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES; - ECORE_X_SELECTION_DATA(sel)->length = sel->num_files; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return ECORE_X_SELECTION_DATA(sel); -} /* _ecore_x_selection_parser_files */ + if (!(targets = (uint32_t *)data)) return NULL; -static Eina_Bool -_ecore_x_selection_data_files_free(void *data) -{ - Ecore_X_Selection_Data_Files *sel; - int i; + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets)); + if (!sel) return NULL; + + sel->num_targets = (size - 2); + sel->targets = malloc((size - 2) * sizeof(char *)); + cookies = + (xcb_get_atom_name_cookie_t *)malloc((size - 2) * + sizeof(xcb_get_atom_name_cookie_t)); + for (i = 0; i < (size - 2); i++) + cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, targets[i + 2]); - sel = data; - if (sel->files) + for (i = 0; i < (size - 2); i++) { - for (i = 0; i < sel->num_files; i++) - free(sel->files[i]); - free(sel->files); + xcb_get_atom_name_reply_t *reply; + char *name; + int len = 0; + + reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL); + len = reply->name_len; + name = (char *)malloc(len + 1); + memcpy(name, xcb_get_atom_name_name(reply), len); + name[len] = '\0'; + sel->targets[i - 2] = name; } + free(cookies); + free(data); - free(sel); - return 0; -} /* _ecore_x_selection_data_files_free */ + ECORE_XCB_SELECTION_DATA(sel)->free = + _ecore_xcb_selection_data_targets_free; + ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TARGETS; + ECORE_XCB_SELECTION_DATA(sel)->length = size; -static void * -_ecore_x_selection_parser_text(const char *target __UNUSED__, - void *_data, - int size, - int format __UNUSED__) + return sel; +} + +/* +static int +_ecore_xcb_selection_data_free(void *data) { - Ecore_X_Selection_Data_Text *sel; - char *data = _data; + Ecore_X_Selection_Data *sel; - sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text)); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (data[size - 1]) - { - /* Isn't nul terminated */ - size++; - data = realloc(data, size); - data[size - 1] = 0; - } - - sel->text = (char *)data; - ECORE_X_SELECTION_DATA(sel)->length = size; - ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TEXT; - ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_text_free; - return sel; -} /* _ecore_x_selection_parser_text */ + if (!(sel = data)) return 0; + if (sel->data) free(sel->data); + free(sel); + return 1; +} +*/ -static Eina_Bool -_ecore_x_selection_data_text_free(void *data) +static int +_ecore_xcb_selection_data_text_free(void *data) { Ecore_X_Selection_Data_Text *sel; - sel = data; - free(sel->text); + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sel = data)) return 0; + if (sel->text) free(sel->text); free(sel); return 1; -} /* _ecore_x_selection_data_text_free */ +} -static void * -_ecore_x_selection_parser_targets(const char *target __UNUSED__, - void *data, - int size, - int format __UNUSED__) +static int +_ecore_xcb_selection_data_targets_free(void *data) { Ecore_X_Selection_Data_Targets *sel; - uint32_t *targets; - xcb_get_atom_name_cookie_t *cookies; - int i; - - sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets)); - targets = (uint32_t *)data; - sel->num_targets = size - 2; - sel->targets = malloc((size - 2) * sizeof(char *)); - cookies = (xcb_get_atom_name_cookie_t *)malloc ((size - 2) * sizeof (xcb_get_atom_name_cookie_t)); - for (i = 0; i < size - 2; i++) - cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, targets[i + 2]); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* FIXME: do we let the declaration of reply inside the loop ? */ - for (i = 0; i < size - 2; i++) + if (!(sel = data)) return 0; + if (sel->targets) { - xcb_get_atom_name_reply_t *reply; - char *name; - int length; + int i = 0; - reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL); - length = xcb_get_atom_name_name_length(reply); - name = (char *)malloc (length + 1); - memcpy(name, xcb_get_atom_name_name(reply), length); - name[length] = '\0'; - sel->targets[i - 2] = name; + for (i = 0; i < sel->num_targets; i++) + if (sel->targets[i]) free(sel->targets[i]); + if (sel->targets) free(sel->targets); } - free(cookies); - free(data); - - ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_targets_free; - ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TARGETS; - ECORE_X_SELECTION_DATA(sel)->length = size; - return sel; -} /* _ecore_x_selection_parser_targets */ + free(sel); + return 1; +} -static Eina_Bool -_ecore_x_selection_data_targets_free(void *data) +static int +_ecore_xcb_selection_data_files_free(void *data) { - Ecore_X_Selection_Data_Targets *sel; - int i; + Ecore_X_Selection_Data_Files *sel; - sel = data; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (sel->targets) + if (!(sel = data)) return 0; + if (sel->files) { - for (i = 0; i < sel->num_targets; i++) - free(sel->targets[i]); - free(sel->targets); + int i = 0; + + for (i = 0; i < sel->num_files; i++) + if (sel->files[i]) free(sel->files[i]); + if (sel->files) free(sel->files); } + free(sel); + return 1; +} +static int +_ecore_xcb_selection_data_default_free(void *data) +{ + Ecore_X_Selection_Data *sel; + + if (!(sel = data)) return 1; + free(sel->data); free(sel); return 1; -} /* _ecore_x_selection_data_targets_free */ +} + +static Ecore_X_Atom +_ecore_xcb_selection_target_atom_get(const char *target) +{ + Ecore_X_Atom x_target; + + if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) + x_target = ECORE_X_ATOM_TEXT; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) + x_target = ECORE_X_ATOM_COMPOUND_TEXT; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) + x_target = ECORE_X_ATOM_STRING; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) + x_target = ECORE_X_ATOM_UTF8_STRING; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME)) + x_target = ECORE_X_ATOM_FILE_NAME; + else + x_target = ecore_x_atom_get(target); + return x_target; +} + +char * +_ecore_xcb_selection_target_get(Ecore_X_Atom target) +{ + if (target == ECORE_X_ATOM_FILE_NAME) + return strdup(ECORE_X_SELECTION_TARGET_FILENAME); + else if (target == ECORE_X_ATOM_STRING) + return strdup(ECORE_X_SELECTION_TARGET_STRING); + else if (target == ECORE_X_ATOM_UTF8_STRING) + return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING); + else if (target == ECORE_X_ATOM_TEXT) + return strdup(ECORE_X_SELECTION_TARGET_TEXT); + else + return ecore_x_atom_name_get(target); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_shape.c b/src/lib/ecore_x/xcb/ecore_xcb_shape.c index 3bd330d..526742a 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_shape.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_shape.c @@ -1,289 +1,51 @@ #include "ecore_xcb_private.h" - -/** - * @defgroup Ecore_X_Shape_Group X Shape extension - * - * Functions that use the shape extension of the X server to change shape of given windows. - */ - -#ifdef ECORE_XCB_SHAPE -static int _shape_available = 0; -static xcb_shape_query_version_cookie_t _ecore_xcb_shape_init_cookie; -#endif /* ECORE_XCB_SHAPE */ - -/* To avoid round trips, the initialization is separated in 2 - functions: _ecore_xcb_shape_init and - _ecore_xcb_shape_init_finalize. The first one gets the cookies and - the second one gets the replies. */ - -void -_ecore_x_shape_init(const xcb_query_extension_reply_t *reply) -{ -#ifdef ECORE_XCB_SHAPE - if (reply && (reply->present)) - _ecore_xcb_shape_init_cookie = xcb_shape_query_version_unchecked(_ecore_xcb_conn); - -#endif /* ECORE_XCB_SHAPE */ -} /* _ecore_x_shape_init */ - -void -_ecore_x_shape_init_finalize(void) -{ -#ifdef ECORE_XCB_SHAPE - xcb_shape_query_version_reply_t *reply; - - reply = xcb_shape_query_version_reply(_ecore_xcb_conn, - _ecore_xcb_shape_init_cookie, - NULL); - if (reply) - { - _shape_available = 1; - free(reply); - } - -#endif /* ECORE_XCB_SHAPE */ -} /* _ecore_x_shape_init_finalize */ - -/** - * Sets the shape of the given window to the given pixmap. - * @param dest_win The given window. - * @param source_mask A 2-bit depth pixmap that provides the new shape of the window. - * - * Sets the shape of the window @p dest_win to the pixmap @p source_mask. - * @ingroup Ecore_X_Shape_Group - */ -EAPI void -ecore_x_window_shape_mask_set(Ecore_X_Window dest_win, - Ecore_X_Pixmap source_mask) -{ #ifdef ECORE_XCB_SHAPE - xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, dest_win, 0, 0, source_mask); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_mask_set */ +# include +#endif -EAPI void -ecore_x_window_shape_window_set(Ecore_X_Window dest_win, - Ecore_X_Window shape_win) -{ -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, 0, 0, shape_win); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_window_set */ +/* external variables */ +int _ecore_xcb_event_shape = -1; -EAPI void -ecore_x_window_shape_window_set_xy(Ecore_X_Window dest_win, - Ecore_X_Window shape_win, - int x, - int y) +void +_ecore_xcb_shape_init(void) { -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, x, y, shape_win); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_window_set_xy */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Sets the shape of the given window to a rectangle. - * @param dest_win The given window. - * @param x The X coordinate of the top left corner of the rectangle. - * @param y The Y coordinate of the top left corner of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. - * - * Sets the shape of the window @p dest_win to a rectangle defined by - * @p x, @p y, @p width and @p height. - * @ingroup Ecore_X_Shape_Group - */ -EAPI void -ecore_x_window_shape_rectangle_set(Ecore_X_Window dest_win, - int x, - int y, - int width, - int height) -{ #ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shape_id); +#endif +} - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 1, &rect); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_rectangle_set */ - -EAPI void -ecore_x_window_shape_rectangles_set(Ecore_X_Window dest_win, - Ecore_X_Rectangle *rects, - int num) +void +_ecore_xcb_shape_finalize(void) { #ifdef ECORE_XCB_SHAPE - if (num > 0) - xcb_shape_rectangles(_ecore_xcb_conn, - XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, - 0, dest_win, 0, 0, num, (xcb_rectangle_t *)rects); - else - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 0, NULL); + const xcb_query_extension_reply_t *ext_reply; +#endif -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_rectangles_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -EAPI void -ecore_x_window_shape_window_add(Ecore_X_Window dest_win, - Ecore_X_Window shape_win) -{ #ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, 0, 0, shape_win); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_window_add */ - -EAPI void -ecore_x_window_shape_window_add_xy(Ecore_X_Window dest_win, - Ecore_X_Window shape_win, - int x, - int y) -{ -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, x, y, shape_win); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_window_add_xy */ - -EAPI void -ecore_x_window_shape_rectangle_add(Ecore_X_Window dest_win, - int x, - int y, - int width, - int height) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 1, &rect); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_rectangle_add */ - -EAPI void -ecore_x_window_shape_rectangle_clip(Ecore_X_Window dest_win, - int x, - int y, - int width, - int height) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - xcb_shape_rectangles(_ecore_xcb_conn, - XCB_SHAPE_SO_INTERSECT, XCB_SHAPE_SK_BOUNDING, - 0, dest_win, 0, 0, 1, &rect); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_rectangle_clip */ - -EAPI void -ecore_x_window_shape_rectangles_add(Ecore_X_Window dest_win, - Ecore_X_Rectangle *rects, - int num) -{ -#ifdef ECORE_XCB_SHAPE - if (num > 0) - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, num, (const xcb_rectangle_t *)rects); - else - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 0, NULL); - -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_rectangles_add */ - -/** - * Sends the ShapeGetRectangles request. - * @param window Requested window. - * @ingroup Ecore_X_Shape_Group - */ -EAPI void -ecore_x_window_shape_rectangles_get_prefetch(Ecore_X_Window window) -{ -#ifdef ECORE_XCB_SHAPE - xcb_shape_get_rectangles_cookie_t cookie; - - cookie = xcb_shape_get_rectangles_unchecked(_ecore_xcb_conn, window, XCB_SHAPE_SK_BOUNDING); - _ecore_xcb_cookie_cache(cookie.sequence); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_rectangles_get_prefetch */ - -/** - * Gets the reply of the ShapeGetRectangles request sent by ecore_x_window_shape_rectangles_get_prefetch(). - * @ingroup Ecore_X_Shape_Group - */ -EAPI void -ecore_x_window_shape_rectangles_get_fetch(void) -{ -#ifdef ECORE_XCB_SHAPE - xcb_shape_get_rectangles_cookie_t cookie; - xcb_shape_get_rectangles_reply_t *reply; - - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_shape_get_rectangles_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_rectangles_get_fetch */ - -/** - * To document. - * @param window Unused. - * @param num_ret To document. - * @return To document. - * - * To use this function, you must call before, and in order, - * ecore_x_window_shape_rectangles_get_prefetch(), which sends the ShapeGetRectangles request, - * then ecore_x_window_shape_rectangles_get_fetch(), which gets the reply. - * @ingroup Ecore_X_Shape_Group - */ -EAPI Ecore_X_Rectangle * -ecore_x_window_shape_rectangles_get(Ecore_X_Window window __UNUSED__, - int *num_ret) -{ - Ecore_X_Rectangle *rects = NULL; - uint32_t num = 0; -#ifdef ECORE_XCB_SHAPE - xcb_shape_get_rectangles_reply_t *reply; - - reply = _ecore_xcb_reply_get(); - if (!reply) + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_shape_id); + if ((ext_reply) && (ext_reply->present)) { - if (num_ret) - *num_ret = 0; - - return NULL; + xcb_shape_query_version_cookie_t cookie; + xcb_shape_query_version_reply_t *reply; + Eina_Bool _shape_avail = EINA_FALSE; + + cookie = xcb_shape_query_version_unchecked(_ecore_xcb_conn); + reply = xcb_shape_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if ((reply->major_version >= XCB_SHAPE_MAJOR_VERSION) && + (reply->minor_version >= XCB_SHAPE_MINOR_VERSION)) + _shape_avail = EINA_TRUE; + + free(reply); + } + + if (_shape_avail) + _ecore_xcb_event_shape = ext_reply->first_event; } - - num = reply->rectangles_len; - rects = malloc(sizeof(Ecore_X_Rectangle) * num); - if (rects) - memcpy (rects, - xcb_shape_get_rectangles_rectangles(reply), - num * sizeof (Ecore_X_Rectangle)); - else - num = 0; - -#endif /* ECORE_XCB_SHAPE */ - - if (num_ret) - *num_ret = num; - - return rects; -} /* ecore_x_window_shape_rectangles_get */ - -EAPI void -ecore_x_window_shape_events_select(Ecore_X_Window dest_win, - Eina_Bool on) -{ -#ifdef ECORE_XCB_SHAPE - xcb_shape_select_input(_ecore_xcb_conn, dest_win, on ? 1 : 0); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_shape_events_select */ - +#endif +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_sync.c b/src/lib/ecore_x/xcb/ecore_xcb_sync.c index b4e867c..2f9a219 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_sync.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_sync.c @@ -1,221 +1,298 @@ #include "ecore_xcb_private.h" +# ifdef ECORE_XCB_SYNC +# include +# endif -/** - * @defgroup Ecore_X_Sync_Group X Sync Extension Functions - * - * Functions related to the X Sync extension. - */ +/* local variables */ +static Eina_Bool _sync_avail = EINA_FALSE; -#ifdef ECORE_XCB_SYNC -static int _sync_available = 0; -static xcb_sync_initialize_cookie_t _ecore_xcb_sync_init_cookie; -#endif /* ECORE_XCB_SYNC */ - -/* To avoid round trips, the initialization is separated in 2 - functions: _ecore_xcb_sync_init and - _ecore_xcb_sync_init_finalize. The first one gets the cookies and - the second one gets the replies and set the atoms. */ +/* external variables */ +int _ecore_xcb_event_sync = -1; -void -_ecore_x_sync_init(const xcb_query_extension_reply_t *reply) +void +_ecore_xcb_sync_init(void) { -#ifdef ECORE_XCB_SYNC - if (reply && (reply->present)) - _ecore_xcb_sync_init_cookie = xcb_sync_initialize_unchecked(_ecore_xcb_conn, - XCB_SYNC_MAJOR_VERSION, - XCB_SYNC_MINOR_VERSION); + LOGFN(__FILE__, __LINE__, __FUNCTION__); -#endif /* ECORE_XCB_SYNC */ -} /* _ecore_x_sync_init */ +#ifdef ECORE_XCB_SYNC + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_sync_id); +#endif +} -void -_ecore_x_sync_init_finalize(void) +void +_ecore_xcb_sync_finalize(void) { #ifdef ECORE_XCB_SYNC - xcb_sync_initialize_reply_t *reply; + const xcb_query_extension_reply_t *ext_reply; +#endif - reply = xcb_sync_initialize_reply(_ecore_xcb_conn, - _ecore_xcb_sync_init_cookie, NULL); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (reply) +#ifdef ECORE_XCB_SYNC + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_sync_id); + if ((ext_reply) && (ext_reply->present)) { - if (reply->major_version >= 3) - _sync_available = 1; + xcb_sync_initialize_cookie_t cookie; + xcb_sync_initialize_reply_t *reply; - free(reply); + cookie = + xcb_sync_initialize_unchecked(_ecore_xcb_conn, + XCB_SYNC_MAJOR_VERSION, + XCB_SYNC_MINOR_VERSION); + reply = xcb_sync_initialize_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (reply->major_version >= 3) _sync_avail = EINA_TRUE; + free(reply); + } + + if (_sync_avail) + _ecore_xcb_event_sync = ext_reply->first_event; } +#endif +} -#endif /* ECORE_XCB_SYNC */ -} /* _ecore_x_sync_init_finalize */ - -/** - * Return whether the X server supports the Sync Extension. - * @return 1 if the X Sync Extension is available, 0 otherwise. - * - * Return 1 if the X server supports the Sync Extension version 3.0, - * 0 otherwise. - * @ingroup Ecore_X_Sync_Group - */ -EAPI Eina_Bool -ecore_x_sync_query(void) +void +_ecore_xcb_sync_magic_send(int val, Ecore_X_Window win) { -#ifdef ECORE_XCB_SYNC - return _sync_available; -#else /* ifdef ECORE_XCB_SYNC */ - return 0; -#endif /* ECORE_XCB_SYNC */ -} /* ecore_x_sync_query */ - -/** - * Create a new alarm. - * @param counter A counter. - * @return A newly created alarm. - * - * Create a new alarm. - * @ingroup Ecore_X_Sync_Group - */ -EAPI Ecore_X_Sync_Alarm -ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, 27777, XCB_EVENT_MASK_NO_EVENT, + 0x7162534, (0x10000000 + val), win, 0, 0); +} + +/* public functions */ +EAPI Ecore_X_Sync_Alarm +ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter) { #ifdef ECORE_XCB_SYNC - uint32_t value_list[6]; + uint32_t list[6], mask; xcb_sync_int64_t init; Ecore_X_Sync_Alarm alarm; - uint32_t value_mask; +#endif + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!_sync_avail) || (!counter)) return 0; + +#ifdef ECORE_XCB_SYNC init.lo = 0; init.hi = 0; xcb_sync_set_counter(_ecore_xcb_conn, counter, init); - value_mask = - XCB_SYNC_CA_COUNTER | XCB_SYNC_CA_VALUE_TYPE | - XCB_SYNC_CA_VALUE | XCB_SYNC_CA_TEST_TYPE | - XCB_SYNC_CA_DELTA | XCB_SYNC_CA_EVENTS; - value_list[0] = counter; - value_list[1] = XCB_SYNC_VALUETYPE_ABSOLUTE; - value_list[2] = 1; - value_list[3] = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON; - value_list[4] = 1; - value_list[5] = 1; + mask = (XCB_SYNC_CA_COUNTER | XCB_SYNC_CA_VALUE_TYPE | + XCB_SYNC_CA_VALUE | XCB_SYNC_CA_TEST_TYPE | + XCB_SYNC_CA_DELTA | XCB_SYNC_CA_EVENTS); + list[0] = counter; + list[1] = XCB_SYNC_VALUETYPE_ABSOLUTE; + list[2] = 1; + list[3] = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON; + list[4] = 1; + list[5] = 1; alarm = xcb_generate_id(_ecore_xcb_conn); - xcb_sync_create_alarm(_ecore_xcb_conn, - alarm, - value_mask, - (const uint32_t *)value_list); - ecore_x_sync(); + xcb_sync_create_alarm(_ecore_xcb_conn, alarm, mask, list); + ecore_x_sync(); // needed + return alarm; -#else /* ifdef ECORE_XCB_SYNC */ +#endif return 0; -#endif /* ECORE_XCB_SYNC */ -} /* ecore_x_sync_alarm_new */ - -/** - * Delete an alarm. - * @param alarm The alarm to delete. - * @return 1 on success, 0 otherwise. - * - * Delete the @p alarm. Returns 1 on success, 0 otherwise. - * @ingroup Ecore_X_Sync_Group - */ -EAPI Eina_Bool -ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm) +} + +EAPI Eina_Bool +ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!_sync_avail) || (!alarm)) return EINA_FALSE; + #ifdef ECORE_XCB_SYNC xcb_sync_destroy_alarm(_ecore_xcb_conn, alarm); - return 1; -#else /* ifdef ECORE_XCB_SYNC */ - return 0; -#endif /* ECORE_XCB_SYNC */ -} /* ecore_x_sync_alarm_free */ + return EINA_TRUE; +#endif -/* FIXME: round trip */ + return EINA_FALSE; +} -EAPI Eina_Bool -ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter, unsigned int *val) +EAPI Eina_Bool +ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter, unsigned int *val) { #ifdef ECORE_XCB_SYNC xcb_sync_query_counter_cookie_t cookie; xcb_sync_query_counter_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if ((!_sync_avail) || (!counter)) return EINA_FALSE; + +#ifdef ECORE_XCB_SYNC cookie = xcb_sync_query_counter_unchecked(_ecore_xcb_conn, counter); reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) + if (reply) { - *val = (unsigned int)reply->counter_value.lo; + if (val) *val = (unsigned int)reply->counter_value.lo; free(reply); - return 1; + return EINA_TRUE; } +#endif + return EINA_FALSE; +} -#endif /* ECORE_XCB_SYNC */ - - return 0; -} /* ecore_x_sync_counter_query */ - -EAPI Ecore_X_Sync_Counter -ecore_x_sync_counter_new(int val) +EAPI void +ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, int by) { #ifdef ECORE_XCB_SYNC - xcb_sync_counter_t counter; xcb_sync_int64_t v; +#endif - counter = xcb_generate_id(_ecore_xcb_conn); - v.hi = (val < 0) ? ~0 : 0; - v.lo = val; - xcb_sync_create_counter(_ecore_xcb_conn, counter, v); - return counter; -#else /* ! ECORE_XCB_SYNC */ - return 0; -#endif /* ! ECORE_XCB_SYNC */ -} /* ecore_x_sync_counter_new */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -EAPI void -ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter) -{ -#ifdef ECORE_XCB_SYNC - xcb_sync_destroy_counter(_ecore_xcb_conn, counter); -#endif /* ECORE_XCB_SYNC */ -} /* ecore_x_sync_counter_free */ + if ((!_sync_avail) || (!counter)) return; -EAPI void -ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, int by) -{ #ifdef ECORE_XCB_SYNC - xcb_sync_int64_t v; - v.hi = (by < 0) ? ~0 : 0; v.lo = by; + xcb_sync_change_counter(_ecore_xcb_conn, counter, v); -#endif /* ECORE_XCB_SYNC */ -} /* ecore_x_sync_counter_inc */ +#endif +} -EAPI void -ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter, int val) +EAPI void +ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter, int val) { #ifdef ECORE_XCB_SYNC xcb_sync_query_counter_cookie_t cookie; xcb_sync_query_counter_reply_t *reply; - xcb_sync_int64_t v1; - xcb_sync_int64_t v2; + xcb_sync_int64_t v1, v2; xcb_sync_waitcondition_t cond; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!_sync_avail) || (!counter)) return; - /* what's the purpose of that call ?? as the value is erased... */ +#ifdef ECORE_XCB_SYNC cookie = xcb_sync_query_counter_unchecked(_ecore_xcb_conn, counter); reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; v1 = reply->counter_value; free(reply); v1.hi = (val < 0) ? ~0 : 0; v1.lo = val; v2.hi = ((val + 1) < 0) ? ~0 : 0; - v2.lo = val + 1; + v2.lo = (val + 1); + cond.trigger.counter = counter; cond.trigger.wait_type = XCB_SYNC_VALUETYPE_ABSOLUTE; cond.trigger.wait_value = v1; cond.trigger.test_type = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON; cond.event_threshold = v2; - xcb_sync_await(_ecore_xcb_conn, 1, (const xcb_sync_waitcondition_t *)&cond); -#endif /* ECORE_XCB_SYNC */ -} /* ecore_x_sync_counter_val_wait */ + xcb_sync_await(_ecore_xcb_conn, 1, &cond); +#endif +} + +EAPI Ecore_X_Sync_Counter +ecore_x_sync_counter_new(int val) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_counter_t counter; + xcb_sync_int64_t v; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_sync_avail) return 0; + +#ifdef ECORE_XCB_SYNC + v.hi = (val < 0) ? ~0 : 0; + v.lo = val; + + counter = xcb_generate_id(_ecore_xcb_conn); + xcb_sync_create_counter(_ecore_xcb_conn, counter, v); + + return counter; +#endif + + return 0; +} + +EAPI void +ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!_sync_avail) || (!counter)) return; + +#ifdef ECORE_XCB_SYNC + xcb_sync_destroy_counter(_ecore_xcb_conn, counter); +#endif +} + +EAPI void +ecore_x_sync_counter_set(Ecore_X_Sync_Counter counter, int val) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_int64_t v; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!_sync_avail) || (!counter)) return; + +#ifdef ECORE_XCB_SYNC + v.hi = (val < 0) ? ~0 : 0; + v.lo = val; + + xcb_sync_set_counter(_ecore_xcb_conn, counter, v); +#endif +} + +EAPI void +ecore_x_sync_counter_2_set(Ecore_X_Sync_Counter counter, int val_hi, unsigned int val_lo) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_int64_t v; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!_sync_avail) || (!counter)) return; + +#ifdef ECORE_XCB_SYNC + v.hi = val_hi; + v.lo = val_lo; + + xcb_sync_set_counter(_ecore_xcb_conn, counter, v); +#endif +} + +EAPI Eina_Bool +ecore_x_sync_counter_2_query(Ecore_X_Sync_Counter counter, int *val_hi, unsigned int *val_lo) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_query_counter_cookie_t cookie; + xcb_sync_query_counter_reply_t *reply; + xcb_sync_int64_t value; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!_sync_avail) || (!counter)) return EINA_FALSE; + +#ifdef ECORE_XCB_SYNC + cookie = + xcb_sync_query_counter_unchecked(_ecore_xcb_conn, + (xcb_sync_counter_t)counter); + reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + value = reply->counter_value; + free(reply); + if (val_hi) *val_hi = (int)value.hi; + if (val_lo) *val_lo = (unsigned int)value.lo; + return EINA_TRUE; +#endif + return EINA_FALSE; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_textlist.c b/src/lib/ecore_x/xcb/ecore_xcb_textlist.c new file mode 100644 index 0000000..942719d --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_textlist.c @@ -0,0 +1,469 @@ +#include "ecore_xcb_private.h" +//#include "Ecore_X_Atoms.h" +#include +#ifdef HAVE_ICONV +# include +#endif +#ifndef CODESET +# define CODESET "INVALID" +#endif + +static int _ecore_xcb_textlist_get_buffer_size(Eina_Bool is_wide, void *list, int count); +static int _ecore_xcb_textlist_get_wc_len(wchar_t *wstr); +static void *_ecore_xcb_textlist_alloc_list(Eina_Bool is_wide, int count, int nitems); +static void _ecore_xcb_textlist_copy_list(Eina_Bool is_wide, void *text, char **list, int count); +static wchar_t *_ecore_xcb_textlist_copy_wchar(wchar_t *str1, wchar_t *str2); +static int _ecore_xcb_textlist_len_wchar(wchar_t *str); + +#ifdef HAVE_ICONV +Eina_Bool +_ecore_xcb_utf8_textlist_to_textproperty(char **list, int count, Ecore_Xcb_Encoding_Style style, Ecore_Xcb_Textproperty *ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textlist_to_textproperty("utf8string", list, count, + style, ret); +} +#endif + +Eina_Bool +_ecore_xcb_mb_textlist_to_textproperty(char **list, int count, Ecore_Xcb_Encoding_Style style, Ecore_Xcb_Textproperty *ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textlist_to_textproperty("multiByte", list, count, + style, ret); +} + +/* NB: This Function May Not Be Correct !!! + * (as I do not know text conversion, locales, etc, etc very well) + * + * Portions were ripped from libX11 XTextListToTextProperty + */ +Eina_Bool +_ecore_xcb_textlist_to_textproperty(const char *type, char **list, int count, Ecore_Xcb_Encoding_Style style, Ecore_Xcb_Textproperty *ret) +{ + Eina_Bool is_wide = EINA_FALSE; + Ecore_X_Atom encoding; + int len = 0, nitems = 0, i = 0; + size_t from_left = 0, to_left = 0; + int unconv_num = 0, val = 0; + char *buff, *to, *value, *from; + const char *to_type, *from_type; + char **mb = NULL; + wchar_t **wc = NULL; +#ifdef HAVE_ICONV + iconv_t conv; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!strcmp("wideChar", type)) is_wide = EINA_TRUE; + len = _ecore_xcb_textlist_get_buffer_size(is_wide, list, count); + if (!(buff = (char *)malloc(len * sizeof(char)))) return EINA_FALSE; + from_type = nl_langinfo(CODESET); + switch (style) + { + case XcbStringStyle: + case XcbStdICCTextStyle: + encoding = ECORE_X_ATOM_STRING; + to_type = nl_langinfo(CODESET); +// to_type = "string"; + break; + case XcbUTF8StringStyle: + encoding = ECORE_X_ATOM_UTF8_STRING; + to_type = "UTF-8"; + break; + case XcbCompoundTextStyle: + encoding = ECORE_X_ATOM_COMPOUND_TEXT; + to_type = nl_langinfo(CODESET); +// to_type = "compoundText"; + break; + case XcbTextStyle: + encoding = ECORE_X_ATOM_TEXT; + to_type = nl_langinfo(CODESET); +// to_type = "multiByte"; + if (!is_wide) + { + nitems = 0; + mb = (char **)list; + to = buff; + for (i = 0; ((i < count) && (len > 0)); i++) + { + if (*mb) strcpy(to, *mb); + else *to = '\0'; + from_left = (*mb ? strlen(*mb) : 0) + 1; + nitems += from_left; + to += from_left; + mb++; + } + unconv_num = 0; + goto done; + } + break; + default: + free(buff); + return EINA_FALSE; + break; + } + + if (count < 1) + { + nitems = 0; + goto done; + } + +retry: +#ifdef HAVE_ICONV + conv = iconv_open(to_type, from_type); +#endif + + if (is_wide) + wc = (wchar_t **)list; + else + mb = (char **)list; + + to = buff; + to_left = len; + unconv_num = 0; + for (i = 1; to_left > 0; i++) + { + if (is_wide) + { + from = (char *)*wc; + from_left = _ecore_xcb_textlist_get_wc_len(*wc); + wc++; + } + else + { + from = *mb; + from_left = (*mb ? strlen(*mb) : 0); + mb++; + } + +#ifdef HAVE_ICONV + val = iconv(conv, &from, &from_left, &to, &to_left); +#endif + if (val < 0) continue; + if ((val > 0) && (style == XcbStdICCTextStyle) && + (encoding == ECORE_X_ATOM_STRING)) + { +#ifdef HAVE_ICONV + iconv_close(conv); +#endif + encoding = ECORE_X_ATOM_COMPOUND_TEXT; + goto retry; + } + + unconv_num += val; + *to++ = '\0'; + to_left --; + if (i >= count) break; + } + +#ifdef HAVE_ICONV + iconv_close(conv); +#endif + nitems = (to - buff); + +done: + if (nitems <= 0) nitems = 1; + if (!(value = (char *)malloc(nitems * sizeof(char)))) + { + free(buff); + return EINA_FALSE; + } + if (nitems == 1) + *value = 0; + else + memcpy(value, buff, nitems); + nitems--; + free(buff); + + ret->value = value; + ret->encoding = encoding; + ret->format = 8; + ret->nitems = nitems; + + return EINA_TRUE; +} + +#ifdef HAVE_ICONV +Eina_Bool +_ecore_xcb_utf8_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, char ***list_ret, int *count_ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textproperty_to_textlist(text_prop, "utf8String", + list_ret, count_ret); +} +#endif + +Eina_Bool +_ecore_xcb_mb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, char ***list_ret, int *count_ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textproperty_to_textlist(text_prop, "multiByte", + list_ret, count_ret); +} + +Eina_Bool +_ecore_xcb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, const char *type, char ***list_ret, int *count_ret) +{ + Eina_Bool is_wide = EINA_FALSE; + Eina_Bool do_strcpy = EINA_FALSE; + const char *from_type; + char *buff, *to, *from; + char *lptr, *sptr; + int nitems = 0, len = 0, num = 0, ret = 0; + size_t from_left = 0, to_left = 0; +#ifdef HAVE_ICONV + iconv_t conv = 0; +#endif + + *list_ret = NULL; + *count_ret = 0; + if (!strcmp("wideChar", type)) is_wide = EINA_TRUE; + + nitems = text_prop->nitems; + if (nitems <= 0) return EINA_TRUE; + + if (text_prop->format != 8) return EINA_FALSE; + + from_type = nl_langinfo(CODESET); + if (text_prop->encoding == ECORE_X_ATOM_UTF8_STRING) + from_type = "UTF-8"; + + if (is_wide) + len = (text_prop->nitems + 1) * sizeof(wchar_t); + else + { + if (!strcmp(type, "utf8String")) + len = text_prop->nitems * 6 + 1; + else + len = text_prop->nitems * MB_CUR_MAX + 1; + } + + buff = (char *)malloc(len * sizeof(char)); + if (!buff) return EINA_FALSE; + + to = buff; + to_left = len; + + if (!strcmp(from_type, type)) + do_strcpy = EINA_TRUE; + else + { +#ifdef HAVE_ICONV + conv = iconv_open(type, from_type); +#endif + if (!conv) + { + free(buff); + return EINA_FALSE; + } + } + + lptr = sptr = text_prop->value; + num = *count_ret = 0; + while (1) + { + if ((nitems == 0) || (*sptr == 0)) + { + from = lptr; + from_left = sptr - lptr; + lptr = sptr; + if (do_strcpy) + { + int l = 0; + + l = MIN(from_left, to_left); + strncpy(to, from, l); + from += len; + to += len; + from_left -= l; + to_left -= l; + ret = 0; + } + else + ret = iconv(conv, &from, &from_left, &to, &to_left); + + if (ret < 0) continue; + num += ret; + (*count_ret)++; + if (nitems == 0) break; + lptr = ++sptr; + if (is_wide) + { + *((wchar_t *)to) = (wchar_t)0; + to += sizeof(wchar_t); + to_left -= sizeof(wchar_t); + } + else + { + *((char *)to) = '\0'; + to++; + to_left--; + } + } + else + sptr++; + + nitems--; + } + +#if HAVE_ICONV + if (!do_strcpy) iconv_close(conv); +#endif + + if (is_wide) + { + *((wchar_t *)to) = (wchar_t)0; + to_left -= sizeof(wchar_t); + } + else + { + *((char *)to) = '\0'; + to_left--; + } + + *list_ret = + _ecore_xcb_textlist_alloc_list(is_wide, *count_ret, (len - to_left)); + if (*list_ret) + _ecore_xcb_textlist_copy_list(is_wide, buff, *list_ret, *count_ret); + + free(buff); + + return EINA_TRUE; +} + +static int +_ecore_xcb_textlist_get_buffer_size(Eina_Bool is_wide, void *list, int count) +{ + int len = 0; + char **mb; + wchar_t **wc; + + if (!list) return 0; + if (is_wide) + { + wc = (wchar_t **)list; + for (; count-- > 0; wc++) + if (*wc) len += _ecore_xcb_textlist_get_wc_len(*wc) + 1; + len *= 5; + } + else + { + mb = (char **)list; + for (; count-- > 0; mb++) + if (*mb) len += strlen(*mb) + 1; + len *= 3; + } + len = (len / 2048 + 1) * 2048; + return len; +} + +static int +_ecore_xcb_textlist_get_wc_len(wchar_t *wstr) +{ + wchar_t *ptr; + + ptr = wstr; + while (*ptr) + ptr++; + + return (ptr - wstr); +} + +static void * +_ecore_xcb_textlist_alloc_list(Eina_Bool is_wide, int count, int nitems) +{ + if (is_wide) + { + wchar_t **list; + + list = (wchar_t **)malloc(count * sizeof(wchar_t *)); + if (!list) return NULL; + *list = (wchar_t *)malloc(nitems * sizeof(wchar_t)); + if (!*list) + { + free(list); + return NULL; + } + return *list; + } + else + { + char **list; + + list = (char **)malloc(count * sizeof(char *)); + if (!list) return NULL; + *list = (char *)malloc(nitems * sizeof(char)); + if (!*list) + { + free(list); + return NULL; + } + return *list; + } +} + +static void +_ecore_xcb_textlist_copy_list(Eina_Bool is_wide, void *text, char **list, int count) +{ + int len = 0; + + if (is_wide) + { + wchar_t *txt, *str, **wlist; + + txt = (wchar_t *)text; + wlist = (wchar_t **)list; + for (str = *wlist; count > 0; count--, wlist++) + { + _ecore_xcb_textlist_copy_wchar(str, txt); + *wlist = str; + len = (_ecore_xcb_textlist_len_wchar(str) + 1); + str += len; + txt += len; + } + } + else + { + char *txt, *str, **slist; + + txt = (char *)text; + slist = (char **)list; + for (str = *slist; count > 0; count--, slist++) + { + strcpy(str, txt); + *slist = str; + len = strlen(str) + 1; + str += len; + txt += len; + } + } +} + +static wchar_t * +_ecore_xcb_textlist_copy_wchar(wchar_t *str1, wchar_t *str2) +{ + wchar_t *tmp; + + tmp = str1; + while ((*str1++ = *str2++)) + ; + return tmp; +} + +static int +_ecore_xcb_textlist_len_wchar(wchar_t *str) +{ + wchar_t *ptr; + + ptr = str; + while (*ptr) + ptr++; + return (ptr - str); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_vsync.c b/src/lib/ecore_x/xcb/ecore_xcb_vsync.c new file mode 100644 index 0000000..a793c1f --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_vsync.c @@ -0,0 +1,359 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_DRI +# include +# include +# include +#endif + +#define ECORE_XCB_VSYNC_DRI2 1 +#define DRM_EVENT_CONTEXT_VERSION 2 + +#ifdef ECORE_XCB_DRI + +/* relevant header bits of dri/drm inlined here to avoid needing external */ +/* headers to build drm */ +typedef unsigned int drm_magic_t; + +typedef enum +{ + DRM_VBLANK_ABSOLUTE = 0x00000000, + DRM_VBLANK_RELATIVE = 0x00000001, + DRM_VBLANK_EVENT = 0x04000000, + DRM_VBLANK_FLIP = 0x08000000, + DRM_VBLANK_NEXTONMISS = 0x10000000, + DRM_VBLANK_SECONDARY = 0x20000000, + DRM_VBLANK_SIGNAL = 0x40000000 +} drmVBlankSeqType; + +typedef struct _drmVBlankReq +{ + drmVBlankSeqType type; + unsigned int sequence; + unsigned long signal; +} drmVBlankReq; + +typedef struct _drmVBlankReply +{ + drmVBlankSeqType type; + unsigned int sequence; + long tval_sec, tval_usec; +} drmVBlankReply; + +typedef union _drmVBlank +{ + drmVBlankReq request; + drmVBlankReply reply; +} drmVBlank; + +typedef struct _drmEventContext +{ + int version; + void (*vblank_handler)(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data); + void (*page_flip_handler)(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data); +} drmEventContext; + +static int (*sym_drmClose) (int fd) = NULL; +static int (*sym_drmGetMagic) (int fd, drm_magic_t * magic) = NULL; +static int (*sym_drmWaitVBlank) (int fd, drmVBlank *vbl) = NULL; +static int (*sym_drmHandleEvent) (int fd, drmEventContext *evctx) = NULL; + +#endif + +/* local function prototypes */ +static Eina_Bool _ecore_xcb_dri_link(void); +static Eina_Bool _ecore_xcb_dri_start(void); +static void _ecore_xcb_dri_shutdown(void); + +static Eina_Bool _ecore_xcb_dri_cb(void *data __UNUSED__, Ecore_Fd_Handler *fdh __UNUSED__); +static void _ecore_xcb_dri_tick_begin(void *data __UNUSED__); +static void _ecore_xcb_dri_tick_end(void *data __UNUSED__); +static void _ecore_xcb_dri_tick_schedule(void); +static void _ecore_xcb_dri_vblank_handler(int fd __UNUSED__, unsigned int frame __UNUSED__, unsigned int sec __UNUSED__, unsigned int usec __UNUSED__, void *data __UNUSED__); + +/* local variables */ +static Eina_Bool _dri2_avail = EINA_FALSE; +static Ecore_X_Window _vsync_root = 0; +static int _drm_fd = -1; +static Ecore_Fd_Handler *_drm_fdh = NULL; +static unsigned int _drm_magic = 0; +static Eina_Bool _drm_event_busy = EINA_FALSE; +static void *_drm_lib = NULL; +#ifdef ECORE_XCB_DRI +static drmEventContext _drm_evctx; +#endif + +void +_ecore_xcb_dri_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_DRI + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_dri2_id); +#endif +} + +void +_ecore_xcb_dri_finalize(void) +{ +#ifdef ECORE_XCB_DRI + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_DRI + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_dri2_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_dri2_query_version_cookie_t dcookie; + xcb_dri2_query_version_reply_t *dreply; + + dcookie = + xcb_dri2_query_version_unchecked(_ecore_xcb_conn, + XCB_DRI2_MAJOR_VERSION, + XCB_DRI2_MINOR_VERSION); + dreply = xcb_dri2_query_version_reply(_ecore_xcb_conn, dcookie, NULL); + if (dreply) + { + if (dreply->major_version >= 2) _dri2_avail = EINA_TRUE; + free(dreply); + } + } +#endif +} + +EAPI Eina_Bool +ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win) +{ +#ifdef ECORE_XCB_DRI + Ecore_X_Window root; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_dri2_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_DRI + root = ecore_x_window_root_get(win); + if (root != _vsync_root) + { + _vsync_root = root; + if (_vsync_root) + { + if (!_ecore_xcb_dri_link()) + { + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + _ecore_xcb_dri_shutdown(); + if (!_ecore_xcb_dri_start()) + { + _vsync_root = 0; + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + ecore_animator_custom_source_tick_begin_callback_set + (_ecore_xcb_dri_tick_begin, NULL); + ecore_animator_custom_source_tick_end_callback_set + (_ecore_xcb_dri_tick_end, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); + } + else + { + if (_drm_fd >= 0) + { + _ecore_xcb_dri_shutdown(); + ecore_animator_custom_source_tick_begin_callback_set + (NULL, NULL); + ecore_animator_custom_source_tick_end_callback_set + (NULL, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + } + } + } + return EINA_TRUE; +#else + return EINA_FALSE; + win = 0; +#endif +} + +/* local functions */ +static Eina_Bool +_ecore_xcb_dri_link(void) +{ +#ifdef ECORE_XCB_DRI + const char *_drm_libs[] = + { + "libdrm.so.2", + "libdrm.so.1", + "libdrm.so.0", + "libdrm.so", + NULL, + }; + int i = 0, fail = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_DRI +# define SYM(lib, xx) \ + do { \ + sym_## xx = dlsym(lib, #xx); \ + if (!(sym_## xx)) { \ + fprintf(stderr, "%s\n", dlerror()); \ + fail = 1; \ + } \ + } while (0); + + if (_drm_lib) return EINA_TRUE; + + for (i = 0; _drm_libs[i]; i++) + { + _drm_lib = dlopen(_drm_libs[i], (RTLD_LOCAL | RTLD_LAZY)); + if (_drm_lib) + { + fail = 0; + SYM(_drm_lib, drmClose); + SYM(_drm_lib, drmGetMagic); + SYM(_drm_lib, drmWaitVBlank); + SYM(_drm_lib, drmHandleEvent); + if (fail) + { + dlclose(_drm_lib); + _drm_lib = NULL; + } + else + break; + } + } + if (!_drm_lib) return EINA_FALSE; + return EINA_TRUE; +#endif + return EINA_FALSE; +} + +static Eina_Bool +_ecore_xcb_dri_start(void) +{ +#ifdef ECORE_XCB_DRI + xcb_dri2_connect_cookie_t cookie; + xcb_dri2_connect_reply_t *reply; + xcb_dri2_authenticate_cookie_t acookie; + xcb_dri2_authenticate_reply_t *areply; + char *device = NULL, *driver = NULL; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_dri2_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_DRI + cookie = xcb_dri2_connect_unchecked(_ecore_xcb_conn, + _vsync_root, XCB_DRI2_DRIVER_TYPE_DRI); + reply = xcb_dri2_connect_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + driver = xcb_dri2_connect_driver_name(reply); + device = xcb_dri2_connect_device_name(reply); + free(reply); + + if (!(_drm_fd = open(device, O_RDWR))) + { + _drm_fd = -1; + return EINA_FALSE; + } + + sym_drmGetMagic(_drm_fd, &_drm_magic); + + acookie = + xcb_dri2_authenticate_unchecked(_ecore_xcb_conn, _vsync_root, _drm_magic); + areply = xcb_dri2_authenticate_reply(_ecore_xcb_conn, acookie, NULL); + if (!areply) + { + close(_drm_fd); + _drm_fd = -1; + return EINA_FALSE; + } + free(areply); + + memset(&_drm_evctx, 0, sizeof(_drm_evctx)); + _drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; + _drm_evctx.vblank_handler = _ecore_xcb_dri_vblank_handler; + _drm_evctx.page_flip_handler = NULL; + + _drm_fdh = ecore_main_fd_handler_add(_drm_fd, ECORE_FD_READ, + _ecore_xcb_dri_cb, NULL, NULL, NULL); + if (!_drm_fdh) + { + close(_drm_fd); + _drm_fd = -1; + return EINA_FALSE; + } + + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + +static void +_ecore_xcb_dri_shutdown(void) +{ + if (_drm_fd >= 0) + { + close(_drm_fd); + _drm_fd = -1; + } + if (_drm_fdh) + { + ecore_main_fd_handler_del(_drm_fdh); + _drm_fdh = NULL; + } +} + +static Eina_Bool +_ecore_xcb_dri_cb(void *data __UNUSED__, Ecore_Fd_Handler *fdh __UNUSED__) +{ +#ifdef ECORE_XCB_DRI + sym_drmHandleEvent(_drm_fd, &_drm_evctx); +#endif + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_xcb_dri_tick_begin(void *data __UNUSED__) +{ + _drm_event_busy = EINA_TRUE; + _ecore_xcb_dri_tick_schedule(); +} + +static void +_ecore_xcb_dri_tick_end(void *data __UNUSED__) +{ + _drm_event_busy = EINA_FALSE; +} + +static void +_ecore_xcb_dri_tick_schedule(void) +{ +#ifdef ECORE_XCB_DRI + drmVBlank vbl; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_DRI + vbl.request.type = (DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT); + vbl.request.sequence = 1; + vbl.request.signal = 0; + + sym_drmWaitVBlank(_drm_fd, &vbl); +#endif +} + +static void +_ecore_xcb_dri_vblank_handler(int fd __UNUSED__, unsigned int frame __UNUSED__, unsigned int sec __UNUSED__, unsigned int usec __UNUSED__, void *data __UNUSED__) +{ + ecore_animator_custom_tick(); + if (_drm_event_busy) _ecore_xcb_dri_tick_schedule(); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window.c b/src/lib/ecore_x/xcb/ecore_xcb_window.c index c76b1f5..a643836 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_window.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_window.c @@ -1,30 +1,28 @@ -#include - -#include - #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" +#ifdef ECORE_XCB_RENDER +# include +#endif +#ifdef ECORE_XCB_SHAPE +# include +#endif +/* local function prototypes */ +static Ecore_X_Window _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent, int x, int y, int w, int h, uint8_t override_redirect, uint8_t save_under); +static Ecore_X_Window _ecore_xcb_window_at_xy_get(Ecore_X_Window base, int bx, int by, int x, int y, Ecore_X_Window *skip, int skip_num); +static int _ecore_xcb_window_modifiers_get(unsigned int state); +static xcb_visualtype_t *_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id); + +/* local variables */ static int ignore_num = 0; static Ecore_X_Window *ignore_list = NULL; -static Ecore_X_Window _ecore_x_window_at_xy_get(Ecore_X_Window base, - int16_t base_x, - int16_t base_y, - int16_t x, - int16_t y, - Ecore_X_Window *skip, - int skip_num); - -#ifdef ECORE_XCB_RENDER -static Ecore_X_Window _ecore_x_window_argb_internal_new(Ecore_X_Window parent, - int16_t x, - int16_t y, - uint16_t w, - uint16_t h, - uint8_t override_redirect, - uint8_t save_under); -#endif /* ECORE_XCB_RENDER */ +/* external variables */ +int _ecore_xcb_button_grabs_num = 0; +int _ecore_xcb_key_grabs_num = 0; +Ecore_X_Window *_ecore_xcb_button_grabs = NULL; +Ecore_X_Window *_ecore_xcb_key_grabs = NULL; +Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data, int type, void *event); +void *_ecore_xcb_window_grab_replay_data; /** * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions @@ -43,57 +41,53 @@ static Ecore_X_Window _ecore_x_window_argb_internal_new(Ecore_X_Window pare * @return The new window handle. * @ingroup Ecore_X_Window_Create_Group */ -EAPI Ecore_X_Window -ecore_x_window_new(Ecore_X_Window parent, - int x, - int y, - int width, - int height) -{ - uint32_t value_list[9]; - Ecore_X_Window window; - xcb_visualid_t vis = { XCB_WINDOW_CLASS_COPY_FROM_PARENT }; - uint32_t value_mask; - - if (parent == 0) - parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; +EAPI Ecore_X_Window +ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h) +{ + Ecore_X_Window win; + uint32_t mask, mask_list[9]; - value_mask = - XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | - XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT | - XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - value_list[0] = XCB_NONE; - value_list[1] = 0; - value_list[2] = XCB_GRAVITY_NORTH_WEST; - value_list[3] = XCB_GRAVITY_NORTH_WEST; - value_list[4] = XCB_BACKING_STORE_NOT_USEFUL; - value_list[5] = 0; - value_list[6] = 0; - value_list[7] = - XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE; - value_list[8] = XCB_EVENT_MASK_NO_EVENT; + if (parent == 0) + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + /* NB: Order here is very important due to xcb_cw_t enum */ + mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | + XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | + XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | + XCB_CW_DONT_PROPAGATE); + + mask_list[0] = XCB_BACK_PIXMAP_NONE; + mask_list[1] = 0; + mask_list[2] = XCB_GRAVITY_NORTH_WEST; + mask_list[3] = XCB_GRAVITY_NORTH_WEST; + mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL; + mask_list[5] = 0; + mask_list[6] = 0; + mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | + XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | + XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE | + XCB_EVENT_MASK_VISIBILITY_CHANGE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_FOCUS_CHANGE | + XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_COLOR_MAP_CHANGE); + mask_list[8] = XCB_EVENT_MASK_NO_EVENT; - window = xcb_generate_id(_ecore_xcb_conn); - xcb_create_window(_ecore_xcb_conn, - XCB_WINDOW_CLASS_COPY_FROM_PARENT, - window, parent, x, y, width, height, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - vis, - value_mask, - value_list); + win = xcb_generate_id(_ecore_xcb_conn); + xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT, + win, parent, x, y, w, h, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + XCB_COPY_FROM_PARENT, mask, mask_list); - if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root) - ecore_x_window_defaults_set(window); + if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root) + ecore_x_window_defaults_set(win); - return window; -} /* ecore_x_window_new */ + return win; +} /** * Creates a window with the override redirect attribute set to @c True. @@ -106,53 +100,50 @@ ecore_x_window_new(Ecore_X_Window parent, * @return The new window handle. * @ingroup Ecore_X_Window_Create_Group */ -EAPI Ecore_X_Window -ecore_x_window_override_new(Ecore_X_Window parent, - int x, - int y, - int width, - int height) -{ - uint32_t value_list[9]; - Ecore_X_Window window; - xcb_visualid_t vis = { XCB_WINDOW_CLASS_COPY_FROM_PARENT }; - uint32_t value_mask; +EAPI Ecore_X_Window +ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h) +{ + Ecore_X_Window win; + uint32_t mask, mask_list[9]; - if (parent == 0) - parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - value_mask = - XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | - XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT | - XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE; + if (parent == 0) + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + /* NB: Order here is very important due to xcb_cw_t enum */ + mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | + XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | + XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | + XCB_CW_DONT_PROPAGATE); + + mask_list[0] = XCB_BACK_PIXMAP_NONE; + mask_list[1] = 0; + mask_list[2] = XCB_GRAVITY_NORTH_WEST; + mask_list[3] = XCB_GRAVITY_NORTH_WEST; + mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL; + mask_list[5] = 1; + mask_list[6] = 0; + mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | + XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | + XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE | + XCB_EVENT_MASK_VISIBILITY_CHANGE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_FOCUS_CHANGE | + XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_COLOR_MAP_CHANGE); + mask_list[8] = XCB_EVENT_MASK_NO_EVENT; - value_list[0] = XCB_NONE; - value_list[1] = 0; - value_list[2] = XCB_GRAVITY_NORTH_WEST; - value_list[3] = XCB_GRAVITY_NORTH_WEST; - value_list[4] = XCB_BACKING_STORE_NOT_USEFUL; - value_list[5] = 1; - value_list[6] = 0; - value_list[7] = - XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE; - value_list[8] = XCB_EVENT_MASK_NO_EVENT; + win = xcb_generate_id(_ecore_xcb_conn); + xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT, + win, parent, x, y, w, h, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + XCB_COPY_FROM_PARENT, mask, mask_list); - window = xcb_generate_id(_ecore_xcb_conn); - xcb_create_window(_ecore_xcb_conn, - XCB_WINDOW_CLASS_COPY_FROM_PARENT, - window, parent, x, y, width, height, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - vis, - value_mask, - value_list); - return window; -} /* ecore_x_window_override_new */ + return win; +} /** * Creates a new input window. @@ -165,49 +156,42 @@ ecore_x_window_override_new(Ecore_X_Window parent, * @return The new window. * @ingroup Ecore_X_Window_Create_Group */ -EAPI Ecore_X_Window -ecore_x_window_input_new(Ecore_X_Window parent, - int x, - int y, - int width, - int height) -{ - uint32_t value_list[3]; - Ecore_X_Window window; - xcb_visualid_t vis = { XCB_WINDOW_CLASS_COPY_FROM_PARENT }; - uint32_t value_mask; +EAPI Ecore_X_Window +ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h) +{ + Ecore_X_Window win; + uint32_t mask, mask_list[3]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); if (parent == 0) - parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - value_mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE; - - value_list[0] = 1; - value_list[1] = - XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE; - value_list[2] = XCB_EVENT_MASK_NO_EVENT; - - window = xcb_generate_id(_ecore_xcb_conn); - xcb_create_window(_ecore_xcb_conn, - XCB_WINDOW_CLASS_COPY_FROM_PARENT, - window, parent, x, y, width, height, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - vis, - value_mask, - value_list); + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + /* NB: Order here is very important due to xcb_cw_t enum */ + mask = (XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | + XCB_CW_DONT_PROPAGATE); + + mask_list[0] = 1; + mask_list[1] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | + XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | + XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE | + XCB_EVENT_MASK_VISIBILITY_CHANGE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_FOCUS_CHANGE | + XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_COLOR_MAP_CHANGE); + mask_list[2] = XCB_EVENT_MASK_NO_EVENT; - if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root) - { - } + win = xcb_generate_id(_ecore_xcb_conn); + xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT, + win, parent, x, y, w, h, 0, + XCB_WINDOW_CLASS_INPUT_ONLY, + XCB_COPY_FROM_PARENT, mask, mask_list); - return window; -} /* ecore_x_window_input_new */ + return win; +} /** * Creates a new window. @@ -215,28 +199,22 @@ ecore_x_window_input_new(Ecore_X_Window parent, * window of the default display is used. * @param x X position. * @param y Y position. - * @param width Width. - * @param height Height. - * @return The new window handle. + * @param w Width. + * @param h Height. + * @return The new window handle. * @ingroup Ecore_X_Window_Create_Group */ -EAPI Ecore_X_Window -ecore_x_window_manager_argb_new(Ecore_X_Window parent, - int x, - int y, - int width, - int height) +EAPI Ecore_X_Window +ecore_x_window_manager_argb_new(Ecore_X_Window parent, int x, int y, int w, int h) { - Ecore_X_Window window = 0; + Ecore_X_Window win = 0; -#ifdef ECORE_XCB_RENDER - window = _ecore_x_window_argb_internal_new(parent, - x, y, width, height, - 1, 0); -#endif /* ECORE_XCB_RENDER */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return window; -} /* ecore_x_window_manager_argb_new */ + win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0); + + return win; +} /** * Creates a new window. @@ -244,28 +222,22 @@ ecore_x_window_manager_argb_new(Ecore_X_Window parent, * window of the default display is used. * @param x X position. * @param y Y position. - * @param width Width. - * @param height Height. - * @return The new window handle. + * @param w Width. + * @param h Height. + * @return The new window handle. * @ingroup Ecore_X_Window_Create_Group */ -EAPI Ecore_X_Window -ecore_x_window_argb_new(Ecore_X_Window parent, - int x, - int y, - int width, - int height) +EAPI Ecore_X_Window +ecore_x_window_argb_new(Ecore_X_Window parent, int x, int y, int w, int h) { - Ecore_X_Window window = 0; + Ecore_X_Window win = 0; -#ifdef ECORE_XCB_RENDER - window = _ecore_x_window_argb_internal_new(parent, - x, y, width, height, - 0, 0); -#endif /* ECORE_XCB_RENDER */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return window; -} /* ecore_x_window_argb_new */ + win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 0, 0); + + return win; +} /** * Creates a window with the override redirect attribute set to @c True. @@ -273,28 +245,22 @@ ecore_x_window_argb_new(Ecore_X_Window parent, * window of the default display is used. * @param x X position. * @param y Y position. - * @param width Width. - * @param height Height. - * @return The new window handle. + * @param w Width. + * @param h Height. + * @return The new window handle. * @ingroup Ecore_X_Window_Create_Group */ -EAPI Ecore_X_Window -ecore_x_window_override_argb_new(Ecore_X_Window parent, - int x, - int y, - int width, - int height) +EAPI Ecore_X_Window +ecore_x_window_override_argb_new(Ecore_X_Window parent, int x, int y, int w, int h) { - Ecore_X_Window window = 0; + Ecore_X_Window win = 0; -#ifdef ECORE_XCB_RENDER - window = _ecore_x_window_argb_internal_new(parent, - x, y, width, height, - 1, 0); -#endif /* ECORE_XCB_RENDER */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return window; -} /* ecore_x_window_override_argb_new */ + win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0); + + return win; +} /** * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions @@ -304,131 +270,122 @@ ecore_x_window_override_argb_new(Ecore_X_Window parent, /** * Deletes the given window. - * @param window The given window. + * @param win The given window. * @ingroup Ecore_X_Window_Destroy_Group */ -EAPI void -ecore_x_window_free(Ecore_X_Window window) +EAPI void +ecore_x_window_free(Ecore_X_Window win) { - /* sorry sir, deleting the root window doesn't sound like - * a smart idea. - */ - if (window) - xcb_destroy_window(_ecore_xcb_conn, window); -} /* ecore_x_window_free */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (win) + { + /* xcb_destroy_notify_event_t ev; */ + /* Ecore_X_Window root; */ + + /* if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1) */ + /* root = ((xcb_screen_t *)_ecore_xcb_screen)->root; */ + /* else */ + /* { */ + /* xcb_get_geometry_cookie_t cookie; */ + /* xcb_get_geometry_reply_t *reply; */ + + /* cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); */ + /* reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); */ + /* if (!reply) return; */ + /* root = reply->root; */ + /* free(reply); */ + /* } */ + + /* memset(&ev, 0, sizeof(xcb_destroy_notify_event_t)); */ + + /* ev.response_type = XCB_DESTROY_NOTIFY; */ + /* ev.window = win; */ + /* ev.event = root; */ + + /* xcb_send_event(_ecore_xcb_conn, 0, root, */ + /* XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | */ + /* XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, */ + /* (const char *)&ev); */ + + xcb_destroy_window(_ecore_xcb_conn, win); + ecore_x_sync(); + } +} /** * Sends a delete request to the given window. - * @param window The given window. + * @param win The given window. * @ingroup Ecore_X_Window_Destroy_Group */ -EAPI void -ecore_x_window_delete_request_send(Ecore_X_Window window) +EAPI void +ecore_x_window_delete_request_send(Ecore_X_Window win) { - xcb_client_message_event_t ev; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + XCB_EVENT_MASK_NO_EVENT, + ECORE_X_ATOM_WM_DELETE_WINDOW, + XCB_CURRENT_TIME, 0, 0, 0); +} - /* sorry sir, deleting the root window doesn't sound like - * a smart idea. - */ - if (window == 0) - return; +EAPI void +ecore_x_window_configure(Ecore_X_Window win, Ecore_X_Window_Configure_Mask mask, int x, int y, int w, int h, int border_width, Ecore_X_Window sibling, int stack_mode) +{ + uint16_t vmask = 0; + uint32_t vlist[7]; + unsigned int i = 0; - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.sequence = 0; - ev.window = window; - ev.type = ECORE_X_ATOM_WM_PROTOCOLS; - ev.data.data32[0] = ECORE_X_ATOM_WM_DELETE_WINDOW; - ev.data.data32[1] = XCB_CURRENT_TIME; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - xcb_send_event(_ecore_xcb_conn, 0, window, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -} /* ecore_x_window_delete_request_send */ + if (!win) return; -/** - * @defgroup Ecore_X_Window_Configure_Group X Window Configure Functions - * - * Functions to configure X windows. - */ + if (mask & XCB_CONFIG_WINDOW_X) + { + vmask |= XCB_CONFIG_WINDOW_X; + vlist[i++] = x; + } + if (mask & XCB_CONFIG_WINDOW_Y) + { + vmask |= XCB_CONFIG_WINDOW_Y; + vlist[i++] = y; + } + if (mask & XCB_CONFIG_WINDOW_WIDTH) + { + vmask |= XCB_CONFIG_WINDOW_WIDTH; + vlist[i++] = w; + } + if (mask & XCB_CONFIG_WINDOW_HEIGHT) + { + vmask |= XCB_CONFIG_WINDOW_HEIGHT; + vlist[i++] = h; + } + if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) + { + vmask |= XCB_CONFIG_WINDOW_BORDER_WIDTH; + vlist[i++] = border_width; + } + if (mask & XCB_CONFIG_WINDOW_SIBLING) + { + vmask |= XCB_CONFIG_WINDOW_SIBLING; + vlist[i++] = sibling; + } + if (mask & XCB_CONFIG_WINDOW_STACK_MODE) + { + vmask |= XCB_CONFIG_WINDOW_STACK_MODE; + vlist[i++] = stack_mode; + } + + xcb_configure_window(_ecore_xcb_conn, win, vmask, + (const uint32_t *)&vlist); +} /** - * Configures the given window with the given mask. - * @param window The given window. - * @param mask The given mask. - * @param x The X coordinate of the window. - * @param y The Y coordinate of the window. - * @param width The width of the window. - * @param height The height of the window. - * @param border_width The border width of the window. - * @param sibling The sibling window of the window. - * @param stack_mode The stack mode of the window. - * @ingroup Ecore_X_Window_Configure_Group + * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions + * + * Functions that change or retrieve the geometry of X windows. */ -EAPI void -ecore_x_window_configure(Ecore_X_Window window, - Ecore_X_Window_Configure_Mask mask, - int x, - int y, - int width, - int height, - int border_width, - Ecore_X_Window sibling, - int stack_mode) -{ - uint32_t *value_list; - uint32_t value_mask; - int length = 0; - - if (!window) - return; - - value_mask = mask; - for (; value_mask; value_mask >>= 1) - if (value_mask & 1) - length++; - - value_list = (uint32_t *)malloc(sizeof(uint32_t) * length); - if (!value_list) - return; - - value_mask = mask; - for (; value_mask; value_mask >>= 1, value_list++) - if (value_mask & 1) - { - switch (value_mask) { - case XCB_CONFIG_WINDOW_X: - *value_list = x; - break; - - case XCB_CONFIG_WINDOW_Y: - *value_list = y; - break; - - case XCB_CONFIG_WINDOW_WIDTH: - *value_list = width; - break; - - case XCB_CONFIG_WINDOW_HEIGHT: - *value_list = height; - break; - - case XCB_CONFIG_WINDOW_BORDER_WIDTH: - *value_list = border_width; - break; - - case XCB_CONFIG_WINDOW_SIBLING: - *value_list = sibling; - break; - - case XCB_CONFIG_WINDOW_STACK_MODE: - *value_list = stack_mode; - break; - } /* switch */ - } - - xcb_configure_window(_ecore_xcb_conn, window, mask, value_list); - free(value_list); -} /* ecore_x_window_configure */ /** * Moves a window to the position @p x, @p y. @@ -436,163 +393,176 @@ ecore_x_window_configure(Ecore_X_Window window, * The position is relative to the upper left hand corner of the * parent window. * - * @param window The window to move. - * @param x X position. - * @param y Y position. - * @ingroup Ecore_X_Window_Configure_Group + * @param win The window to move. + * @param x X position. + * @param y Y position. + * @ingroup Ecore_X_Window_Geometry_Group */ -EAPI void -ecore_x_window_move(Ecore_X_Window window, - int x, - int y) +EAPI void +ecore_x_window_move(Ecore_X_Window win, int x, int y) { - uint32_t value_list[2]; - uint32_t value_mask; + uint32_t list[2], mask; - if (!window) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - value_mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; + if (!win) return; - value_list[0] = x; - value_list[1] = y; + mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y); + list[0] = x; + list[1] = y; - xcb_configure_window(_ecore_xcb_conn, window, value_mask, value_list); -} /* ecore_x_window_move */ + xcb_configure_window(_ecore_xcb_conn, win, mask, + (const uint32_t *)&list); +} /** * Resizes a window. - * @param window The window to resize. - * @param width New width of the window. - * @param height New height of the window. - * @ingroup Ecore_X_Window_Configure_Group + * @param win The window to resize. + * @param w New width of the window. + * @param h New height of the window. + * @ingroup Ecore_X_Window_Geometry_Group */ -EAPI void -ecore_x_window_resize(Ecore_X_Window window, - int width, - int height) +EAPI void +ecore_x_window_resize(Ecore_X_Window win, int w, int h) { - uint32_t value_list[2]; - uint32_t value_mask; - - if (!window) - return; - - if (width < 1) - width = 1; + uint32_t list[2], mask; - if (height < 1) - height = 1; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - value_mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + if (!win) return; + if (w < 1) w = 1; + if (h < 1) h = 1; - value_list[0] = width; - value_list[1] = height; + mask = (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT); + list[0] = w; + list[1] = h; - xcb_configure_window(_ecore_xcb_conn, window, value_mask, value_list); -} /* ecore_x_window_resize */ + xcb_configure_window(_ecore_xcb_conn, win, mask, + (const uint32_t *)&list); +} /** * Moves and resizes a window. - * @param window The window to move and resize. - * @param x New X position of the window. - * @param y New Y position of the window. - * @param width New width of the window. - * @param height New height of the window. - * @ingroup Ecore_X_Window_Configure_Group + * @param win The window to move and resize. + * @param x New X position of the window. + * @param y New Y position of the window. + * @param w New width of the window. + * @param h New height of the window. + * @ingroup Ecore_X_Window_Geometry_Group */ -EAPI void -ecore_x_window_move_resize(Ecore_X_Window window, - int x, - int y, - int width, - int height) +EAPI void +ecore_x_window_move_resize(Ecore_X_Window win, int x, int y, int w, int h) { - uint32_t value_list[4]; - uint32_t value_mask; + uint32_t list[4], mask; - if (!window) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (width < 1) - width = 1; + if (!win) return; + if (w < 1) w = 1; + if (h < 1) h = 1; - if (height < 1) - height = 1; + mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT); + list[0] = x; + list[1] = y; + list[2] = w; + list[3] = h; - value_mask = - XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + xcb_configure_window(_ecore_xcb_conn, win, mask, + (const uint32_t *)&list); +} - value_list[0] = x; - value_list[1] = y; - value_list[2] = width; - value_list[3] = height; +/** + * Retrieves the width of the border of the given window. + * @param win The given window. + * @return Width of the border of @p win. + * @ingroup Ecore_X_Window_Geometry_Group + */ +EAPI int +ecore_x_window_border_width_get(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - xcb_configure_window(_ecore_xcb_conn, window, value_mask, value_list); -} /* ecore_x_window_move_resize */ + if (!win) return 0; + return ecore_x_drawable_border_width_get(win); +} /** * Sets the width of the border of the given window. - * @param window The given window. - * @param border_width The new border width. - * @ingroup Ecore_X_Window_Configure_Group + * @param win The given window. + * @param width The new border width. + * @ingroup Ecore_X_Window_Geometry_Group */ -EAPI void -ecore_x_window_border_width_set(Ecore_X_Window window, - int border_width) +EAPI void +ecore_x_window_border_width_set(Ecore_X_Window win, int border_width) { - uint32_t value_list; + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* doesn't make sense to call this on a root window */ - if (!window) - return; + if (!win) return; - value_list = border_width; + list = border_width; - xcb_configure_window(_ecore_xcb_conn, window, XCB_CONFIG_WINDOW_BORDER_WIDTH, &value_list); -} /* ecore_x_window_border_width_set */ + xcb_configure_window(_ecore_xcb_conn, win, + XCB_CONFIG_WINDOW_BORDER_WIDTH, &list); +} + +/** + * @defgroup Ecore_X_Window_Z_Order_Group X Window Z Order Functions + * + * Functions that change the Z order of X windows. + */ /** * Raises the given window. - * @param window The window to raise. - * @ingroup Ecore_X_Window_Configure_Group + * @param win The window to raise. + * @ingroup Ecore_X_Window_Z_Order_Group */ -EAPI void -ecore_x_window_raise(Ecore_X_Window window) +EAPI void +ecore_x_window_raise(Ecore_X_Window win) { - uint32_t value_list; + uint32_t list[] = { XCB_STACK_MODE_ABOVE }; - if (!window) - return; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - value_list = XCB_STACK_MODE_ABOVE; - - xcb_configure_window(_ecore_xcb_conn, window, XCB_CONFIG_WINDOW_STACK_MODE, &value_list); -} /* ecore_x_window_raise */ + xcb_configure_window(_ecore_xcb_conn, win, + XCB_CONFIG_WINDOW_STACK_MODE, list); +} /** * Lowers the given window. - * @param window The window to lower. - * @ingroup Ecore_X_Window_Configure_Group + * @param win The window to lower. + * @ingroup Ecore_X_Window_Z_Order_Group */ -EAPI void -ecore_x_window_lower(Ecore_X_Window window) +EAPI void +ecore_x_window_lower(Ecore_X_Window win) { - uint32_t value_list; + uint32_t list[] = { XCB_STACK_MODE_BELOW }; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!window) - return; + xcb_configure_window(_ecore_xcb_conn, win, + XCB_CONFIG_WINDOW_STACK_MODE, list); +} - value_list = XCB_STACK_MODE_BELOW; +/** + * Retrieves the depth of the given window. + * @param win The given window. + * @return Depth of the window. + */ +EAPI int +ecore_x_window_depth_get(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - xcb_configure_window(_ecore_xcb_conn, window, XCB_CONFIG_WINDOW_STACK_MODE, &value_list); -} /* ecore_x_window_lower */ + return ecore_x_drawable_depth_get(win); +} /** - * @defgroup Ecore_X_Window_Change_Properties_Group X Window Change Property Functions + * @defgroup Ecore_X_Window_Properties_Group X Window Property Functions * - * Functions that change window properties. + * Functions that set window properties. */ /** @@ -601,47 +571,36 @@ ecore_x_window_lower(Ecore_X_Window window) * The default properties set for the window are @c WM_CLIENT_MACHINE and * @c _NET_WM_PID. * - * @param window The given window. - * @ingroup Ecore_X_Window_Change_Property_Group + * @param win The given window. + * @ingroup Ecore_X_Window_Properties_Groups */ -EAPI void -ecore_x_window_defaults_set(Ecore_X_Window window) +EAPI void +ecore_x_window_defaults_set(Ecore_X_Window win) { - char buf[MAXHOSTNAMELEN]; - pid_t pid; + char buff[MAXHOSTNAMELEN], **argv; int argc; - char **argv; - - /* - * Set WM_CLIENT_MACHINE. - */ - gethostname(buf, MAXHOSTNAMELEN); - buf[MAXHOSTNAMELEN - 1] = '\0'; - /* The ecore function uses UTF8 which Xlib may not like (especially - * with older clients) */ - /* ecore_xcb_window_prop_string_set(win, ECORE_X_ATOM_WM_CLIENT_MACHINE, - (char *)buf); */ - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - ECORE_X_ATOM_WM_CLIENT_MACHINE, - ECORE_X_ATOM_STRING, - 8, strlen(buf), buf); - - /* - * Set _NET_WM_PID - */ - pid = getpid(); - ecore_x_netwm_pid_set(window, pid); + pid_t pid; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_netwm_window_type_set(window, ECORE_X_WINDOW_TYPE_NORMAL); + gethostname(buff, MAXHOSTNAMELEN); + buff[MAXHOSTNAMELEN - 1] = '\0'; + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, + ECORE_X_ATOM_WM_CLIENT_MACHINE, ECORE_X_ATOM_STRING, + 8, strlen(buff), buff); + + pid = getpid(); + ecore_x_netwm_pid_set(win, pid); + ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NORMAL); ecore_app_args_get(&argc, &argv); - ecore_x_icccm_command_set(window, argc, argv); -} /* ecore_x_window_defaults_set */ + ecore_x_icccm_command_set(win, argc, argv); +} /** * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions * - * Functions to change the visibility of X windows. + * Functions to access and change the visibility of X windows. */ /** @@ -649,1437 +608,1293 @@ ecore_x_window_defaults_set(Ecore_X_Window window) * * Synonymous to "mapping" a window in X Window System terminology. * - * @param window The window to show. - * @ingroup Ecore_X_Window_Visibility_Group + * @param win The window to show. + * @ingroup Ecore_X_Window_Visibility */ -EAPI void -ecore_x_window_show(Ecore_X_Window window) +EAPI void +ecore_x_window_show(Ecore_X_Window win) { - xcb_map_window(_ecore_xcb_conn, window); -} /* ecore_x_window_show */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (win) + { + xcb_map_window(_ecore_xcb_conn, win); + ecore_x_flush(); + } +} /** * Hides a window. * * Synonymous to "unmapping" a window in X Window System terminology. * - * @param window The window to hide. - * @ingroup Ecore_X_Window_Visibility_Group + * @param win The window to hide. + * @ingroup Ecore_X_Window_Visibility */ -EAPI void -ecore_x_window_hide(Ecore_X_Window window) -{ - xcb_unmap_notify_event_t ev; - Ecore_X_Window root; - - /* ICCCM: SEND unmap event... */ - root = window; - /* FIXME: is it correct ? */ - if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1) - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - else +EAPI void +ecore_x_window_hide(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (win) { - xcb_get_geometry_cookie_t cookie; - xcb_get_geometry_reply_t *rep; - Ecore_X_Drawable draw; - - /* FIXME: can we avoid round trips, here ? */ - draw = window; - cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, draw); - rep = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); - if (!rep) - return; - - root = rep->root; - free(rep); - } + xcb_unmap_notify_event_t ev; + Ecore_X_Window root; + + if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1) + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + else + { + xcb_get_geometry_cookie_t cookie; + xcb_get_geometry_reply_t *reply; + + cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); + reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + root = reply->root; + free(reply); + } - ev.response_type = XCB_UNMAP_NOTIFY; - ev.pad0 = 0; - ev.sequence = 0; - ev.event = root; - ev.window = window; - ev.from_configure = 0; + memset(&ev, 0, sizeof(xcb_unmap_notify_event_t)); - xcb_send_event(_ecore_xcb_conn, 0, root, - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, - (const char *)&ev); - xcb_unmap_window(_ecore_xcb_conn, window); -} /* ecore_x_window_hide */ + ev.response_type = XCB_UNMAP_NOTIFY; + ev.window = win; + ev.event = root; + ev.from_configure = 0; + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT), + (const char *)&ev); + + xcb_unmap_window(_ecore_xcb_conn, win); + } +} /** - * @defgroup Ecore_X_Window_Input_Focus_Group X Window Input Focus Functions + * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions * - * Functions that manage the focus of an X Window. + * Functions that give the focus to an X Window. */ /** - * Sets the focus to the window @p window. - * @param window The window to focus. - * @ingroup Ecore_X_Window_Input_Focus_Group + * Sets the focus to the window @p win. + * @param win The window to focus. + * @ingroup Ecore_X_Window_Focus_Functions */ -EAPI void -ecore_x_window_focus(Ecore_X_Window window) +EAPI void +ecore_x_window_focus(Ecore_X_Window win) { - Ecore_X_Time time = XCB_CURRENT_TIME; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (window == 0) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - /* xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_NONE, win, time); */ - xcb_set_input_focus(_ecore_xcb_conn, - XCB_INPUT_FOCUS_POINTER_ROOT, window, time); -} /* ecore_x_window_focus */ + xcb_set_input_focus(_ecore_xcb_conn, + XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME); +} /** * Sets the focus to the given window at a specific time. - * @param window The window to focus. - * @param time When to set the focus to the window. - * @ingroup Ecore_X_Window_Input_Focus_Group + * @param win The window to focus. + * @param t When to set the focus to the window. + * @ingroup Ecore_X_Window_Focus_Functions */ -EAPI void -ecore_x_window_focus_at_time(Ecore_X_Window window, - Ecore_X_Time time) +EAPI void +ecore_x_window_focus_at_time(Ecore_X_Window win, Ecore_X_Time time) { - if (window == 0) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_NONE, win, time); */ - xcb_set_input_focus(_ecore_xcb_conn, - XCB_INPUT_FOCUS_POINTER_ROOT, window, time); -} /* ecore_x_window_focus_at_time */ + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_PARENT, win, time); +} /** - * @defgroup Ecore_X_Window_Reparent_Group X Window Reparent Functions + * @defgroup Ecore_X_Window_Parent_Group X Window Parent Functions * * Functions that retrieve or changes the parent window of a window. */ /** * Moves a window to within another window at a given position. - * @param window The window to reparent. + * @param win The window to reparent. * @param new_parent The new parent window. * @param x X position within new parent window. * @param y Y position within new parent window. - * @ingroup Ecore_X_Window_Reparent_Group + * @ingroup Ecore_X_Window_Parent_Group */ -EAPI void -ecore_x_window_reparent(Ecore_X_Window window, - Ecore_X_Window new_parent, - int x, - int y) +EAPI void +ecore_x_window_reparent(Ecore_X_Window win, Ecore_X_Window parent, int x, int y) { - if (new_parent == 0) - new_parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - xcb_reparent_window(_ecore_xcb_conn, window, new_parent, x, y); -} /* ecore_x_window_reparent */ + if (parent == 0) + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; -/** - * @defgroup Ecore_X_Window_Change_Attributes_Group X Window Change Attributes Functions - * - * Functions that change the attributes of a window. - */ + xcb_reparent_window(_ecore_xcb_conn, win, parent, x, y); +} -/** - * Sets the background pixmap of the given window. - * @param window The given window. - * @param pixmap The pixmap to set to. - * @ingroup Ecore_X_Window_Change_Attributes_Group - */ -EAPI void -ecore_x_window_pixmap_set(Ecore_X_Window window, - Ecore_X_Pixmap pixmap) +EAPI void +ecore_x_window_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pixmap) { - uint32_t value_list; + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - value_list = pixmap; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_BACK_PIXMAP, &value_list); -} /* ecore_x_window_pixmap_set */ + list = pixmap; + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_BACK_PIXMAP, &list); +} /** * Sets the background color of the given window. - * @param window The given window. - * @param red The red component of the color to set to. - * @param green The green component of the color to set to. - * @param blue The blue component of the color to set to. - * @ingroup Ecore_X_Window_Change_Attributes_Group + * @param win The given window + * @param r red value (0...65536, 16 bits) + * @param g green value (0...65536, 16 bits) + * @param b blue value (0...65536, 16 bits) */ -EAPI void -ecore_x_window_background_color_set(Ecore_X_Window window, - unsigned short red, - unsigned short green, - unsigned short blue) +EAPI void +ecore_x_window_background_color_set(Ecore_X_Window win, unsigned short red, unsigned short green, unsigned short blue) { xcb_alloc_color_cookie_t cookie; - xcb_alloc_color_reply_t *rep; - uint32_t value_list; - - /* FIXME: should I provide a reply, and not the color components, here ? */ - /* (because of roundtrips) */ - cookie = xcb_alloc_color_unchecked(_ecore_xcb_conn, - ((xcb_screen_t *)_ecore_xcb_screen)->default_colormap, - red, green, blue); - rep = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL); - if (!rep) - return; - - value_list = rep->pixel; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_BACK_PIXEL, &value_list); - free(rep); -} /* ecore_x_window_background_color_set */ - -/** - * Sets the bit gravity of the given window. - * @param window The given window. - * @param gravity The gravity. - * @ingroup Ecore_X_Window_Change_Attributes_Group - */ -EAPI void -ecore_x_window_pixel_gravity_set(Ecore_X_Window window, - Ecore_X_Gravity gravity) + xcb_alloc_color_reply_t *reply; + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + cookie = + xcb_alloc_color_unchecked(_ecore_xcb_conn, + ((xcb_screen_t *)_ecore_xcb_screen)->default_colormap, + red, green, blue); + reply = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + list = reply->pixel; + free(reply); + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_BACK_PIXEL, &list); +} + +EAPI void +ecore_x_window_pixel_gravity_set(Ecore_X_Window win, Ecore_X_Gravity gravity) { - uint32_t value_list; + uint32_t list; - value_list = gravity; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_BIT_GRAVITY, &value_list); -} /* ecore_x_window_pixel_gravity_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Sets the gravity of the given window. - * @param window The given window. - * @param gravity The gravity. - * @ingroup Ecore_X_Window_Change_Attributes_Group - */ -EAPI void -ecore_x_window_gravity_set(Ecore_X_Window window, - Ecore_X_Gravity gravity) + list = gravity; + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_BIT_GRAVITY, &list); +} + +EAPI void +ecore_x_window_gravity_set(Ecore_X_Window win, Ecore_X_Gravity gravity) { - uint32_t value_list; + uint32_t list; - value_list = gravity; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_WIN_GRAVITY, &value_list); -} /* ecore_x_window_gravity_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Sets the override attribute of the given window. - * @param window The given window. - * @param override_redirect The override_redirect boolean. - * @ingroup Ecore_X_Window_Change_Attributes_Group - */ -EAPI void -ecore_x_window_override_set(Ecore_X_Window window, - Eina_Bool override_redirect) + list = gravity; + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_WIN_GRAVITY, &list); +} + +EAPI void +ecore_x_window_override_set(Ecore_X_Window win, Eina_Bool override) { - uint32_t value_list; + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + list = override; - value_list = override_redirect; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_OVERRIDE_REDIRECT, &value_list); -} /* ecore_x_window_override_set */ + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_OVERRIDE_REDIRECT, &list); +} /** - * Shows the cursor of the given window. - * @param window The given window. - * @param show If set to @c 0, hide the cursor. Show it otherwise. - * @ingroup Ecore_X_Window_Change_Attributes_Group + * To be documented. + * + * FIXME: To be fixed. */ -EAPI void -ecore_x_window_cursor_show(Ecore_X_Window window, - Eina_Bool show) +EAPI void +ecore_x_window_cursor_show(Ecore_X_Window win, Eina_Bool show) { - if (window == 0) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; + uint32_t list = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!show) + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + if (!show) { Ecore_X_Cursor cursor; - Ecore_X_Drawable draw; - Ecore_X_Pixmap pixmap; - Ecore_X_Pixmap mask; + Ecore_X_Pixmap p, m; Ecore_X_GC gc; xcb_point_t point; - uint32_t value_list; - - draw = window; - pixmap = xcb_generate_id(_ecore_xcb_conn); - xcb_create_pixmap(_ecore_xcb_conn, - 1, pixmap, draw, - 1, 1); - mask = xcb_generate_id(_ecore_xcb_conn); - xcb_create_pixmap(_ecore_xcb_conn, - 1, mask, draw, - 1, 1); + p = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, 1, p, win, 1, 1); + m = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, 1, m, win, 1, 1); gc = xcb_generate_id(_ecore_xcb_conn); - xcb_create_gc (_ecore_xcb_conn, gc, draw, 0, NULL); - value_list = 0; - xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &value_list); - - draw = mask; + xcb_create_gc(_ecore_xcb_conn, gc, win, 0, NULL); + xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list); point.x = 0; point.y = 0; - xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN, draw, - gc, 1, &point); - + xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN, + win, gc, 1, &point); xcb_free_gc(_ecore_xcb_conn, gc); cursor = xcb_generate_id(_ecore_xcb_conn); - xcb_create_cursor(_ecore_xcb_conn, cursor, - pixmap, mask, - 0, 0, 0, - 0, 0, 0, - 0, 0); - value_list = cursor; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_CURSOR, &value_list); + xcb_create_cursor(_ecore_xcb_conn, cursor, + p, m, 0, 0, 0, 0, 0, 0, 0, 0); + list = cursor; + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_CURSOR, &list); xcb_free_cursor(_ecore_xcb_conn, cursor); - xcb_free_pixmap(_ecore_xcb_conn, mask); - xcb_free_pixmap(_ecore_xcb_conn, pixmap); + xcb_free_pixmap(_ecore_xcb_conn, m); + xcb_free_pixmap(_ecore_xcb_conn, p); } - else + else { - uint32_t value_list; - - value_list = 0; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_CURSOR, &value_list); + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_CURSOR, &list); } -} /* ecore_x_window_cursor_show */ +} -/** - * Sets the cursor of the given window. - * @param window The given window. - * @param cursor The given cursor. - * @ingroup Ecore_X_Window_Change_Attributes_Group - */ -EAPI void -ecore_x_window_cursor_set(Ecore_X_Window window, - Ecore_X_Cursor cursor) +EAPI void +ecore_x_window_cursor_set(Ecore_X_Window win, Ecore_X_Cursor cursor) { - uint32_t value_list; + uint32_t list; - value_list = cursor; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_CURSOR, &value_list); -} /* ecore_x_window_cursor_set */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Todo - * @param window The given window. - * @ingroup Ecore_X_Window_Change_Attributes_Group - */ -EAPI void -ecore_x_window_container_manage(Ecore_X_Window window) + list = cursor; + + xcb_change_window_attributes(_ecore_xcb_conn, win, XCB_CW_CURSOR, &list); +} + +EAPI void +ecore_x_window_container_manage(Ecore_X_Window win) { - uint32_t value_list; + uint32_t list; - value_list = - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_EVENT_MASK, &value_list); -} /* ecore_x_window_container_manage */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Todo - * @param window The given window. - * @ingroup Ecore_X_Window_Change_Attributes_Group - */ -EAPI void -ecore_x_window_client_manage(Ecore_X_Window window) -{ - uint32_t value_list; - - value_list = - XCB_EVENT_MASK_VISIBILITY_CHANGE | -/* XCB_EVENT_MASK_RESIZE_REDIRECT | */ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_FOCUS_CHANGE | - XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_EVENT_MASK, &value_list); -#ifdef ECORE_XCB_SHAPE - xcb_shape_select_input(_ecore_xcb_conn, window, 1); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_client_manage */ + list = (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT); -/** - * Todo - * @param window The given window. - * @ingroup Ecore_X_Window_Change_Attributes_Group - */ -EAPI void -ecore_x_window_sniff(Ecore_X_Window window) + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +} + +EAPI void +ecore_x_window_client_manage(Ecore_X_Window win) { - uint32_t value_list; + uint32_t list; - value_list = - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | - XCB_EVENT_MASK_PROPERTY_CHANGE; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_EVENT_MASK, &value_list); -} /* ecore_x_window_sniff */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + list = (XCB_EVENT_MASK_VISIBILITY_CHANGE | + XCB_EVENT_MASK_FOCUS_CHANGE | + XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_COLOR_MAP_CHANGE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY); + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); -/** - * Todo - * @param window The given window. - * @ingroup Ecore_X_Window_Change_Attributes_Group - */ -EAPI void -ecore_x_window_client_sniff(Ecore_X_Window window) -{ - uint32_t value_list; - - value_list = - XCB_EVENT_MASK_VISIBILITY_CHANGE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_FOCUS_CHANGE | - XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE; - xcb_change_window_attributes(_ecore_xcb_conn, window, - XCB_CW_EVENT_MASK, &value_list); #ifdef ECORE_XCB_SHAPE - xcb_shape_select_input(_ecore_xcb_conn, window, 1); -#endif /* ECORE_XCB_SHAPE */ -} /* ecore_x_window_client_sniff */ + xcb_shape_select_input(_ecore_xcb_conn, win, 1); +#endif +} -/** - * Clears an area of the given window. - * @param window The given window. - * @param x The X coordinate of the area. - * @param y The Y coordinate of the area. - * @param width The width of the area. - * @param height The height of the area. - * @ingroup Ecore_X_Window_Clear_Area_Group - */ -EAPI void -ecore_x_window_area_clear(Ecore_X_Window window, - int x, - int y, - int width, - int height) +EAPI void +ecore_x_window_sniff(Ecore_X_Window win) { - xcb_clear_area(_ecore_xcb_conn, 0, window, x, y, width, height); -} /* ecore_x_window_area_clear */ + uint32_t list; -/** - * Exposes an area of the given window. - * @param window The given window. - * @param x The X coordinate of the area. - * @param y The Y coordinate of the area. - * @param width The width of the area. - * @param height The height of the area. - * @ingroup Ecore_X_Window_Clear_Area_Group - */ -EAPI void -ecore_x_window_area_expose(Ecore_X_Window window, - int x, - int y, - int width, - int height) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + list = (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_PROPERTY_CHANGE); + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +} + +EAPI void +ecore_x_window_client_sniff(Ecore_X_Window win) { - xcb_clear_area(_ecore_xcb_conn, 1, window, x, y, width, height); -} /* ecore_x_window_area_expose */ + uint32_t list; -/** - * @defgroup Ecore_X_Window_Save_Set_Group X Window Change Save Set Functions - * - * Functions that either inserts or deletes the specified window from - * the client's save-set. - */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Inserts the window in the client's save-set. - * @param window The window to insert in the client's save-set. - * @ingroup Ecore_X_Window_Save_Set_Group - */ -EAPI void -ecore_x_window_save_set_add(Ecore_X_Window window) + list = (XCB_EVENT_MASK_VISIBILITY_CHANGE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_FOCUS_CHANGE | + XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_COLOR_MAP_CHANGE); + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +#ifdef ECORE_XCB_SHAPE + xcb_shape_select_input(_ecore_xcb_conn, win, 1); +#endif + +} + +EAPI void +ecore_x_window_area_clear(Ecore_X_Window win, int x, int y, int w, int h) { - xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, window); -} /* ecore_x_window_save_set_add */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Deletes the window from the client's save-set. - * @param window The window to delete from the client's save-set. - * @ingroup Ecore_X_Window_Save_Set_Group - */ -EAPI void -ecore_x_window_save_set_del(Ecore_X_Window window) + xcb_clear_area(_ecore_xcb_conn, 0, win, x, y, w, h); +} + +EAPI void +ecore_x_window_area_expose(Ecore_X_Window win, int x, int y, int w, int h) { - xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, window); -} /* ecore_x_window_save_set_del */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/****************************** -* -* Request that have a reply -* -******************************/ + xcb_clear_area(_ecore_xcb_conn, 1, win, x, y, w, h); +} -/** - * Sends the GetInputFocus request. - * @ingroup Ecore_X_Window_Input_Focus_Group - */ -EAPI void -ecore_x_get_input_focus_prefetch(void) +EAPI void +ecore_x_window_save_set_add(Ecore_X_Window win) { - xcb_get_input_focus_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_get_input_focus_prefetch */ + xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, win); +} -/** - * Gets the reply of the GetInputFocus request sent by ecore_x_get_input_focus_prefetch(). - * @ingroup Ecore_X_Window_Input_Focus_Group - */ -EAPI void -ecore_x_get_input_focus_fetch(void) +EAPI void +ecore_x_window_save_set_del(Ecore_X_Window win) { - xcb_get_input_focus_cookie_t cookie; - xcb_get_input_focus_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_get_input_focus_fetch */ + xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, win); +} /** - * Gets the window that has focus. + * gets the focus to the window @p win. * @return The window that has focus. - * - * Returns the window that has the focus. If an error aoocured, @c 0 - * is returned, otherwise the function returns the window that has focus. - * - * To use this function, you must call before, and in order, - * ecore_x_get_input_focus_prefetch(), which sends the GetInputFocus request, - * then ecore_x_get_input_focus_fetch(), which gets the reply. - * @ingroup Ecore_X_Window_Input_Focus_Group + * @ingroup Ecore_X_Window_Focus_Functions */ -EAPI Ecore_X_Window -ecore_x_window_focus_get(void) +EAPI Ecore_X_Window +ecore_x_window_focus_get(void) { + xcb_get_input_focus_cookie_t cookie; xcb_get_input_focus_reply_t *reply; - Ecore_X_Window window = 0; + Ecore_X_Window focus = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return window; + cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn); + reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + focus = reply->focus; + free(reply); + return focus; +} + +EAPI int +ecore_x_window_argb_get(Ecore_X_Window win) +{ + uint8_t ret = 0; +#ifdef ECORE_XCB_RENDER + Ecore_X_Visual visual; +#endif - return reply->focus; -} /* ecore_x_window_focus_get */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * @defgroup Ecore_X_Window_Get_Attributes_Group X Window Get Attributes Functions - * - * Functions that get the attributes of a window. - */ +// if (!win) return ret; -/** - * Sends the GetWindowAttributes request. - * @ingroup Ecore_X_Window_Get_Attributes_Group - */ -EAPI void -ecore_x_get_window_attributes_prefetch(Ecore_X_Window window) -{ - xcb_get_window_attributes_cookie_t cookie; +#ifdef ECORE_XCB_RENDER + /* grab the window's visual */ + visual = _ecore_xcb_window_visual_get(win); - cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_get_window_attributes_prefetch */ + /* check if this visual supports alpha */ + ret = _ecore_xcb_render_visual_supports_alpha(visual); +#endif -/** - * Gets the reply of the GetWindowAttributes request sent by ecore_x_get_window_attributes_prefetch(). - * @ingroup Ecore_X_Window_Get_Attributes_Group - */ -EAPI void -ecore_x_get_window_attributes_fetch(void) + return ret; +} + +EAPI Eina_Bool +ecore_x_window_manage(Ecore_X_Window win) { xcb_get_window_attributes_cookie_t cookie; xcb_get_window_attributes_reply_t *reply; + xcb_void_cookie_t change_cookie; + xcb_generic_error_t *err; + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); + cookie = xcb_get_window_attributes(_ecore_xcb_conn, win); reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_get_window_attributes_fetch */ + if (!reply) return EINA_FALSE; -/** - * Retrieves the attributes of a window. - * @param windows Unused. - * @param att_ret Pointer to an Ecore_X_Window_Attributes - * structure in which the attributes of a window - * are to be stored. - * - * Retrieves the attributes of a window. If - * @p att_ret is @c NULL, the function does nothing. If an error - * occurred, @p att_ret is set to 0. Otherwise, the @p att_ret structure - * is filled with the attributes os the requested window. - * - * To use this function, you must call before, and in order, - * ecore_x_get_window_attributes_prefetch(), which sends the GetWindowAttributes request, - * then ecore_x_get_window_attributes_fetch(), which gets the reply. - * @ingroup Ecore_X_Window_Get_Attributes_Group - */ -EAPI Eina_Bool -ecore_x_window_attributes_get(Ecore_X_Window window __UNUSED__, - Ecore_X_Window_Attributes *att_ret) -{ - xcb_get_window_attributes_reply_t *reply; + ecore_x_sync(); // needed - if (!att_ret) - return 0; + list = (XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | + XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | + reply->your_event_mask); + free(reply); - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + change_cookie = xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); - memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes)); + ecore_x_sync(); // needed - if (reply->map_state != XCB_MAP_STATE_UNMAPPED) - att_ret->visible = 1; + err = xcb_request_check(_ecore_xcb_conn, change_cookie); + if (err) return EINA_FALSE; - if (reply->map_state == XCB_MAP_STATE_VIEWABLE) - att_ret->viewable = 1; + return EINA_TRUE; +} - if (reply->override_redirect) - att_ret->override = 1; +EAPI Eina_Bool +ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret) +{ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + xcb_get_geometry_cookie_t gcookie; + xcb_get_geometry_reply_t *greply; - if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY) - att_ret->input_only = 1; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (reply->save_under) - att_ret->save_under = 1; + cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); + gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); - att_ret->event_mask.mine = reply->your_event_mask; + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes)); + + if (reply->map_state != XCB_MAP_STATE_UNMAPPED) + att_ret->visible = 1; + if (reply->map_state == XCB_MAP_STATE_VIEWABLE) + att_ret->viewable = 1; + if (reply->override_redirect) att_ret->override = 1; + if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY) + att_ret->input_only = 1; + if (reply->save_under) att_ret->save_under = 1; + att_ret->event_mask.mine = reply->your_event_mask; att_ret->event_mask.all = reply->all_event_masks; att_ret->event_mask.no_propagate = reply->do_not_propagate_mask; att_ret->window_gravity = reply->win_gravity; att_ret->pixel_gravity = reply->bit_gravity; att_ret->colormap = reply->colormap; - att_ret->visual = reply->visual; + att_ret->visual = _ecore_xcb_window_find_visual_by_id(reply->visual); - return 1; -} /* ecore_x_window_attributes_get */ + free(reply); -/** - * Finds out whether the given window is currently visible. - * @param window Unused. - * @return 1 if the window is visible, otherwise 0. - * - * Finds out whether the given window is currently visible. - * If an error occurred, or if the window is not visible, 0 is - * returned. Otherwise 1 is returned. - * - * To use this function, you must call before, and in order, - * ecore_x_get_window_attributes_prefetch(), which sends the GetWindowAttributes request, - * then ecore_x_get_window_attributes_fetch(), which gets the reply. - * @ingroup Ecore_X_Window_Get_Attributes_Group - */ -EAPI int -ecore_x_window_visible_get(Ecore_X_Window window __UNUSED__) -{ - xcb_get_window_attributes_reply_t *reply; + greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL); + if (!greply) return EINA_TRUE; - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + /* xcb_translate_coordinates_reply_t *trans; */ + /* xcb_query_tree_cookie_t tcookie; */ + /* xcb_query_tree_reply_t *treply; */ - return (reply->map_state == XCB_MAP_STATE_VIEWABLE) ? 1 : 0; -} /* ecore_x_window_visible_get */ + /* tcookie = xcb_query_tree(_ecore_xcb_conn, win); */ + /* treply = xcb_query_tree_reply(_ecore_xcb_conn, tcookie, NULL); */ -/** - * Sends the QueryPointer request. - * @ingroup Ecore_X_Window_Parent_Group - */ -EAPI void -ecore_x_pointer_xy_get_prefetch(Ecore_X_Window window) -{ - xcb_query_pointer_cookie_t cookie; + /* trans = */ + /* xcb_translate_coordinates_reply(_ecore_xcb_conn, */ + /* xcb_translate_coordinates(_ecore_xcb_conn, */ + /* win, treply->parent, greply->x, greply->y), NULL); */ + /* free(treply); */ + + att_ret->root = greply->root; + att_ret->depth = greply->depth; +// att_ret->x = trans->dst_x; +// att_ret->y = trans->dst_y; + att_ret->x = greply->x; + att_ret->y = greply->y; + att_ret->w = greply->width; + att_ret->h = greply->height; + att_ret->border = greply->border_width; - cookie = xcb_query_pointer_unchecked(_ecore_xcb_conn, window); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_pointer_xy_get_prefetch */ +// free(trans); + + free(greply); + return EINA_TRUE; +} /** - * Gets the reply of the QueryPointer request sent by ecore_x_query_pointer_prefetch(). - * @ingroup Ecore_X_Window_Parent_Group + * Retrieves the size of the given window. + * @param win The given window. + * @param w Pointer to an integer into which the width is to be stored. + * @param h Pointer to an integer into which the height is to be stored. + * @ingroup Ecore_X_Window_Geometry_Group */ -EAPI void -ecore_x_pointer_xy_get_fetch(void) +EAPI void +ecore_x_window_size_get(Ecore_X_Window win, int *width, int *height) { - xcb_query_pointer_cookie_t cookie; - xcb_query_pointer_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_query_pointer_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_pointer_xy_get_fetch */ + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + ecore_x_drawable_geometry_get(win, NULL, NULL, width, height); +} /** - * Retrieves the coordinates of the pointer. - * @param window Unused. - * @param x The X coordinate of the pointer. - * @param y The Y coordinate of the pointer. - * - * Retrieves the coordinates of the pointer. - * If the window used in - * ecore_x_query_pointer_prefetch() is not on the same screen than - * the root window or if an error occurred, @p x and @p y are set - * to 0. Otherwise, they are respectively set to the X and Y - * coordinates of the pointer. - * - * To use this function, you must call before, and in order, - * ecore_x_query_pointer_prefetch(), which sends the QueryPointer request, - * then ecore_x_query_pointer_fetch(), which gets the reply. - * @ingroup Ecore_X_Window_Parent_Group + * Set if a window should be ignored. + * @param win The given window. + * @param ignore if to ignore */ -EAPI void -ecore_x_pointer_xy_get(Ecore_X_Window window __UNUSED__, - int *x, - int *y) +EAPI void +ecore_x_window_ignore_set(Ecore_X_Window win, int ignore) { - xcb_query_pointer_reply_t *reply; + int i = 0, j = 0, count = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) + if (ignore) { - if (x) - *x = 0; + if (ignore_list) + { + for (i = 0; i < ignore_num; i++) + if (win == ignore_list[i]) return; - if (y) - *y = 0; + ignore_list = + realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window)); + if (!ignore_list) return; - return; + ignore_list[ignore_num++] = win; + } + else + { + ignore_num = 0; + ignore_list = malloc(sizeof(Ecore_X_Window)); + if (!ignore_list) return; + ignore_list[ignore_num++] = win; + } } + else + { + if (!ignore_list) return; + for (count = ignore_num, i = 0, j = 0; i < count; i++) + { + if (win != ignore_list[i]) + ignore_list[j++] = ignore_list[i]; + else + ignore_num--; + } + if (ignore_num <= 0) + { + free(ignore_list); + ignore_list = NULL; + return; + } - if (x) - *x = reply->win_x; - - if (y) - *y = reply->win_y; -} /* ecore_x_pointer_xy_get */ + ignore_list = + realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window)); + } +} /** - * Sends the QueryTree request. - * @ingroup Ecore_X_Window_Parent_Group + * Get the ignore list + * @param num number of windows in the list + * @return list of windows to ignore */ -EAPI void -ecore_x_query_tree_prefetch(Ecore_X_Window window) +EAPI Ecore_X_Window * +ecore_x_window_ignore_list(int *num) { - xcb_query_tree_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, window); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_query_tree_prefetch */ + if (num) *num = ignore_num; + return ignore_list; +} /** - * Gets the reply of the QueryTree request sent by ecore_x_query_tree_prefetch(). - * @ingroup Ecore_X_Window_Parent_Group + * Get a list of all the root windows on the server. + * + * @note The returned array will need to be freed after use. + * @param num_ret Pointer to integer to put number of windows returned in. + * @return An array of all the root windows. @c NULL is returned if memory + * could not be allocated for the list, or if @p num_ret is @c NULL. */ -EAPI void -ecore_x_query_tree_fetch(void) +EAPI Ecore_X_Window * +ecore_x_window_root_list(int *num_ret) { - xcb_query_tree_cookie_t cookie; - xcb_query_tree_reply_t *reply; + xcb_screen_iterator_t iter; + const xcb_setup_t *setup; + uint8_t i, num; + Ecore_X_Window *roots; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_query_tree_fetch */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Retrieves the parent window of the given window. - * @param window Unused. - * @return The parent window of @p window. - * - * Retrieves the parent window of the given window. If - * an error occurred, @c 0 is returned. - * - * To use this function, you must call before, and in order, - * ecore_x_query_tree_prefetch(), which sends the QueryTree request, - * then ecore_x_query_tree_fetch(), which gets the reply. - * @ingroup Ecore_X_Window_Parent_Group - */ -EAPI Ecore_X_Window -ecore_x_window_parent_get(Ecore_X_Window window __UNUSED__) -{ - xcb_query_tree_reply_t *reply; + if (!num_ret) return NULL; - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + setup = xcb_get_setup(_ecore_xcb_conn); + iter = xcb_setup_roots_iterator(setup); + num = setup->roots_len; + if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL; + *num_ret = num; + for (i = 0; iter.rem; xcb_screen_next(&iter), i++) + roots[i] = iter.data->root; - return reply->parent; -} /* ecore_x_window_parent_get */ + return roots; +} -/** - * Retrieves the children windows of the given window. - * @param window Unused. - * @param num children windows count. - * @return The children windows. - * - * Retrieves the children windows of the given window. If - * an error occurred, @c 0 is returned. - * - * To use this function, you must call before, and in order, - * ecore_x_query_tree_prefetch(), which sends the QueryTree request, - * then ecore_x_query_tree_fetch(), which gets the reply. - * @ingroup Ecore_X_Window_Parent_Group - */ EAPI Ecore_X_Window * -ecore_x_window_children_get(Ecore_X_Window window __UNUSED__, - int *num) +ecore_x_window_children_get(Ecore_X_Window win, int *num) { + xcb_query_tree_cookie_t cookie; xcb_query_tree_reply_t *reply; + xcb_window_t *w; Ecore_X_Window *windows = NULL; - if (num) - *num = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return NULL; + if (num) *num = 0; + cookie = xcb_query_tree(_ecore_xcb_conn, win); + reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + if (num) *num = reply->children_len; windows = malloc(sizeof(Ecore_X_Window) * reply->children_len); - if (!windows) - return NULL; - - if (num) - *num = reply->children_len; - - memcpy(windows, - xcb_query_tree_children(reply), - sizeof(Ecore_X_Window) * reply->children_len); - - return windows; -} /* ecore_x_window_children_get */ - -/* FIXME: I've tried to remove the round trips. 3 cookies are */ -/* created at the beginning of the function. Because of */ -/* the recursivity of the algo, I can't find better trick */ -static Ecore_X_Window -_ecore_x_window_at_xy_get(Ecore_X_Window base, - int16_t base_x, - int16_t base_y, - int16_t x, - int16_t y, - Ecore_X_Window *skip, - int skip_num) -{ - xcb_get_window_attributes_cookie_t cookie_get_window_attributes; - xcb_get_geometry_cookie_t cookie_get_geometry; - xcb_query_tree_cookie_t cookie_query_tree; - xcb_get_window_attributes_reply_t *reply_get_window_attributes; - xcb_get_geometry_reply_t *reply_get_geometry; - xcb_query_tree_reply_t *reply_query_tree; - Ecore_X_Window window = 0; - Ecore_X_Window child = 0; - int16_t win_x; - int16_t win_y; - uint16_t win_width; - uint16_t win_height; - xcb_window_t *wins = NULL; - int tree_c_len; - int i; - - cookie_get_window_attributes = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, base); - cookie_get_geometry = xcb_get_geometry_unchecked(_ecore_xcb_conn, base); - cookie_query_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, base); - - reply_get_window_attributes = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_get_window_attributes, NULL); - if (!reply_get_window_attributes) + if (windows) { - reply_get_geometry = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_get_geometry, NULL); - if (reply_get_geometry) - free(reply_get_geometry); + unsigned int i = 0; - reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL); - if (reply_query_tree) - free(reply_query_tree); - - return window; + w = xcb_query_tree_children(reply); + for (i = 0; i < reply->children_len; i++) + windows[i] = w[i]; } - if (reply_get_window_attributes->map_state != XCB_MAP_STATE_VIEWABLE) - { - free(reply_get_window_attributes); - reply_get_geometry = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_get_geometry, NULL); - if (reply_get_geometry) - free(reply_get_geometry); - - reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL); - if (reply_query_tree) - free(reply_query_tree); - - return window; - } - - free(reply_get_window_attributes); - - reply_get_geometry = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_get_geometry, NULL); - if (!reply_get_geometry) - { - reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL); - if (reply_query_tree) - free(reply_query_tree); - - return window; - } - - win_x = reply_get_geometry->x; - win_y = reply_get_geometry->y; - win_width = reply_get_geometry->width; - win_height = reply_get_geometry->height; - - free(reply_get_geometry); - - win_x += base_x; - win_y += base_y; - - if (!((x >= win_x) && - (y >= win_y) && - (x < (int16_t)(win_x + win_width)) && - (y < (int16_t)(win_y + win_height)))) - { - reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL); - if (reply_query_tree) - free(reply_query_tree); - - return window; - } - - reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL); - if (!reply_query_tree) - { - if (skip) - { - int i; - - for (i = 0; i < skip_num; i++) - if (base == skip[i]) - return window; - - } - - return base; - } - - wins = xcb_query_tree_children(reply_query_tree); - tree_c_len = xcb_query_tree_children_length(reply_query_tree); - for(i = 0; i < tree_c_len; i++) - { - if (skip) - { - int j; - - for (j = 0; j < skip_num; j++) - if (wins[i] == skip[j]) - continue; - - } - - child = _ecore_x_window_at_xy_get(wins[i], win_x, win_y, x, y, skip, skip_num); - if (child) - { - free(reply_query_tree); + free(reply); + return windows; +} - return child; - } - } +/** + * Retrieves the root window a given window is on. + * @param win The window to get the root window of + * @return The root window of @p win + * @ingroup Ecore_X_Window_Geometry_Group + */ +EAPI Ecore_X_Window +ecore_x_window_root_get(Ecore_X_Window win) +{ + xcb_get_geometry_cookie_t gcookie; + xcb_get_geometry_reply_t *greply; + Ecore_X_Window window = 0; - if (skip) - { - int i; + /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ - for (i = 0; i < skip_num; i++) - if (base == skip[i]) - { - /* We return 0. child has an xid equal to 0 */ - free(reply_query_tree); - return child; - } + gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); + greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL); + if (!greply) return 0; + window = greply->root; + free(greply); - } + return window; +} - free(reply_query_tree); +EAPI Ecore_X_Window +ecore_x_window_root_first_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return base; -} /* _ecore_x_window_at_xy_get */ + return ((xcb_screen_t *)_ecore_xcb_screen)->root; +} /** - * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions + * Retrieves the geometry of the given window. * - * Functions that change or retrieve the geometry of X windows. + * Note that the x & y coordingates are relative to your parent. In + * particular for reparenting window managers - relative to you window border. + * If you want screen coordinates either walk the window tree to the root, + * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary + * applications can use elm_win_screen_position_get(). + * + * @param win The given window. + * @param x Pointer to an integer in which the X position is to be stored. + * @param y Pointer to an integer in which the Y position is to be stored. + * @param w Pointer to an integer in which the width is to be stored. + * @param h Pointer to an integer in which the height is to be stored. + * @ingroup Ecore_X_Window_Geometry_Group */ +EAPI void +ecore_x_window_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + ecore_x_drawable_geometry_get(win, x, y, w, h); +} /** * Retrieves the top, visible window at the given location. * @param x The given X position. * @param y The given Y position. - * @return The window at that position. + * @return The window at that position. * @ingroup Ecore_X_Window_Geometry_Group */ -EAPI Ecore_X_Window -ecore_x_window_at_xy_get(int x, - int y) +EAPI Ecore_X_Window +ecore_x_window_at_xy_get(int x, int y) { - Ecore_X_Window window; - Ecore_X_Window root; + Ecore_X_Window root, win = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* FIXME: Proper function to determine current root/virtual root - * window missing here */ root = ((xcb_screen_t *)_ecore_xcb_screen)->root; ecore_x_grab(); - window = _ecore_x_window_at_xy_get(root, 0, 0, x, y, NULL, 0); + win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, NULL, 0); ecore_x_ungrab(); - return window ? window : root; -} /* ecore_x_window_at_xy_get */ + return win ? win : root; +} /** * Retrieves the top, visible window at the given location, * but skips the windows in the list. * @param x The given X position. * @param y The given Y position. - * @return The window at that position. + * @return The window at that position. * @ingroup Ecore_X_Window_Geometry_Group */ -EAPI Ecore_X_Window -ecore_x_window_at_xy_with_skip_get(int x, - int y, - Ecore_X_Window *skip, - int skip_num) +EAPI Ecore_X_Window +ecore_x_window_at_xy_with_skip_get(int x, int y, Ecore_X_Window *skip, int skip_num) { - Ecore_X_Window window; - Ecore_X_Window root; + Ecore_X_Window root, win = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* FIXME: Proper function to determine current root/virtual root - * window missing here */ root = ((xcb_screen_t *)_ecore_xcb_screen)->root; ecore_x_grab(); - window = _ecore_x_window_at_xy_get(root, 0, 0, x, y, skip, skip_num); + win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, skip, skip_num); ecore_x_ungrab(); - return window ? window : root; -} /* ecore_x_window_at_xy_with_skip_get */ + return win ? win : root; +} -/** - * Retrieves the top, visible window at the given location, - * but begins at the @p begin window instead of the root one. - * @param begin The window from which we begin. - * @param x The given X position. - * @param y The given Y position. - * @return The window at that position. - * @ingroup Ecore_X_Window_Geometry_Group - */ -EAPI Ecore_X_Window -ecore_x_window_at_xy_begin_get(Ecore_X_Window begin, - int x, - int y) +EAPI Ecore_X_Window +ecore_x_window_at_xy_begin_get(Ecore_X_Window begin, int x, int y) { - Ecore_X_Window window; + Ecore_X_Window win = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); ecore_x_grab(); - window = _ecore_x_window_at_xy_get(begin, 0, 0, x, y, NULL, 0); + win = _ecore_xcb_window_at_xy_get(begin, 0, 0, x, y, NULL, 0); ecore_x_ungrab(); - return window ? window : begin; -} /* ecore_x_window_at_xy_begin_get */ + return win ? win : begin; +} -/* FIXME: Should I provide the replies (or the cookies), instead of - creating them in the function ? */ -#ifdef ECORE_XCB_RENDER -static Ecore_X_Window -_ecore_x_window_argb_internal_new(Ecore_X_Window parent, - int16_t x, - int16_t y, - uint16_t w, - uint16_t h, - uint8_t override_redirect, - uint8_t save_under) +/** + * Retrieves the parent window of the given window. + * @param win The given window. + * @return The parent window of @p win. + * @ingroup Ecore_X_Window_Parent_Group + */ +EAPI Ecore_X_Window +ecore_x_window_parent_get(Ecore_X_Window win) { - uint32_t value_list[10]; - xcb_depth_iterator_t iter_depth; - xcb_visualtype_iterator_t iter_visualtype; - xcb_render_query_pict_formats_cookie_t cookie_pict_format; - xcb_render_query_pict_formats_reply_t *rep_pict_format; - Ecore_X_Screen *screen = NULL; - Ecore_X_Window win = { 0 }; - xcb_visualid_t vis = { 0 }; - Ecore_X_Colormap colormap; - uint32_t value_mask; + xcb_query_tree_cookie_t cookie; + xcb_query_tree_reply_t *reply; + Ecore_X_Window window = 0; - cookie_pict_format = xcb_render_query_pict_formats_unchecked(_ecore_xcb_conn); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (parent == 0) - { - parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; - screen = ((xcb_screen_t *)_ecore_xcb_screen); - } - else - { - xcb_screen_iterator_t iter_screen; - xcb_get_geometry_reply_t *rep; - Ecore_X_Drawable draw; - Ecore_X_Window root; +// if (!win) return 0; + cookie = xcb_query_tree(_ecore_xcb_conn, win); + reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + window = reply->parent; + free(reply); - draw = parent; - rep = xcb_get_geometry_reply(_ecore_xcb_conn, - xcb_get_geometry_unchecked(_ecore_xcb_conn, - draw), - NULL); - if (!rep) - return win; + return window; +} - root = rep->root; +/** + * Finds out whether the given window is currently visible. + * @param win The given window. + * @return 1 if the window is visible, otherwise 0. + * @ingroup Ecore_X_Window_Visibility_Group + */ +EAPI int +ecore_x_window_visible_get(Ecore_X_Window win) +{ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + int ret = EINA_FALSE; - free(rep); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - for (; iter_screen.rem; xcb_screen_next(&iter_screen)) - { - if (iter_screen.data->root == root) - { - screen = iter_screen.data; - } - } - } + cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; - if (!screen) - return win; + if (reply->map_state == XCB_MAP_STATE_VIEWABLE) + ret = EINA_TRUE; - /* we get the X visual types */ - iter_depth = xcb_screen_allowed_depths_iterator(screen); - for (; iter_depth.rem; xcb_depth_next(&iter_depth)) { - if (iter_depth.data->depth == 32) - { - iter_visualtype = xcb_depth_visuals_iterator(iter_depth.data); - break; - } - } + free(reply); + return ret; +} - /* we get the X render visual id */ - rep_pict_format = xcb_render_query_pict_formats_reply(_ecore_xcb_conn, - cookie_pict_format, - NULL); - if (!rep_pict_format) - return win; +EAPI void +ecore_x_window_button_grab(Ecore_X_Window win, int button, Ecore_X_Event_Mask mask, int mod, int any_mod) +{ + int i = 0; + uint16_t m, locks[8], ev; + uint8_t b; + Ecore_X_Window *t; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + b = button; + if (b == 0) + b = XCB_BUTTON_INDEX_ANY; + + m = _ecore_xcb_window_modifiers_get(mod); + if (any_mod) m = XCB_MOD_MASK_ANY; + + locks[0] = 0; + locks[1] = ECORE_X_LOCK_CAPS; + locks[2] = ECORE_X_LOCK_NUM; + locks[3] = ECORE_X_LOCK_SCROLL; + locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; + locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; + locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + + ev = mask; + for (i = 0; i < 8; i++) + xcb_grab_button(_ecore_xcb_conn, 0, win, ev, + XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, + XCB_NONE, XCB_NONE, b, m | locks[i]); + + _ecore_xcb_button_grabs_num++; + t = realloc(_ecore_xcb_button_grabs, + _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window)); + if (!t) return; + + _ecore_xcb_button_grabs = t; + _ecore_xcb_button_grabs[_ecore_xcb_button_grabs_num - 1] = win; +} + +EAPI void +ecore_x_window_button_ungrab(Ecore_X_Window win, int button, int mod, int any_mod) +{ + int i = 0; + uint16_t m = 0, locks[8]; + uint8_t b; - for (; iter_visualtype.rem; xcb_visualtype_next(&iter_visualtype)) { - if (iter_visualtype.data->_class == XCB_VISUAL_CLASS_TRUE_COLOR) - { - xcb_render_pictforminfo_iterator_t iter_forminfo; - xcb_render_pictscreen_iterator_t iter_pictscreen; - xcb_render_pictformat_t pict_format = { 0 }; - - iter_forminfo = xcb_render_query_pict_formats_formats_iterator(rep_pict_format); - for (; iter_forminfo.rem; xcb_render_pictforminfo_next(&iter_forminfo)) { - if (iter_forminfo.data->type == XCB_RENDER_PICT_TYPE_DIRECT && - iter_forminfo.data->direct.alpha_mask && iter_forminfo.data->depth == 32) - { - pict_format = iter_forminfo.data->id; - break; - } - } - if (pict_format == 0) - { - free(rep_pict_format); - return win; - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); - iter_pictscreen = xcb_render_query_pict_formats_screens_iterator(rep_pict_format); - for (; iter_pictscreen.rem; xcb_render_pictscreen_next(&iter_pictscreen)) { - xcb_render_pictdepth_iterator_t iter_depth; - - iter_depth = xcb_render_pictscreen_depths_iterator(iter_pictscreen.data); - for (; iter_depth.rem; xcb_render_pictdepth_next(&iter_depth)) { - xcb_render_pictvisual_iterator_t iter_visual; - - iter_visual = xcb_render_pictdepth_visuals_iterator(iter_depth.data); - for (; iter_visual.rem; xcb_render_pictvisual_next(&iter_visual)) { - if ((iter_visual.data->visual == iter_visualtype.data->visual_id) && - (pict_format == iter_visual.data->format)) - { - vis = iter_visual.data->visual; - break; - } - } - } - } - } - } + b = button; + if (b == 0) b = XCB_BUTTON_INDEX_ANY; + + m = _ecore_xcb_window_modifiers_get(mod); + if (any_mod) m = XCB_MOD_MASK_ANY; - free(rep_pict_format); + locks[0] = 0; + locks[1] = ECORE_X_LOCK_CAPS; + locks[2] = ECORE_X_LOCK_NUM; + locks[3] = ECORE_X_LOCK_SCROLL; + locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; + locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; + locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; - if (vis == 0) - return win; + for (i = 0; i < 8; i++) + xcb_ungrab_button(_ecore_xcb_conn, b, win, m | locks[i]); + + _ecore_xcb_sync_magic_send(1, win); +} + +EAPI void +ecore_x_window_key_grab(Ecore_X_Window win, const char *key, int mod, int any_mod) +{ + xcb_keycode_t keycode = XCB_NO_SYMBOL; + uint16_t m = 0, locks[8]; + int i = 0; + Ecore_X_Window *t; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + keycode = _ecore_xcb_keymap_string_to_keycode(key); + if (keycode == XCB_NO_SYMBOL) return; + + m = _ecore_xcb_window_modifiers_get(mod); + if (any_mod) m = XCB_MOD_MASK_ANY; + + locks[0] = 0; + locks[1] = ECORE_X_LOCK_CAPS; + locks[2] = ECORE_X_LOCK_NUM; + locks[3] = ECORE_X_LOCK_SCROLL; + locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; + locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; + locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + + for (i = 0; i < 8; i++) + xcb_grab_key(_ecore_xcb_conn, 0, win, m | locks[i], + keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); + _ecore_xcb_key_grabs_num++; + t = realloc(_ecore_xcb_key_grabs, + _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window)); + if (!t) return; + _ecore_xcb_key_grabs = t; + _ecore_xcb_key_grabs[_ecore_xcb_key_grabs_num - 1] = win; +} + +EAPI void +ecore_x_window_key_ungrab(Ecore_X_Window win, const char *key, int mod, int any_mod) +{ + xcb_keycode_t keycode = XCB_NO_SYMBOL; + uint16_t m = 0, locks[8]; + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + keycode = _ecore_xcb_keymap_string_to_keycode(key); + if (keycode == XCB_NO_SYMBOL) return; + + m = _ecore_xcb_window_modifiers_get(mod); + if (any_mod) m = XCB_MOD_MASK_ANY; + + locks[0] = 0; + locks[1] = ECORE_X_LOCK_CAPS; + locks[2] = ECORE_X_LOCK_NUM; + locks[3] = ECORE_X_LOCK_SCROLL; + locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; + locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; + locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + + for (i = 0; i < 8; i++) + xcb_ungrab_key(_ecore_xcb_conn, keycode, win, m | locks[i]); + + _ecore_xcb_sync_magic_send(2, win); +} + +/* local functions */ +Ecore_X_Window +_ecore_xcb_window_root_of_screen_get(int screen) +{ + xcb_screen_iterator_t iter; + + iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); + for (; iter.rem; --screen, xcb_screen_next(&iter)) + if (screen == 0) + { + xcb_screen_t *s; + + if ((s = iter.data)) + return s->root; + } + return 0; +} + +static Ecore_X_Window +_ecore_xcb_window_argb_internal_new(Ecore_X_Window parent, int x, int y, int w, int h, uint8_t override_redirect, uint8_t save_under) +{ + Ecore_X_Window win = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RENDER + uint32_t value_list[10]; + uint32_t value_mask, vis; + Ecore_X_Colormap colormap; + + if (parent == 0) + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + vis = + _ecore_xcb_render_find_visual_id(XCB_RENDER_PICT_TYPE_DIRECT, EINA_TRUE); colormap = xcb_generate_id(_ecore_xcb_conn); - xcb_create_colormap(_ecore_xcb_conn, XCB_COLORMAP_ALLOC_NONE, colormap, parent, vis); + xcb_create_colormap(_ecore_xcb_conn, XCB_COLORMAP_ALLOC_NONE, + colormap, parent, vis); - value_mask = - XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | - XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT | - XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE | - XCB_CW_COLORMAP; + value_mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | + XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | + XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | + XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE | XCB_CW_COLORMAP); - value_list[0] = XCB_NONE; + value_list[0] = XCB_BACK_PIXMAP_NONE; value_list[1] = 0; value_list[2] = XCB_GRAVITY_NORTH_WEST; value_list[3] = XCB_GRAVITY_NORTH_WEST; value_list[4] = XCB_BACKING_STORE_NOT_USEFUL; value_list[5] = override_redirect; value_list[6] = save_under; - value_list[7] = - XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE; + value_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | + XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | + XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE | + XCB_EVENT_MASK_VISIBILITY_CHANGE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_FOCUS_CHANGE | + XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_COLOR_MAP_CHANGE); value_list[8] = XCB_EVENT_MASK_NO_EVENT; value_list[9] = colormap; win = xcb_generate_id(_ecore_xcb_conn); - xcb_create_window(_ecore_xcb_conn, - 32, /* depth */ - win, parent, - x, y, w, h, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - vis, - value_mask, + xcb_create_window(_ecore_xcb_conn, 32, win, parent, x, y, w, h, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, vis, value_mask, value_list); xcb_free_colormap(_ecore_xcb_conn, colormap); if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root) - ecore_x_window_defaults_set(win); + ecore_x_window_defaults_set(win); +#endif return win; -} /* _ecore_x_window_argb_internal_new */ +} -#endif /* ECORE_XCB_RENDER */ - -/* FIXME: round trip */ -EAPI int -ecore_x_window_argb_get(Ecore_X_Window win) +static Ecore_X_Window +_ecore_xcb_window_at_xy_get(Ecore_X_Window base, int bx, int by, int x, int y, Ecore_X_Window *skip, int skip_num) { - uint8_t ret = 0; -#ifdef ECORE_XCB_RENDER - xcb_render_pictforminfo_iterator_t iter_forminfo; - xcb_render_pictscreen_iterator_t iter_pictscreen; - xcb_render_pictformat_t pict_format = { 0 }; - xcb_render_query_pict_formats_reply_t *rep_pictformat; - xcb_get_window_attributes_reply_t *rep; - xcb_visualid_t visual; - - rep = xcb_get_window_attributes_reply(_ecore_xcb_conn, - xcb_get_window_attributes_unchecked(_ecore_xcb_conn, - win), - NULL); - if (!rep) - return ret; - - visual = rep->visual; - - free(rep); - - rep_pictformat = xcb_render_query_pict_formats_reply(_ecore_xcb_conn, - xcb_render_query_pict_formats_unchecked(_ecore_xcb_conn), - NULL); - if (!rep_pictformat) - return ret; - - iter_forminfo = xcb_render_query_pict_formats_formats_iterator(rep_pictformat); - for (; iter_forminfo.rem; xcb_render_pictforminfo_next(&iter_forminfo)) - { - if ((iter_forminfo.data->type == XCB_RENDER_PICT_TYPE_DIRECT) && - (iter_forminfo.data->direct.alpha_mask)) - { - pict_format = iter_forminfo.data->id; - break; - } - } - if (pict_format == 0) - { - free(rep_pictformat); + xcb_query_tree_cookie_t cookie; + xcb_query_tree_reply_t *reply; + Ecore_X_Window *windows = NULL; + int wx, wy, ww, wh, num, i = 0; + Eina_Bool skipit = EINA_FALSE; - return ret; - } + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_visible_get(base)) return 0; + + ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh); + wx += bx; + wy += by; + + if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh)))) + return 0; + + cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, base); + reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + + num = reply->children_len; + windows = xcb_query_tree_children(reply); - iter_pictscreen = xcb_render_query_pict_formats_screens_iterator(rep_pictformat); - for (; iter_pictscreen.rem; xcb_render_pictscreen_next(&iter_pictscreen)) + for (i = (num - 1); i >= 0; --i) { - xcb_render_pictdepth_iterator_t iter_depth; + skipit = EINA_FALSE; - iter_depth = xcb_render_pictscreen_depths_iterator(iter_pictscreen.data); - for (; iter_depth.rem; xcb_render_pictdepth_next(&iter_depth)) + if (skip) { - xcb_render_pictvisual_iterator_t iter_visual; + int j = 0; - iter_visual = xcb_render_pictdepth_visuals_iterator(iter_depth.data); - for (; iter_visual.rem; xcb_render_pictvisual_next(&iter_visual)) + for (j = 0; j < skip_num; j++) { - if ((iter_visual.data->visual == visual) && - (pict_format == iter_visual.data->format)) + if (windows[i] == skip[j]) { - ret = 1; - break; + skipit = EINA_TRUE; + goto onward; } } } +onward: + if (!skipit) + { + Ecore_X_Window child = 0; + + child = + _ecore_xcb_window_at_xy_get(windows[i], + wx, wy, x, y, skip, skip_num); + if (child) + { + if (reply) free(reply); + return child; + } + } } - free(rep_pictformat); -#endif /* ECORE_XCB_RENDER */ + if (reply) free(reply); + return base; +} - return ret; -} /* ecore_x_window_argb_get */ +Ecore_X_Visual +_ecore_xcb_window_visual_get(Ecore_X_Window win) +{ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + Ecore_X_Visual visual = 0; -/** - * Set if a window should be ignored. - * @param window The given window. - * @param ignore if to ignore - */ -EAPI void -ecore_x_window_ignore_set(Ecore_X_Window window, - int ignore) + cookie = xcb_get_window_attributes(_ecore_xcb_conn, win); + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + visual = _ecore_xcb_window_find_visual_by_id(reply->visual); + free(reply); + + return visual; +} + +void +_ecore_xcb_window_button_grab_remove(Ecore_X_Window win) { - int i, j; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (ignore) + if (_ecore_xcb_button_grabs_num > 0) { - if (ignore_list) + int i = 0, shuffle = 0; + + for (i = 0; i < _ecore_xcb_button_grabs_num; i++) { - for (i = 0; i < ignore_num; i++) - { - if (window == ignore_list[i]) - return; - } - ignore_list = realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window)); - if (!ignore_list) - return; + if (shuffle) + _ecore_xcb_button_grabs[i - 1] = _ecore_xcb_button_grabs[i]; - ignore_list[ignore_num++] = window; + if ((!shuffle) && (_ecore_xcb_button_grabs[i] == win)) + shuffle = 1; } - else + + if (shuffle) { - ignore_num = 0; - ignore_list = malloc(sizeof(Ecore_X_Window)); - ignore_list[ignore_num++] = window; + Ecore_X_Window *t; + + _ecore_xcb_button_grabs_num--; + if (_ecore_xcb_button_grabs_num <= 0) + { + free(_ecore_xcb_button_grabs); + _ecore_xcb_button_grabs = NULL; + return; + } + + t = realloc(_ecore_xcb_button_grabs, + _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window)); + if (!t) return; + _ecore_xcb_button_grabs = t; } } - else +} + +void +_ecore_xcb_window_key_grab_remove(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (_ecore_xcb_key_grabs_num > 0) { - if (!ignore_list) - return; + int i = 0, shuffle = 0; - for (i = 0, j = 0; i < ignore_num; i++) + for (i = 0; i < _ecore_xcb_key_grabs_num; i++) { - if (window != ignore_list[i]) - ignore_list[i] = ignore_list[j++]; - else - ignore_num--; - } - ignore_list = realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window)); - } -} /* ecore_x_window_ignore_set */ + if (shuffle) + _ecore_xcb_key_grabs[i - 1] = _ecore_xcb_key_grabs[i]; -/** - * Get the ignore list - * @param num number of windows in the list - * @return list of windows to ignore - */ -EAPI Ecore_X_Window * -ecore_x_window_ignore_list(int *num) -{ - if (num) - *num = ignore_num; + if ((!shuffle) && (_ecore_xcb_key_grabs[i] == win)) + shuffle = 1; + } - return ignore_list; -} /* ecore_x_window_ignore_list */ + if (shuffle) + { + Ecore_X_Window *t; -/** - * Retrieves the size of the given window. - * @param win The given window. - * @param w Pointer to an integer into which the width is to be stored. - * @param h Pointer to an integer into which the height is to be stored. - * - * To use this function, you must call before, and in order, - * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request, - * then ecore_x_drawable_geometry_get_fetch(), which gets the reply. - * @ingroup Ecore_X_Window_Geometry_Group - */ -EAPI void -ecore_x_window_size_get(Ecore_X_Window window, - int *width, - int *height) -{ - if (window == 0) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; + _ecore_xcb_key_grabs_num--; + if (_ecore_xcb_key_grabs_num <= 0) + { + free(_ecore_xcb_key_grabs); + _ecore_xcb_key_grabs = NULL; + return; + } - ecore_x_drawable_geometry_get(window, NULL, NULL, width, height); -} /* ecore_x_window_size_get */ + t = realloc(_ecore_xcb_key_grabs, + _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window)); + if (!t) return; + _ecore_xcb_key_grabs = t; + } + } +} -/** - * Retrieves the geometry of the given window. - * @param win The given window. - * @param x Pointer to an integer in which the X position is to be stored. - * @param y Pointer to an integer in which the Y position is to be stored. - * @param w Pointer to an integer in which the width is to be stored. - * @param h Pointer to an integer in which the height is to be stored. - * - * To use this function, you must call before, and in order, - * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request, - * then ecore_x_drawable_geometry_get_fetch(), which gets the reply. - * @ingroup Ecore_X_Window_Geometry_Group - */ -EAPI void -ecore_x_window_geometry_get(Ecore_X_Window window, - int *x, - int *y, - int *width, - int *height) +void +_ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win, Ecore_X_Window child_win, int type, void *event, Ecore_X_Time timestamp) { - if (!window) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; + int i = 0; - ecore_x_drawable_geometry_get(window, x, y, width, height); -} /* ecore_x_window_geometry_get */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); -/** - * Retrieves the width of the border of the given window. - * @param win The given window. - * @return Width of the border of @p win. - * @ingroup Ecore_X_Window_Geometry_Group - */ -EAPI int -ecore_x_window_border_width_get(Ecore_X_Window win) -{ - /* doesn't make sense to call this on a root window */ - if (!win) - return 0; + for (i = 0; i < _ecore_xcb_button_grabs_num; i++) + { + if ((_ecore_xcb_button_grabs[i] == event_win) || + (_ecore_xcb_button_grabs[i] == child_win)) + { + Eina_Bool replay = EINA_FALSE; - return ecore_x_drawable_border_width_get(win); -} /* ecore_x_window_border_width_get */ + if (_ecore_xcb_window_grab_replay_func) + { + replay = + _ecore_xcb_window_grab_replay_func(_ecore_xcb_window_grab_replay_data, + type, event); + } + if (replay) + { + xcb_allow_events(_ecore_xcb_conn, + XCB_ALLOW_REPLAY_POINTER, timestamp); + } + else + { + xcb_allow_events(_ecore_xcb_conn, + XCB_ALLOW_ASYNC_POINTER, timestamp); + } + break; + } + } +} -/** - * Retrieves the depth of the given window. - * @param win The given window. - * @return Depth of the window. - */ -EAPI int -ecore_x_window_depth_get(Ecore_X_Window win) +static int +_ecore_xcb_window_modifiers_get(unsigned int state) { - return ecore_x_drawable_depth_get(win); -} /* ecore_x_window_depth_get */ + int xmodifiers = 0; + + if (state & ECORE_EVENT_MODIFIER_SHIFT) + xmodifiers |= ECORE_X_MODIFIER_SHIFT; + if (state & ECORE_EVENT_MODIFIER_CTRL) + xmodifiers |= ECORE_X_MODIFIER_CTRL; + if (state & ECORE_EVENT_MODIFIER_ALT) + xmodifiers |= ECORE_X_MODIFIER_ALT; + if (state & ECORE_EVENT_MODIFIER_WIN) + xmodifiers |= ECORE_X_MODIFIER_WIN; + if (state & ECORE_EVENT_LOCK_SCROLL) + xmodifiers |= ECORE_X_LOCK_SCROLL; + if (state & ECORE_EVENT_LOCK_NUM) + xmodifiers |= ECORE_X_LOCK_NUM; + if (state & ECORE_EVENT_LOCK_CAPS) + xmodifiers |= ECORE_X_LOCK_CAPS; + if (state & ECORE_EVENT_LOCK_SHIFT) + xmodifiers |= ECORE_X_LOCK_SHIFT; + + return xmodifiers; +} + +static xcb_visualtype_t * +_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id) +{ + xcb_depth_iterator_t diter; + xcb_visualtype_iterator_t viter; + diter = xcb_screen_allowed_depths_iterator(_ecore_xcb_screen); + for (; diter.rem; xcb_depth_next(&diter)) + { + viter = xcb_depth_visuals_iterator(diter.data); + for (; viter.rem; xcb_visualtype_next(&viter)) + { + if (viter.data->visual_id == id) + return viter.data; + } + } + return 0; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c b/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c index 07f8433..9961d45 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c @@ -1,878 +1,623 @@ -#include -#include - #include "ecore_xcb_private.h" -#include "Ecore_X_Atoms.h" - -/* - * Set CARD32 (array) property - */ -EAPI void -ecore_x_window_prop_card32_set(Ecore_X_Window win, - Ecore_X_Atom atom, - unsigned int *val, - unsigned int num) -{ - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, - atom, ECORE_X_ATOM_CARDINAL, 32, num, (const void *)val); -} /* ecore_x_window_prop_card32_set */ - -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - * @param atom The atom. - */ -EAPI void -ecore_x_window_prop_card32_get_prefetch(Ecore_X_Window window, - Ecore_X_Atom atom) -{ - xcb_get_property_cookie_t cookie; +#include - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window, - atom, - ECORE_X_ATOM_CARDINAL, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_window_prop_card32_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_window_prop_card32_get_prefetch(). - */ -EAPI void -ecore_x_window_prop_card32_get_fetch(void) +EAPI int +ecore_x_window_prop_card32_get(Ecore_X_Window win, Ecore_X_Atom atom, unsigned int *val, unsigned int len) { xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; + int num = 0; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_window_prop_card32_get_fetch */ - -/* - * Get CARD32 (array) property - * - * At most len items are returned in val. - * If the property was successfully fetched the number of items stored in - * val is returned, otherwise -1 is returned. - * Note: Return value 0 means that the property exists but has no elements. - */ -EAPI int -ecore_x_window_prop_card32_get(Ecore_X_Window win __UNUSED__, - Ecore_X_Atom atom __UNUSED__, - unsigned int *val, - unsigned int len) -{ - xcb_get_property_reply_t *reply; - - reply = _ecore_xcb_reply_get(); - if (!reply || - (reply->type != ECORE_X_ATOM_CARDINAL) || - (reply->format != 32)) - return -1; - - if (reply->value_len < len) - len = xcb_get_property_value_length(reply); - - if (val) - memcpy(val, xcb_get_property_value(reply), len); - - return (int)len; -} /* ecore_x_window_prop_card32_get */ - -/* - * Get CARD32 (array) property of any length - * - * If the property was successfully fetched the number of items stored in - * val is returned, otherwise -1 is returned. - * Note: Return value 0 means that the property exists but has no elements. - */ -EAPI int -ecore_x_window_prop_card32_list_get(Ecore_X_Window win __UNUSED__, - Ecore_X_Atom atom __UNUSED__, - unsigned int **plist) -{ - xcb_get_property_reply_t *reply; - int num = -1; - - if (plist) - *plist = NULL; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return -1; + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, + ECORE_X_ATOM_CARDINAL, 0, 0x7fffffff); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return -1; - if ((reply->type == XCB_NONE) || - (reply->value_len == 0)) - num = 0; - else if ((reply->type == ECORE_X_ATOM_CARDINAL) && - (reply->format == 32)) + if ((reply->type != ECORE_X_ATOM_CARDINAL) || (reply->format != 32)) + num = -1; + else if (reply->value_len == 0) + num = 0; + else { - uint32_t *val; + if (reply->value_len < len) + len = reply->value_len; - num = xcb_get_property_value_length(reply); - if (plist) + if (val) { - val = (uint32_t *)malloc (num); - if (!val) - goto error; + unsigned int i = 0; + unsigned char *v; - memcpy(val, xcb_get_property_value(reply), num); - *plist = val; + v = xcb_get_property_value(reply); + for (i = 0; i < len; i++) + val[i] = ((unsigned long *)v)[i]; + num = len; } } -error: - + if (reply) free(reply); return num; -} /* ecore_x_window_prop_card32_list_get */ - -/* - * Set X ID (array) property - */ -EAPI void -ecore_x_window_prop_xid_set(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom type, - Ecore_X_ID *xids, - unsigned int num) -{ - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, - atom, type, 32, num, xids); -} /* ecore_x_window_prop_xid_set */ - -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - * @param atom The atom. - * @param type The atom type. - */ -EAPI void -ecore_x_window_prop_xid_get_prefetch(Ecore_X_Window window, - Ecore_X_Atom atom, - Ecore_X_Atom type) -{ - xcb_get_property_cookie_t cookie; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window, - atom, - type, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_window_prop_xid_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_window_prop_xid_get_prefetch(). - */ -EAPI void -ecore_x_window_prop_xid_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; +} - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_window_prop_xid_get_fetch */ - -/* - * Get X ID (array) property - * - * At most len items are returned in val. - * If the property was successfully fetched the number of items stored in - * val is returned, otherwise -1 is returned. - * Note: Return value 0 means that the property exists but has no elements. - */ -EAPI int -ecore_x_window_prop_xid_get(Ecore_X_Window win __UNUSED__, - Ecore_X_Atom atom __UNUSED__, - Ecore_X_Atom type __UNUSED__, - Ecore_X_ID *xids, - unsigned int len) +EAPI void +ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom, unsigned int *val, unsigned int num) { - xcb_get_property_reply_t *reply; - int num = len; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return -1; +#if SIZEOF_INT == SIZEOF_LONG + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, + ECORE_X_ATOM_CARDINAL, 32, num, (unsigned char *)val); +#else + long *v2; + unsigned int i; - if (reply->type == XCB_NONE) - num = 0; - else if (reply->format == 32) - { - if (reply->value_len < len) - num = xcb_get_property_value_length(reply); + v2 = malloc(num * sizeof(long)); + if (!v2) return; + for (i = 0; i < num; i++) + v2[i] = val[i]; - if (xids) - memcpy(xids, xcb_get_property_value(reply), num); - } + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, + ECORE_X_ATOM_CARDINAL, 32, num, (unsigned char *)v2); + free(v2); +#endif +} - return num; -} /* ecore_x_window_prop_xid_get */ - -/* - * Get X ID (array) property - * - * If the property was successfully fetched the number of items stored in - * val is returned, otherwise -1 is returned. - * The returned array must be freed with free(). - * Note: Return value 0 means that the property exists but has no elements. - */ -EAPI int -ecore_x_window_prop_xid_list_get(Ecore_X_Window win __UNUSED__, - Ecore_X_Atom atom __UNUSED__, - Ecore_X_Atom type __UNUSED__, - Ecore_X_ID **pxids) +EAPI int +ecore_x_window_prop_card32_list_get(Ecore_X_Window win, Ecore_X_Atom atom, unsigned int **list) { + xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; int num = -1; - if (pxids) - *pxids = NULL; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return -1; + if (list) *list = NULL; - if ((reply->type == XCB_NONE) || - (reply->value_len == 0)) - num = 0; - else if ((reply->type == ECORE_X_ATOM_CARDINAL) && - (reply->format == 32)) - { - uint32_t *val; + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, + XCB_ATOM_CARDINAL, 0, 0x7fffffff); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return -1; - num = xcb_get_property_value_length(reply); - if (pxids) + if ((reply->type != XCB_ATOM_CARDINAL) || (reply->format != 32)) + num = -1; + else if ((reply->value_len == 0) || (!xcb_get_property_value(reply))) + num = 0; + else + { + num = reply->value_len; + if (list) { - val = (uint32_t *)malloc (num); - if (!val) - return -1; - - memcpy(val, xcb_get_property_value(reply), num); - *pxids = val; + unsigned int *val; + void *data; + int i = 0; + + val = malloc(num * sizeof(unsigned int)); + if (!val) + { + free(reply); + return num; + } + data = xcb_get_property_value(reply); + for (i = 0; i < num; i++) + val[i] = ((unsigned long *)data)[i]; + *list = val; } } + free(reply); return num; -} /* ecore_x_window_prop_xid_list_get */ - -/* - * Remove/add/toggle X ID list item. - */ -EAPI void -ecore_x_window_prop_xid_list_change(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom type, - Ecore_X_ID item, - int op) -{ - Ecore_X_ID *lst; - int i; - int num; +} - num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst); - if (num < 0) - return; /* Error - assuming invalid window */ +EAPI int +ecore_x_window_prop_atom_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom *list, unsigned int len) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* Is it there? */ - for (i = 0; i < num; i++) - { - if (lst[i] == item) - break; - } + return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_ATOM, list, len); +} - if (i < num) - { - /* Was in list */ - if (op == ECORE_X_PROP_LIST_ADD) - goto done; +EAPI void +ecore_x_window_prop_atom_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom *list, unsigned int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* Remove it */ - num--; - for (; i < num; i++) - lst[i] = lst[i + 1]; - } - else - { - /* Was not in list */ - if (op == ECORE_X_PROP_LIST_REMOVE) - goto done; + /* xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, */ + /* ECORE_X_ATOM_ATOM, 32, num, list); */ + ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_ATOM, list, num); +} - /* Add it */ - num++; - lst = realloc(lst, num * sizeof(Ecore_X_ID)); - lst[i] = item; - } +EAPI void +ecore_x_window_prop_xid_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom type, Ecore_X_ID *xids, unsigned int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +#if SIZEOF_INT == SIZEOF_LONG + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, + type, 32, num, (unsigned char *)xids); +#else + long *v2; + unsigned int i; - ecore_x_window_prop_xid_set(win, atom, type, lst, num); + v2 = malloc(num * sizeof(long)); + if (!v2) return; + for (i = 0; i < num; i++) + v2[i] = xids[i]; -done: - if (lst) - free(lst); -} /* ecore_x_window_prop_xid_list_change */ - -/* - * Set Atom (array) property - */ -EAPI void -ecore_x_window_prop_atom_set(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom *list, - unsigned int num) -{ - ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_ATOM, list, num); -} /* ecore_x_window_prop_atom_set */ - -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - * @param atom Property atom. - */ -EAPI void -ecore_x_window_prop_atom_get_prefetch(Ecore_X_Window window, - Ecore_X_Atom atom) -{ - xcb_get_property_cookie_t cookie; + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, + type, 32, num, (unsigned char *)v2); + free(v2); +#endif +} - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window, - atom, - ECORE_X_ATOM_ATOM, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_window_prop_atom_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_window_prop_atom_get_prefetch(). - */ -EAPI void -ecore_x_window_prop_atom_get_fetch(void) +EAPI int +ecore_x_window_prop_xid_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom type, Ecore_X_ID *xids, unsigned int len) { xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; + int num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); + num = len; + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, type, + 0, 0x7fffffff); reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_window_prop_atom_get_fetch */ - -/* - * Get Atom (array) property - * - * At most len items are returned in val. - * If the property was successfully fetched the number of items stored in - * val is returned, otherwise -1 is returned. - * Note: Return value 0 means that the property exists but has no elements. - */ -EAPI int -ecore_x_window_prop_atom_get(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom *list, - unsigned int len) -{ - return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_ATOM, list, len); -} /* ecore_x_window_prop_atom_get */ - -/* - * Get Atom (array) property - * - * If the property was successfully fetched the number of items stored in - * val is returned, otherwise -1 is returned. - * The returned array must be freed with free(). - * Note: Return value 0 means that the property exists but has no elements. - */ -EAPI int -ecore_x_window_prop_atom_list_get(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom **plist) -{ - return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_ATOM, plist); -} /* ecore_x_window_prop_atom_list_get */ - -/* - * Remove/add/toggle atom list item. - */ -EAPI void -ecore_x_window_prop_atom_list_change(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom item, - int op) -{ - ecore_x_window_prop_xid_list_change(win, atom, ECORE_X_ATOM_ATOM, item, op); -} /* ecore_x_window_prop_atom_list_change */ - -/* - * Set Window (array) property - */ -EAPI void -ecore_x_window_prop_window_set(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Window *list, - unsigned int num) -{ - ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_WINDOW, list, num); -} /* ecore_x_window_prop_window_set */ - -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - * @param atom The atom. - */ -EAPI void -ecore_x_window_prop_window_get_prefetch(Ecore_X_Window window, - Ecore_X_Atom atom) + if (!reply) return -1; + + if ((reply->type != type) || (reply->format != 32)) + num = -1; + else if (reply->value_len == 0) + num = 0; + else + { + unsigned int i = 0; + unsigned char *v; + + if (reply->value_len < len) + len = reply->value_len; + + v = xcb_get_property_value(reply); + for (i = 0; i < len; i++) + xids[i] = ((unsigned long *)v)[i]; + + num = len; + } + + if (reply) free(reply); + return num; +} + +EAPI void +ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom type, const char *str) { - xcb_get_property_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window, - atom, - ECORE_X_ATOM_WINDOW, - 0, 0x7fffffff); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_window_prop_window_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_window_prop_window_get_prefetch(). - */ -EAPI void -ecore_x_window_prop_window_get_fetch(void) + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, type, + ECORE_X_ATOM_UTF8_STRING, 8, strlen(str), str); +} + +EAPI char * +ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type) { xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; + char *str = NULL; + int len = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); + cookie = + xcb_get_property_unchecked(_ecore_xcb_conn, 0, + win ? win : ((xcb_screen_t *)_ecore_xcb_screen)->root, + type, XCB_GET_PROPERTY_TYPE_ANY, 0, 1000000L); reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_window_prop_window_get_fetch */ - -/* - * Get Window (array) property - * - * At most len items are returned in val. - * If the property was successfully fetched the number of items stored in - * val is returned, otherwise -1 is returned. - * Note: Return value 0 means that the property exists but has no elements. - */ -EAPI int -ecore_x_window_prop_window_get(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Window *list, - unsigned int len) + if (!reply) return NULL; + + len = ((reply->value_len * reply->format) / 8); + str = (char *)malloc((len + 1) * sizeof(char)); + memcpy(str, xcb_get_property_value(reply), len); + str[len] = '\0'; + + if (reply->type != ECORE_X_ATOM_UTF8_STRING) + { + Ecore_Xcb_Textproperty prop; + int count = 0; + char **list = NULL; + Eina_Bool ret = EINA_FALSE; + + prop.value = strdup(str); + prop.nitems = len; + prop.encoding = reply->type; + +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textproperty_to_textlist(&prop, &list, &count); +#else + ret = _ecore_xcb_mb_textproperty_to_textlist(&prop, &list, &count); +#endif + if (ret) + { + if (count > 0) + str = strdup(list[0]); + else + str = strdup((char *)prop.value); + + if (list) free(list); + } + else + str = strdup((char *)prop.value); + } + + free(reply); + return str; +} + +EAPI int +ecore_x_window_prop_window_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window *list, unsigned int len) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_WINDOW, list, len); -} /* ecore_x_window_prop_window_get */ - -/* - * Get Window (array) property - * - * If the property was successfully fetched the number of items stored in - * val is returned, otherwise -1 is returned. - * The returned array must be freed with free(). - * Note: Return value 0 means that the property exists but has no elements. - */ -EAPI int -ecore_x_window_prop_window_list_get(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Window **plist) +} + +EAPI void +ecore_x_window_prop_window_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window *list, unsigned int num) { - return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_WINDOW, plist); -} /* ecore_x_window_prop_window_list_get */ - -/** - * To be documented. - * - * FIXME: To be fixed. - */ -EAPI Ecore_X_Atom -ecore_x_window_prop_any_type(void) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_WINDOW, list, num); +} + +EAPI int +ecore_x_window_prop_window_list_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window **plst) { - return XCB_GET_PROPERTY_TYPE_ANY; -} /* ecore_x_window_prop_any_type */ - -/** - * To be documented. - * @param window The window. - * @param property The property atom. - * @param type The type atom. - * @param size The size. - * @param data The data. - * @param number The size of the data. - * - * FIXME: To be fixed. - */ -EAPI void -ecore_x_window_prop_property_set(Ecore_X_Window window, - Ecore_X_Atom property, - Ecore_X_Atom type, - int size, - void *data, - int number) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_WINDOW, plst); +} + +EAPI Ecore_X_Atom +ecore_x_window_prop_any_type(void) { - if (window == 0) - window = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window, - property, type, - size, number, data); -} /* ecore_x_window_prop_property_set */ - -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - * @param property Property atom. - * @param type Type atom. - */ -EAPI void -ecore_x_window_prop_property_get_prefetch(Ecore_X_Window window, - Ecore_X_Atom property, - Ecore_X_Atom type) + return XCB_ATOM_ANY; +} + +EAPI void +ecore_x_window_prop_property_del(Ecore_X_Window win, Ecore_X_Atom property) { - xcb_get_property_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xcb_delete_property(_ecore_xcb_conn, win, property); +} - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root, - property, type, 0, LONG_MAX); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_window_prop_property_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_window_prop_property_get_prefetch(). - */ -EAPI void -ecore_x_window_prop_property_get_fetch(void) +EAPI void +ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, void *data, int num) { - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_window_prop_property_get_fetch */ - -/** - * To be documented. - * @param window The window (Unused). - * @param property The property atom (Unused). - * @param type The type atom (Unused). - * @param size The size (Unused). - * @param data The returned data. - * @param num The size of the data. - * @return 1 on success, 0 otherwise. - * - * FIXME: To be fixed. - */ -EAPI int -ecore_x_window_prop_property_get(Ecore_X_Window window __UNUSED__, - Ecore_X_Atom property __UNUSED__, - Ecore_X_Atom type __UNUSED__, - int size __UNUSED__, - unsigned char **data, - int *num) + if (win == 0) + win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + if (size != 32) + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, + property, type, size, num, (unsigned char *)data); + else + { + unsigned long *dat; + int i = 0, *ptr; + + dat = malloc(sizeof(unsigned long) * num); + if (dat) + { + for (ptr = (int *)data, i = 0; i < num; i++) + dat[i] = ptr[i]; + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, + property, type, size, num, + (unsigned char *)dat); + free(dat); + } + } +} + +EAPI int +ecore_x_window_prop_property_get(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, unsigned char **data, int *num) { + xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; + int format = 0; + unsigned int i = 0; + void *value; - /* make sure these are initialized */ - if (num) - *num = 0L; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (data) - *data = NULL; - else /* we can't store the retrieved data, so just return */ - return 0; + if (num) *num = 0; - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; + if (data) + *data = NULL; + else + return 0; - if ((reply->format != size) || - (reply->value_len == 0)) - return 0; + if (win == 0) + win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - *data = malloc(reply->value_len); - if (!*data) - return 0; + cookie = + xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, + property, type, 0, LONG_MAX); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + if ((reply->format != size) || (reply->value_len == 0)) + { + free(reply); + return 0; + } - memcpy(*data, xcb_get_property_value(reply), - xcb_get_property_value_length(reply)); + if (!(*data = malloc(reply->value_len * reply->format / 8))) + { + free(reply); + return 0; + } - if (num) - *num = reply->value_len; + value = xcb_get_property_value(reply); + switch (reply->format) + { + case 8: + for (i = 0; i < reply->value_len; i++) + (*data)[i] = ((unsigned char *)value)[i]; + break; + case 16: + for (i = 0; i < reply->value_len; i++) + ((unsigned short *)*data)[i] = ((unsigned short *)value)[i]; + break; + case 32: + for (i = 0; i < reply->value_len; i++) + ((unsigned int *)*data)[i] = ((unsigned long *)value)[i]; + break; + } - return reply->format; -} /* ecore_x_window_prop_property_get */ + if (num) *num = reply->value_len; + format = reply->format; + free(reply); + return format; +} -EAPI void -ecore_x_window_prop_property_del(Ecore_X_Window window, - Ecore_X_Atom property) +EAPI int +ecore_x_window_prop_atom_list_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom **list) { - xcb_delete_property(_ecore_xcb_conn, window, property); -} /* ecore_x_window_prop_property_del */ - -/** - * Sends the ListProperties request. - * @param window Window whose properties are requested. - */ -EAPI void -ecore_x_window_prop_list_prefetch(Ecore_X_Window window) -{ - xcb_list_properties_cookie_t cookie; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - cookie = xcb_list_properties_unchecked(_ecore_xcb_conn, window); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_window_prop_list_prefetch */ + return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_ATOM, list); +} -/** - * Gets the reply of the ListProperties request sent by ecore_x_window_prop_list_prefetch(). - */ -EAPI void -ecore_x_window_prop_list_fetch(void) +EAPI void +ecore_x_window_prop_atom_list_change(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom item, int op) { - xcb_list_properties_cookie_t cookie; - xcb_list_properties_reply_t *reply; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_window_prop_xid_list_change(win, atom, ECORE_X_ATOM_ATOM, item, op); +} - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_list_properties_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_window_prop_list_fetch */ - -/** - * To be documented. - * @param window The window (Unused). - * @param num_ret The number of atoms. - * @return The returned atoms. - * - * FIXME: To be fixed. - */ -EAPI Ecore_X_Atom * -ecore_x_window_prop_list(Ecore_X_Window window __UNUSED__, - int *num_ret) +EAPI int +ecore_x_window_prop_xid_list_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom type, Ecore_X_ID **xids) { - xcb_list_properties_reply_t *reply; - Ecore_X_Atom *atoms; + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + int num = -1; - if (num_ret) - *num_ret = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - reply = _ecore_xcb_reply_get(); - if (!reply) - return NULL; + if (xids) *xids = NULL; - atoms = (Ecore_X_Atom *)malloc(reply->atoms_len * sizeof(Ecore_X_Atom)); - if (!atoms) - return NULL; + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, type, + 0, 0x7fffffff); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return -1; - memcpy(atoms, - xcb_list_properties_atoms(reply), - reply->atoms_len * sizeof(Ecore_X_Atom)); - if(num_ret) - *num_ret = reply->atoms_len; + if ((reply->type != type) || (reply->format != 32)) + num = -1; + else if ((reply->value_len == 0) || (!xcb_get_property_value(reply))) + num = 0; + else + { + Ecore_X_Atom *alst; + void *val; + + num = xcb_get_property_value_length(reply); + val = xcb_get_property_value(reply); + alst = malloc(num * sizeof(Ecore_X_ID)); + if (alst) + { + int i = 0; - return atoms; -} /* ecore_x_window_prop_list */ - -/** - * Set a window string property. - * @param win The window - * @param type The property - * @param str The string - * - * Set a window string property - */ -EAPI void -ecore_x_window_prop_string_set(Ecore_X_Window win, - Ecore_X_Atom type, - const char *str) -{ - if (win == 0) - win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, - type, ECORE_X_ATOM_UTF8_STRING, - 8, strlen(str), str); -} /* ecore_x_window_prop_string_set */ - -/** - * Sends the GetProperty request. - * @param window Window whose properties are requested. - * @param type The atom. - */ -EAPI void -ecore_x_window_prop_string_get_prefetch(Ecore_X_Window window, - Ecore_X_Atom type) -{ - xcb_get_property_cookie_t cookie; + for (i = 0; i < num; i++) + alst[i] = ((unsigned long *)val)[i]; + *xids = alst; + } + } - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, - window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root, - type, XCB_GET_PROPERTY_TYPE_ANY, 0L, 1000000L); - _ecore_xcb_cookie_cache(cookie.sequence); -} /* ecore_x_window_prop_string_get_prefetch */ - -/** - * Gets the reply of the GetProperty request sent by ecore_x_window_prop_string_get_prefetch(). - */ -EAPI void -ecore_x_window_prop_string_get_fetch(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; + free(reply); + return num; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -} /* ecore_x_window_prop_string_get_fetch */ - -/** - * Get a window string property. - * @param window The window - * @param type The property - * - * Return window string property of a window. String must be free'd when done. - * - * To use this function, you must call before, and in order, - * ecore_x_window_prop_string_get_prefetch(), which sends the GetProperty request, - * then ecore_x_window_prop_string_get_fetch(), which gets the reply. - */ -EAPI char * -ecore_x_window_prop_string_get(Ecore_X_Window window __UNUSED__, - Ecore_X_Atom type __UNUSED__) + /* if ((reply->type == XCB_NONE) || (reply->value_len == 0)) */ + /* num = 0; */ + /* else if ((reply->type == ECORE_X_ATOM_CARDINAL) && (reply->format == 32)) */ + /* { */ + /* num = xcb_get_property_value_length(reply); */ + /* if (xids) */ + /* { */ + /* uint32_t *val; */ + /* int i = 0; */ + /* void *value; */ + + /* val = (uint32_t *)malloc(num * sizeof(Ecore_X_ID)); */ + /* if (!val) */ + /* { */ + /* free(reply); */ + /* return -1; */ + /* } */ + + /* for (i = 0; i < num; i++) */ + /* val[i] = ((unsigned long *)value)[i]; */ + + /* *xids = val; */ + /* } */ + /* } */ + + /* free(reply); */ + /* return num; */ +} + +EAPI void +ecore_x_window_prop_xid_list_change(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom type, Ecore_X_ID item, int op) { - xcb_get_property_reply_t *reply; - char *str = NULL; + Ecore_X_ID *lst; + int i = 0, num = 0; - reply = _ecore_xcb_reply_get(); - if (!reply) - return NULL; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (reply->type == ECORE_X_ATOM_UTF8_STRING) + num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst); + if (num < 0) return; + + for (i = 0; i < num; i++) { - int length; - - length = reply->value_len; - str = (char *)malloc(length + 1); - memcpy(str, - xcb_get_property_value(reply), - length); - str[length] = '\0'; + if (lst[i] == item) break; } - else + + if (i < num) { - /* FIXME: to be done... */ - -/* #ifdef X_HAVE_UTF8_STRING */ -/* s = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xtp, */ -/* &list, &items); */ -/* #else */ -/* s = XmbTextPropertyToTextList(_ecore_xcb_conn, &xtp, */ -/* &list, &items); */ -/* #endif */ -/* if ((s == XLocaleNotSupported) || */ -/* (s == XNoMemory) || (s == XConverterNotFound)) */ -/* { */ -/* str = strdup((char *)xtp.value); */ -/* } */ -/* else if ((s >= Success) && (items > 0)) */ -/* { */ -/* str = strdup(list[0]); */ -/* } */ -/* if (list) */ -/* XFreeStringList(list); */ + if (op == ECORE_X_PROP_LIST_ADD) + goto done; + num--; + for (; i < num; i++) + lst[i] = lst[i + 1]; } + else + { + if (op == ECORE_X_PROP_LIST_REMOVE) + goto done; + num++; + lst = realloc(lst, num * sizeof(Ecore_X_ID)); + lst[i] = item; + } + ecore_x_window_prop_xid_set(win, atom, type, lst, num); - return str; -} /* ecore_x_window_prop_string_get */ +done: + if (lst) free(lst); +} -/* FIXME : round trips because of GetWMProtocols */ -/* should we rewrite its code ? */ -EAPI Eina_Bool -ecore_x_window_prop_protocol_isset(Ecore_X_Window window, - Ecore_X_WM_Protocol protocol) +EAPI Eina_Bool +ecore_x_window_prop_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol) { - xcb_get_property_cookie_t cookie; - xcb_get_wm_protocols_reply_t protocols; + Eina_Bool ret = EINA_FALSE; Ecore_X_Atom proto; - uint32_t i; - uint8_t ret = 0; - - /* check for invalid values */ - if (protocol >= ECORE_X_WM_PROTOCOL_NUM) - return ret; - - proto = _ecore_xcb_atoms_wm_protocols[protocol]; + xcb_get_wm_protocols_reply_t protos; + xcb_get_property_cookie_t cookie; + uint8_t reply; + uint32_t count = 0, i = 0; - cookie = xcb_get_wm_protocols(_ecore_xcb_conn, window, ECORE_X_ATOM_WM_PROTOCOLS); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protocols, NULL)) - return ret; + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE; - for (i = 0; i < protocols.atoms_len; i++) - if (protocols.atoms[i] == proto) - { - ret = 1; - break; - } + proto = _ecore_xcb_atoms_wm_protocol[protocol]; + cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, + ECORE_X_ATOM_WM_PROTOCOLS); + reply = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL); + if (!reply) return EINA_FALSE; - xcb_get_wm_protocols_reply_wipe(&protocols); + count = protos.atoms_len; + for (i = 0; i < count; i++) + { + if (protos.atoms[i] == proto) + { + ret = EINA_TRUE; + break; + } + } + xcb_get_wm_protocols_reply_wipe(&protos); return ret; -} /* ecore_x_window_prop_protocol_isset */ - -/** - * To be documented. - * @param window The window. - * @param num_ret The number of WM protocols. - * @return The returned WM protocols. - * - * FIXME: To be fixed. - */ - -/* FIXME : round trips because of get_wm_protocols */ -/* should we rewrite its code ? */ +} EAPI Ecore_X_WM_Protocol * -ecore_x_window_prop_protocol_list_get(Ecore_X_Window window, - int *num_ret) +ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, int *num_ret) { + xcb_get_wm_protocols_reply_t protos; xcb_get_property_cookie_t cookie; - xcb_get_wm_protocols_reply_t protocols; + uint8_t reply; + uint32_t count = 0, i = 0; Ecore_X_WM_Protocol *prot_ret = NULL; - uint32_t protos_count; - uint32_t i; - cookie = xcb_get_wm_protocols(_ecore_xcb_conn, window, ECORE_X_ATOM_WM_PROTOCOLS); + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!num_ret) return NULL; - if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protocols, NULL)) - return NULL; + *num_ret = 0; - if ((protocols.atoms_len <= 0)) - return NULL; + cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, + ECORE_X_ATOM_WM_PROTOCOLS); + reply = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL); + if (!reply) return NULL; + + count = protos.atoms_len; + if (count <= 0) + { + xcb_get_wm_protocols_reply_wipe(&protos); + return NULL; + } - prot_ret = calloc(1, protocols.atoms_len * sizeof(Ecore_X_WM_Protocol)); - if (!prot_ret) + prot_ret = calloc(1, count * sizeof(Ecore_X_WM_Protocol)); + if (!prot_ret) { - xcb_get_wm_protocols_reply_wipe(&protocols); + xcb_get_wm_protocols_reply_wipe(&protos); return NULL; } - for (i = 0; i < protocols.atoms_len; i++) + for (i = 0; i < count; i++) { Ecore_X_WM_Protocol j; prot_ret[i] = -1; - for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++) + for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++) { - if (_ecore_xcb_atoms_wm_protocols[j] == protocols.atoms[i]) - prot_ret[i] = j; + if (_ecore_xcb_atoms_wm_protocol[j] == protos.atoms[i]) + prot_ret[i] = j; } } - xcb_get_wm_protocols_reply_wipe(&protocols); - *num_ret = protos_count; + if (num_ret) *num_ret = count; + + xcb_get_wm_protocols_reply_wipe(&protos); return prot_ret; -} /* ecore_x_window_prop_protocol_list_get */ +} +EAPI Ecore_X_Atom * +ecore_x_window_prop_list(Ecore_X_Window win, int *num) +{ + xcb_list_properties_cookie_t cookie; + xcb_list_properties_reply_t *reply; + xcb_atom_t *atm; + Ecore_X_Atom *atoms; + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (num) *num = 0; + + cookie = xcb_list_properties_unchecked(_ecore_xcb_conn, win); + reply = xcb_list_properties_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + + atoms = (Ecore_X_Atom *)malloc(reply->atoms_len * sizeof(Ecore_X_Atom)); + if (!atoms) + { + free(reply); + return NULL; + } + + atm = xcb_list_properties_atoms(reply); + for (i = 0; i < reply->atoms_len; i++) + atoms[i] = atm[i]; + + if (num) *num = reply->atoms_len; + free(reply); + + return atoms; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c b/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c index 13d8392..931ffc6 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c @@ -1,19 +1,16 @@ -/* #include "Ecore.h" */ #include "ecore_xcb_private.h" -#include "Ecore_X.h" -typedef struct _Shadow Shadow; +typedef struct _Shadow Shadow; struct _Shadow { - Shadow *parent; - Shadow **children; + Shadow *parent, **children; Ecore_X_Window win; - int children_num; - short x, y; + int children_num; + short x, y; unsigned short w, h; }; -static int shadow_count = 0; +//static int shadow_count = 0; static Shadow **shadow_base = NULL; static int shadow_num = 0; @@ -21,61 +18,33 @@ static int shadow_num = 0; static Shadow * _ecore_x_window_tree_walk(Ecore_X_Window window) { - Shadow *s; - Shadow **sl; + Shadow *s, **sl; xcb_get_window_attributes_reply_t *reply_attr; xcb_get_geometry_reply_t *reply_geom; xcb_query_tree_reply_t *reply_tree; xcb_get_window_attributes_cookie_t cookie_attr; xcb_get_geometry_cookie_t cookie_geom; xcb_query_tree_cookie_t cookie_tree; - int i; - int j; + int i, j; cookie_attr = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window); - cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window); - cookie_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, window); - reply_attr = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_attr, NULL); - if (!reply_attr) - { - reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL); - if (reply_geom) - free(reply_geom); - - reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL); - if (reply_tree) - free(reply_tree); - - return NULL; - } - + if (!reply_attr) return NULL; if (reply_attr->map_state != XCB_MAP_STATE_VIEWABLE) { - reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL); - if (reply_geom) - free(reply_geom); - - reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL); - if (reply_tree) - free(reply_tree); - + free(reply_attr); return NULL; } free(reply_attr); - s = calloc(1, sizeof(Shadow)); - if (!s) - return NULL; - + cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window); reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL); - if (!reply_geom) - { - reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL); - if (reply_tree) - free(reply_tree); + if (!reply_geom) return NULL; + if (!(s = calloc(1, sizeof(Shadow)))) + { + free(reply_geom); return NULL; } @@ -87,11 +56,10 @@ _ecore_x_window_tree_walk(Ecore_X_Window window) free(reply_geom); + cookie_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, window); reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL); if (reply_tree) { -/* if (XQueryTree(_ecore_xcb_conn, s->win, &root_win, &parent_win, */ -/* &list, &num)) */ xcb_window_t *list; int num; @@ -106,7 +74,7 @@ _ecore_x_window_tree_walk(Ecore_X_Window window) { s->children[i] = _ecore_x_window_tree_walk(list[i]); if (s->children[i]) - s->children[i]->parent = s; + s->children[i]->parent = s; } /* compress list down */ j = 0; @@ -128,8 +96,7 @@ _ecore_x_window_tree_walk(Ecore_X_Window window) { s->children_num = j; sl = realloc(s->children, sizeof(Shadow *) * j); - if (sl) - s->children = sl; + if (sl) s->children = sl; } } @@ -137,143 +104,132 @@ _ecore_x_window_tree_walk(Ecore_X_Window window) } return s; -} /* _ecore_x_window_tree_walk */ +} static void _ecore_x_window_tree_shadow_free1(Shadow *s) { - int i; - - if (!s) - return; + int i = 0; + if (!s) return; if (s->children) { for (i = 0; i < s->children_num; i++) { if (s->children[i]) - _ecore_x_window_tree_shadow_free1(s->children[i]); + _ecore_x_window_tree_shadow_free1(s->children[i]); } free(s->children); } free(s); -} /* _ecore_x_window_tree_shadow_free1 */ +} static void _ecore_x_window_tree_shadow_free(void) { - int i; + int i = 0; - if (!shadow_base) - return; + if (!shadow_base) return; for (i = 0; i < shadow_num; i++) { - if (!shadow_base[i]) - continue; - + if (!shadow_base[i]) continue; _ecore_x_window_tree_shadow_free1(shadow_base[i]); } free(shadow_base); shadow_base = NULL; shadow_num = 0; -} /* _ecore_x_window_tree_shadow_free */ +} static void _ecore_x_window_tree_shadow_populate(void) { - Ecore_X_Window *roots; - int i, num; + Ecore_X_Window *roots = NULL; + int i = 0, num = 0; - roots = ecore_x_window_root_list(&num); - if (roots) + if ((roots = ecore_x_window_root_list(&num))) { shadow_base = calloc(1, sizeof(Shadow *) * num); if (shadow_base) { shadow_num = num; for (i = 0; i < num; i++) - shadow_base[i] = _ecore_x_window_tree_walk(roots[i]); + shadow_base[i] = _ecore_x_window_tree_walk(roots[i]); } free(roots); } -} /* _ecore_x_window_tree_shadow_populate */ +} +/* static void _ecore_x_window_tree_shadow_start(void) { shadow_count++; - if (shadow_count > 1) - return; - + if (shadow_count > 1) return; _ecore_x_window_tree_shadow_populate(); -} /* _ecore_x_window_tree_shadow_start */ +} static void _ecore_x_window_tree_shadow_stop(void) { shadow_count--; - if (shadow_count != 0) - return; - + if (shadow_count != 0) return; _ecore_x_window_tree_shadow_free(); -} /* _ecore_x_window_tree_shadow_stop */ +} +*/ Shadow * _ecore_x_window_shadow_tree_find_shadow(Shadow *s, Ecore_X_Window win) { Shadow *ss; - int i; + int i = 0; - if (s->win == win) - return s; + if (s->win == win) return s; if (s->children) { for (i = 0; i < s->children_num; i++) { - if (!s->children[i]) - continue; + if (!s->children[i]) continue; - if ((ss = _ecore_x_window_shadow_tree_find_shadow(s->children[i], win))) - return ss; + if ((ss = + _ecore_x_window_shadow_tree_find_shadow(s->children[i], win))) + return ss; } } return NULL; -} /* _ecore_x_window_shadow_tree_find_shadow */ +} Shadow * _ecore_x_window_shadow_tree_find(Ecore_X_Window base) { Shadow *s; - int i; + int i = 0; for (i = 0; i < shadow_num; i++) { - if (!shadow_base[i]) - continue; + if (!shadow_base[i]) continue; - if ((s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], base))) - return s; + if ((s = + _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], base))) + return s; } return NULL; -} /* _ecore_x_window_shadow_tree_find */ +} static Ecore_X_Window -_ecore_x_window_shadow_tree_at_xy_get_shadow(Shadow *s, int bx, int by, int x, int y, - Ecore_X_Window *skip, int skip_num) +_ecore_x_window_shadow_tree_at_xy_get_shadow(Shadow *s, int bx, int by, int x, int y, Ecore_X_Window *skip, int skip_num) { Ecore_X_Window child; - int i, j; - int wx, wy; + int i = 0, j = 0, wx = 0, wy = 0; wx = s->x + bx; wy = s->y + by; if (!((x >= wx) && (y >= wy) && (x < (wx + s->w)) && (y < (wy + s->h)))) - return 0; + return 0; if (s->children) { @@ -281,8 +237,7 @@ _ecore_x_window_shadow_tree_at_xy_get_shadow(Shadow *s, int bx, int by, int x, i for (i = s->children_num - 1; i >= 0; --i) { - if (!s->children[i]) - continue; + if (!s->children[i]) continue; skipit = 0; if (skip) @@ -296,40 +251,35 @@ _ecore_x_window_shadow_tree_at_xy_get_shadow(Shadow *s, int bx, int by, int x, i } } } - onward: if (!skipit) { - if ((child = _ecore_x_window_shadow_tree_at_xy_get_shadow(s->children[i], wx, wy, x, y, skip, skip_num))) - { - return child; - } + if ((child = + _ecore_x_window_shadow_tree_at_xy_get_shadow(s->children[i], wx, wy, x, y, skip, skip_num))) + return child; } } } return s->win; -} /* _ecore_x_window_shadow_tree_at_xy_get_shadow */ +} static Ecore_X_Window -_ecore_x_window_shadow_tree_at_xy_get(Ecore_X_Window base, int bx, int by, int x, int y, - Ecore_X_Window *skip, int skip_num) +_ecore_x_window_shadow_tree_at_xy_get(Ecore_X_Window base, int bx, int by, int x, int y, Ecore_X_Window *skip, int skip_num) { Shadow *s; if (!shadow_base) { _ecore_x_window_tree_shadow_populate(); - if (!shadow_base) - return 0; + if (!shadow_base) return 0; } s = _ecore_x_window_shadow_tree_find(base); - if (!s) - return 0; + if (!s) return 0; return _ecore_x_window_shadow_tree_at_xy_get_shadow(s, bx, by, x, y, skip, skip_num); -} /* _ecore_x_window_shadow_tree_at_xy_get */ +} /** * Retrieves the top, visible window at the given location, @@ -347,7 +297,7 @@ EAPI Ecore_X_Window ecore_x_window_shadow_tree_at_xy_with_skip_get(Ecore_X_Window base, int x, int y, Ecore_X_Window *skip, int skip_num) { return _ecore_x_window_shadow_tree_at_xy_get(base, 0, 0, x, y, skip, skip_num); -} /* ecore_x_window_shadow_tree_at_xy_with_skip_get */ +} /** * Retrieves the parent window a given window has. This uses the shadow window @@ -358,34 +308,30 @@ ecore_x_window_shadow_tree_at_xy_with_skip_get(Ecore_X_Window base, int x, int y * @ingroup Ecore_X_Window_Geometry_Group */ EAPI Ecore_X_Window -ecore_x_window_shadow_parent_get(Ecore_X_Window root, Ecore_X_Window win) +ecore_x_window_shadow_parent_get(Ecore_X_Window root __UNUSED__, Ecore_X_Window win) { Shadow *s; - int i; + int i = 0; if (!shadow_base) { _ecore_x_window_tree_shadow_populate(); - if (!shadow_base) - return 0; + if (!shadow_base) return 0; } for (i = 0; i < shadow_num; i++) { - if (!shadow_base[i]) - continue; + if (!shadow_base[i]) continue; s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], win); if (s) { - if (!s->parent) - return 0; - + if (!s->parent) return 0; return s->parent->win; } } return 0; -} /* ecore_x_window_shadow_parent_get */ +} /** * Flushes the window shadow tree so nothing is stored. @@ -395,5 +341,4 @@ EAPI void ecore_x_window_shadow_tree_flush(void) { _ecore_x_window_tree_shadow_free(); -} /* ecore_x_window_shadow_tree_flush */ - +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c b/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c new file mode 100644 index 0000000..82b9a2f --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c @@ -0,0 +1,587 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_SHAPE +# include +#endif + +/** + * @defgroup Ecore_X_Window_Shape X Window Shape Functions + * + * These functions use the shape extension of the X server to change + * shape of given windows. + */ + +/** + * Sets the input shape of the given window to that given by the pixmap @p mask. + * @param win The given window. + * @param mask A 1-bit depth pixmap that provides the new input shape of the + * window. + * @ingroup Ecore_X_Window_Shape + */ +EAPI void +ecore_x_window_shape_input_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, + win, 0, 0, mask); + +#else + return; + win = 0; + mask = 0; +#endif +} + +/** + * Sets the shape of the given window to that given by the pixmap @p mask. + * @param win The given window. + * @param mask A 2-bit depth pixmap that provides the new shape of the + * window. + * @ingroup Ecore_X_Window_Shape + */ +EAPI void +ecore_x_window_shape_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, + win, 0, 0, mask); + +#else + return; + win = 0; + mask = 0; +#endif +} + +EAPI void +ecore_x_window_shape_window_set(Ecore_X_Window win, Ecore_X_Window shape_win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, + XCB_SHAPE_SK_BOUNDING, win, 0, 0, shape_win); +#else + return; + win = 0; + shape_win = 0; +#endif +} + +EAPI void +ecore_x_window_shape_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, + XCB_SHAPE_SK_BOUNDING, win, x, y, shape_win); +#else + return; + win = 0; + shape_win = 0; + x = 0; + y = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + if (num > 0) + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, num, (xcb_rectangle_t *)&rects); + else + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 0, NULL); +#else + return; + win = 0; + num = 0; + rects = NULL; +#endif +} + +EAPI void +ecore_x_window_shape_window_add(Ecore_X_Window win, Ecore_X_Window shape_win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, + win, 0, 0, shape_win); +#else + return; + win = 0; + shape_win = 0; +#endif +} + +EAPI void +ecore_x_window_shape_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, + win, x, y, shape_win); +#else + return; + win = 0; + shape_win = 0; + x = 0; + y = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangle_subtract(Ecore_X_Window win, int x, int y, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SUBTRACT, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_INTERSECT, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + if (num > 0) + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, num, (xcb_rectangle_t *)&rects); + else + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 0, NULL); +#else + return; + win = 0; + num = 0; + rects = NULL; +#endif +} + +EAPI Ecore_X_Rectangle * +ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret) +{ + Ecore_X_Rectangle *rects = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (num_ret) *num_ret = 0; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_get_rectangles_cookie_t cookie; + xcb_shape_get_rectangles_reply_t *reply; + xcb_rectangle_t *r; + unsigned int i = 0; + + cookie = + xcb_shape_get_rectangles(_ecore_xcb_conn, win, XCB_SHAPE_SK_BOUNDING); + reply = xcb_shape_get_rectangles_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + if (num_ret) *num_ret = reply->rectangles_len; + + if (reply->rectangles_len < 1) + { + free(reply); + if (num_ret) *num_ret = 0; + return NULL; + } + + rects = malloc(sizeof(Ecore_X_Rectangle) * reply->rectangles_len); + if (!rects) + { + free(reply); + if (num_ret) *num_ret = 0; + return NULL; + } + r = xcb_shape_get_rectangles_rectangles(reply); + for (i = 0; i < reply->rectangles_len; i++) + { + rects[i].x = r[i].x; + rects[i].y = r[i].y; + rects[i].width = r[i].width; + rects[i].height = r[i].height; + } + + free(reply); + + return rects; +#else + return rects; + win = 0; +#endif +} + +EAPI void +ecore_x_window_shape_events_select(Ecore_X_Window win, Eina_Bool on) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_select_input(_ecore_xcb_conn, win, on); +#else + return; + win = 0; + on = 0; +#endif +} + +EAPI Ecore_X_Rectangle * +ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win, int *num_ret) +{ + Ecore_X_Rectangle *rects = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (num_ret) *num_ret = 0; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_get_rectangles_cookie_t cookie; + xcb_shape_get_rectangles_reply_t *reply; + xcb_rectangle_t *r; + unsigned int i = 0; + + cookie = + xcb_shape_get_rectangles(_ecore_xcb_conn, win, XCB_SHAPE_SK_INPUT); + reply = xcb_shape_get_rectangles_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + if (num_ret) *num_ret = reply->rectangles_len; + + if (reply->rectangles_len < 1) + { + free(reply); + if (num_ret) *num_ret = 0; + return NULL; + } + + rects = malloc(sizeof(Ecore_X_Rectangle) * reply->rectangles_len); + if (!rects) + { + free(reply); + if (num_ret) *num_ret = 0; + return NULL; + } + r = xcb_shape_get_rectangles_rectangles(reply); + for (i = 0; i < reply->rectangles_len; i++) + { + rects[i].x = r[i].x; + rects[i].y = r[i].y; + rects[i].width = r[i].width; + rects[i].height = r[i].height; + } + + free(reply); + + return rects; +#else + return rects; + win = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + if (!rects) return; + + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, num, (xcb_rectangle_t *)rects); +#else + return; + win = 0; + num = 0; + rects = NULL; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win, int x, int y, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SUBTRACT, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +// DBG("Window Shape Input Window Set XY: %d %d %d %d", win, shape_win, x, y); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, + XCB_SHAPE_SK_INPUT, win, x, y, shape_win); +#else + return; + win = 0; + shape_win = 0; + x = 0; + y = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +// DBG("Window Shape Input Window Add XY: %d %d %d %d", win, shape_win, x, y); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_INPUT, + XCB_SHAPE_SK_INPUT, win, x, y, shape_win); +#else + return; + win = 0; + shape_win = 0; + x = 0; + y = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_window_set(Ecore_X_Window win, Ecore_X_Window shape_win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +// DBG("Window Shape Input Window Set: %d %d", win, shape_win); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, + XCB_SHAPE_SK_INPUT, win, 0, 0, shape_win); +#else + return; + win = 0; + shape_win = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_INTERSECT, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + if (num > 0) + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, num, (xcb_rectangle_t *)&rects); + else + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 0, NULL); +#else + return; + win = 0; + num = 0; + rects = NULL; +#endif +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c b/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c new file mode 100644 index 0000000..c4648ea --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c @@ -0,0 +1,603 @@ +#include "ecore_xcb_private.h" +# ifdef ECORE_XCB_XFIXES +# include +# endif + +/* local function prototypes */ +static xcb_rectangle_t *_ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects, int num); +static Ecore_X_Rectangle *_ecore_xcb_rect_to_ecore(xcb_rectangle_t *rects, int num); + +/* local variables */ +static Eina_Bool _xfixes_avail = EINA_FALSE; + +/* external variables */ +int _ecore_xcb_event_xfixes = -1; + +void +_ecore_xcb_xfixes_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xfixes_id); +#endif +} + +void +_ecore_xcb_xfixes_finalize(void) +{ +#ifdef ECORE_XCB_XFIXES + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xfixes_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_xfixes_query_version_cookie_t cookie; + xcb_xfixes_query_version_reply_t *reply; + + cookie = + xcb_xfixes_query_version_unchecked(_ecore_xcb_conn, + XCB_XFIXES_MAJOR_VERSION, + XCB_XFIXES_MINOR_VERSION); + reply = xcb_xfixes_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (reply->major_version >= 3) + _xfixes_avail = EINA_TRUE; + free(reply); + } + + if (_xfixes_avail) + _ecore_xcb_event_xfixes = ext_reply->first_event; + } +#endif +} + +Eina_Bool +_ecore_xcb_xfixes_avail_get(void) +{ + return _xfixes_avail; +} + +/** + * @defgroup Ecore_X_Fixes_Group X Fixes Extension Functions + * + * Functions related to the X Fixes extension. + */ + +/** + * Create a region from rectangles. + * @param rects The rectangles used to initialize the region. + * @param num The number of rectangles. + * @return The newly created region. + * + * Create a region initialized to the specified list of rectangles + * @p rects. The rectangles may be specified in any order, their union + * becomes the region. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI Ecore_X_Region +ecore_x_region_new(Ecore_X_Rectangle *rects, int num) +{ + Ecore_X_Region region = 0; +#ifdef ECORE_XCB_XFIXES + xcb_rectangle_t *xrects; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xrects = _ecore_xcb_rect_to_xcb(rects, num); + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region(_ecore_xcb_conn, region, num, xrects); + free(xrects); +#endif + + return region; +} + +/** + * Create a region from a pixmap. + * @param bitmap The bitmap used to initialize the region. + * @return The newly created region. + * + * Creates a region initialized to the set of 'one' pixels in @p bitmap + * (which must be of depth 1, else Match error). + * @ingroup Ecore_X_Fixes_Group + */ +EAPI Ecore_X_Region +ecore_x_region_new_from_bitmap(Ecore_X_Pixmap bitmap) +{ + Ecore_X_Region region = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region_from_bitmap(_ecore_xcb_conn, region, bitmap); +#endif + + return region; +} + +/** + * Create a region from a window. + * @param window The window used to initialize the region. + * @param type The type of the region. + * @return The newly created region. + * + * Creates a region initialized to the specified @p window region. See + * the Shape extension for the definition of Bounding and Clip + * regions. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI Ecore_X_Region +ecore_x_region_new_from_window(Ecore_X_Window win, Ecore_X_Region_Type type) +{ + Ecore_X_Region region = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region_from_window(_ecore_xcb_conn, region, win, type); +#endif + + return region; +} + +/** + * Create a region from a graphic context. + * @param gc The graphic context used to initialize the region. + * @return The newly created region. + * + * Creates a region initialized from the clip list of @p gc. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI Ecore_X_Region +ecore_x_region_new_from_gc(Ecore_X_GC gc) +{ + Ecore_X_Region region = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region_from_gc(_ecore_xcb_conn, region, gc); +#endif + + return region; +} + +/** + * Create a region from a picture. + * @param picture The picture used to initialize the region. + * @return The newly created region. + * + * Creates a region initialized from the clip list of @p picture. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI Ecore_X_Region +ecore_x_region_new_from_picture(Ecore_X_Picture picture) +{ + Ecore_X_Region region = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region_from_picture(_ecore_xcb_conn, region, picture); +#endif + + return region; +} + +/** + * Destroy a region. + * @param region The region to destroy. + * + * Destroy the specified @p region. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_free(Ecore_X_Region region) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_destroy_region(_ecore_xcb_conn, region); +#endif +} + +/** + * Set the content of a region. + * @param region The region to destroy. + * @param rects The rectangles used to set the region. + * @param num The number of rectangles. + * + * Replace the current contents of @p region with the region formed + * by the union of the rectangles @p rects. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_set(Ecore_X_Region region, Ecore_X_Rectangle *rects, int num) +{ +#ifdef ECORE_XCB_XFIXES + xcb_rectangle_t *xrects; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xrects = _ecore_xcb_rect_to_xcb(rects, num); + xcb_xfixes_set_region(_ecore_xcb_conn, region, num, xrects); + free(xrects); +#endif +} + +/** + * Copy the content of a region. + * @param dest The destination region. + * @param source The source region. + * + * Replace the contents of @p dest with the contents of @p source. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_copy(Ecore_X_Region dest, Ecore_X_Region source) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + // NB: Hmmmm...this may need converting to/fro xcb_rectangle_t +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_copy_region(_ecore_xcb_conn, source, dest); +#endif +} + +/** + * Make the union of two regions. + * @param dest The destination region. + * @param source1 The first source region. + * @param source2 The second source region. + * + * Replace the contents of @p dest with the union of @p source1 and + * @p source2. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_combine(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_union_region(_ecore_xcb_conn, source1, source2, dest); +#endif +} + +/** + * Make the intersection of two regions. + * @param dest The destination region. + * @param source1 The first source region. + * @param source2 The second source region. + * + * Replace the contents of @p dest with the intersection of @p source1 and + * @p source2. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_intersect(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_intersect_region(_ecore_xcb_conn, source1, source2, dest); +#endif +} + +/** + * Make the subtraction of two regions. + * @param dest The destination region. + * @param source1 The first source region. + * @param source2 The second source region. + * + * Replace the contents of @p dest with the subtraction of @p source1 by + * @p source2. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_subtract(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_subtract_region(_ecore_xcb_conn, source1, source2, dest); +#endif +} + +/** + * Make the subtraction of regions by bounds. + * @param dest The destination region. + * @param bounds The bounds. + * @param source The source region. + * + * The @p source region is subtracted from the region specified by + * @p bounds. The result is placed in @p dest, replacing its + * contents. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_invert(Ecore_X_Region dest, Ecore_X_Rectangle *bounds, Ecore_X_Region source) +{ +#ifdef ECORE_XCB_XFIXES + xcb_rectangle_t xrects; + int num = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + while (bounds + num) + num++; + + xrects.x = bounds->x; + xrects.y = bounds->y; + xrects.width = bounds->width; + xrects.height = bounds->height; + +// xrects = _ecore_xcb_rect_to_xcb(bounds, num); + xcb_xfixes_invert_region(_ecore_xcb_conn, source, xrects, dest); +// free(xrects); +#endif +} + +/** + * Translate a region. + * @param region The region to translate. + * @param dx The horizontal translation. + * @param dy The vertical translation. + * + * The @p region is translated by @p dx and @p dy in place. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_translate(Ecore_X_Region region, int dx, int dy) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_translate_region(_ecore_xcb_conn, region, dx, dy); +#endif +} + +/** + * Extent a region. + * @param dest The destination region. + * @param source The source region. + * + * The extents of the @p source region are placed in @p dest. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_extents(Ecore_X_Region dest, Ecore_X_Region source) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_region_extents(_ecore_xcb_conn, source, dest); +#endif +} + +/** + * Return the rectangles that compose a region. + * @param region The region (Unused). + * @param num The number of returned rectangles. + * @param bounds The returned bounds of the region. + * @return The returned rectangles. + * + * The @p region passed to ecore_xcb_region_fetch_prefetch() is + * returned as a list of rectagles in XY-banded order. + * + * To use this function, you must call before, and in order, + * ecore_xcb_region_fetch_prefetch(), which sends the XFixesFetchRegion request, + * then ecore_xcb_region_fetch_fetch(), which gets the reply. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI Ecore_X_Rectangle * +ecore_x_region_fetch(Ecore_X_Region region, int *num, Ecore_X_Rectangle *bounds) +{ + Ecore_X_Rectangle extents = { 0, 0, 0, 0 }; + Ecore_X_Rectangle *rects = NULL; +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_fetch_region_cookie_t cookie; + xcb_xfixes_fetch_region_reply_t *reply; + xcb_rectangle_t *r; + int n = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (num) *num = 0; + if (bounds) *bounds = extents; + +#ifdef ECORE_XCB_XFIXES + cookie = xcb_xfixes_fetch_region_unchecked(_ecore_xcb_conn, region); + reply = xcb_xfixes_fetch_region_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + + r = xcb_xfixes_fetch_region_rectangles(reply); + n = xcb_xfixes_fetch_region_rectangles_length(reply); + rects = _ecore_xcb_rect_to_ecore(r, n); + if (num) *num = n; + + /* rects = (Ecore_X_Rectangle *)malloc(n * sizeof(Ecore_X_Rectangle)); */ + /* if (!rects) */ + /* { */ + /* free(reply); */ + /* return NULL; */ + /* } */ + + /* for (i = 0; i < n; i++) */ + /* { */ + /* rects[i].x = r[i].x; */ + /* rects[i].y = r[i].y; */ + /* rects[i].width = r[i].width; */ + /* rects[i].height = r[i].height; */ + /* } */ + + (*bounds).x = reply->extents.x; + (*bounds).y = reply->extents.y; + (*bounds).width = reply->extents.width; + (*bounds).height = reply->extents.height; + + free(reply); +#endif + + return rects; +} + +/** + * Expand a region. + * @param dest The destination region. + * @param source The source region. + * @param left The number of pixels to add on the left. + * @param right The number of pixels to add on the right. + * @param top The number of pixels to add at the top. + * @param bottom The number of pixels to add at the bottom. + * + * Put in @p dest the area specified by expanding each rectangle in + * the @p source region by the specified number of pixels to the + * @p left, @p right, @p top and @p bottom. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_expand(Ecore_X_Region dest, Ecore_X_Region source, unsigned int left, unsigned int right, unsigned int top, unsigned int bottom) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_expand_region(_ecore_xcb_conn, source, dest, left, right, top, bottom); +#endif +} + +/** + * Change clip-mask in a graphic context to the specified region. + * @param region The region to change. + * @param gc The clip-mask graphic context. + * @param x_origin The horizontal translation. + * @param y_origin The vertical translation. + * + * Changes clip-mask in @p gc to the specified @p region and + * sets the clip origin with the values of @p x_origin and @p y_origin. + * Output will be clippped to remain contained within the region. The + * clip origin is interpreted relative to the origin of whatever + * destination drawable is specified in a graphics request. The + * region is interpreted relative to the clip origin. Future changes + * to region have no effect on the gc clip-mask. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_gc_clip_set(Ecore_X_Region region, Ecore_X_GC gc, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_set_gc_clip_region(_ecore_xcb_conn, gc, region, x, y); +#endif +} + +/** + * Change the shape extension of a window. + * @param region The region. + * @param dest The window whose shape is changed. + * @param type The kind of shape. + * @param x_offset The horizontal offset. + * @param y_offset The vertical offset. + * + * Set the specified Shape extension region of @p window to @p region, + * offset by @p x_offset and @p y_offset. Future changes to region + * have no effect on the window shape. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_window_shape_set(Ecore_X_Region region, Ecore_X_Window dest, Ecore_X_Shape_Type type, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_set_window_shape_region(_ecore_xcb_conn, dest, type, x, y, region); +#endif +} + +/** + * Change clip-mask in picture to the specified region. + * @param region The region. + * @param picture The picture. + * @param x_origin The X coordinate of the origin. + * @param y_origin The Y coordinate of the origin. + * + * Changes clip-mask in picture to the specified @p region + * and sets the clip origin. Input and output will be clipped to + * remain contained within the region. The clip origin is interpreted + * relative to the origin of the drawable associated with @p picture. The + * region is interpreted relative to the clip origin. Future changes + * to region have no effect on the picture clip-mask. + * @ingroup Ecore_X_Fixes_Group + */ +EAPI void +ecore_x_region_picture_clip_set(Ecore_X_Region region, Ecore_X_Picture picture, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_set_picture_clip_region(_ecore_xcb_conn, picture, region, x, y); +#endif +} + +/* local function prototypes */ +static xcb_rectangle_t * +_ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects, int num) +{ + xcb_rectangle_t *xrect; + int i = 0; + + if (!num) return NULL; + + xrect = malloc(sizeof(xcb_rectangle_t) * num); + if (!xrect) return NULL; + + for (i = 0; i < num; i++) + { + xrect[i].x = rects[i].x; + xrect[i].y = rects[i].y; + xrect[i].width = rects[i].width; + xrect[i].height = rects[i].height; + } + + return xrect; +} + +static Ecore_X_Rectangle * +_ecore_xcb_rect_to_ecore(xcb_rectangle_t *rects, int num) +{ + Ecore_X_Rectangle *erect; + int i = 0; + + if (!num) return NULL; + + erect = malloc(sizeof(Ecore_X_Rectangle) * num); + if (!erect) return NULL; + + for (i = 0; i < num; i++) + { + erect[i].x = rects[i].x; + erect[i].y = rects[i].y; + erect[i].width = rects[i].width; + erect[i].height = rects[i].height; + } + + return erect; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c b/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c index 04e4f14..062bb20 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c @@ -1,212 +1,132 @@ #include "ecore_xcb_private.h" - -/** - * @defgroup Ecore_X_Xinerama_Group X Xinerama Extension Functions - * - * Functions related to the X Xinerama extension. - */ - #ifdef ECORE_XCB_XINERAMA -static int _xinerama_available = 0; -static xcb_xinerama_query_version_cookie_t _ecore_xcb_xinerama_init_cookie; -#endif /* ECORE_XCB_XINERAMA */ +# include +#endif -/* To avoid round trips, the initialization is separated in 2 - functions: _ecore_xcb_xinerama_init and - _ecore_xcb_xinerama_init_finalize. The first one gets the cookies and - the second one gets the replies. */ +/* local variables */ +static Eina_Bool _xinerama_avail = EINA_FALSE; +static Eina_Bool _xinerama_active = EINA_FALSE; -void -_ecore_x_xinerama_init(const xcb_query_extension_reply_t *reply) +void +_ecore_xcb_xinerama_init(void) { -#ifdef ECORE_XCB_XINERAMA - if (reply && (reply->present)) - _ecore_xcb_xinerama_init_cookie = xcb_xinerama_query_version_unchecked(_ecore_xcb_conn, 1, 2); + LOGFN(__FILE__, __LINE__, __FUNCTION__); -#endif /* ECORE_XCB_XINERAMA */ -} /* _ecore_x_xinerama_init */ +#ifdef ECORE_XCB_XINERAMA + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xinerama_id); +#endif +} -void -_ecore_x_xinerama_init_finalize(void) +void +_ecore_xcb_xinerama_finalize(void) { #ifdef ECORE_XCB_XINERAMA - xcb_xinerama_query_version_reply_t *reply; + const xcb_query_extension_reply_t *ext_reply; +#endif - reply = xcb_xinerama_query_version_reply(_ecore_xcb_conn, - _ecore_xcb_xinerama_init_cookie, NULL); + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (reply) +#ifdef ECORE_XCB_XINERAMA + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xinerama_id); + if ((ext_reply) && (ext_reply->present)) { - if ((reply->major >= 1) && - (reply->minor >= 1)) - _xinerama_available = 1; + xcb_xinerama_query_version_cookie_t cookie; + xcb_xinerama_query_version_reply_t *reply; + + cookie = + xcb_xinerama_query_version_unchecked(_ecore_xcb_conn, + XCB_XINERAMA_MAJOR_VERSION, + XCB_XINERAMA_MINOR_VERSION); + reply = + xcb_xinerama_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + _xinerama_avail = EINA_TRUE; + // NB: Do we need to compare version numbers here ? + free(reply); + } - free(reply); + if (_xinerama_avail) + { + xcb_xinerama_is_active_cookie_t acookie; + xcb_xinerama_is_active_reply_t *areply; + + acookie = xcb_xinerama_is_active_unchecked(_ecore_xcb_conn); + areply = + xcb_xinerama_is_active_reply(_ecore_xcb_conn, acookie, NULL); + if (areply) + { + _xinerama_active = areply->state; + free(areply); + } + } } +#endif +} -#endif /* ECORE_XCB_XINERAMA */ -} /* _ecore_x_xinerama_init_finalize */ - -/** - * Return whether the X server supports the Xinerama Extension. - * @return 1 if the X Xinerama Extension is available, 0 otherwise. - * - * Return 1 if the X server supports the Fixes Xinerama version 1.1, - * 0 otherwise. - * @ingroup Ecore_X_Xinerama_Group - */ -EAPI Eina_Bool -ecore_x_xinerama_query(void) -{ -#ifdef ECORE_XCB_XINERAMA - return _xinerama_available; -#else /* ifdef ECORE_XCB_XINERAMA */ - return 0; -#endif /* ECORE_XCB_XINERAMA */ -} /* ecore_x_xinerama_query */ - -/** - * Sends the XineramaQueryScreens request. - * @ingroup Ecore_X_Xinerama_Group - */ -EAPI void -ecore_x_xinerama_query_screens_prefetch(void) -{ -#ifdef ECORE_XCB_XINERAMA - xcb_xinerama_query_screens_cookie_t cookie; - - cookie = xcb_xinerama_query_screens_unchecked(_ecore_xcb_conn); - _ecore_xcb_cookie_cache(cookie.sequence); -#endif /* ECORE_XCB_XINERAMA */ -} /* ecore_x_xinerama_query_screens_prefetch */ - -/** - * Gets the reply of the XineramaQueryScreens request sent by ecore_x_xinerama_query_screens_prefetch(). - * @ingroup Ecore_X_Xinerama_Group - */ -EAPI void -ecore_x_xinerama_query_screens_fetch(void) +EAPI int +ecore_x_xinerama_screen_count_get(void) { + int count = 0; #ifdef ECORE_XCB_XINERAMA xcb_xinerama_query_screens_cookie_t cookie; xcb_xinerama_query_screens_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_xinerama_avail) return 0; - cookie.sequence = _ecore_xcb_cookie_get(); - reply = xcb_xinerama_query_screens_reply(_ecore_xcb_conn, cookie, NULL); - _ecore_xcb_reply_cache(reply); -#endif /* ECORE_XCB_XINERAMA */ -} /* ecore_x_xinerama_query_screens_fetch */ - -/** - * Return the number of screens. - * @return The screen count. - * - * Return the number of screens. - * - * To use this function, you must call before, and in order, - * ecore_x_xinerama_query_screens_prefetch(), which sends the XineramaQueryScreens request, - * then ecore_x_xinerama_query_screens_fetch(), which gets the reply. - * @ingroup Ecore_X_Xinerama_Group - */ -EAPI int -ecore_x_xinerama_screen_count_get(void) -{ - int screen_count = 0; #ifdef ECORE_XCB_XINERAMA - xcb_xinerama_screen_info_iterator_t iter; - xcb_xinerama_query_screens_reply_t *reply; + cookie = xcb_xinerama_query_screens_unchecked(_ecore_xcb_conn); + reply = + xcb_xinerama_query_screens_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + count = reply->number; +#endif + + return count; +} - reply = _ecore_xcb_reply_get(); - if (!reply) - return 0; - - iter = xcb_xinerama_query_screens_screen_info_iterator(reply); - screen_count = iter.rem; -#endif /* ECORE_XCB_XINERAMA */ - - return screen_count; -} /* ecore_x_xinerama_screen_count_get */ - -/** - * Get the geometry of the screen. - * @param screen The screen (Unused). - * @param x The X coordinate of the screen. - * @param y The Y coordinate of the screen - * @param width The width of the screen - * @param height The height of the screen - * @return 1 on success, 0 otherwise. - * - * Get the geometry of the screen whose number is @p screen. The - * returned values are stored in @p x, @p y, @p width and @p height. - * - * To use this function, you must call before, and in order, - * ecore_x_xinerama_query_screens_prefetch(), which sends the XineramaQueryScreens request, - * then ecore_x_xinerama_query_screens_fetch(), which gets the reply. - * @ingroup Ecore_X_Xinerama_Group - */ -EAPI Eina_Bool -ecore_x_xinerama_screen_geometry_get(int screen, - int *x, - int *y, - int *width, - int *height) +EAPI Eina_Bool +ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h) { #ifdef ECORE_XCB_XINERAMA - xcb_xinerama_screen_info_iterator_t iter; + xcb_xinerama_query_screens_cookie_t cookie; xcb_xinerama_query_screens_reply_t *reply; + xcb_xinerama_screen_info_t *info; +#endif - reply = _ecore_xcb_reply_get(); - if (!reply) - { - if (x) - *x = 0; - - if (y) - *y = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (width) - *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; + if (h) *h = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; - if (height) - *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; + if (!_xinerama_avail) return EINA_FALSE; - return 0; - } +#ifdef ECORE_XCB_XINERAMA + cookie = xcb_xinerama_query_screens_unchecked(_ecore_xcb_conn); + reply = + xcb_xinerama_query_screens_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; - iter = xcb_xinerama_query_screens_screen_info_iterator(reply); - for (; iter.rem; screen--, xcb_xinerama_screen_info_next(&iter)) + info = xcb_xinerama_query_screens_screen_info(reply); + if (!info) { - if (screen == 0) - { - if (x) - *x = iter.data->x_org; - - if (y) - *y = iter.data->y_org; - - if (width) - *width = iter.data->width; - - if (height) - *height = iter.data->height; - - return 1; - } + free(reply); + return EINA_FALSE; } -#endif /* ECORE_XCB_XINERAMA */ - - if (x) - *x = 0; - - if (y) - *y = 0; - - if (width) - *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; - if (height) - *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; + if (x) *x = info[screen].x_org; + if (y) *y = info[screen].y_org; + if (w) *w = info[screen].width; + if (h) *h = info[screen].height; - return 0; -} /* ecore_x_xinerama_screen_geometry_get */ + free(reply); + return EINA_TRUE; +#endif + return EINA_FALSE; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xtest.c b/src/lib/ecore_x/xcb/ecore_xcb_xtest.c new file mode 100644 index 0000000..a0e8ea6 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_xtest.c @@ -0,0 +1,212 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_XTEST +# include +# include +#endif + +/* local variables */ +static Eina_Bool _test_avail = EINA_FALSE; + +void +_ecore_xcb_xtest_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XTEST + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_test_id); +#endif +} + +void +_ecore_xcb_xtest_finalize(void) +{ +#ifdef ECORE_XCB_XTEST + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XTEST + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_test_id); + if ((ext_reply) && (ext_reply->present)) + _test_avail = EINA_TRUE; +#endif +} + +EAPI Eina_Bool +#ifdef ECORE_XCB_XTEST +ecore_x_test_fake_key_down(const char *key) +#else +ecore_x_test_fake_key_down(const char *key __UNUSED__) +#endif +{ +#ifdef ECORE_XCB_XTEST + xcb_keycode_t keycode = 0; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_test_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_XTEST + keycode = _ecore_xcb_keymap_string_to_keycode(key); + if (keycode == XCB_NO_SYMBOL) return EINA_FALSE; + + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_PRESS, + keycode, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + +EAPI Eina_Bool +#ifdef ECORE_XCB_XTEST +ecore_x_test_fake_key_up(const char *key) +#else +ecore_x_test_fake_key_up(const char *key __UNUSED__) +#endif +{ +#ifdef ECORE_XCB_XTEST + xcb_keycode_t keycode = 0; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_test_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_XTEST + keycode = _ecore_xcb_keymap_string_to_keycode(key); + if (keycode == XCB_NO_SYMBOL) return EINA_FALSE; + + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_RELEASE, + keycode, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + +EAPI Eina_Bool +#ifdef ECORE_XCB_XTEST +ecore_x_test_fake_key_press(const char *key) +#else +ecore_x_test_fake_key_press(const char *key __UNUSED__) +#endif +{ +#ifdef ECORE_XCB_XTEST + xcb_keycode_t keycode = 0; + xcb_keysym_t keysym = 0; + xcb_keycode_t shift_code = 0; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; + Eina_Bool shift = EINA_FALSE; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_test_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_XTEST + keycode = _ecore_xcb_keymap_string_to_keycode(key); + keysym = _ecore_xcb_keymap_keycode_to_keysym(keycode, 0); + if (keysym == XCB_NO_SYMBOL) + { + keysym = _ecore_xcb_keymap_keycode_to_keysym(keycode, 1); + if (keysym != XCB_NO_SYMBOL) + shift = EINA_TRUE; + } + + if (shift) + { + xcb_keycode_t *keycodes; + int i = 0; + + keycodes = _ecore_xcb_keymap_keysym_to_keycode(XK_Shift_L); + while (keycodes[i] != XCB_NO_SYMBOL) + { + if (keycodes[i] != 0) + { + shift_code = keycodes[i]; + break; + } + i++; + } + } + + if (shift) + { + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_PRESS, + shift_code, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + } + + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_PRESS, + keycode, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_RELEASE, + keycode, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + + if (shift) + { + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_RELEASE, + shift_code, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + } + + return EINA_TRUE; +#endif + + return EINA_FALSE; +} -- 2.7.4