Ecore_X: Add new xcb code (still not 100% complete tho).
authordevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 Jul 2011 15:35:42 +0000 (15:35 +0000)
committerdevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 Jul 2011 15:35:42 +0000 (15:35 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@61376 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

39 files changed:
src/lib/ecore_x/xcb/Makefile.am
src/lib/ecore_x/xcb/ecore_xcb.c
src/lib/ecore_x/xcb/ecore_xcb_atoms.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_composite.c
src/lib/ecore_x/xcb/ecore_xcb_cursor.c
src/lib/ecore_x/xcb/ecore_xcb_damage.c
src/lib/ecore_x/xcb/ecore_xcb_dnd.c
src/lib/ecore_x/xcb/ecore_xcb_dpms.c
src/lib/ecore_x/xcb/ecore_xcb_drawable.c
src/lib/ecore_x/xcb/ecore_xcb_e.c
src/lib/ecore_x/xcb/ecore_xcb_error.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_events.c
src/lib/ecore_x/xcb/ecore_xcb_extensions.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_gc.c
src/lib/ecore_x/xcb/ecore_xcb_icccm.c
src/lib/ecore_x/xcb/ecore_xcb_image.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_input.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_keymap.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_mwm.c
src/lib/ecore_x/xcb/ecore_xcb_netwm.c
src/lib/ecore_x/xcb/ecore_xcb_pixmap.c
src/lib/ecore_x/xcb/ecore_xcb_private.h
src/lib/ecore_x/xcb/ecore_xcb_randr.c
src/lib/ecore_x/xcb/ecore_xcb_region.c
src/lib/ecore_x/xcb/ecore_xcb_render.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_reply.c [deleted file]
src/lib/ecore_x/xcb/ecore_xcb_screensaver.c
src/lib/ecore_x/xcb/ecore_xcb_selection.c
src/lib/ecore_x/xcb/ecore_xcb_shape.c
src/lib/ecore_x/xcb/ecore_xcb_sync.c
src/lib/ecore_x/xcb/ecore_xcb_textlist.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_vsync.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_window.c
src/lib/ecore_x/xcb/ecore_xcb_window_prop.c
src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c
src/lib/ecore_x/xcb/ecore_xcb_window_shape.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_xfixes.c [new file with mode: 0644]
src/lib/ecore_x/xcb/ecore_xcb_xinerama.c
src/lib/ecore_x/xcb/ecore_xcb_xtest.c [new file with mode: 0644]

index f31cadf..7e48f36 100644 (file)
@@ -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
 
index c74e54c..bb5e4c9 100644 (file)
-#include <string.h>
-
-#include <X11/keysym.h>
-
-#include <Ecore.h>
-#include <Ecore_Input.h>
-
 #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 (file)
index 0000000..882c17d
--- /dev/null
@@ -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);
+     }
+}
index bf7b9aa..2d36a8b 100644 (file)
 #include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_COMPOSITE
+# include <xcb/composite.h>
+#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
+}
index 2895d0b..f71d595 100644 (file)
 #include "ecore_xcb_private.h"
-#include <xcb/shm.h>
-#include <xcb/xcb_image.h>
+# include <xcb/xproto.h>
+# include <xcb/xcb_image.h>
+#ifdef ECORE_XCB_CURSOR
+# include <xcb/render.h>
+# include <xcb/xcb_renderutil.h>
+#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
index ab97445..899f0d4 100644 (file)
 #include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_DAMAGE
+#  include <xcb/damage.h>
+# 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
+}
index 9e289d1..0c7d8ea 100644 (file)
@@ -1,9 +1,29 @@
-#include <string.h>
-
-#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;
+     }
+}
index 1bc0f49..2cf45b7 100644 (file)
 #include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_DAMAGE
+# include <xcb/dpms.h>
+#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);
+}
index 55a55e5..6d8da79 100644 (file)
@@ -1,5 +1,4 @@
 #include "ecore_xcb_private.h"
-#include <xcb/xcb.h>
 
 /**
  * @defgroup Ecore_X_Drawable_Group X Drawable Functions
  */
 
 /**
- * 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;
+}
index c33eb8f..a75bb55 100644 (file)
-/*
- * 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 (file)
index 0000000..c58c13c
--- /dev/null
@@ -0,0 +1,95 @@
+#include "ecore_xcb_private.h"
+#include <xcb/xcb_event.h>
+
+/* 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;
+}
index 0f39591..f84e893 100644 (file)
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* ifdef HAVE_CONFIG_H */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <Ecore.h>
-#include <Ecore_Input.h>
-
 #include "ecore_xcb_private.h"
-#include "Ecore_X_Atoms.h"
-
-/** OpenBSD does not define CODESET
- * FIXME ??
- */
+//#include "Ecore_X_Atoms.h"
+#include <langinfo.h>
+#include <xcb/xcb_icccm.h>
+#include <xcb/xcb_event.h>
+# ifdef ECORE_XCB_DAMAGE
+#  include <xcb/damage.h>
+# endif
+# ifdef ECORE_XCB_RANDR
+#  include <xcb/randr.h>
+# endif
+# ifdef ECORE_XCB_SCREENSAVER
+#  include <xcb/screensaver.h>
+# endif
+# ifdef ECORE_XCB_SYNC
+#  include <xcb/sync.h>
+# endif
+# ifdef ECORE_XCB_XFIXES
+#  include <xcb/xfixes.h>
+# 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 (file)
index 0000000..cd24997
--- /dev/null
@@ -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);
+}
index 4d5ce05..d7fb7e3 100644 (file)
 /**
  * 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);
+}
index 291e22e..6c86686 100644 (file)
-/*
- * Various ICCCM related functions.
- *
- * This is ALL the code involving anything ICCCM related, for both WM and
- * client.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <xcb/xcb_icccm.h>
-
 #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 <xcb/xcb_icccm.h>
 
-/*
- * 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 (file)
index 0000000..2de3b74
--- /dev/null
@@ -0,0 +1,670 @@
+#include "ecore_xcb_private.h"
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <xcb/xcb_image.h>
+#include <xcb/xcb_event.h>
+
+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 (file)
index 0000000..a5b2120
--- /dev/null
@@ -0,0 +1,188 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_XINPUT
+# include <xcb/xinput.h>
+# include <xcb/xcb_event.h>
+#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 (file)
index 0000000..ab7ca86
--- /dev/null
@@ -0,0 +1,447 @@
+#include "ecore_xcb_private.h"
+#define NEED_KEYSYM_TABLE
+#define NEED_VTABLE
+#include "ecore_xcb_keysym_table.h"
+#include <xcb/xcb_keysyms.h>
+#include <X11/keysym.h>
+
+/* 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;
+}
index 872bdec..9d3aa71 100644 (file)
-/*
- * 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 */
-
+}
index ff0f42b..0741504 100644 (file)
-/*
- * _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
- */
-
-#include <stdio.h>
-#include <string.h>
-
 #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-<number>" */
-             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-<number>" */
+             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;
+     }
+}
index e374a7a..6a9e797 100644 (file)
  * @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);
+}
index 00761f1..5330de2 100644 (file)
 #ifndef __ECORE_XCB_PRIVATE_H__
-#define __ECORE_XCB_PRIVATE_H__
-
-#include "config.h"
-
-#include <sys/param.h>
-
-#ifndef MAXHOSTNAMELEN
-# define MAXHOSTNAMELEN 256
-#endif /* ifndef MAXHOSTNAMELEN */
-
-#ifndef XK_MISCELLANY
-# define XK_MISCELLANY  1
-#endif /* XK_MISCELLANY */
-
-#include <xcb/xcb.h>
-#include <xcb/xcb_icccm.h>
-#include <xcb/xcb_keysyms.h>
-#include <xcb/bigreq.h>
-#ifdef ECORE_XCB_CURSOR
-# include <xcb/cursor.h>
-#endif /* ECORE_XCB_CURSOR */
-#ifdef ECORE_XCB_DAMAGE
-# include <xcb/damage.h>
-#endif /* ECORE_XCB_DAMAGE */
-#ifdef ECORE_XCB_COMPOSITE
-# include <xcb/composite.h>
-#endif /* ECORE_XCB_COMPOSITE */
-#ifdef ECORE_XCB_DPMS
-# include <xcb/dpms.h>
-#endif /* ECORE_XCB_DPMS */
-#ifdef ECORE_XCB_RANDR
-# include <xcb/randr.h>
-#endif /* ECORE_XCB_RANDR */
-#ifdef ECORE_XCB_RENDER
-# include <xcb/render.h>
-#endif /* ECORE_XCB_RENDER */
-#ifdef ECORE_XCB_SCREENSAVER
-# include <xcb/screensaver.h>
-#endif /* ECORE_XCB_SCREENSAVER */
-#ifdef ECORE_XCB_SHAPE
-# include <xcb/shape.h>
-#endif /* ECORE_XCB_SHAPE */
-#ifdef ECORE_XCB_SYNC
-# include <xcb/sync.h>
-#endif /* ECORE_XCB_SYNC */
-#ifdef ECORE_XCB_XFIXES
-# include <xcb/xfixes.h>
-#endif /* ECORE_XCB_XFIXES */
-#ifdef ECORE_XCB_XINERAMA
-# include <xcb/xinerama.h>
-#endif /* ECORE_XCB_XINERAMA */
-#ifdef ECORE_XCB_XPRINT
-# include <xcb/xprint.h>
-#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 <unistd.h> // included for close & gethostname functions
+
+/* generic xcb includes */
+# include <xcb/xcb.h>
+# include <xcb/bigreq.h>
+# include <xcb/shm.h>
+
+/* 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 <stdio.h>
+#  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
index 84806d4..9f8b297 100644 (file)
 #include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_RANDR
+#  include <xcb/randr.h>
+# 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;
+}
index 369ad3b..2151cb7 100644 (file)
@@ -1,32 +1,11 @@
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* ifdef HAVE_CONFIG_H */
-
-#include <pixman.h>
-
 #include "ecore_xcb_private.h"
+#include <pixman.h>
 
 /*
- * [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 (file)
index 0000000..059d9a3
--- /dev/null
@@ -0,0 +1,229 @@
+#include "ecore_xcb_private.h"
+#include <ctype.h>
+#ifdef ECORE_XCB_RENDER
+# include <xcb/render.h>
+# include <xcb/xcb_renderutil.h>
+#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 (file)
index 4f50a51..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#include <stdlib.h>
-
-#include <Eina.h>
-
-/*
- * 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 */
-
index 3f8f0bf..7d0007b 100644 (file)
 #include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_SCREENSAVER
+#  include <xcb/screensaver.h>
+# 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;
+}
index ec5f664..be352ea 100644 (file)
@@ -1,63 +1,70 @@
-#include <string.h>
-
 #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);
+}
index 3bd330d..526742a 100644 (file)
 #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 <xcb/shape.h>
+#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
+}
index b4e867c..2f9a219 100644 (file)
 #include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_SYNC
+#  include <xcb/sync.h>
+# 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 (file)
index 0000000..942719d
--- /dev/null
@@ -0,0 +1,469 @@
+#include "ecore_xcb_private.h"
+//#include "Ecore_X_Atoms.h"
+#include <langinfo.h>
+#ifdef HAVE_ICONV
+# include <iconv.h>
+#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 (file)
index 0000000..a793c1f
--- /dev/null
@@ -0,0 +1,359 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_DRI
+# include <fcntl.h>
+# include <dlfcn.h>
+# include <xcb/dri2.h>
+#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();
+}
index c76b1f5..a643836 100644 (file)
@@ -1,30 +1,28 @@
-#include <string.h>
-
-#include <Ecore.h>
-
 #include "ecore_xcb_private.h"
-#include "Ecore_X_Atoms.h"
+#ifdef ECORE_XCB_RENDER
+# include <xcb/render.h>
+#endif
+#ifdef ECORE_XCB_SHAPE
+# include <xcb/shape.h>
+#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;
+}
index 07f8433..9961d45 100644 (file)
-#include <stdlib.h>
-#include <string.h>
-
 #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 <xcb/xcb_icccm.h>
 
-   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;
+}
index 13d8392..931ffc6 100644 (file)
@@ -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 (file)
index 0000000..82b9a2f
--- /dev/null
@@ -0,0 +1,587 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_SHAPE
+# include <xcb/shape.h>
+#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 (file)
index 0000000..c4648ea
--- /dev/null
@@ -0,0 +1,603 @@
+#include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_XFIXES
+#  include <xcb/xfixes.h>
+# 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;
+}
index 04e4f14..062bb20 100644 (file)
 #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 <xcb/xinerama.h>
+#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 (file)
index 0000000..a0e8ea6
--- /dev/null
@@ -0,0 +1,212 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_XTEST
+# include <xcb/xtest.h>
+# include <X11/keysym.h>
+#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;
+}