summaryrefslogtreecommitdiff
path: root/src/lib/ecore_x
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/ecore_x')
-rw-r--r--src/lib/ecore_x/Ecore_X.h2407
-rw-r--r--src/lib/ecore_x/Ecore_X_Atoms.h292
-rw-r--r--src/lib/ecore_x/Ecore_X_Cursor.h87
-rw-r--r--src/lib/ecore_x/ecore_x_atoms_decl.h602
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb.c1583
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_atoms.c149
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_composite.c290
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_cursor.c400
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_damage.c155
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_dnd.c688
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_dpms.c320
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_drawable.c123
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_e.c1576
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_error.c123
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_events.c2824
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_extensions.c148
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_gc.c173
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_gesture.c203
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_icccm.c1569
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_image.c738
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_input.c274
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_keymap.c491
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_mwm.c104
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_netwm.c1604
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_pixmap.c128
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_private.h468
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_randr.c3807
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_region.c159
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_render.c225
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_screensaver.c370
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_selection.c1026
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_shape.c50
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_sync.c338
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_textlist.c509
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_vsync.c375
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_window.c2238
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_window_prop.c720
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c410
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_window_shape.c790
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c116
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_xfixes.c744
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_xinerama.c139
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_xtest.c215
-rw-r--r--src/lib/ecore_x/xlib/ecore_x.c2242
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_atoms.c109
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_composite.c176
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_cursor.c246
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_damage.c71
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_dnd.c706
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_dpms.c247
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_drawable.c118
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_e.c1670
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_error.c126
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_events.c2523
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_fixes.c365
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_gc.c171
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_gesture.c137
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_icccm.c1214
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_image.c626
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_mwm.c106
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_netwm.c2083
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_pixmap.c121
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_private.h379
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_randr.c103
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_randr.h7
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_randr_11.c334
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_randr_12.c2438
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c463
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_randr_13.c68
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_region.c158
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_screensaver.c204
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_selection.c1021
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_sync.c159
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_test.c167
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_vsync.c351
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_window.c1727
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_window_prop.c760
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_window_shape.c658
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_xi2.c336
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_xinerama.c91
80 files changed, 52231 insertions, 0 deletions
diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h
new file mode 100644
index 0000000000..b3fc0fabab
--- /dev/null
+++ b/src/lib/ecore_x/Ecore_X.h
@@ -0,0 +1,2407 @@
+#ifndef _ECORE_X_H
+#define _ECORE_X_H
+
+#include <Eina.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif // ifdef EAPI
+
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else // ifdef BUILDING_DLL
+# define EAPI __declspec(dllimport)
+# endif // ifdef BUILDING_DLL
+#else // ifdef _MSC_VER
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else // if __GNUC__ >= 4
+# define EAPI
+# endif // if __GNUC__ >= 4
+# else // ifdef __GNUC__
+# define EAPI
+# endif // ifdef __GNUC__
+#endif // ifdef _MSC_VER
+
+#include <sys/types.h>
+
+/**
+ * @file
+ * @brief Ecore functions for dealing with the X Windows System
+ *
+ * Ecore_X provides a wrapper and convenience functions for using the
+ * X Windows System. Function groups for this part of the library
+ * include the following:
+ * @li @ref Ecore_X_Init_Group
+ * @li @ref Ecore_X_Display_Attr_Group
+ * @li @ref Ecore_X_Flush_Group
+ */
+
+typedef unsigned int Ecore_X_ID;
+#ifndef _ECORE_X_WINDOW_PREDEF
+typedef Ecore_X_ID Ecore_X_Window;
+#endif // ifndef _ECORE_X_WINDOW_PREDEF
+typedef void *Ecore_X_Visual;
+typedef Ecore_X_ID Ecore_X_Pixmap;
+typedef Ecore_X_ID Ecore_X_Drawable;
+#ifdef HAVE_ECORE_X_XCB
+typedef Ecore_X_ID Ecore_X_GC;
+#else // ifdef HAVE_ECORE_X_XCB
+typedef void *Ecore_X_GC;
+#endif /* HAVE_ECORE_X_XCB */
+typedef Ecore_X_ID Ecore_X_Atom;
+typedef Ecore_X_ID Ecore_X_Colormap;
+typedef Ecore_X_ID Ecore_X_Time;
+typedef Ecore_X_ID Ecore_X_Cursor;
+typedef void Ecore_X_Display;
+typedef void Ecore_X_Connection;
+typedef void Ecore_X_Screen;
+typedef Ecore_X_ID Ecore_X_Sync_Counter;
+typedef Ecore_X_ID Ecore_X_Sync_Alarm;
+typedef void Ecore_X_XRegion;
+
+typedef Ecore_X_ID Ecore_X_Randr_Output;
+typedef Ecore_X_ID Ecore_X_Randr_Crtc;
+typedef Ecore_X_ID Ecore_X_Randr_Mode;
+typedef unsigned short Ecore_X_Randr_Size_ID;
+typedef int Ecore_X_Randr_Screen;
+
+typedef Ecore_X_ID Ecore_X_Device;
+
+#ifdef __cplusplus
+extern "C" {
+#endif // ifdef __cplusplus
+
+typedef struct _Ecore_X_Rectangle
+{
+ int x, y;
+ unsigned int width, height;
+} Ecore_X_Rectangle;
+
+typedef struct _Ecore_X_Icon
+{
+ unsigned int width, height;
+ unsigned int *data;
+} Ecore_X_Icon;
+
+typedef enum _Ecore_X_GC_Value_Mask
+{
+ ECORE_X_GC_VALUE_MASK_FUNCTION = (1L << 0),
+ ECORE_X_GC_VALUE_MASK_PLANE_MASK = (1L << 1),
+ ECORE_X_GC_VALUE_MASK_FOREGROUND = (1L << 2),
+ ECORE_X_GC_VALUE_MASK_BACKGROUND = (1L << 3),
+ ECORE_X_GC_VALUE_MASK_LINE_WIDTH = (1L << 4),
+ ECORE_X_GC_VALUE_MASK_LINE_STYLE = (1L << 5),
+ ECORE_X_GC_VALUE_MASK_CAP_STYLE = (1L << 6),
+ ECORE_X_GC_VALUE_MASK_JOIN_STYLE = (1L << 7),
+ ECORE_X_GC_VALUE_MASK_FILL_STYLE = (1L << 8),
+ ECORE_X_GC_VALUE_MASK_FILL_RULE = (1L << 9),
+ ECORE_X_GC_VALUE_MASK_TILE = (1L << 10),
+ ECORE_X_GC_VALUE_MASK_STIPPLE = (1L << 11),
+ ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_X = (1L << 12),
+ ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_Y = (1L << 13),
+ ECORE_X_GC_VALUE_MASK_FONT = (1L << 14),
+ ECORE_X_GC_VALUE_MASK_SUBWINDOW_MODE = (1L << 15),
+ ECORE_X_GC_VALUE_MASK_GRAPHICS_EXPOSURES = (1L << 16),
+ ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_X = (1L << 17),
+ ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_Y = (1L << 18),
+ ECORE_X_GC_VALUE_MASK_CLIP_MASK = (1L << 19),
+ ECORE_X_GC_VALUE_MASK_DASH_OFFSET = (1L << 20),
+ ECORE_X_GC_VALUE_MASK_DASH_LIST = (1L << 21),
+ ECORE_X_GC_VALUE_MASK_ARC_MODE = (1L << 22)
+} Ecore_X_GC_Value_Mask;
+
+typedef enum _Ecore_X_Composite_Update_Type
+{
+ ECORE_X_COMPOSITE_UPDATE_AUTOMATIC,
+ ECORE_X_COMPOSITE_UPDATE_MANUAL
+} Ecore_X_Composite_Update_Type;
+
+/**
+ * @typedef _Ecore_X_Window_State
+ * Defines the different states of the window of Ecore_X.
+ */
+typedef enum _Ecore_X_Window_State
+{
+ ECORE_X_WINDOW_STATE_UNKNOWN = 0,
+ ECORE_X_WINDOW_STATE_ICONIFIED, /** The window is iconified. */
+ ECORE_X_WINDOW_STATE_MODAL, /** The window is a modal dialog box. */
+ ECORE_X_WINDOW_STATE_STICKY, /** The window manager should keep the window's position fixed
+ * even if the virtual desktop scrolls. */
+ ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, /** The window has the maximum vertical size. */
+ ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, /** The window has the maximum horizontal size. */
+ ECORE_X_WINDOW_STATE_SHADED, /** The window is shaded. */
+ ECORE_X_WINDOW_STATE_SKIP_TASKBAR, /** The window should not be included in the taskbar. */
+ ECORE_X_WINDOW_STATE_SKIP_PAGER, /** The window should not be included in the pager. */
+ ECORE_X_WINDOW_STATE_HIDDEN, /** The window is invisible (i.e. minimized/iconified) */
+ ECORE_X_WINDOW_STATE_FULLSCREEN, /** The window should fill the entire screen and have no
+ * window border/decorations */
+ ECORE_X_WINDOW_STATE_ABOVE,
+ ECORE_X_WINDOW_STATE_BELOW,
+ ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION
+} Ecore_X_Window_State;
+
+typedef enum _Ecore_X_Window_State_Action
+{
+ ECORE_X_WINDOW_STATE_ACTION_REMOVE,
+ ECORE_X_WINDOW_STATE_ACTION_ADD,
+ ECORE_X_WINDOW_STATE_ACTION_TOGGLE
+} Ecore_X_Window_State_Action;
+
+typedef enum _Ecore_X_Window_Stack_Mode
+{
+ ECORE_X_WINDOW_STACK_ABOVE = 0,
+ ECORE_X_WINDOW_STACK_BELOW = 1,
+ ECORE_X_WINDOW_STACK_TOP_IF = 2,
+ ECORE_X_WINDOW_STACK_BOTTOM_IF = 3,
+ ECORE_X_WINDOW_STACK_OPPOSITE = 4
+} Ecore_X_Window_Stack_Mode;
+
+typedef enum _Ecore_X_Randr_Orientation
+{
+ ECORE_X_RANDR_ORIENTATION_ROT_0 = (1 << 0),
+ ECORE_X_RANDR_ORIENTATION_ROT_90 = (1 << 1),
+ ECORE_X_RANDR_ORIENTATION_ROT_180 = (1 << 2),
+ ECORE_X_RANDR_ORIENTATION_ROT_270 = (1 << 3),
+ ECORE_X_RANDR_ORIENTATION_FLIP_X = (1 << 4),
+ ECORE_X_RANDR_ORIENTATION_FLIP_Y = (1 << 5)
+} Ecore_X_Randr_Orientation;
+
+typedef enum _Ecore_X_Randr_Connection_Status
+{
+ ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED = 0,
+ ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED = 1,
+ ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN = 2
+} Ecore_X_Randr_Connection_Status;
+
+typedef enum _Ecore_X_Randr_Output_Policy
+{
+ ECORE_X_RANDR_OUTPUT_POLICY_ABOVE = 1,
+ ECORE_X_RANDR_OUTPUT_POLICY_RIGHT = 2,
+ ECORE_X_RANDR_OUTPUT_POLICY_BELOW = 3,
+ ECORE_X_RANDR_OUTPUT_POLICY_LEFT = 4,
+ ECORE_X_RANDR_OUTPUT_POLICY_CLONE = 5,
+ ECORE_X_RANDR_OUTPUT_POLICY_NONE = 6,
+ ECORE_X_RANDR_OUTPUT_POLICY_ASK = 7
+} Ecore_X_Randr_Output_Policy;
+
+typedef enum _Ecore_X_Randr_Relative_Alignment
+{
+ ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE = 0,
+ ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL = 1,
+ ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR = 2
+} Ecore_X_Randr_Relative_Alignment;
+
+typedef enum _Ecore_X_Render_Subpixel_Order
+{
+ ECORE_X_RENDER_SUBPIXEL_ORDER_UNKNOWN = 0,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_HORIZONTAL_RGB = 1,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_HORIZONTAL_BGR = 2,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_VERTICAL_RGB = 3,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_VERTICAL_BGR = 4,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_NONE = 5
+} Ecore_X_Render_Subpixel_Order;
+
+typedef enum _Ecore_X_Randr_Edid_Display_Interface_Type
+{
+ ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_UNDEFINED,
+ ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DVI,
+ ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_HDMI_A,
+ ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_HDMI_B,
+ ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_MDDI,
+ ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT
+} Ecore_X_Randr_Edid_Display_Interface_Type;
+
+typedef enum _Ecore_X_Randr_Edid_Display_Colorscheme
+{
+ ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_MONOCHROME_GRAYSCALE = 0x00,
+ ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB = 0x08,
+ ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_NON_RGB = 0x10,
+ ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_UNDEFINED = 0x18,
+ ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4 = 0x444000,
+ ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4 = 0x444,
+ ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2 = 0x422
+} Ecore_X_Randr_Edid_Display_Colorscheme;
+
+typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio
+{
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3 = 0x0,
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9 = 0x1,
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10 = 0x2,
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4 = 0x4,
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9 = 0x8
+} Ecore_X_Randr_Edid_Aspect_Ratio;
+
+#define ECORE_X_RANDR_EDID_UNKNOWN_VALUE -1
+
+#define ECORE_X_SELECTION_TARGET_TARGETS "TARGETS"
+#define ECORE_X_SELECTION_TARGET_TEXT "TEXT"
+#define ECORE_X_SELECTION_TARGET_COMPOUND_TEXT "COMPOUND_TEXT"
+#define ECORE_X_SELECTION_TARGET_STRING "STRING"
+#define ECORE_X_SELECTION_TARGET_UTF8_STRING "UTF8_STRING"
+#define ECORE_X_SELECTION_TARGET_FILENAME "FILENAME"
+
+#define ECORE_X_DND_VERSION 5
+
+typedef enum _Ecore_X_Selection
+{
+ ECORE_X_SELECTION_PRIMARY,
+ ECORE_X_SELECTION_SECONDARY,
+ ECORE_X_SELECTION_XDND,
+ ECORE_X_SELECTION_CLIPBOARD,
+ ECORE_X_SELECTION_OTHER
+} Ecore_X_Selection;
+
+typedef enum _Ecore_X_Event_Mode
+{
+ ECORE_X_EVENT_MODE_NORMAL,
+ ECORE_X_EVENT_MODE_WHILE_GRABBED,
+ ECORE_X_EVENT_MODE_GRAB,
+ ECORE_X_EVENT_MODE_UNGRAB
+} Ecore_X_Event_Mode;
+
+typedef enum _Ecore_X_Event_Detail
+{
+ ECORE_X_EVENT_DETAIL_ANCESTOR,
+ ECORE_X_EVENT_DETAIL_VIRTUAL,
+ ECORE_X_EVENT_DETAIL_INFERIOR,
+ ECORE_X_EVENT_DETAIL_NON_LINEAR,
+ ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL,
+ ECORE_X_EVENT_DETAIL_POINTER,
+ ECORE_X_EVENT_DETAIL_POINTER_ROOT,
+ ECORE_X_EVENT_DETAIL_DETAIL_NONE
+} Ecore_X_Event_Detail;
+
+typedef enum _Ecore_X_Event_Mask
+{
+ ECORE_X_EVENT_MASK_NONE = 0L,
+ ECORE_X_EVENT_MASK_KEY_DOWN = (1L << 0),
+ ECORE_X_EVENT_MASK_KEY_UP = (1L << 1),
+ ECORE_X_EVENT_MASK_MOUSE_DOWN = (1L << 2),
+ ECORE_X_EVENT_MASK_MOUSE_UP = (1L << 3),
+ ECORE_X_EVENT_MASK_MOUSE_IN = (1L << 4),
+ ECORE_X_EVENT_MASK_MOUSE_OUT = (1L << 5),
+ ECORE_X_EVENT_MASK_MOUSE_MOVE = (1L << 6),
+ ECORE_X_EVENT_MASK_WINDOW_DAMAGE = (1L << 15),
+ ECORE_X_EVENT_MASK_WINDOW_VISIBILITY = (1L << 16),
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE = (1L << 17),
+ ECORE_X_EVENT_MASK_WINDOW_RESIZE_MANAGE = (1L << 18),
+ ECORE_X_EVENT_MASK_WINDOW_MANAGE = (1L << 19),
+ ECORE_X_EVENT_MASK_WINDOW_CHILD_CONFIGURE = (1L << 20),
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE = (1L << 21),
+ ECORE_X_EVENT_MASK_WINDOW_PROPERTY = (1L << 22),
+ ECORE_X_EVENT_MASK_WINDOW_COLORMAP = (1L << 23),
+ ECORE_X_EVENT_MASK_WINDOW_GRAB = (1L << 24),
+ ECORE_X_EVENT_MASK_MOUSE_WHEEL = (1L << 29),
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_IN = (1L << 30),
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_OUT = (1L << 31)
+} Ecore_X_Event_Mask;
+
+typedef enum _Ecore_X_Gravity
+{
+ ECORE_X_GRAVITY_FORGET = 0,
+ ECORE_X_GRAVITY_UNMAP = 0,
+ ECORE_X_GRAVITY_NW = 1,
+ ECORE_X_GRAVITY_N = 2,
+ ECORE_X_GRAVITY_NE = 3,
+ ECORE_X_GRAVITY_W = 4,
+ ECORE_X_GRAVITY_CENTER = 5,
+ ECORE_X_GRAVITY_E = 6,
+ ECORE_X_GRAVITY_SW = 7,
+ ECORE_X_GRAVITY_S = 8,
+ ECORE_X_GRAVITY_SE = 9,
+ ECORE_X_GRAVITY_STATIC = 10
+} Ecore_X_Gravity;
+
+/* Needed for ecore_x_region_window_shape_set */
+typedef enum _Ecore_X_Shape_Type
+{
+ ECORE_X_SHAPE_BOUNDING,
+ ECORE_X_SHAPE_CLIP,
+ ECORE_X_SHAPE_INPUT
+} Ecore_X_Shape_Type;
+
+typedef enum _Ecore_X_Mapping_Type
+{
+ ECORE_X_MAPPING_MODIFIER,
+ ECORE_X_MAPPING_KEYBOARD,
+ ECORE_X_MAPPING_MOUSE
+} Ecore_X_Mapping_Type;
+
+typedef enum _Ecore_X_Randr_Property_Change
+{
+ ECORE_X_RANDR_PROPERTY_CHANGE_ADD,
+ ECORE_X_RANDR_PROPERTY_CHANGE_DEL
+} Ecore_X_Randr_Property_Change;
+
+typedef enum _Ecore_X_Netwm_Direction
+{
+ ECORE_X_NETWM_DIRECTION_SIZE_TL = 0,
+ ECORE_X_NETWM_DIRECTION_SIZE_T = 1,
+ ECORE_X_NETWM_DIRECTION_SIZE_TR = 2,
+ ECORE_X_NETWM_DIRECTION_SIZE_R = 3,
+ ECORE_X_NETWM_DIRECTION_SIZE_BR = 4,
+ ECORE_X_NETWM_DIRECTION_SIZE_B = 5,
+ ECORE_X_NETWM_DIRECTION_SIZE_BL = 6,
+ ECORE_X_NETWM_DIRECTION_SIZE_L = 7,
+ ECORE_X_NETWM_DIRECTION_MOVE = 8,
+ ECORE_X_NETWM_DIRECTION_CANCEL = 11,
+} Ecore_X_Netwm_Direction;
+
+/**
+ * @typedef _Ecore_X_Error_Code
+ * Defines the error codes of Ecore_X which wraps the X Window Systems
+ * protocol's errors.
+ *
+ * @since 1.7.0
+ */
+typedef enum _Ecore_X_Error_Code
+{
+ /** Everything is okay. */
+ ECORE_X_ERROR_CODE_SUCCESS = 0, /** Bad request code */
+ ECORE_X_ERROR_CODE_BAD_REQUEST = 1, /** Int parameter out of range */
+ ECORE_X_ERROR_CODE_BAD_VALUE = 2, /** Parameter not a Window */
+ ECORE_X_ERROR_CODE_BAD_WINDOW = 3, /** Parameter not a Pixmap */
+ ECORE_X_ERROR_CODE_BAD_PIXMAP = 4, /** Parameter not an Atom */
+ ECORE_X_ERROR_CODE_BAD_ATOM = 5, /** Parameter not a Cursor */
+ ECORE_X_ERROR_CODE_BAD_CURSOR = 6, /** Parameter not a Font */
+ ECORE_X_ERROR_CODE_BAD_FONT = 7, /** Parameter mismatch */
+ ECORE_X_ERROR_CODE_BAD_MATCH = 8, /** Parameter not a Pixmap or Window */
+ ECORE_X_ERROR_CODE_BAD_DRAWABLE = 9, /** Bad access */
+ ECORE_X_ERROR_CODE_BAD_ACCESS = 10, /** Insufficient resources */
+ ECORE_X_ERROR_CODE_BAD_ALLOC = 11, /** No such colormap */
+ ECORE_X_ERROR_CODE_BAD_COLOR = 12, /** Parameter not a GC */
+ ECORE_X_ERROR_CODE_BAD_GC = 13, /** Choice not in range or already used */
+ ECORE_X_ERROR_CODE_BAD_ID_CHOICE = 14, /** Font or color name doesn't exist */
+ ECORE_X_ERROR_CODE_BAD_NAME = 15, /** Request length incorrect */
+ ECORE_X_ERROR_CODE_BAD_LENGTH = 16, /** Server is defective */
+ ECORE_X_ERROR_CODE_BAD_IMPLEMENTATION = 17,
+} Ecore_X_Error_Code;
+
+typedef struct _Ecore_X_Event_Mouse_In Ecore_X_Event_Mouse_In;
+typedef struct _Ecore_X_Event_Mouse_Out Ecore_X_Event_Mouse_Out;
+typedef struct _Ecore_X_Event_Window_Focus_In Ecore_X_Event_Window_Focus_In;
+typedef struct _Ecore_X_Event_Window_Focus_Out Ecore_X_Event_Window_Focus_Out;
+typedef struct _Ecore_X_Event_Window_Keymap Ecore_X_Event_Window_Keymap;
+typedef struct _Ecore_X_Event_Window_Damage Ecore_X_Event_Window_Damage;
+typedef struct _Ecore_X_Event_Window_Visibility_Change Ecore_X_Event_Window_Visibility_Change;
+typedef struct _Ecore_X_Event_Window_Create Ecore_X_Event_Window_Create;
+typedef struct _Ecore_X_Event_Window_Destroy Ecore_X_Event_Window_Destroy;
+typedef struct _Ecore_X_Event_Window_Hide Ecore_X_Event_Window_Hide;
+typedef struct _Ecore_X_Event_Window_Show Ecore_X_Event_Window_Show;
+typedef struct _Ecore_X_Event_Window_Show_Request Ecore_X_Event_Window_Show_Request;
+typedef struct _Ecore_X_Event_Window_Reparent Ecore_X_Event_Window_Reparent;
+typedef struct _Ecore_X_Event_Window_Configure Ecore_X_Event_Window_Configure;
+typedef struct _Ecore_X_Event_Window_Configure_Request Ecore_X_Event_Window_Configure_Request;
+typedef struct _Ecore_X_Event_Window_Gravity Ecore_X_Event_Window_Gravity;
+typedef struct _Ecore_X_Event_Window_Resize_Request Ecore_X_Event_Window_Resize_Request;
+typedef struct _Ecore_X_Event_Window_Stack Ecore_X_Event_Window_Stack;
+typedef struct _Ecore_X_Event_Window_Stack_Request Ecore_X_Event_Window_Stack_Request;
+typedef struct _Ecore_X_Event_Window_Property Ecore_X_Event_Window_Property;
+typedef struct _Ecore_X_Event_Window_Colormap Ecore_X_Event_Window_Colormap;
+typedef struct _Ecore_X_Event_Mapping_Change Ecore_X_Event_Mapping_Change;
+typedef struct _Ecore_X_Event_Window_Mapping Ecore_X_Event_Window_Mapping;
+typedef struct _Ecore_X_Event_Selection_Clear Ecore_X_Event_Selection_Clear;
+typedef struct _Ecore_X_Event_Selection_Request Ecore_X_Event_Selection_Request;
+typedef struct _Ecore_X_Event_Selection_Notify Ecore_X_Event_Selection_Notify;
+typedef struct _Ecore_X_Event_Fixes_Selection_Notify Ecore_X_Event_Fixes_Selection_Notify;
+typedef struct _Ecore_X_Selection_Data Ecore_X_Selection_Data;
+typedef struct _Ecore_X_Selection_Data_Files Ecore_X_Selection_Data_Files;
+typedef struct _Ecore_X_Selection_Data_Text Ecore_X_Selection_Data_Text;
+typedef struct _Ecore_X_Selection_Data_Targets Ecore_X_Selection_Data_Targets;
+typedef struct _Ecore_X_Event_Xdnd_Enter Ecore_X_Event_Xdnd_Enter;
+typedef struct _Ecore_X_Event_Xdnd_Position Ecore_X_Event_Xdnd_Position;
+typedef struct _Ecore_X_Event_Xdnd_Status Ecore_X_Event_Xdnd_Status;
+typedef struct _Ecore_X_Event_Xdnd_Leave Ecore_X_Event_Xdnd_Leave;
+typedef struct _Ecore_X_Event_Xdnd_Drop Ecore_X_Event_Xdnd_Drop;
+typedef struct _Ecore_X_Event_Xdnd_Finished Ecore_X_Event_Xdnd_Finished;
+typedef struct _Ecore_X_Event_Client_Message Ecore_X_Event_Client_Message;
+typedef struct _Ecore_X_Event_Window_Shape Ecore_X_Event_Window_Shape;
+typedef struct _Ecore_X_Event_Screensaver_Notify Ecore_X_Event_Screensaver_Notify;
+typedef struct _Ecore_X_Event_Gesture_Notify_Flick Ecore_X_Event_Gesture_Notify_Flick;
+typedef struct _Ecore_X_Event_Gesture_Notify_Pan Ecore_X_Event_Gesture_Notify_Pan;
+typedef struct _Ecore_X_Event_Gesture_Notify_PinchRotation Ecore_X_Event_Gesture_Notify_PinchRotation;
+typedef struct _Ecore_X_Event_Gesture_Notify_Tap Ecore_X_Event_Gesture_Notify_Tap;
+typedef struct _Ecore_X_Event_Gesture_Notify_TapNHold Ecore_X_Event_Gesture_Notify_TapNHold;
+typedef struct _Ecore_X_Event_Gesture_Notify_Hold Ecore_X_Event_Gesture_Notify_Hold;
+typedef struct _Ecore_X_Event_Gesture_Notify_Group Ecore_X_Event_Gesture_Notify_Group;
+typedef struct _Ecore_X_Event_Sync_Counter Ecore_X_Event_Sync_Counter;
+typedef struct _Ecore_X_Event_Sync_Alarm Ecore_X_Event_Sync_Alarm;
+typedef struct _Ecore_X_Event_Screen_Change Ecore_X_Event_Screen_Change;
+typedef struct _Ecore_X_Event_Randr_Crtc_Change Ecore_X_Event_Randr_Crtc_Change;
+typedef struct _Ecore_X_Event_Randr_Output_Change Ecore_X_Event_Randr_Output_Change;
+typedef struct _Ecore_X_Event_Randr_Output_Property_Notify Ecore_X_Event_Randr_Output_Property_Notify;
+
+typedef struct _Ecore_X_Event_Window_Delete_Request Ecore_X_Event_Window_Delete_Request;
+typedef struct _Ecore_X_Event_Window_Move_Resize_Request Ecore_X_Event_Window_Move_Resize_Request;
+typedef struct _Ecore_X_Event_Window_State_Request Ecore_X_Event_Window_State_Request;
+typedef struct _Ecore_X_Event_Frame_Extents_Request Ecore_X_Event_Frame_Extents_Request;
+typedef struct _Ecore_X_Event_Ping Ecore_X_Event_Ping;
+typedef struct _Ecore_X_Event_Desktop_Change Ecore_X_Event_Desktop_Change;
+
+typedef struct _Ecore_X_Event_Startup_Sequence Ecore_X_Event_Startup_Sequence;
+
+typedef struct _Ecore_X_Event_Generic Ecore_X_Event_Generic;
+
+typedef struct _Ecore_X_Randr_Screen_Size Ecore_X_Randr_Screen_Size;
+typedef struct _Ecore_X_Randr_Screen_Size_MM Ecore_X_Randr_Screen_Size_MM;
+
+typedef struct _Ecore_X_Xdnd_Position Ecore_X_Xdnd_Position;
+
+struct _Ecore_X_Event_Mouse_In
+{
+ int modifiers;
+ int x, y;
+ Eina_Bool same_screen : 1;
+ struct
+ {
+ int x, y;
+ } root;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window root_win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Mouse_Out
+{
+ int modifiers;
+ int x, y;
+ int same_screen;
+ struct
+ {
+ int x, y;
+ } root;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window root_win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Focus_In
+{
+ Ecore_X_Window win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Focus_Out
+{
+ Ecore_X_Window win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Keymap
+{
+ Ecore_X_Window win;
+};
+
+struct _Ecore_X_Event_Window_Damage
+{
+ Ecore_X_Window win;
+ int x, y, w, h;
+ int count;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Visibility_Change
+{
+ Ecore_X_Window win;
+ int fully_obscured;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Create
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent;
+ int override;
+ int x, y, w, h;
+ int border;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Destroy
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Hide
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Show
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Show_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Reparent
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window parent;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Configure
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window abovewin;
+ int x, y, w, h;
+ int border;
+ Eina_Bool override : 1;
+ Eina_Bool from_wm : 1;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Configure_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent_win;
+ Ecore_X_Window abovewin;
+ int x, y, w, h;
+ int border;
+ Ecore_X_Window_Stack_Mode detail;
+ unsigned long value_mask;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Gravity
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Resize_Request
+{
+ Ecore_X_Window win;
+ int w, h;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Stack
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window_Stack_Mode detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Stack_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent;
+ Ecore_X_Window_Stack_Mode detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Property
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom atom;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Colormap
+{
+ Ecore_X_Window win;
+ Ecore_X_Colormap cmap;
+ Eina_Bool installed : 1;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Mapping_Change
+{
+ Ecore_X_Mapping_Type type;
+ int keycode;
+ int num;
+};
+
+struct _Ecore_X_Event_Selection_Clear
+{
+ Ecore_X_Window win;
+ Ecore_X_Selection selection;
+ Ecore_X_Atom atom;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Selection_Request
+{
+ Ecore_X_Window owner;
+ Ecore_X_Window requestor;
+ Ecore_X_Time time;
+ Ecore_X_Atom selection;
+ Ecore_X_Atom target;
+ Ecore_X_Atom property;
+};
+
+typedef enum
+{
+ ECORE_X_OWNER_CHANGE_REASON_NEW_OWNER,
+ ECORE_X_OWNER_CHANGE_REASON_DESTROY,
+ ECORE_X_OWNER_CHANGE_REASON_CLOSE
+} Ecore_X_Owner_Change_Reason;
+
+struct _Ecore_X_Event_Fixes_Selection_Notify
+{
+ Ecore_X_Window win;
+ Ecore_X_Window owner;
+ Ecore_X_Time time;
+ Ecore_X_Time selection_time;
+ Ecore_X_Selection selection;
+ Ecore_X_Atom atom;
+ Ecore_X_Owner_Change_Reason reason;
+};
+
+struct _Ecore_X_Event_Selection_Notify
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Selection selection;
+ Ecore_X_Atom atom;
+ char *target;
+ void *data;
+};
+
+struct _Ecore_X_Selection_Data
+{
+ enum
+ {
+ ECORE_X_SELECTION_CONTENT_NONE,
+ ECORE_X_SELECTION_CONTENT_TEXT,
+ ECORE_X_SELECTION_CONTENT_FILES,
+ ECORE_X_SELECTION_CONTENT_TARGETS,
+ ECORE_X_SELECTION_CONTENT_CUSTOM
+ } content;
+ unsigned char *data;
+ int length;
+ int format;
+ int (*free)(void *data);
+};
+
+struct _Ecore_X_Selection_Data_Files
+{
+ Ecore_X_Selection_Data data;
+ char **files;
+ int num_files;
+};
+
+struct _Ecore_X_Selection_Data_Text
+{
+ Ecore_X_Selection_Data data;
+ char *text;
+};
+
+struct _Ecore_X_Selection_Data_Targets
+{
+ Ecore_X_Selection_Data data;
+ char **targets;
+ int num_targets;
+};
+
+struct _Ecore_X_Event_Xdnd_Enter
+{
+ Ecore_X_Window win, source;
+
+ char **types;
+ int num_types;
+};
+
+struct _Ecore_X_Event_Xdnd_Position
+{
+ Ecore_X_Window win, source;
+ struct
+ {
+ int x, y;
+ } position;
+ Ecore_X_Atom action;
+};
+
+struct _Ecore_X_Xdnd_Position
+{
+ Ecore_X_Window win, prev;
+ struct
+ {
+ int x, y;
+ } position;
+};
+
+struct _Ecore_X_Event_Xdnd_Status
+{
+ Ecore_X_Window win, target;
+ Eina_Bool will_accept : 1;
+ Ecore_X_Rectangle rectangle;
+ Ecore_X_Atom action;
+};
+
+struct _Ecore_X_Event_Xdnd_Leave
+{
+ Ecore_X_Window win, source;
+};
+
+struct _Ecore_X_Event_Xdnd_Drop
+{
+ Ecore_X_Window win, source;
+ Ecore_X_Atom action;
+ struct
+ {
+ int x, y;
+ } position;
+};
+
+struct _Ecore_X_Event_Xdnd_Finished
+{
+ Ecore_X_Window win, target;
+ Eina_Bool completed : 1;
+ Ecore_X_Atom action;
+};
+
+struct _Ecore_X_Event_Client_Message
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom message_type;
+ int format;
+ union
+ {
+ char b[20];
+ short s[10];
+ long l[5];
+ } data;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Shape
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Shape_Type type;
+ int x, y, w, h;
+ Eina_Bool shaped : 1;
+};
+
+struct _Ecore_X_Event_Screensaver_Notify
+{
+ Ecore_X_Window win;
+ Eina_Bool on : 1;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Sync_Counter
+{
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Sync_Alarm
+{
+ Ecore_X_Time time;
+ Ecore_X_Sync_Alarm alarm;
+};
+
+struct _Ecore_X_Randr_Screen_Size
+{
+ int width, height;
+};
+
+struct _Ecore_X_Randr_Screen_Size_MM
+{
+ int width, height, width_mm, height_mm;
+};
+
+struct _Ecore_X_Event_Screen_Change
+{
+ Ecore_X_Window win;
+ Ecore_X_Window root;
+ Ecore_X_Randr_Screen_Size_MM size; /* in pixel and millimeters */
+ Ecore_X_Time time;
+ Ecore_X_Time config_time;
+ Ecore_X_Randr_Orientation orientation;
+ Ecore_X_Render_Subpixel_Order subpixel_order;
+ Ecore_X_Randr_Size_ID size_id;
+};
+
+struct _Ecore_X_Event_Randr_Crtc_Change
+{
+ Ecore_X_Window win;
+ Ecore_X_Randr_Crtc crtc;
+ Ecore_X_Randr_Mode mode;
+ Ecore_X_Randr_Orientation orientation;
+ Eina_Rectangle geo;
+};
+
+struct _Ecore_X_Event_Randr_Output_Change
+{
+ Ecore_X_Window win;
+ Ecore_X_Randr_Output output;
+ Ecore_X_Randr_Crtc crtc;
+ Ecore_X_Randr_Mode mode;
+ Ecore_X_Randr_Orientation orientation;
+ Ecore_X_Randr_Connection_Status connection;
+ Ecore_X_Render_Subpixel_Order subpixel_order;
+};
+
+struct _Ecore_X_Event_Randr_Output_Property_Notify
+{
+ Ecore_X_Window win;
+ Ecore_X_Randr_Output output;
+ Ecore_X_Atom property;
+ Ecore_X_Time time;
+ Ecore_X_Randr_Property_Change state;
+};
+
+struct _Ecore_X_Event_Window_Delete_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Title_Change
+{
+ Ecore_X_Window win;
+ char *title;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Visible_Title_Change
+{
+ Ecore_X_Window win;
+ char *title;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Icon_Name_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Client_Machine_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Name_Class_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ char *clas;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Pid_Change
+{
+ Ecore_X_Window win;
+ pid_t pid;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Desktop_Change
+{
+ Ecore_X_Window win;
+ long desktop;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Startup_Sequence
+{
+ Ecore_X_Window win;
+};
+
+struct _Ecore_X_Event_Window_Move_Resize_Request
+{
+ Ecore_X_Window win;
+ int x, y;
+ int direction;
+ int button;
+ int source;
+};
+
+struct _Ecore_X_Event_Window_State_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window_State_Action action;
+ Ecore_X_Window_State state[2];
+ int source;
+};
+
+struct _Ecore_X_Event_Frame_Extents_Request
+{
+ Ecore_X_Window win;
+};
+
+struct _Ecore_X_Event_Ping
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Desktop_Change
+{
+ Ecore_X_Window win;
+ unsigned int desk;
+ int source;
+};
+
+struct _Ecore_X_Event_Generic
+{
+ int extension;
+ int evtype;
+ unsigned int cookie;
+ void *data;
+};
+
+EAPI extern int ECORE_X_EVENT_ANY; /**< low level event dependent on
+ backend in use, if Xlib will be XEvent, if XCB will be xcb_generic_event_t.
+ @warning avoid using it.
+ */
+EAPI extern int ECORE_X_EVENT_MOUSE_IN;
+EAPI extern int ECORE_X_EVENT_MOUSE_OUT;
+EAPI extern int ECORE_X_EVENT_WINDOW_FOCUS_IN;
+EAPI extern int ECORE_X_EVENT_WINDOW_FOCUS_OUT;
+EAPI extern int ECORE_X_EVENT_WINDOW_KEYMAP;
+EAPI extern int ECORE_X_EVENT_WINDOW_DAMAGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_CREATE;
+EAPI extern int ECORE_X_EVENT_WINDOW_DESTROY;
+EAPI extern int ECORE_X_EVENT_WINDOW_HIDE;
+EAPI extern int ECORE_X_EVENT_WINDOW_SHOW;
+EAPI extern int ECORE_X_EVENT_WINDOW_SHOW_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_REPARENT;
+EAPI extern int ECORE_X_EVENT_WINDOW_CONFIGURE;
+EAPI extern int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_GRAVITY;
+EAPI extern int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_STACK;
+EAPI extern int ECORE_X_EVENT_WINDOW_STACK_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_PROPERTY;
+EAPI extern int ECORE_X_EVENT_WINDOW_COLORMAP;
+EAPI extern int ECORE_X_EVENT_WINDOW_MAPPING;
+EAPI extern int ECORE_X_EVENT_MAPPING_CHANGE;
+EAPI extern int ECORE_X_EVENT_SELECTION_CLEAR;
+EAPI extern int ECORE_X_EVENT_SELECTION_REQUEST;
+EAPI extern int ECORE_X_EVENT_SELECTION_NOTIFY;
+EAPI extern int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY;
+EAPI extern int ECORE_X_EVENT_CLIENT_MESSAGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_SHAPE;
+EAPI extern int ECORE_X_EVENT_SCREENSAVER_NOTIFY;
+EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_FLICK;
+EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_PAN;
+EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION;
+EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_TAP;
+EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD;
+EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD;
+EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP;
+EAPI extern int ECORE_X_EVENT_SYNC_COUNTER;
+EAPI extern int ECORE_X_EVENT_SYNC_ALARM;
+EAPI extern int ECORE_X_EVENT_SCREEN_CHANGE;
+EAPI extern int ECORE_X_EVENT_RANDR_CRTC_CHANGE;
+EAPI extern int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE;
+EAPI extern int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY;
+EAPI extern int ECORE_X_EVENT_DAMAGE_NOTIFY;
+
+EAPI extern int ECORE_X_EVENT_WINDOW_DELETE_REQUEST;
+
+EAPI extern int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_STATE_REQUEST;
+EAPI extern int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST;
+EAPI extern int ECORE_X_EVENT_PING;
+EAPI extern int ECORE_X_EVENT_DESKTOP_CHANGE;
+
+EAPI extern int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW;
+EAPI extern int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
+EAPI extern int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE;
+EAPI extern int ECORE_X_EVENT_XKB_STATE_NOTIFY; /** @since 1.7 */
+EAPI extern int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY; /** @since 1.7 */
+
+EAPI extern int ECORE_X_EVENT_GENERIC;
+
+EAPI extern int ECORE_X_EVENT_XDND_ENTER;
+EAPI extern int ECORE_X_EVENT_XDND_POSITION;
+EAPI extern int ECORE_X_EVENT_XDND_STATUS;
+EAPI extern int ECORE_X_EVENT_XDND_LEAVE;
+EAPI extern int ECORE_X_EVENT_XDND_DROP;
+EAPI extern int ECORE_X_EVENT_XDND_FINISHED;
+
+EAPI extern int ECORE_X_MODIFIER_SHIFT; /**< @since 1.7 */
+EAPI extern int ECORE_X_MODIFIER_CTRL; /**< @since 1.7 */
+EAPI extern int ECORE_X_MODIFIER_ALT; /**< @since 1.7 */
+EAPI extern int ECORE_X_MODIFIER_WIN; /**< @since 1.7 */
+EAPI extern int ECORE_X_MODIFIER_ALTGR; /**< @since 1.7 */
+
+EAPI extern int ECORE_X_LOCK_SCROLL;
+EAPI extern int ECORE_X_LOCK_NUM;
+EAPI extern int ECORE_X_LOCK_CAPS;
+EAPI extern int ECORE_X_LOCK_SHIFT;
+
+EAPI extern int ECORE_X_RAW_BUTTON_PRESS; /**< @since 1.8 */
+EAPI extern int ECORE_X_RAW_BUTTON_RELEASE; /**< @since 1.8 */
+EAPI extern int ECORE_X_RAW_MOTION; /**< @since 1.8 */
+
+typedef enum _Ecore_X_WM_Protocol
+{
+ /** If enabled the window manager will be asked to send a
+ * delete message instead of just closing (destroying) the window. */
+ ECORE_X_WM_PROTOCOL_DELETE_REQUEST,
+
+ /** If enabled the window manager will be told that the window
+ * explicitly sets input focus. */
+ ECORE_X_WM_PROTOCOL_TAKE_FOCUS,
+
+ /** If enabled the window manager can ping the window to check
+ * if it is alive. */
+ ECORE_X_NET_WM_PROTOCOL_PING,
+
+ /** If enabled the window manager can sync updating with the
+ * window (?) */
+ ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST,
+
+ /** Number of defined items */
+ ECORE_X_WM_PROTOCOL_NUM
+} Ecore_X_WM_Protocol;
+
+typedef enum _Ecore_X_Window_Input_Mode
+{
+ /** The window can never be focused */
+ ECORE_X_WINDOW_INPUT_MODE_NONE,
+
+ /** The window can be focused by the WM but doesn't focus itself */
+ ECORE_X_WINDOW_INPUT_MODE_PASSIVE,
+
+ /** The window sets the focus itself if one of its sub-windows
+ * already is focused */
+ ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL,
+
+ /** The window sets the focus itself even if another window
+ * is currently focused */
+ ECORE_X_WINDOW_INPUT_MODE_ACTIVE_GLOBAL
+} Ecore_X_Window_Input_Mode;
+
+/**
+ * @typedef _Ecore_X_Window_State_Hint
+ * Defines the different state hint of the window of Ecore_X.
+ */
+typedef enum _Ecore_X_Window_State_Hint
+{
+ /** Do not provide any state hint to the window manager */
+ ECORE_X_WINDOW_STATE_HINT_NONE = -1,
+
+ /** The window wants to remain hidden and NOT iconified */
+ ECORE_X_WINDOW_STATE_HINT_WITHDRAWN,
+
+ /** The window wants to be mapped normally */
+ ECORE_X_WINDOW_STATE_HINT_NORMAL,
+
+ /** The window wants to start in an iconified state */
+ ECORE_X_WINDOW_STATE_HINT_ICONIC
+} Ecore_X_Window_State_Hint;
+
+typedef enum _Ecore_X_Window_Type
+{
+ ECORE_X_WINDOW_TYPE_UNKNOWN = 0,
+ ECORE_X_WINDOW_TYPE_DESKTOP,
+ ECORE_X_WINDOW_TYPE_DOCK,
+ ECORE_X_WINDOW_TYPE_TOOLBAR,
+ ECORE_X_WINDOW_TYPE_MENU,
+ ECORE_X_WINDOW_TYPE_UTILITY,
+ ECORE_X_WINDOW_TYPE_SPLASH,
+ ECORE_X_WINDOW_TYPE_DIALOG,
+ ECORE_X_WINDOW_TYPE_NORMAL,
+ ECORE_X_WINDOW_TYPE_DROPDOWN_MENU,
+ ECORE_X_WINDOW_TYPE_POPUP_MENU,
+ ECORE_X_WINDOW_TYPE_TOOLTIP,
+ ECORE_X_WINDOW_TYPE_NOTIFICATION,
+ ECORE_X_WINDOW_TYPE_COMBO,
+ ECORE_X_WINDOW_TYPE_DND
+} Ecore_X_Window_Type;
+
+typedef enum _Ecore_X_Action
+{
+ ECORE_X_ACTION_MOVE,
+ ECORE_X_ACTION_RESIZE,
+ ECORE_X_ACTION_MINIMIZE,
+ ECORE_X_ACTION_SHADE,
+ ECORE_X_ACTION_STICK,
+ ECORE_X_ACTION_MAXIMIZE_HORZ,
+ ECORE_X_ACTION_MAXIMIZE_VERT,
+ ECORE_X_ACTION_FULLSCREEN,
+ ECORE_X_ACTION_CHANGE_DESKTOP,
+ ECORE_X_ACTION_CLOSE,
+ ECORE_X_ACTION_ABOVE,
+ ECORE_X_ACTION_BELOW
+} Ecore_X_Action;
+
+typedef enum _Ecore_X_Window_Configure_Mask
+{
+ ECORE_X_WINDOW_CONFIGURE_MASK_X = (1 << 0),
+ ECORE_X_WINDOW_CONFIGURE_MASK_Y = (1 << 1),
+ ECORE_X_WINDOW_CONFIGURE_MASK_W = (1 << 2),
+ ECORE_X_WINDOW_CONFIGURE_MASK_H = (1 << 3),
+ ECORE_X_WINDOW_CONFIGURE_MASK_BORDER_WIDTH = (1 << 4),
+ ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING = (1 << 5),
+ ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE = (1 << 6)
+} Ecore_X_Window_Configure_Mask;
+
+typedef enum _Ecore_X_Virtual_Keyboard_State
+{
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN = 0,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_ON,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_IP,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_HOST,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_FILE,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_URL,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_KEYPAD,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_J2ME
+} Ecore_X_Virtual_Keyboard_State;
+
+typedef enum _Ecore_X_Illume_Mode
+{
+ ECORE_X_ILLUME_MODE_UNKNOWN = 0,
+ ECORE_X_ILLUME_MODE_SINGLE,
+ ECORE_X_ILLUME_MODE_DUAL_TOP,
+ ECORE_X_ILLUME_MODE_DUAL_LEFT
+} Ecore_X_Illume_Mode;
+
+typedef enum _Ecore_X_Illume_Quickpanel_State
+{
+ ECORE_X_ILLUME_QUICKPANEL_STATE_UNKNOWN = 0,
+ ECORE_X_ILLUME_QUICKPANEL_STATE_OFF,
+ ECORE_X_ILLUME_QUICKPANEL_STATE_ON
+} Ecore_X_Illume_Quickpanel_State;
+
+typedef enum _Ecore_X_Illume_Indicator_State
+{
+ ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN = 0,
+ ECORE_X_ILLUME_INDICATOR_STATE_OFF,
+ ECORE_X_ILLUME_INDICATOR_STATE_ON
+} Ecore_X_Illume_Indicator_State;
+
+typedef enum _Ecore_X_Illume_Clipboard_State
+{
+ ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN = 0,
+ ECORE_X_ILLUME_CLIPBOARD_STATE_OFF,
+ ECORE_X_ILLUME_CLIPBOARD_STATE_ON
+} Ecore_X_Illume_Clipboard_State;
+
+typedef enum _Ecore_X_Illume_Indicator_Opacity_Mode
+{
+ ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN = 0,
+ ECORE_X_ILLUME_INDICATOR_OPAQUE,
+ ECORE_X_ILLUME_INDICATOR_TRANSLUCENT,
+ ECORE_X_ILLUME_INDICATOR_TRANSPARENT
+} Ecore_X_Illume_Indicator_Opacity_Mode;
+
+typedef enum _Ecore_X_Illume_Window_State
+{
+ ECORE_X_ILLUME_WINDOW_STATE_NORMAL = 0,
+ ECORE_X_ILLUME_WINDOW_STATE_FLOATING
+} Ecore_X_Illume_Window_State;
+
+/* Window layer constants */
+#define ECORE_X_WINDOW_LAYER_BELOW 2
+#define ECORE_X_WINDOW_LAYER_NORMAL 4
+#define ECORE_X_WINDOW_LAYER_ABOVE 6
+
+/* Property list operations */
+#define ECORE_X_PROP_LIST_REMOVE 0
+#define ECORE_X_PROP_LIST_ADD 1
+#define ECORE_X_PROP_LIST_TOGGLE 2
+
+EAPI int ecore_x_init(const char *name);
+EAPI int ecore_x_shutdown(void);
+EAPI int ecore_x_disconnect(void);
+EAPI Ecore_X_Display *ecore_x_display_get(void);
+EAPI Ecore_X_Connection *ecore_x_connection_get(void);
+EAPI int ecore_x_fd_get(void);
+EAPI Ecore_X_Screen *ecore_x_default_screen_get(void);
+EAPI void ecore_x_screen_size_get(const Ecore_X_Screen *screen, int *w, int *h);
+EAPI int ecore_x_screen_count_get(void);
+EAPI int ecore_x_screen_index_get(const Ecore_X_Screen *screen);
+EAPI Ecore_X_Screen *ecore_x_screen_get(int index);
+
+EAPI void ecore_x_double_click_time_set(double t);
+EAPI double ecore_x_double_click_time_get(void);
+EAPI void ecore_x_flush(void);
+EAPI void ecore_x_sync(void);
+EAPI void ecore_x_killall(Ecore_X_Window root);
+EAPI void ecore_x_kill(Ecore_X_Window win);
+EAPI int ecore_x_dpi_get(void);
+EAPI Eina_Bool ecore_x_bell(int percent);
+EAPI unsigned int ecore_x_visual_id_get(Ecore_X_Visual visual);
+
+EAPI Ecore_X_Visual ecore_x_default_visual_get(Ecore_X_Display *disp, Ecore_X_Screen *screen);
+EAPI Ecore_X_Colormap ecore_x_default_colormap_get(Ecore_X_Display *disp, Ecore_X_Screen *screen);
+EAPI int ecore_x_default_depth_get(Ecore_X_Display *disp, Ecore_X_Screen *screen);
+
+EAPI Ecore_X_Time ecore_x_current_time_get(void);
+
+EAPI void ecore_x_error_handler_set(void (*func)(void *data), const void *data);
+EAPI void ecore_x_io_error_handler_set(void (*func)(void *data), const void *data);
+EAPI int ecore_x_error_request_get(void);
+EAPI int ecore_x_error_code_get(void);
+EAPI Ecore_X_ID ecore_x_error_resource_id_get(void);
+
+EAPI void ecore_x_event_mask_set(Ecore_X_Window w, Ecore_X_Event_Mask mask);
+EAPI void ecore_x_event_mask_unset(Ecore_X_Window w, Ecore_X_Event_Mask mask);
+
+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);
+EAPI Eina_Bool ecore_x_selection_primary_set(Ecore_X_Window w, const void *data, int size);
+EAPI Eina_Bool ecore_x_selection_primary_clear(void);
+EAPI Eina_Bool ecore_x_selection_secondary_set(Ecore_X_Window w, const void *data, int size);
+EAPI Eina_Bool ecore_x_selection_secondary_clear(void);
+EAPI Eina_Bool ecore_x_selection_xdnd_set(Ecore_X_Window w, const void *data, int size);
+EAPI Eina_Bool ecore_x_selection_xdnd_clear(void);
+EAPI Eina_Bool ecore_x_selection_clipboard_set(Ecore_X_Window w, const void *data, int size);
+EAPI Eina_Bool ecore_x_selection_clipboard_clear(void);
+EAPI void ecore_x_selection_primary_request(Ecore_X_Window w, const char *target);
+EAPI void ecore_x_selection_secondary_request(Ecore_X_Window w, const char *target);
+EAPI void ecore_x_selection_xdnd_request(Ecore_X_Window w, const char *target);
+EAPI void ecore_x_selection_clipboard_request(Ecore_X_Window w, const char *target);
+EAPI Eina_Bool ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret, int *len, Ecore_X_Atom *targprop, int *targsize);
+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 *));
+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 *tprop, int *tsize));
+EAPI void ecore_x_selection_converter_del(char *target);
+EAPI void ecore_x_selection_converter_atom_del(Ecore_X_Atom target);
+EAPI void ecore_x_selection_parser_add(const char *target, void *(*func)(const char *target, void *data, int size, int format));
+EAPI void ecore_x_selection_parser_del(const char *target);
+EAPI void ecore_x_selection_owner_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Time tm);
+EAPI Ecore_X_Window ecore_x_selection_owner_get(Ecore_X_Atom atom);
+EAPI 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); /** @since 1.8 */
+
+EAPI void ecore_x_dnd_aware_set(Ecore_X_Window win, Eina_Bool on);
+EAPI int ecore_x_dnd_version_get(Ecore_X_Window win);
+EAPI Eina_Bool ecore_x_dnd_type_isset(Ecore_X_Window win, const char *type);
+EAPI void ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, Eina_Bool on);
+EAPI void ecore_x_dnd_types_set(Ecore_X_Window win, const char **types, unsigned int num_types);
+EAPI void ecore_x_dnd_actions_set(Ecore_X_Window win, Ecore_X_Atom *actions, unsigned int num_actions);
+EAPI Eina_Bool ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size);
+EAPI Eina_Bool ecore_x_dnd_drop(void);
+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);
+EAPI void ecore_x_dnd_source_action_set(Ecore_X_Atom action);
+EAPI Ecore_X_Atom ecore_x_dnd_source_action_get(void);
+EAPI void ecore_x_dnd_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *data), const void *data);
+
+EAPI Ecore_X_Window ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI int ecore_x_window_argb_get(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_window_manager_argb_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_argb_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_override_argb_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h);
+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);
+EAPI void ecore_x_window_cursor_set(Ecore_X_Window win, Ecore_X_Cursor c);
+EAPI void ecore_x_window_free(Ecore_X_Window win);
+EAPI void ecore_x_window_ignore_set(Ecore_X_Window win, int ignore);
+EAPI Ecore_X_Window *ecore_x_window_ignore_list(int *num);
+
+EAPI void ecore_x_window_delete_request_send(Ecore_X_Window win);
+EAPI void ecore_x_window_show(Ecore_X_Window win);
+EAPI void ecore_x_window_hide(Ecore_X_Window win);
+EAPI void ecore_x_window_move(Ecore_X_Window win, int x, int y);
+EAPI void ecore_x_window_resize(Ecore_X_Window win, int w, int h);
+EAPI void ecore_x_window_move_resize(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_focus(Ecore_X_Window win);
+EAPI void ecore_x_window_focus_at_time(Ecore_X_Window win, Ecore_X_Time t);
+EAPI Ecore_X_Window ecore_x_window_focus_get(void);
+EAPI void ecore_x_window_raise(Ecore_X_Window win);
+EAPI void ecore_x_window_lower(Ecore_X_Window win);
+EAPI void ecore_x_window_reparent(Ecore_X_Window win, Ecore_X_Window new_parent, int x, int y);
+EAPI void ecore_x_window_size_get(Ecore_X_Window win, int *w, int *h);
+EAPI void ecore_x_window_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_window_border_width_get(Ecore_X_Window win);
+EAPI void ecore_x_window_border_width_set(Ecore_X_Window win, int width);
+EAPI int ecore_x_window_depth_get(Ecore_X_Window win);
+EAPI void ecore_x_window_cursor_show(Ecore_X_Window win, Eina_Bool show);
+EAPI void ecore_x_window_defaults_set(Ecore_X_Window win);
+EAPI int ecore_x_window_visible_get(Ecore_X_Window win);
+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);
+EAPI Ecore_X_Window ecore_x_window_shadow_parent_get(Ecore_X_Window root, Ecore_X_Window win);
+EAPI void ecore_x_window_shadow_tree_flush(void);
+EAPI Ecore_X_Window ecore_x_window_root_get(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_window_at_xy_get(int x, int y);
+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_begin_get(Ecore_X_Window begin, int x, int y);
+EAPI Ecore_X_Window ecore_x_window_parent_get(Ecore_X_Window win);
+
+EAPI void ecore_x_window_background_color_set(Ecore_X_Window win, unsigned short r, unsigned short g, unsigned short b);
+EAPI void ecore_x_window_gravity_set(Ecore_X_Window win, Ecore_X_Gravity grav);
+EAPI void ecore_x_window_pixel_gravity_set(Ecore_X_Window win, Ecore_X_Gravity grav);
+EAPI void ecore_x_window_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pmap);
+EAPI void ecore_x_window_area_clear(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_area_expose(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_override_set(Ecore_X_Window win, Eina_Bool override);
+
+EAPI void ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom, unsigned int *val, unsigned int num);
+EAPI int ecore_x_window_prop_card32_get(Ecore_X_Window win, Ecore_X_Atom atom, unsigned int *val, unsigned int len);
+EAPI int ecore_x_window_prop_card32_list_get(Ecore_X_Window win, Ecore_X_Atom atom, unsigned int **plst);
+
+EAPI void ecore_x_window_prop_xid_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom type, Ecore_X_ID *lst, unsigned int num);
+EAPI int ecore_x_window_prop_xid_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom type, Ecore_X_ID *lst, unsigned int len);
+EAPI int ecore_x_window_prop_xid_list_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom type, Ecore_X_ID **plst);
+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);
+EAPI void ecore_x_window_prop_atom_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom *val, unsigned int num);
+EAPI int ecore_x_window_prop_atom_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom *val, unsigned int len);
+EAPI int ecore_x_window_prop_atom_list_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom **plst);
+EAPI void ecore_x_window_prop_atom_list_change(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Atom item, int op);
+EAPI void ecore_x_window_prop_window_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window *val, unsigned int num);
+EAPI int ecore_x_window_prop_window_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window *val, unsigned int len);
+EAPI int ecore_x_window_prop_window_list_get(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window **plst);
+
+EAPI Ecore_X_Atom ecore_x_window_prop_any_type(void);
+EAPI void ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_Atom format, int size, void *data, int number);
+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);
+EAPI void ecore_x_window_prop_property_del(Ecore_X_Window win, Ecore_X_Atom property);
+EAPI Ecore_X_Atom *ecore_x_window_prop_list(Ecore_X_Window win, int *num_ret);
+EAPI void ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom type, const char *str);
+EAPI char *ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type);
+EAPI Eina_Bool ecore_x_window_prop_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol);
+EAPI Ecore_X_WM_Protocol *ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, int *num_ret);
+
+EAPI void ecore_x_window_shape_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask);
+EAPI void ecore_x_window_shape_window_set(Ecore_X_Window win, Ecore_X_Window shape_win);
+EAPI void ecore_x_window_shape_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y);
+EAPI void ecore_x_window_shape_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num);
+EAPI void ecore_x_window_shape_input_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num);
+EAPI void ecore_x_window_shape_input_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangle_subtract(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_input_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y);
+EAPI void ecore_x_window_shape_input_window_set(Ecore_X_Window win, Ecore_X_Window shape_win);
+EAPI void ecore_x_window_shape_window_add(Ecore_X_Window win, Ecore_X_Window shape_win);
+EAPI void ecore_x_window_shape_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y);
+EAPI void ecore_x_window_shape_input_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y);
+EAPI void ecore_x_window_shape_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_input_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num);
+EAPI void ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num);
+EAPI Ecore_X_Rectangle *ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret);
+EAPI Ecore_X_Rectangle *ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win, int *num_ret);
+EAPI void ecore_x_window_shape_events_select(Ecore_X_Window win, Eina_Bool on);
+EAPI void ecore_x_window_shape_input_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask);
+
+EAPI Ecore_X_Pixmap ecore_x_pixmap_new(Ecore_X_Window win, int w, int h, int dep);
+EAPI void ecore_x_pixmap_free(Ecore_X_Pixmap pmap);
+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_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap);
+
+EAPI Ecore_X_GC ecore_x_gc_new(Ecore_X_Drawable draw, Ecore_X_GC_Value_Mask value_mask, const unsigned int *value_list);
+EAPI void ecore_x_gc_free(Ecore_X_GC gc);
+EAPI void ecore_x_gc_foreground_set(Ecore_X_GC gc, unsigned long foreground);
+EAPI void ecore_x_gc_background_set(Ecore_X_GC gc, unsigned long background);
+
+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);
+EAPI Eina_Bool ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, const void *data, int len);
+EAPI Eina_Bool ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y);
+EAPI Eina_Bool ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b);
+EAPI Eina_Bool ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b);
+EAPI Eina_Bool ecore_x_mouse_in_send(Ecore_X_Window win, int x, int y);
+EAPI Eina_Bool ecore_x_mouse_out_send(Ecore_X_Window win, int x, int y);
+
+EAPI void ecore_x_drawable_geometry_get(Ecore_X_Drawable d, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_drawable_border_width_get(Ecore_X_Drawable d);
+EAPI int ecore_x_drawable_depth_get(Ecore_X_Drawable d);
+EAPI void ecore_x_drawable_rectangle_fill(Ecore_X_Drawable d, Ecore_X_GC gc, int x, int y, int width, int height);
+
+EAPI Eina_Bool ecore_x_cursor_color_supported_get(void);
+EAPI Ecore_X_Cursor ecore_x_cursor_new(Ecore_X_Window win, int *pixels, int w, int h, int hot_x, int hot_y);
+EAPI void ecore_x_cursor_free(Ecore_X_Cursor c);
+EAPI Ecore_X_Cursor ecore_x_cursor_shape_get(int shape);
+EAPI void ecore_x_cursor_size_set(int size);
+EAPI int ecore_x_cursor_size_get(void);
+
+/* FIXME: these funcs need categorising */
+EAPI Ecore_X_Window *ecore_x_window_root_list(int *num_ret);
+EAPI Ecore_X_Window ecore_x_window_root_first_get(void);
+EAPI Eina_Bool ecore_x_window_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_container_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_client_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_sniff(Ecore_X_Window win);
+EAPI void ecore_x_window_client_sniff(Ecore_X_Window win);
+
+EAPI Ecore_X_Atom ecore_x_atom_get(const char *name);
+EAPI void ecore_x_atoms_get(const char **names, int num, Ecore_X_Atom *atoms);
+EAPI char *ecore_x_atom_name_get(Ecore_X_Atom atom);
+
+EAPI void ecore_x_icccm_init(void);
+EAPI void ecore_x_icccm_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state);
+EAPI Ecore_X_Window_State_Hint ecore_x_icccm_state_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_delete_window_send(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_icccm_move_resize_send(Ecore_X_Window win, int x, int y, int w, int h);
+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);
+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);
+EAPI void 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);
+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);
+EAPI void ecore_x_icccm_title_set(Ecore_X_Window win, const char *t);
+EAPI char *ecore_x_icccm_title_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_protocol_atoms_set(Ecore_X_Window win, Ecore_X_Atom *protos, int num);
+EAPI void ecore_x_icccm_protocol_set(Ecore_X_Window win, Ecore_X_WM_Protocol protocol, Eina_Bool on);
+EAPI Eina_Bool ecore_x_icccm_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol);
+EAPI void ecore_x_icccm_name_class_set(Ecore_X_Window win, const char *n, const char *c);
+EAPI void ecore_x_icccm_name_class_get(Ecore_X_Window win, char **n, char **c);
+EAPI char *ecore_x_icccm_client_machine_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_command_set(Ecore_X_Window win, int argc, char **argv);
+EAPI void ecore_x_icccm_command_get(Ecore_X_Window win, int *argc, char ***argv);
+EAPI char *ecore_x_icccm_icon_name_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_icon_name_set(Ecore_X_Window win, const char *t);
+EAPI void ecore_x_icccm_colormap_window_set(Ecore_X_Window win, Ecore_X_Window subwin);
+EAPI void ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, Ecore_X_Window subwin);
+EAPI void ecore_x_icccm_transient_for_set(Ecore_X_Window win, Ecore_X_Window forwin);
+EAPI void ecore_x_icccm_transient_for_unset(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_icccm_transient_for_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_window_role_set(Ecore_X_Window win, const char *role);
+EAPI char *ecore_x_icccm_window_role_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_client_leader_set(Ecore_X_Window win, Ecore_X_Window l);
+EAPI Ecore_X_Window ecore_x_icccm_client_leader_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_iconic_request_send(Ecore_X_Window win, Ecore_X_Window root);
+
+typedef enum _Ecore_X_MWM_Hint_Func
+{
+ ECORE_X_MWM_HINT_FUNC_ALL = (1 << 0),
+ ECORE_X_MWM_HINT_FUNC_RESIZE = (1 << 1),
+ ECORE_X_MWM_HINT_FUNC_MOVE = (1 << 2),
+ ECORE_X_MWM_HINT_FUNC_MINIMIZE = (1 << 3),
+ ECORE_X_MWM_HINT_FUNC_MAXIMIZE = (1 << 4),
+ ECORE_X_MWM_HINT_FUNC_CLOSE = (1 << 5)
+} Ecore_X_MWM_Hint_Func;
+
+typedef enum _Ecore_X_MWM_Hint_Decor
+{
+ ECORE_X_MWM_HINT_DECOR_ALL = (1 << 0),
+ ECORE_X_MWM_HINT_DECOR_BORDER = (1 << 1),
+ ECORE_X_MWM_HINT_DECOR_RESIZEH = (1 << 2),
+ ECORE_X_MWM_HINT_DECOR_TITLE = (1 << 3),
+ ECORE_X_MWM_HINT_DECOR_MENU = (1 << 4),
+ ECORE_X_MWM_HINT_DECOR_MINIMIZE = (1 << 5),
+ ECORE_X_MWM_HINT_DECOR_MAXIMIZE = (1 << 6)
+} Ecore_X_MWM_Hint_Decor;
+
+typedef enum _Ecore_X_MWM_Hint_Input
+{
+ ECORE_X_MWM_HINT_INPUT_MODELESS = 0,
+ ECORE_X_MWM_HINT_INPUT_PRIMARY_APPLICATION_MODAL = 1,
+ ECORE_X_MWM_HINT_INPUT_SYSTEM_MODAL = 2,
+ ECORE_X_MWM_HINT_INPUT_FULL_APPLICATION_MODAL = 3
+} Ecore_X_MWM_Hint_Input;
+
+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);
+EAPI void ecore_x_mwm_borderless_set(Ecore_X_Window win, Eina_Bool borderless);
+
+/* netwm */
+EAPI void ecore_x_netwm_init(void);
+EAPI void ecore_x_netwm_shutdown(void);
+EAPI void ecore_x_netwm_wm_identify(Ecore_X_Window root, Ecore_X_Window check, const char *wm_name);
+EAPI void ecore_x_netwm_supported_set(Ecore_X_Window root, Ecore_X_Atom *supported, int num);
+EAPI Eina_Bool ecore_x_netwm_supported_get(Ecore_X_Window root, Ecore_X_Atom **supported, int *num);
+EAPI void ecore_x_netwm_desk_count_set(Ecore_X_Window root, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_roots_set(Ecore_X_Window root, Ecore_X_Window *vroots, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_names_set(Ecore_X_Window root, const char **names, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width, unsigned int height);
+EAPI void ecore_x_netwm_desk_workareas_set(Ecore_X_Window root, unsigned int *areas, unsigned int n_desks);
+EAPI unsigned int *ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, unsigned int *n_desks);
+EAPI void ecore_x_netwm_desk_current_set(Ecore_X_Window root, unsigned int desk);
+EAPI void ecore_x_netwm_desk_viewports_set(Ecore_X_Window root, unsigned int *origins, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_layout_set(Ecore_X_Window root, int orientation, int columns, int rows, int starting_corner);
+EAPI void ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, Eina_Bool on);
+EAPI void ecore_x_netwm_client_list_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients);
+EAPI void ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients);
+EAPI void ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win);
+EAPI void ecore_x_netwm_client_active_request(Ecore_X_Window root, Ecore_X_Window win, int type, Ecore_X_Window current_win);
+EAPI void ecore_x_netwm_name_set(Ecore_X_Window win, const char *name);
+EAPI int ecore_x_netwm_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_startup_id_set(Ecore_X_Window win, const char *id);
+EAPI int ecore_x_netwm_startup_id_get(Ecore_X_Window win, char **id);
+EAPI void ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name);
+EAPI int ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name);
+EAPI int ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name);
+EAPI int ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk);
+EAPI Eina_Bool ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk);
+EAPI void ecore_x_netwm_strut_set(Ecore_X_Window win, int left, int right, int top, int bottom);
+EAPI Eina_Bool ecore_x_netwm_strut_get(Ecore_X_Window win, int *left, int *right, int *top, int *bottom);
+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);
+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);
+
+EAPI void ecore_x_netwm_icons_set(Ecore_X_Window win, Ecore_X_Icon *icon, int num);
+
+EAPI Eina_Bool ecore_x_netwm_icons_get(Ecore_X_Window win, Ecore_X_Icon **icon, int *num);
+EAPI void ecore_x_netwm_icon_geometry_set(Ecore_X_Window win, int x, int y, int width, int height);
+EAPI Eina_Bool ecore_x_netwm_icon_geometry_get(Ecore_X_Window win, int *x, int *y, int *width, int *height);
+EAPI void ecore_x_netwm_pid_set(Ecore_X_Window win, int pid);
+EAPI Eina_Bool ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid);
+EAPI void ecore_x_netwm_handled_icons_set(Ecore_X_Window win);
+EAPI Eina_Bool ecore_x_netwm_handled_icons_get(Ecore_X_Window win);
+EAPI void ecore_x_netwm_user_time_set(Ecore_X_Window win, unsigned int time);
+EAPI Eina_Bool ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *time);
+EAPI void ecore_x_netwm_window_state_set(Ecore_X_Window win, 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);
+EAPI void ecore_x_netwm_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type);
+EAPI Eina_Bool ecore_x_netwm_window_type_get(Ecore_X_Window win, Ecore_X_Window_Type *type);
+EAPI int ecore_x_netwm_window_types_get(Ecore_X_Window win, Ecore_X_Window_Type **types);
+EAPI Eina_Bool ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, Ecore_X_Action action);
+EAPI void ecore_x_netwm_allowed_action_set(Ecore_X_Window win, Ecore_X_Action *action, unsigned int num);
+EAPI Eina_Bool ecore_x_netwm_allowed_action_get(Ecore_X_Window win, Ecore_X_Action **action, unsigned int *num);
+EAPI void ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity);
+EAPI Eina_Bool ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity);
+EAPI void ecore_x_netwm_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb);
+EAPI Eina_Bool ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb);
+EAPI Eina_Bool ecore_x_netwm_sync_counter_get(Ecore_X_Window win, Ecore_X_Sync_Counter *counter);
+EAPI void ecore_x_netwm_ping_send(Ecore_X_Window win);
+EAPI void ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial);
+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);
+EAPI void ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop);
+EAPI void ecore_x_netwm_moveresize_request_send(Ecore_X_Window win, int x, int y, Ecore_X_Netwm_Direction direction, unsigned int button);
+
+EAPI void ecore_x_e_init(void);
+EAPI void ecore_x_e_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb);
+EAPI void ecore_x_e_virtual_keyboard_set(Ecore_X_Window win, unsigned int is_keyboard);
+EAPI Eina_Bool ecore_x_e_virtual_keyboard_get(Ecore_X_Window win);
+EAPI void ecore_x_e_virtual_keyboard_state_set(Ecore_X_Window win, Ecore_X_Virtual_Keyboard_State state);
+EAPI Ecore_X_Virtual_Keyboard_State ecore_x_e_virtual_keyboard_state_get(Ecore_X_Window win);
+EAPI void ecore_x_e_virtual_keyboard_state_send(Ecore_X_Window win, Ecore_X_Virtual_Keyboard_State state);
+
+/* Illume functions */
+EAPI void ecore_x_e_illume_zone_set(Ecore_X_Window win, Ecore_X_Window zone);
+EAPI Ecore_X_Window ecore_x_e_illume_zone_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_zone_list_set(Ecore_X_Window win, Ecore_X_Window *zones, unsigned int n_zones);
+EAPI void ecore_x_e_illume_conformant_set(Ecore_X_Window win, unsigned int is_conformant);
+EAPI Eina_Bool ecore_x_e_illume_conformant_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_mode_set(Ecore_X_Window win, Ecore_X_Illume_Mode mode);
+EAPI Ecore_X_Illume_Mode ecore_x_e_illume_mode_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_mode_send(Ecore_X_Window win, Ecore_X_Illume_Mode mode);
+EAPI void ecore_x_e_illume_focus_back_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_focus_forward_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_focus_home_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_close_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_home_new_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_home_del_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_access_action_next_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_access_action_read_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_access_action_up_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_access_action_down_send(Ecore_X_Window win);
+
+EAPI void ecore_x_e_illume_drag_set(Ecore_X_Window win, unsigned int drag);
+EAPI Eina_Bool ecore_x_e_illume_drag_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_drag_locked_set(Ecore_X_Window win, unsigned int is_locked);
+EAPI Eina_Bool ecore_x_e_illume_drag_locked_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_drag_start_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_drag_end_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_indicator_geometry_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI Eina_Bool ecore_x_e_illume_indicator_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI void ecore_x_e_illume_softkey_geometry_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI Eina_Bool ecore_x_e_illume_softkey_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI void ecore_x_e_illume_keyboard_geometry_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI Eina_Bool ecore_x_e_illume_keyboard_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI void ecore_x_e_illume_quickpanel_set(Ecore_X_Window win, unsigned int is_quickpanel);
+EAPI Eina_Bool ecore_x_e_illume_quickpanel_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_state_set(Ecore_X_Window win, Ecore_X_Illume_Quickpanel_State state);
+EAPI Ecore_X_Illume_Quickpanel_State ecore_x_e_illume_quickpanel_state_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_state_send(Ecore_X_Window win, Ecore_X_Illume_Quickpanel_State state);
+EAPI void ecore_x_e_illume_quickpanel_state_toggle(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_priority_major_set(Ecore_X_Window win, unsigned int priority);
+EAPI int ecore_x_e_illume_quickpanel_priority_major_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_priority_minor_set(Ecore_X_Window win, unsigned int priority);
+EAPI int ecore_x_e_illume_quickpanel_priority_minor_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_zone_set(Ecore_X_Window win, unsigned int zone);
+EAPI int ecore_x_e_illume_quickpanel_zone_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_zone_request_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_position_update_send(Ecore_X_Window win);
+
+EAPI void ecore_x_e_illume_clipboard_state_set(Ecore_X_Window win, Ecore_X_Illume_Clipboard_State state);
+
+EAPI Ecore_X_Illume_Clipboard_State ecore_x_e_illume_clipboard_state_get(Ecore_X_Window win);
+
+EAPI void ecore_x_e_illume_clipboard_geometry_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI Eina_Bool ecore_x_e_illume_clipboard_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI void ecore_x_e_comp_sync_counter_set(Ecore_X_Window win, Ecore_X_Sync_Counter counter);
+EAPI Ecore_X_Sync_Counter ecore_x_e_comp_sync_counter_get(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window root, Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_draw_size_done_send(Ecore_X_Window root, Ecore_X_Window win, int w, int h);
+EAPI void ecore_x_e_comp_sync_supported_set(Ecore_X_Window root, Eina_Bool enabled);
+EAPI Eina_Bool ecore_x_e_comp_sync_supported_get(Ecore_X_Window root);
+EAPI void ecore_x_e_comp_sync_begin_send(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_end_send(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win);
+
+EAPI void ecore_x_e_comp_flush_send(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_dump_send(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pixmap);
+EAPI Ecore_X_Pixmap ecore_x_e_comp_pixmap_get(Ecore_X_Window win);
+
+EAPI char *ecore_x_e_window_profile_get(Ecore_X_Window win);
+EAPI void ecore_x_e_window_profile_set(Ecore_X_Window win, const char *profile);
+EAPI void ecore_x_e_window_profile_list_set(Ecore_X_Window win, const char **profiles, unsigned int num_profiles);
+EAPI Eina_Bool ecore_x_e_window_profile_list_get(Ecore_X_Window win, const char ***profiles, int *ret_num);
+
+EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter);
+EAPI Eina_Bool ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm);
+EAPI Eina_Bool ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter, unsigned int *val);
+EAPI Ecore_X_Sync_Counter ecore_x_sync_counter_new(int val);
+EAPI void ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter);
+EAPI void ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, int by);
+EAPI void ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter, int val);
+
+EAPI void ecore_x_sync_counter_set(Ecore_X_Sync_Counter counter, int val);
+EAPI void ecore_x_sync_counter_2_set(Ecore_X_Sync_Counter counter, int val_hi, unsigned int val_lo);
+EAPI Eina_Bool ecore_x_sync_counter_2_query(Ecore_X_Sync_Counter counter, int *val_hi, unsigned int *val_lo);
+
+EAPI int ecore_x_xinerama_screen_count_get(void);
+EAPI Eina_Bool ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h);
+
+EAPI Eina_Bool ecore_x_screensaver_event_available_get(void);
+EAPI int ecore_x_screensaver_idle_time_get(void);
+EAPI void ecore_x_screensaver_set(int timeout, int interval, int prefer_blanking, int allow_exposures);
+EAPI void ecore_x_screensaver_timeout_set(int timeout);
+EAPI int ecore_x_screensaver_timeout_get(void);
+EAPI void ecore_x_screensaver_blank_set(int timeout);
+EAPI int ecore_x_screensaver_blank_get(void);
+EAPI void ecore_x_screensaver_expose_set(int timeout);
+EAPI int ecore_x_screensaver_expose_get(void);
+EAPI void ecore_x_screensaver_interval_set(int timeout);
+EAPI int ecore_x_screensaver_interval_get(void);
+EAPI void ecore_x_screensaver_event_listen_set(Eina_Bool on);
+EAPI Eina_Bool ecore_x_screensaver_custom_blanking_enable(void); /** @since 1.7 */
+EAPI Eina_Bool ecore_x_screensaver_custom_blanking_disable(void); /** @since 1.7 */
+
+/* FIXME: these funcs need categorising */
+
+typedef struct _Ecore_X_Window_Attributes
+{
+ Ecore_X_Window root;
+ int x, y, w, h;
+ int border;
+ int depth;
+ Eina_Bool visible : 1;
+ Eina_Bool viewable : 1;
+ Eina_Bool override : 1;
+ Eina_Bool input_only : 1;
+ Eina_Bool save_under : 1;
+ struct
+ {
+ Ecore_X_Event_Mask mine;
+ Ecore_X_Event_Mask all;
+ Ecore_X_Event_Mask no_propagate;
+ } event_mask;
+ Ecore_X_Gravity window_gravity;
+ Ecore_X_Gravity pixel_gravity;
+ Ecore_X_Colormap colormap;
+ Ecore_X_Visual visual;
+ /* FIXME: missing
+ * int map_installed;
+ * Screen *screen;
+ */
+} Ecore_X_Window_Attributes;
+
+EAPI Eina_Bool ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret);
+EAPI void ecore_x_window_save_set_add(Ecore_X_Window win);
+EAPI void ecore_x_window_save_set_del(Ecore_X_Window win);
+EAPI Ecore_X_Window *ecore_x_window_children_get(Ecore_X_Window win, int *num);
+
+EAPI Eina_Bool ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold);
+EAPI Eina_Bool ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold);
+EAPI Eina_Bool ecore_x_pointer_mapping_set(unsigned char *map, int nmap);
+EAPI Eina_Bool ecore_x_pointer_mapping_get(unsigned char *map, int nmap);
+EAPI Eina_Bool ecore_x_pointer_grab(Ecore_X_Window win);
+EAPI Eina_Bool ecore_x_pointer_confine_grab(Ecore_X_Window win);
+EAPI void ecore_x_pointer_ungrab(void);
+EAPI Eina_Bool ecore_x_pointer_warp(Ecore_X_Window win, int x, int y);
+EAPI Eina_Bool ecore_x_keyboard_grab(Ecore_X_Window win);
+EAPI void ecore_x_keyboard_ungrab(void);
+EAPI void ecore_x_grab(void);
+EAPI void ecore_x_ungrab(void);
+EAPI void ecore_x_passive_grab_replay_func_set(Eina_Bool (*func)(void *data, int event_type, void *event), void *data);
+EAPI void ecore_x_window_button_grab(Ecore_X_Window win, int button, Ecore_X_Event_Mask event_mask, int mod, int any_mod);
+EAPI void ecore_x_window_button_ungrab(Ecore_X_Window win, int button, int mod, int any_mod);
+EAPI void ecore_x_window_key_grab(Ecore_X_Window win, const char *key, int mod, int any_mod);
+EAPI void ecore_x_window_key_ungrab(Ecore_X_Window win, const char *key, int mod, int any_mod);
+
+EAPI void ecore_x_focus_reset(void);
+EAPI void ecore_x_events_allow_all(void);
+EAPI void ecore_x_pointer_last_xy_get(int *x, int *y);
+EAPI void ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y);
+
+/* ecore_x_region.c */
+EAPI Ecore_X_XRegion *ecore_x_xregion_new(void);
+EAPI void ecore_x_xregion_free(Ecore_X_XRegion *region);
+EAPI Eina_Bool ecore_x_xregion_set(Ecore_X_XRegion *region, Ecore_X_GC gc);
+EAPI void ecore_x_xregion_translate(Ecore_X_XRegion *region, int x, int y);
+EAPI Eina_Bool ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2);
+EAPI Eina_Bool ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2);
+EAPI Eina_Bool ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect);
+EAPI Eina_Bool ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2);
+EAPI Eina_Bool ecore_x_xregion_is_empty(Ecore_X_XRegion *region);
+EAPI Eina_Bool ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, Ecore_X_XRegion *r2);
+EAPI Eina_Bool ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y);
+EAPI Eina_Bool ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect);
+
+/* ecore_x_randr.c */
+
+/* The usage of 'Ecore_X_Randr_None' or 'Ecore_X_Randr_Unset'
+ * depends on the context. In most cases 'Ecore_X_Randr_Unset'
+ * can be used, but in some cases -1 is a special value to
+ * functions, thus 'Ecore_X_Randr_None' (=0) must be used.
+ */
+
+typedef short Ecore_X_Randr_Refresh_Rate;
+typedef int Ecore_X_Randr_Crtc_Gamma;
+typedef int Ecore_X_Randr_Signal_Format;
+typedef int Ecore_X_Randr_Signal_Property;
+typedef int Ecore_X_Randr_Connector_Type;
+
+typedef struct _Ecore_X_Randr_Mode_Info
+{
+ Ecore_X_ID xid;
+ unsigned int width;
+ unsigned int height;
+ unsigned long dotClock;
+ unsigned int hSyncStart;
+ unsigned int hSyncEnd;
+ unsigned int hTotal;
+ unsigned int hSkew;
+ unsigned int vSyncStart;
+ unsigned int vSyncEnd;
+ unsigned int vTotal;
+ char *name;
+ unsigned int nameLength;
+ unsigned long modeFlags;
+} Ecore_X_Randr_Mode_Info;
+
+EAPI int ecore_x_randr_version_get(void);
+EAPI Eina_Bool ecore_x_randr_query(void);
+
+/* ecore_x_randr_11.c */
+EAPI Ecore_X_Randr_Orientation ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root);
+EAPI Ecore_X_Randr_Orientation ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root);
+EAPI Eina_Bool ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Orientation orientation);
+EAPI Ecore_X_Randr_Screen_Size_MM *ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, int *num);
+
+/**
+ * @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);
+EAPI Eina_Bool ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, int size_index);
+EAPI Ecore_X_Randr_Refresh_Rate ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root);
+EAPI Ecore_X_Randr_Refresh_Rate *ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, int size_index, int *num);
+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);
+
+/* ecore_x_randr_12.c */
+EAPI void ecore_x_randr_events_select(Ecore_X_Window win, Eina_Bool on);
+
+EAPI void ecore_x_randr_screen_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm);
+EAPI void ecore_x_randr_screen_size_range_get(Ecore_X_Window root, int *wmin, int *hmin, int *wmax, int *hmax);
+EAPI void ecore_x_randr_screen_reset(Ecore_X_Window root);
+EAPI Eina_Bool ecore_x_randr_screen_current_size_set(Ecore_X_Window root, int w, int h, int w_mm, int h_mm);
+EAPI Ecore_X_Randr_Mode_Info **ecore_x_randr_modes_info_get(Ecore_X_Window root, int *num);
+EAPI Ecore_X_Randr_Mode ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info);
+EAPI void ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode);
+EAPI Ecore_X_Randr_Mode_Info *ecore_x_randr_mode_info_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode);
+EAPI void ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info);
+EAPI Ecore_X_Randr_Crtc *ecore_x_randr_crtcs_get(Ecore_X_Window root, int *num);
+EAPI Ecore_X_Randr_Output *ecore_x_randr_outputs_get(Ecore_X_Window root, int *num);
+EAPI Ecore_X_Randr_Output *ecore_x_randr_window_outputs_get(Ecore_X_Window window, int *num);
+EAPI Ecore_X_Randr_Output *ecore_x_randr_current_output_get(Ecore_X_Window window, int *num);
+EAPI Ecore_X_Randr_Crtc *ecore_x_randr_window_crtcs_get(Ecore_X_Window window, int *num);
+EAPI Ecore_X_Randr_Crtc *ecore_x_randr_current_crtc_get(Ecore_X_Window window, int *num);
+EAPI Ecore_X_Randr_Output *ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num);
+EAPI Ecore_X_Randr_Output *ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num);
+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);
+EAPI void ecore_x_randr_crtc_pos_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y);
+EAPI Eina_Bool ecore_x_randr_crtc_pos_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, int y);
+EAPI Ecore_X_Randr_Mode ecore_x_randr_crtc_mode_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc);
+EAPI Eina_Bool ecore_x_randr_crtc_mode_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int noutputs, Ecore_X_Randr_Mode mode);
+EAPI void ecore_x_randr_crtc_size_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *w, int *h);
+EAPI Ecore_X_Randr_Refresh_Rate ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Mode mode);
+EAPI Ecore_X_Randr_Orientation ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc);
+EAPI Ecore_X_Randr_Orientation ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc);
+EAPI Eina_Bool ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Orientation orientation);
+EAPI Eina_Bool ecore_x_randr_crtc_clone_set(Ecore_X_Window root, Ecore_X_Randr_Crtc original, Ecore_X_Randr_Crtc clone);
+EAPI Eina_Bool ecore_x_randr_crtc_settings_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int noutputs, int x, int y, Ecore_X_Randr_Mode mode, Ecore_X_Randr_Orientation orientation);
+EAPI Eina_Bool ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc_r1, Ecore_X_Randr_Crtc crtc_r2, Ecore_X_Randr_Output_Policy policy, Ecore_X_Randr_Relative_Alignment alignment);
+EAPI Eina_Bool ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode);
+EAPI void ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode);
+EAPI Ecore_X_Randr_Mode *ecore_x_randr_output_modes_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num, int *npreferred);
+EAPI Ecore_X_Randr_Output *ecore_x_randr_output_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num);
+EAPI Ecore_X_Randr_Crtc *ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num);
+EAPI Ecore_X_Randr_Crtc ecore_x_randr_output_crtc_get(Ecore_X_Window root, Ecore_X_Randr_Output output);
+EAPI char *ecore_x_randr_output_name_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *len);
+EAPI int ecore_x_randr_crtc_gamma_ramp_size_get(Ecore_X_Randr_Crtc crtc);
+EAPI Ecore_X_Randr_Crtc_Gamma **ecore_x_randr_crtc_gamma_ramps_get(Ecore_X_Randr_Crtc crtc);
+EAPI Eina_Bool ecore_x_randr_crtc_gamma_ramps_set(Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Crtc_Gamma *red, const Ecore_X_Randr_Crtc_Gamma *green, const Ecore_X_Randr_Crtc_Gamma *blue);
+EAPI Eina_Bool ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, const Ecore_X_Randr_Crtc *not_moved, int nnot_moved, int dx, int dy);
+EAPI Eina_Bool ecore_x_randr_move_crtcs(Ecore_X_Window root, const Ecore_X_Randr_Crtc *crtcs, int ncrtc, int dx, int dy);
+EAPI void ecore_x_randr_mode_size_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode, int *w, int *h);
+EAPI Ecore_X_Randr_Connection_Status ecore_x_randr_output_connection_status_get(Ecore_X_Window root, Ecore_X_Randr_Output output);
+EAPI void ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w, int *h);
+EAPI Eina_Bool ecore_x_randr_output_crtc_set(Ecore_X_Window root, Ecore_X_Randr_Output output, const Ecore_X_Randr_Crtc crtc);
+
+/* ecore_x_randr_12_edid.c */
+
+/**
+ * @brief Validates the header from raw EDID data.
+ *
+ * @param edid The edid structure.
+ * @param edid_length Length of the edid structure.
+ * @return @c EINA_TRUE, if the header is valid, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Checks whether a display's EDID has a valid checksum.
+ *
+ * @param edid The edid structure.
+ * @param edid_length Length of the edid structure.
+ * @return @c EINA_TRUE, if the checksum is valid, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the encoded version from raw EDID data.
+ *
+ * The return value has the minor version in the lowest 8 bits, and the major
+ * version in all the rest of the bits. i.e.
+ *
+ * minor = (version & 0x000000ff);
+ * major = (version & 0xffffff00) >> 8;
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded major and minor version encasuplated an int.
+ */
+EAPI int ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the encoded manufacturer from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded manufacturer identifier.
+ */
+EAPI char *ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the encoded name from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded manufacturer identifier.
+ */
+EAPI char *ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the encoded ASCII from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded ASCII display identifier.
+ */
+EAPI char *ecore_x_randr_edid_display_ascii_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the encoded serial identifier from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded serial identifier.
+ */
+EAPI char *ecore_x_randr_edid_display_serial_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the encoded model number from raw EDID data.
+ *
+ * The manufacturer ID table is necessary for a useful description.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded model number.
+ */
+EAPI int ecore_x_randr_edid_model_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the manufacturer serial number from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The encoded serial manufacturer serial number.
+ */
+EAPI int ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the manufacturer model number from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The manufacturer's model number.
+ */
+EAPI int ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Looks up the DPMS support from raw EDID data.
+ *
+ * @param edid The edid structure.
+ * @param edid_length Length of the edid structure.
+ * @return @c EINA_TRUE, if DPMS is supported in some way, @c EINA_FALSE
+ * otherwise.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_dpms_available_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Looks up the DPMS Standby support from raw EDID data.
+ *
+ * @param edid The edid structure.
+ * @param edid_length Length of the edid structure.
+ * @return @c EINA_TRUE, if DPMS Standby is supported, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Looks up the DPMS Suspend support from raw EDID data.
+ *
+ * @param edid The edid structure.
+ * @param edid_length Length of the edid structure.
+ * @return @c EINA_TRUE, if DPMS Suspend is supported, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Looks up the DPMS Off support from raw EDID data.
+ *
+ * @param edid The edid structure.
+ * @param edid_length Length of the edid structure.
+ * @return @c EINA_TRUE, if DPMS Off is supported, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the preferred aspect ratio from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The preferred aspect ratio.
+ */
+EAPI Ecore_X_Randr_Edid_Aspect_Ratio ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the supported aspect ratios from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The supported aspect ratios.
+ */
+EAPI Ecore_X_Randr_Edid_Aspect_Ratio ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the supported colorschemes from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The supported colorschemes.
+ */
+EAPI Ecore_X_Randr_Edid_Display_Colorscheme ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the display type from raw EDID data.
+ *
+ * @param edid The edid structure.
+ * @param edid_length Length of the edid structure.
+ * @return @c EINA_TRUE, if the display is a digital one, @c EINA_FALSE
+ * otherwise.
+ */
+EAPI Eina_Bool ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, unsigned long edid_length);
+
+/**
+ * @brief Get the display interface type from raw EDID data.
+ *
+ * @param edid the edid structure
+ * @param edid_length length of the edid structure
+ * @return The interface type.
+ */
+EAPI Ecore_X_Randr_Edid_Display_Interface_Type ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, unsigned long edid_length);
+
+/* ecore_x_randr_12.c */
+
+EAPI Eina_Bool ecore_x_randr_output_backlight_available(void);
+EAPI void ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, double level);
+EAPI double ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, Ecore_X_Randr_Output output);
+EAPI Eina_Bool ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, Ecore_X_Randr_Output output, double level);
+EAPI Ecore_X_Randr_Output ecore_x_randr_primary_output_get(Ecore_X_Window root);
+EAPI void ecore_x_randr_primary_output_set(Ecore_X_Window root, Ecore_X_Randr_Output output);
+EAPI Ecore_X_Render_Subpixel_Order ecore_x_randr_output_subpixel_order_get(Ecore_X_Window root, Ecore_X_Randr_Output output);
+EAPI unsigned char *ecore_x_randr_output_edid_get(Ecore_X_Window root, Ecore_X_Randr_Output output, unsigned long *length);
+EAPI Ecore_X_Randr_Output *ecore_x_randr_output_wired_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num);
+EAPI Ecore_X_Randr_Output **ecore_x_randr_output_compatibility_list_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num);
+EAPI Ecore_X_Randr_Signal_Format *ecore_x_randr_output_signal_formats_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num);
+EAPI Eina_Bool ecore_x_randr_output_signal_format_set(Ecore_X_Window root, Ecore_X_Randr_Output output, Ecore_X_Randr_Signal_Format *signal);
+EAPI Ecore_X_Randr_Signal_Property *ecore_x_randr_output_signal_properties_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num);
+EAPI int ecore_x_randr_output_connector_number_get(Ecore_X_Window root, Ecore_X_Randr_Output output);
+EAPI Ecore_X_Randr_Connector_Type ecore_x_randr_output_connector_type_get(Ecore_X_Window root, Ecore_X_Randr_Output output);
+/* WTF - these dont exist in ecore-x!!!!
+EAPI Eina_Rectangle *ecore_x_randr_crtc_panning_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h);
+EAPI Eina_Bool ecore_x_randr_crtc_panning_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, const int y, const int w, const int h);
+EAPI Eina_Rectangle *ecore_x_randr_crtc_tracking_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h);
+EAPI Eina_Bool ecore_x_randr_crtc_tracking_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, const int y, const int w, const int h);
+EAPI Eina_Rectangle *ecore_x_randr_crtc_border_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc);
+EAPI Eina_Bool ecore_x_randr_crtc_border_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int left, const int top, const int right, const int bottom);
+*/
+
+/* XRender Support (horrendously incomplete) */
+typedef Ecore_X_ID Ecore_X_Picture;
+
+/* XFixes Extension Support */
+typedef Ecore_X_ID Ecore_X_Region;
+
+typedef enum _Ecore_X_Region_Type
+{
+ ECORE_X_REGION_BOUNDING,
+ ECORE_X_REGION_CLIP
+} Ecore_X_Region_Type;
+
+EAPI Ecore_X_Region ecore_x_region_new(Ecore_X_Rectangle *rects, int num);
+EAPI Ecore_X_Region ecore_x_region_new_from_bitmap(Ecore_X_Pixmap bitmap);
+EAPI Ecore_X_Region ecore_x_region_new_from_window(Ecore_X_Window win, Ecore_X_Region_Type type);
+EAPI Ecore_X_Region ecore_x_region_new_from_gc(Ecore_X_GC gc);
+EAPI Ecore_X_Region ecore_x_region_new_from_picture(Ecore_X_Picture picture);
+EAPI void ecore_x_region_free(Ecore_X_Region region);
+EAPI void ecore_x_region_set(Ecore_X_Region region, Ecore_X_Rectangle *rects, int num);
+EAPI void ecore_x_region_copy(Ecore_X_Region dest, Ecore_X_Region source);
+EAPI void ecore_x_region_combine(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2);
+EAPI void ecore_x_region_intersect(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2);
+EAPI void ecore_x_region_subtract(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2);
+EAPI void ecore_x_region_invert(Ecore_X_Region dest, Ecore_X_Rectangle *bounds, Ecore_X_Region source);
+EAPI void ecore_x_region_translate(Ecore_X_Region region, int dx, int dy);
+EAPI void ecore_x_region_extents(Ecore_X_Region dest, Ecore_X_Region source);
+EAPI Ecore_X_Rectangle *ecore_x_region_fetch(Ecore_X_Region region, int *num, Ecore_X_Rectangle *bounds);
+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);
+EAPI void ecore_x_region_gc_clip_set(Ecore_X_Region region, Ecore_X_GC gc, int x_origin, int y_origin);
+EAPI void ecore_x_region_window_shape_set(Ecore_X_Region region, Ecore_X_Window win, Ecore_X_Shape_Type type, int x_offset, int y_offset);
+EAPI void ecore_x_region_picture_clip_set(Ecore_X_Region region, Ecore_X_Picture picture, int x_origin, int y_origin);
+
+/**
+ * xfixes selection notification request.
+ *
+ * This lets you choose which selections you want to get notifications for.
+ * @param selection The selection atom.
+ * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ * @since 1.1.0
+ */
+EAPI Eina_Bool ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection);
+
+/* XComposite Extension Support */
+EAPI Eina_Bool ecore_x_composite_query(void);
+EAPI void ecore_x_composite_redirect_window(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
+EAPI void ecore_x_composite_redirect_subwindows(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
+EAPI void ecore_x_composite_unredirect_window(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
+EAPI void ecore_x_composite_unredirect_subwindows(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
+EAPI Ecore_X_Pixmap ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win);
+EAPI void ecore_x_composite_window_events_disable(Ecore_X_Window win);
+EAPI void ecore_x_composite_window_events_enable(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_composite_render_window_enable(Ecore_X_Window root);
+EAPI void ecore_x_composite_render_window_disable(Ecore_X_Window root);
+
+/* XDamage Extension Support */
+typedef Ecore_X_ID Ecore_X_Damage;
+
+typedef enum _Ecore_X_Damage_Report_Level
+{
+ ECORE_X_DAMAGE_REPORT_RAW_RECTANGLES,
+ ECORE_X_DAMAGE_REPORT_DELTA_RECTANGLES,
+ ECORE_X_DAMAGE_REPORT_BOUNDING_BOX,
+ ECORE_X_DAMAGE_REPORT_NON_EMPTY
+} Ecore_X_Damage_Report_Level;
+
+struct _Ecore_X_Event_Damage
+{
+ Ecore_X_Damage_Report_Level level;
+ Ecore_X_Drawable drawable;
+ Ecore_X_Damage damage;
+ int more;
+ Ecore_X_Time time;
+ Ecore_X_Rectangle area;
+ Ecore_X_Rectangle geometry;
+};
+
+typedef struct _Ecore_X_Event_Damage Ecore_X_Event_Damage;
+
+struct _Ecore_X_Event_Xkb
+{
+ int group;
+};
+typedef struct _Ecore_X_Event_Xkb Ecore_X_Event_Xkb; /** @since 1.7 */
+
+EAPI Eina_Bool ecore_x_damage_query(void);
+EAPI Ecore_X_Damage ecore_x_damage_new(Ecore_X_Drawable d, Ecore_X_Damage_Report_Level level);
+EAPI void ecore_x_damage_free(Ecore_X_Damage damage);
+EAPI void ecore_x_damage_subtract(Ecore_X_Damage damage, Ecore_X_Region repair, Ecore_X_Region parts);
+
+EAPI Eina_Bool ecore_x_screen_is_composited(int screen);
+EAPI void ecore_x_screen_is_composited_set(int screen, Ecore_X_Window win);
+
+EAPI Eina_Bool ecore_x_dpms_query(void);
+EAPI Eina_Bool ecore_x_dpms_capable_get(void);
+EAPI Eina_Bool ecore_x_dpms_enabled_get(void);
+EAPI void ecore_x_dpms_enabled_set(int enabled);
+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);
+EAPI unsigned int ecore_x_dpms_timeout_standby_get(void);
+EAPI unsigned int ecore_x_dpms_timeout_suspend_get(void);
+EAPI unsigned int ecore_x_dpms_timeout_off_get(void);
+EAPI void ecore_x_dpms_timeout_standby_set(unsigned int new_timeout);
+EAPI void ecore_x_dpms_timeout_suspend_set(unsigned int new_timeout);
+EAPI void ecore_x_dpms_timeout_off_set(unsigned int new_timeout);
+
+EAPI Eina_Bool ecore_x_test_fake_key_down(const char *key);
+EAPI Eina_Bool ecore_x_test_fake_key_up(const char *key);
+EAPI Eina_Bool ecore_x_test_fake_key_press(const char *key);
+EAPI const char *ecore_x_keysym_string_get(int keysym);
+
+/**
+ * Given a keyname, return the keycode representing that key
+ * @param keyname The key from which to get the keycode.
+ * @return The keycode of the key.
+ *
+ * @since 1.2.0
+ */
+EAPI int ecore_x_keysym_keycode_get(const char *keyname);
+
+typedef struct _Ecore_X_Image Ecore_X_Image;
+
+EAPI Ecore_X_Image *ecore_x_image_new(int w, int h, Ecore_X_Visual vis, int depth);
+EAPI void ecore_x_image_free(Ecore_X_Image *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);
+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);
+EAPI void *ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp);
+EAPI Eina_Bool ecore_x_image_is_argb32_get(Ecore_X_Image *im);
+
+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);
+
+EAPI Eina_Bool ecore_x_input_multi_select(Ecore_X_Window win);
+EAPI Eina_Bool ecore_x_input_raw_select(Ecore_X_Window win); /**< @since 1.8 */
+
+EAPI Eina_Bool ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win);
+
+typedef enum _Ecore_X_Gesture_Event_Mask
+{
+ ECORE_X_GESTURE_EVENT_MASK_NONE = 0L,
+ ECORE_X_GESTURE_EVENT_MASK_FLICK = (1L << 0),
+ ECORE_X_GESTURE_EVENT_MASK_PAN = (1L << 1),
+ ECORE_X_GESTURE_EVENT_MASK_PINCHROTATION = (1L << 2),
+ ECORE_X_GESTURE_EVENT_MASK_TAP = (1L << 3),
+ ECORE_X_GESTURE_EVENT_MASK_TAPNHOLD = (1L << 4),
+ ECORE_X_GESTURE_EVENT_MASK_HOLD = (1L << 5),
+ ECORE_X_GESTURE_EVENT_MASK_GROUP = (1L << 6)
+} Ecore_X_Gesture_Event_Mask;
+
+typedef enum _Ecore_X_Gesture_Event_Type
+{
+ ECORE_X_GESTURE_EVENT_FLICK,
+ ECORE_X_GESTURE_EVENT_PAN,
+ ECORE_X_GESTURE_EVENT_PINCHROTATION,
+ ECORE_X_GESTURE_EVENT_TAP,
+ ECORE_X_GESTURE_EVENT_TAPNHOLD,
+ ECORE_X_GESTURE_EVENT_HOLD,
+ ECORE_X_GESTURE_EVENT_GROUP
+} Ecore_X_Gesture_Event_Type;
+
+typedef enum _Ecore_X_Gesture_Event_Subtype
+{
+ ECORE_X_GESTURE_END,
+ ECORE_X_GESTURE_BEGIN,
+ ECORE_X_GESTURE_UPDATE,
+ ECORE_X_GESTURE_DONE
+} Ecore_X_Gesture_Event_Subtype;
+
+typedef enum _Ecore_X_Gesture_Group_Subtype
+{
+ ECORE_X_GESTURE_GROUP_REMOVED,
+ ECORE_X_GESTURE_GROUP_ADDED,
+ ECORE_X_GESTURE_GROUP_CURRENT
+} Ecore_X_Gesture_Group_Subtype;
+
+typedef enum _Ecore_X_Gesture_Direction
+{
+ ECORE_X_GESTURE_NORTHWARD,
+ ECORE_X_GESTURE_NORTHEASTWARD,
+ ECORE_X_GESTURE_EASTWARD,
+ ECORE_X_GESTURE_SOUTHEASTWARD,
+ ECORE_X_GESTURE_SOUTHWARD,
+ ECORE_X_GESTURE_SOUTHWESTWARD,
+ ECORE_X_GESTURE_WESTWARD,
+ ECORE_X_GESTURE_NORTHWESTWARD
+} Ecore_X_Gesture_Direction;
+
+struct _Ecore_X_Event_Gesture_Notify_Flick
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Gesture_Event_Subtype subtype;
+ int num_fingers;
+ int distance;
+ Ecore_X_Time duration;
+ Ecore_X_Gesture_Direction direction;
+ double angle;
+};
+
+struct _Ecore_X_Event_Gesture_Notify_Pan
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Gesture_Event_Subtype subtype;
+ int num_fingers;
+ int dx;
+ int dy;
+ int distance;
+ Ecore_X_Time duration;
+ Ecore_X_Gesture_Direction direction;
+};
+
+struct _Ecore_X_Event_Gesture_Notify_PinchRotation
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Gesture_Event_Subtype subtype;
+ int num_fingers;
+ int distance;
+ int cx;
+ int cy;
+ double zoom;
+ double angle;
+};
+
+struct _Ecore_X_Event_Gesture_Notify_Tap
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Gesture_Event_Subtype subtype;
+ int num_fingers;
+ int cx;
+ int cy;
+ int tap_repeat;
+ Ecore_X_Time interval;
+};
+
+struct _Ecore_X_Event_Gesture_Notify_TapNHold
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Gesture_Event_Subtype subtype;
+ int num_fingers;
+ int cx;
+ int cy;
+ Ecore_X_Time interval;
+ Ecore_X_Time hold_time;
+};
+
+struct _Ecore_X_Event_Gesture_Notify_Hold
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Gesture_Event_Subtype subtype;
+ int num_fingers;
+ int cx;
+ int cy;
+ Ecore_X_Time hold_time;
+};
+
+struct _Ecore_X_Event_Gesture_Notify_Group
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Gesture_Group_Subtype subtype;
+ int num_groups;
+ int group_id;
+};
+
+EAPI Eina_Bool ecore_x_gesture_supported(void);
+
+EAPI Eina_Bool ecore_x_gesture_events_select(Ecore_X_Window win, Ecore_X_Gesture_Event_Mask mask);
+
+EAPI Ecore_X_Gesture_Event_Mask ecore_x_gesture_events_selected_get(Ecore_X_Window win);
+
+EAPI Eina_Bool ecore_x_gesture_event_grab(Ecore_X_Window win, Ecore_X_Gesture_Event_Type type, int num_fingers);
+
+EAPI Eina_Bool ecore_x_gesture_event_ungrab(Ecore_X_Window win, Ecore_X_Gesture_Event_Type type, int num_fingers);
+
+EAPI void ecore_x_e_illume_indicator_state_set(Ecore_X_Window win, Ecore_X_Illume_Indicator_State state);
+EAPI Ecore_X_Illume_Indicator_State ecore_x_e_illume_indicator_state_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_indicator_state_send(Ecore_X_Window win, Ecore_X_Illume_Indicator_State state);
+
+EAPI void ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win, Ecore_X_Illume_Indicator_Opacity_Mode mode);
+
+EAPI Ecore_X_Illume_Indicator_Opacity_Mode ecore_x_e_illume_indicator_opacity_get(Ecore_X_Window win);
+
+EAPI void ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, Ecore_X_Illume_Indicator_Opacity_Mode mode);
+
+EAPI void
+ecore_x_e_illume_window_state_set(Ecore_X_Window win,
+ Ecore_X_Illume_Window_State state);
+
+EAPI Ecore_X_Illume_Window_State ecore_x_e_illume_window_state_get(Ecore_X_Window win);
+EAPI void ecore_x_xkb_select_group(int group); /* @since 1.7 */
+
+#ifdef __cplusplus
+}
+#endif // ifdef __cplusplus
+
+#include <Ecore_X_Atoms.h>
+#include <Ecore_X_Cursor.h>
+
+#endif // ifndef _ECORE_X_H
diff --git a/src/lib/ecore_x/Ecore_X_Atoms.h b/src/lib/ecore_x/Ecore_X_Atoms.h
new file mode 100644
index 0000000000..ca6351d839
--- /dev/null
+++ b/src/lib/ecore_x/Ecore_X_Atoms.h
@@ -0,0 +1,292 @@
+#ifndef _ECORE_X_ATOMS_H
+#define _ECORE_X_ATOMS_H
+
+/**
+ * @file
+ * @brief Ecore X atoms
+ */
+
+/* generic atoms */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_ATOM;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_CARDINAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_FILE_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_STRING;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEXT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WINDOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_PIXMAP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_VISUALID;
+
+/* dnd atoms */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_XDND;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_XDND;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_AWARE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ENTER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_TYPE_LIST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_POSITION;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_COPY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_MOVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_PRIVATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_ASK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LIST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LINK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_DESCRIPTION;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_PROXY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_STATUS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_LEAVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_DROP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_FINISHED;
+
+/* dnd atoms that need to be exposed to the application interface */
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_COPY;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_MOVE;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_LINK;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_ASK;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE;
+
+/* old E atom */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_FRAME_SIZE;
+
+/* old Gnome atom */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WIN_LAYER;
+
+/* ICCCM: client properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_ICON_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_NORMAL_HINTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_SIZE_HINTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_HINTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_CLASS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_TRANSIENT_FOR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_PROTOCOLS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_WINDOWS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_COMMAND;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_MACHINE;
+
+/* ICCCM: window manager properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_ICON_SIZE;
+
+/* ICCCM: WM_STATEproperty */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_CHANGE_STATE;
+
+/* ICCCM: WM_PROTOCOLS properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_TAKE_FOCUS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_SAVE_YOURSELF;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_DELETE_WINDOW;
+
+/* ICCCM: WM_COLORMAP properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_NOTIFY;
+
+/* ICCCM: session management properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SM_CLIENT_ID;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_LEADER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_WINDOW_ROLE;
+
+/* Motif WM atom */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_MOTIF_WM_HINTS;
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTED;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST_STACKING;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_VIEWPORT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_CURRENT_DESKTOP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_NAMES;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_ACTIVE_WINDOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WORKAREA;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_VIRTUAL_ROOTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_LAYOUT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_SHOWING_DESKTOP;
+
+/* pager */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_CLOSE_WINDOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_MOVERESIZE_WINDOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_MOVERESIZE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_RESTACK_WINDOW;
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_DESKTOP;
+
+/* window type */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND;
+
+/* state */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MODAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_STICKY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SHADED;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_ABOVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_BELOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
+
+/* allowed actions */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MOVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_SHADE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_STICK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_BELOW;
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT_PARTIAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_PID;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_HANDLED_ICONS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_USER_TIME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_ID;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_FRAME_EXTENTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_PING;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_OPACITY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_SHADOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_SHADE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_INFO;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_TARGETS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PRIMARY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_SECONDARY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_CLIPBOARD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_PRIMARY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_SECONDARY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD;
+
+/* currently E specific virtual keyboard extension, aim to submit to netwm spec
+ * later */
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME;
+
+/* Illume specific atoms */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ZONE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ZONE_LIST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CONFORMANT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_SINGLE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_BACK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_HOME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_HOME_NEW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_HOME_DEL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLOSE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_START;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_END;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE_TOGGLE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_POSITION_UPDATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_ON;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN;
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_COUNTER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_BEGIN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_END;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_CANCEL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_FLUSH;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_DUMP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_PIXMAP;
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_PARENT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_POSITION;
+
+/* currently elementary and E specific extension */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST;
+
+/* for sliding window */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY;
+
+/* for SDB(Samsung Debug Bridge) */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT;
+#endif /* _ECORE_X_ATOMS_H */
diff --git a/src/lib/ecore_x/Ecore_X_Cursor.h b/src/lib/ecore_x/Ecore_X_Cursor.h
new file mode 100644
index 0000000000..807541e596
--- /dev/null
+++ b/src/lib/ecore_x/Ecore_X_Cursor.h
@@ -0,0 +1,87 @@
+#ifndef _ECORE_X_CURSOR_H
+#define _ECORE_X_CURSOR_H
+
+/**
+ * @file
+ * @brief Defines the various cursor types for the X Windows system.
+ */
+
+#define ECORE_X_CURSOR_X 0
+#define ECORE_X_CURSOR_ARROW 2
+#define ECORE_X_CURSOR_BASED_ARROW_DOWN 4
+#define ECORE_X_CURSOR_UP 6
+#define ECORE_X_CURSOR_BOAT 8
+#define ECORE_X_CURSOR_BOGOSITY 10
+#define ECORE_X_CURSOR_BOTTOM_LEFT_CORNER 12
+#define ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER 14
+#define ECORE_X_CURSOR_BOTTOM_SIDE 16
+#define ECORE_X_CURSOR_BOTTOM_TEE 18
+#define ECORE_X_CURSOR_BOX_SPIRAL 20
+#define ECORE_X_CURSOR_CENTER_PTR 22
+#define ECORE_X_CURSOR_CIRCLE 24
+#define ECORE_X_CURSOR_CLOCK 26
+#define ECORE_X_CURSOR_COFFEE_MUG 28
+#define ECORE_X_CURSOR_CROSS 30
+#define ECORE_X_CURSOR_CROSS_REVERSE 32
+#define ECORE_X_CURSOR_CROSSHAIR 34
+#define ECORE_X_CURSOR_DIAMOND_CROSS 36
+#define ECORE_X_CURSOR_DOT 38
+#define ECORE_X_CURSOR_DOT_BOX_MASK 40
+#define ECORE_X_CURSOR_DOUBLE_ARROW 42
+#define ECORE_X_CURSOR_DRAFT_LARGE 44
+#define ECORE_X_CURSOR_DRAFT_SMALL 46
+#define ECORE_X_CURSOR_DRAPED_BOX 48
+#define ECORE_X_CURSOR_EXCHANGE 50
+#define ECORE_X_CURSOR_FLEUR 52
+#define ECORE_X_CURSOR_GOBBLER 54
+#define ECORE_X_CURSOR_GUMBY 56
+#define ECORE_X_CURSOR_HAND1 58
+#define ECORE_X_CURSOR_HAND2 60
+#define ECORE_X_CURSOR_HEART 62
+#define ECORE_X_CURSOR_ICON 64
+#define ECORE_X_CURSOR_IRON_CROSS 66
+#define ECORE_X_CURSOR_LEFT_PTR 68
+#define ECORE_X_CURSOR_LEFT_SIDE 70
+#define ECORE_X_CURSOR_LEFT_TEE 72
+#define ECORE_X_CURSOR_LEFTBUTTON 74
+#define ECORE_X_CURSOR_LL_ANGLE 76
+#define ECORE_X_CURSOR_LR_ANGLE 78
+#define ECORE_X_CURSOR_MAN 80
+#define ECORE_X_CURSOR_MIDDLEBUTTON 82
+#define ECORE_X_CURSOR_MOUSE 84
+#define ECORE_X_CURSOR_PENCIL 86
+#define ECORE_X_CURSOR_PIRATE 88
+#define ECORE_X_CURSOR_PLUS 90
+#define ECORE_X_CURSOR_QUESTION_ARROW 92
+#define ECORE_X_CURSOR_RIGHT_PTR 94
+#define ECORE_X_CURSOR_RIGHT_SIDE 96
+#define ECORE_X_CURSOR_RIGHT_TEE 98
+#define ECORE_X_CURSOR_RIGHTBUTTON 100
+#define ECORE_X_CURSOR_RTL_LOGO 102
+#define ECORE_X_CURSOR_SAILBOAT 104
+#define ECORE_X_CURSOR_SB_DOWN_ARROW 106
+#define ECORE_X_CURSOR_SB_H_DOUBLE_ARROW 108
+#define ECORE_X_CURSOR_SB_LEFT_ARROW 110
+#define ECORE_X_CURSOR_SB_RIGHT_ARROW 112
+#define ECORE_X_CURSOR_SB_UP_ARROW 114
+#define ECORE_X_CURSOR_SB_V_DOUBLE_ARROW 116
+#define ECORE_X_CURSOR_SHUTTLE 118
+#define ECORE_X_CURSOR_SIZING 120
+#define ECORE_X_CURSOR_SPIDER 122
+#define ECORE_X_CURSOR_SPRAYCAN 124
+#define ECORE_X_CURSOR_STAR 126
+#define ECORE_X_CURSOR_TARGET 128
+#define ECORE_X_CURSOR_TCROSS 130
+#define ECORE_X_CURSOR_TOP_LEFT_ARROW 132
+#define ECORE_X_CURSOR_TOP_LEFT_CORNER 134
+#define ECORE_X_CURSOR_TOP_RIGHT_CORNER 136
+#define ECORE_X_CURSOR_TOP_SIDE 138
+#define ECORE_X_CURSOR_TOP_TEE 140
+#define ECORE_X_CURSOR_TREK 142
+#define ECORE_X_CURSOR_UL_ANGLE 144
+#define ECORE_X_CURSOR_UMBRELLA 146
+#define ECORE_X_CURSOR_UR_ANGLE 148
+#define ECORE_X_CURSOR_WATCH 150
+#define ECORE_X_CURSOR_XTERM 152
+
+#endif // ifndef _ECORE_X_CURSOR_H
diff --git a/src/lib/ecore_x/ecore_x_atoms_decl.h b/src/lib/ecore_x/ecore_x_atoms_decl.h
new file mode 100644
index 0000000000..155283efe6
--- /dev/null
+++ b/src/lib/ecore_x/ecore_x_atoms_decl.h
@@ -0,0 +1,602 @@
+/* generic atoms */
+EAPI Ecore_X_Atom ECORE_X_ATOM_ATOM = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_CARDINAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_FILE_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_STRING = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_TEXT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WINDOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_PIXMAP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_VISUALID = 0;
+
+/* dnd atoms */
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_XDND = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_XDND = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_AWARE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ENTER = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_TYPE_LIST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_POSITION = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_COPY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_MOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_PRIVATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_ASK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LIST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LINK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_DESCRIPTION = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_PROXY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_STATUS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_LEAVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_DROP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_FINISHED = 0;
+
+/* dnd atoms that need to be exposed to the application interface */
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_COPY = 0;
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_MOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_LINK = 0;
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_ASK = 0;
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE = 0;
+
+/* old E atom */
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_FRAME_SIZE = 0;
+
+/* old Gnome atom */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WIN_LAYER = 0;
+
+/* ICCCM atoms */
+
+/* ICCCM: client properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_ICON_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_NORMAL_HINTS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_SIZE_HINTS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_HINTS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_CLASS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_TRANSIENT_FOR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_PROTOCOLS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_WINDOWS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_COMMAND = 0; /* obsolete */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_MACHINE = 0; /* obsolete */
+
+/* ICCCM: window manager properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_ICON_SIZE = 0;
+
+/* ICCCM: WM_STATE property */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_CHANGE_STATE = 0;
+
+/* ICCCM: WM_PROTOCOLS properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_TAKE_FOCUS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_SAVE_YOURSELF = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_DELETE_WINDOW = 0;
+
+/* ICCCM: WM_COLORMAP properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_NOTIFY = 0;
+
+/* ICCCM: session management properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_SM_CLIENT_ID = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_LEADER = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_WINDOW_ROLE = 0;
+
+/* Motif WM atom */
+EAPI Ecore_X_Atom ECORE_X_ATOM_MOTIF_WM_HINTS = 0;
+
+/* NetWM 1.3 atoms (http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html) */
+
+/*
+ * NetWM: Root Window Properties and related messages (complete)
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTED = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST_STACKING = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_VIEWPORT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_CURRENT_DESKTOP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_NAMES = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_ACTIVE_WINDOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WORKAREA = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_VIRTUAL_ROOTS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_LAYOUT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_SHOWING_DESKTOP = 0;
+
+/*
+ * NetWM: Other Root Window Messages (complete)
+ */
+
+/* pager */
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_CLOSE_WINDOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_MOVERESIZE_WINDOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_MOVERESIZE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_RESTACK_WINDOW = 0;
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS = 0;
+
+/*
+ * NetWM: Application Window Properties (complete)
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_DESKTOP = 0;
+
+/* window type */
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND = 0;
+
+/* state */
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MODAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_STICKY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SHADED = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_HIDDEN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_ABOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_BELOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION = 0;
+
+/* allowed actions */
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_RESIZE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_SHADE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_STICK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CLOSE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_ABOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_BELOW = 0;
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT_PARTIAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_PID = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_HANDLED_ICONS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_USER_TIME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_ID = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_FRAME_EXTENTS = 0;
+
+/*
+ * NetWM: Window Manager Protocols (complete)
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_PING = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER = 0;
+
+/*
+ * NetWM: Not in the spec
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_OPACITY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_SHADOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_SHADE = 0;
+
+/*
+ * Startup Notification (http://standards.freedesktop.org/startup-notification-spec/startup-notification-0.1.txt)
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_INFO = 0;
+
+/* selection atoms */
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_TARGETS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PRIMARY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_SECONDARY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_CLIPBOARD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_PRIMARY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_SECONDARY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD = 0;
+
+/* currently E specific virtual keyboard extension, aim to submit to netwm spec
+ * later */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME = 0;
+
+/* currently E specific illume extension */
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ZONE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ZONE_LIST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CONFORMANT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_SINGLE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_BACK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_HOME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLOSE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_HOME_NEW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_HOME_DEL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_START = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_END = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE_TOGGLE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_POSITION_UPDATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_ON = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE= 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN = 0;
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_COUNTER = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_BEGIN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_END = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_CANCEL = 0;
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_FLUSH = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_DUMP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_PIXMAP = 0;
+
+/* currently Emotion and E17 specific extension */
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_PARENT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_POSITION = 0;
+
+/* for sliding window */
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY = 0;
+
+/* for SDB(Samsung Debug Bridge) */
+EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT = 0;
+
+/* currently elementary and E specific extension */
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST = 0;
+
+typedef struct _Atom_Item Atom_Item;
+
+struct _Atom_Item
+{
+ const char *name;
+ Ecore_X_Atom *atom;
+};
+
+const Atom_Item atom_items[] =
+{
+ { "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_ILLUME_INDICATOR_STATE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE },
+ { "_E_ILLUME_INDICATOR_ON", &ECORE_X_ATOM_E_ILLUME_INDICATOR_ON },
+ { "_E_ILLUME_INDICATOR_OFF", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF },
+ { "_E_ILLUME_INDICATOR_OPACITY_MODE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE },
+ { "_E_ILLUME_INDICATOR_OPAQUE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE },
+ { "_E_ILLUME_INDICATOR_TRANSLUCENT", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT },
+ { "_E_ILLUME_INDICATOR_TRANSPARENT", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT },
+ { "_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLES", &ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE },
+ { "_E_ILLUME_ROTATE_WINDOW_ANGLE", &ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE },
+ { "_E_ILLUME_ROTATE_ROOT_ANGLE", &ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE },
+ { "_E_ILLUME_CLIPBOARD_STATE", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE },
+ { "_E_ILLUME_CLIPBOARD_ON", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON },
+ { "_E_ILLUME_CLIPBOARD_OFF", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF },
+ { "_E_ILLUME_CLIPBOARD_GEOMETRY", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY },
+ { "_E_ILLUME_WINDOW_STATE", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE },
+ { "_E_ILLUME_WINDOW_STATE_NORMAL", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL },
+ { "_E_ILLUME_WINDOW_STATE_FLOATING", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING },
+ { "_E_ILLUME_ACCESS_CONTROL", &ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL },
+ { "_E_ILLUME_ACCESS_ACTION_NEXT", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT },
+ { "_E_ILLUME_ACCESS_ACTION_PREV", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV },
+ { "_E_ILLUME_ACCESS_ACTION_ACTIVATE", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE },
+ { "_E_ILLUME_ACCESS_ACTION_READ", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ },
+ { "_E_ILLUME_ACCESS_ACTION_READ_NEXT", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT },
+ { "_E_ILLUME_ACCESS_ACTION_READ_PREV", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV },
+ { "_E_ILLUME_ACCESS_ACTION_UP", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP },
+ { "_E_ILLUME_ACCESS_ACTION_DOWN", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN },
+ { "_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 },
+ { "_E_VIDEO_PARENT", &ECORE_X_ATOM_E_VIDEO_PARENT },
+ { "_E_VIDEO_POSITION", &ECORE_X_ATOM_E_VIDEO_POSITION }
+};
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb.c b/src/lib/ecore_x/xcb/ecore_xcb.c
new file mode 100644
index 0000000000..2f1e1a2601
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb.c
@@ -0,0 +1,1583 @@
+#include "ecore_xcb_private.h"
+#include <X11/Xlib-xcb.h>
+#include <dlfcn.h>
+
+/* 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 EINA_UNUSED);
+static Eina_Bool _ecore_xcb_fd_handle_buff(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED);
+static Eina_Bool _ecore_xcb_idle_enter(void *data EINA_UNUSED);
+
+/* local variables */
+static int _ecore_xcb_init_count = 0;
+static int _ecore_xcb_grab_count = 0;
+static Ecore_Fd_Handler *_ecore_xcb_fd_handler = NULL;
+static xcb_generic_event_t *_ecore_xcb_event_buffered = NULL;
+static Ecore_Idle_Enterer *_ecore_xcb_idle_enterer = 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;
+Ecore_X_Atom _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_NUM];
+double _ecore_xcb_double_click_time = 0.25;
+
+/**
+ * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions
+ *
+ * Functions that start and shut down the Ecore X Library.
+ */
+
+/**
+ * Initialize the X display connection to the given display.
+ *
+ * @param name Display target name. If @c NULL, the default display is
+ * assumed.
+ * @return The number of times the library has been initialized without
+ * being shut down. 0 is returned if an error occurs.
+ * @ingroup Ecore_X_Init_Group
+ */
+EAPI int
+ecore_x_init(const char *name)
+{
+ char *gl = NULL;
+ uint32_t mask, list[1];
+
+ /* check if we have initialized already */
+ if (++_ecore_xcb_init_count != 1)
+ return _ecore_xcb_init_count;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ /* try to initialize eina */
+ if (!eina_init()) return --_ecore_xcb_init_count;
+
+ /* 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");
+ eina_shutdown();
+ return --_ecore_xcb_init_count;
+ }
+
+ /* 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;
+ }
+
+ /* 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;
+ }
+
+ /* NB: XLib has XInitThreads */
+
+ /* check for env var which says we are not going to use GL @ all
+ *
+ * NB: This is done because if someone wants a 'pure' xcb implementation
+ * of ecore_x, all they need do is export this variable in the environment
+ * and ecore_x will not use xlib stuff at all.
+ *
+ * The upside is you can get pure xcb-based ecore_x (w/ all the speed), but
+ * there is a down-side here in that you cannot get OpenGL without XLib :(
+ */
+ if ((gl = getenv("ECORE_X_NO_XLIB")))
+ {
+ /* we found the env var that says 'Yes, we are not ever gonna try
+ * OpenGL so it is safe to not use XLib at all' */
+
+ /* try to connect to the display server */
+ _ecore_xcb_conn = xcb_connect(name, NULL);
+ }
+ else
+ {
+ /* env var was not specified, so we will assume that the user
+ * may want opengl @ some point. connect this way for opengl to work */
+ void *libxcb, *libxlib;
+ Display *(*_real_display)(const char *display);
+ xcb_connection_t *(*_real_connection)(Display * dpy);
+ void (*_real_queue)(Display *dpy, enum XEventQueueOwner owner);
+ int (*_real_close)(Display *dpy);
+#ifdef EVAS_FRAME_QUEUING
+ Status (*_real_threads)(void);
+#endif
+
+ /* want to dlopen here to avoid actual library linkage */
+ libxlib = dlopen("libX11.so", (RTLD_LAZY | RTLD_GLOBAL));
+ if (!libxlib)
+ libxlib = dlopen("libX11.so.6", (RTLD_LAZY | RTLD_GLOBAL));
+ if (!libxlib)
+ libxlib = dlopen("libX11.so.6.3.0", (RTLD_LAZY | RTLD_GLOBAL));
+ if (!libxlib)
+ {
+ ERR("Could not dlsym to libX11");
+ /* unregister log domain */
+ 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;
+ }
+
+ libxcb = dlopen("libX11-xcb.so", (RTLD_LAZY | RTLD_GLOBAL));
+ if (!libxcb)
+ libxcb = dlopen("libX11-xcb.so.1", (RTLD_LAZY | RTLD_GLOBAL));
+ if (!libxcb)
+ libxcb = dlopen("libX11-xcb.so.1.0.0", (RTLD_LAZY | RTLD_GLOBAL));
+ if (!libxcb)
+ {
+ ERR("Could not dlsym to libX11-xcb");
+ /* unregister log domain */
+ 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;
+ }
+
+ _real_display = dlsym(libxlib, "XOpenDisplay");
+ _real_close = dlsym(libxlib, "XCloseDisplay");
+ _real_connection = dlsym(libxcb, "XGetXCBConnection");
+ _real_queue = dlsym(libxcb, "XSetEventQueueOwner");
+#ifdef EVAS_FRAME_QUEUING
+ _real_threads = dlsym(libxlib, "XInitThreads");
+#endif
+
+ if (_real_display)
+ {
+#ifdef EVAS_FRAME_QUEUING
+ if (_real_threads) _real_threads();
+#endif
+ _ecore_xcb_display = _real_display(name);
+ if (!_ecore_xcb_display)
+ {
+ ERR("Could not open Display via XLib");
+ /* unregister log domain */
+ 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;
+ }
+ if (_real_connection)
+ _ecore_xcb_conn = _real_connection(_ecore_xcb_display);
+ if (!_ecore_xcb_conn)
+ {
+ ERR("Could not get XCB Connection from XLib");
+
+ if (_real_close) _real_close(_ecore_xcb_display);
+
+ /* unregister log domain */
+ 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;
+ }
+ if (_real_queue)
+ _real_queue(_ecore_xcb_display, XCBOwnsEventQueue);
+ }
+ }
+
+ 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;
+ }
+
+ /* grab the default screen */
+ _ecore_xcb_screen =
+ xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data;
+
+ /* 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 */
+
+ /* prefetch extension data */
+ _ecore_xcb_extensions_init();
+
+ /* finalize extensions */
+ _ecore_xcb_extensions_finalize();
+
+ /* 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);
+
+ /* setup xcb events */
+ _ecore_xcb_events_init();
+
+ /* setup xcb keymasks */
+ _ecore_xcb_keymap_init();
+
+ /* finalize xcb keymasks */
+ _ecore_xcb_keymap_finalize();
+
+ /* 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);
+
+ /* prefetch atoms */
+ _ecore_xcb_atoms_init();
+
+ /* finalize atoms */
+ _ecore_xcb_atoms_finalize();
+
+ /* icccm_init: dummy function */
+ ecore_x_icccm_init();
+
+ /* setup netwm */
+ ecore_x_netwm_init();
+
+ /* old e hints init: dummy function */
+ ecore_x_e_init();
+
+ _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;
+
+ /* setup selection */
+ _ecore_xcb_selection_init();
+
+ /* setup dnd */
+ _ecore_xcb_dnd_init();
+
+ _ecore_xcb_idle_enterer =
+ ecore_idle_enterer_add(_ecore_xcb_idle_enter, NULL);
+
+ return _ecore_xcb_init_count;
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * In shutting down the library, the X display connection is terminated
+ * and any event handlers for it are removed.
+ *
+ * @return The number of times the library has been initialized without
+ * being shut down.
+ * @ingroup Ecore_X_Init_Group
+ */
+EAPI int
+ecore_x_shutdown(void)
+{
+ return _ecore_xcb_shutdown(EINA_TRUE);
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * As ecore_x_shutdown, except do not close Display, only connection.
+ *
+ * @return The number of times the library has been initialized without
+ * being shut down. 0 is returned if an error occurs.
+ * @ingroup Ecore_X_Init_Group
+ */
+EAPI int
+ecore_x_disconnect(void)
+{
+ return _ecore_xcb_shutdown(EINA_FALSE);
+}
+
+/**
+ * @defgroup Ecore_X_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.
+ */
+
+/**
+ * Sends all X commands in the X Display buffer.
+ * @ingroup Ecore_X_Flush_Group
+ */
+EAPI void
+ecore_x_flush(void)
+{
+// LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ CHECK_XCB_CONN;
+ xcb_flush(_ecore_xcb_conn);
+}
+
+/**
+ * Retrieves the Ecore_X_Screen handle used for the current X connection.
+ * @return The current default screen.
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+EAPI Ecore_X_Screen *
+ecore_x_default_screen_get(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return (Ecore_X_Screen *)_ecore_xcb_screen;
+}
+
+EAPI Ecore_X_Connection *
+ecore_x_connection_get(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ CHECK_XCB_CONN;
+ return (Ecore_X_Connection *)_ecore_xcb_conn;
+}
+
+/**
+ * Return the last event time
+ */
+EAPI Ecore_X_Time
+ecore_x_current_time_get(void)
+{
+ return _ecore_xcb_events_last_time_get();
+}
+
+/**
+ * Flushes the command buffer and waits until all requests have been
+ * processed by the server.
+ * @ingroup Ecore_X_Flush_Group
+ */
+EAPI void
+ecore_x_sync(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ CHECK_XCB_CONN;
+ free(xcb_get_input_focus_reply(_ecore_xcb_conn,
+ xcb_get_input_focus_unchecked(_ecore_xcb_conn),
+ NULL));
+}
+
+EAPI void
+ecore_x_grab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ CHECK_XCB_CONN;
+ _ecore_xcb_grab_count++;
+ if (_ecore_xcb_grab_count == 1)
+ xcb_grab_server(_ecore_xcb_conn);
+}
+
+EAPI void
+ecore_x_ungrab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ CHECK_XCB_CONN;
+ _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);
+}
+
+/**
+ * Send client message with given type and format 32.
+ *
+ * @param win The window the message is sent to.
+ * @param type The client message type.
+ * @param mask The mask of the message to be sent.
+ * @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
+ *
+ * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
+ */
+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)
+{
+ xcb_client_message_event_t ev;
+ xcb_void_cookie_t cookie;
+ xcb_generic_error_t *err;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ memset(&ev, 0, sizeof(xcb_client_message_event_t));
+
+ 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;
+
+ cookie = xcb_send_event(_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;
+ }
+
+ return EINA_TRUE;
+}
+
+/**
+ * Send client message with given type and format 8.
+ *
+ * @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 @c 20.
+ *
+ * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type,
+ const void *data, int len)
+{
+ xcb_client_message_event_t ev;
+ xcb_void_cookie_t cookie;
+ xcb_generic_error_t *err;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ memset(&ev, 0, sizeof(xcb_client_message_event_t));
+
+ 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);
+
+ cookie = xcb_send_event(_ecore_xcb_conn, 0, win,
+ XCB_EVENT_MASK_NO_EVENT, (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;
+ }
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b)
+{
+ 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__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ memset(&ev, 0, sizeof(xcb_button_press_event_t));
+
+ 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);
+
+ vcookie = xcb_send_event(_ecore_xcb_conn, 1, win,
+ XCB_EVENT_MASK_BUTTON_PRESS, (const char *)&ev);
+
+ err = xcb_request_check(_ecore_xcb_conn, vcookie);
+ if (err)
+ {
+ _ecore_xcb_error_handle(err);
+ free(err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b)
+{
+ 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ memset(&ev, 0, sizeof(xcb_button_release_event_t));
+
+ 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);
+
+ vcookie = xcb_send_event(_ecore_xcb_conn, 1, win,
+ XCB_EVENT_MASK_BUTTON_RELEASE, (const char *)&ev);
+
+ err = xcb_request_check(_ecore_xcb_conn, vcookie);
+ if (err)
+ {
+ _ecore_xcb_error_handle(err);
+ free(err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y)
+{
+ 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ memset(&ev, 0, sizeof(xcb_motion_notify_event_t));
+
+ 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);
+
+ vcookie = xcb_send_event(_ecore_xcb_conn, 1, win,
+ XCB_EVENT_MASK_POINTER_MOTION, (const char *)&ev);
+
+ err = xcb_request_check(_ecore_xcb_conn, vcookie);
+ if (err)
+ {
+ _ecore_xcb_error_handle(err);
+ free(err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_in_send(Ecore_X_Window win, int x, int y)
+{
+ xcb_translate_coordinates_cookie_t cookie;
+ xcb_translate_coordinates_reply_t *reply;
+ xcb_enter_notify_event_t ev;
+ xcb_void_cookie_t vcookie;
+ xcb_generic_error_t *err;
+ Ecore_X_Window root = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ memset(&ev, 0, sizeof(xcb_enter_notify_event_t));
+
+ ev.response_type = XCB_ENTER_NOTIFY;
+ ev.event = win;
+ ev.child = win;
+ ev.root = root;
+ ev.event_x = x;
+ ev.event_y = y;
+ ev.same_screen_focus = 1;
+ ev.mode = XCB_NOTIFY_MODE_NORMAL;
+ ev.detail = XCB_NOTIFY_DETAIL_NONLINEAR;
+ /* ev.focus = 0; */
+ ev.state = 0;
+ ev.root_x = reply->dst_x;
+ ev.root_y = reply->dst_y;
+ ev.time = ecore_x_current_time_get();
+ free(reply);
+
+ vcookie = xcb_send_event(_ecore_xcb_conn, 1, win,
+ XCB_EVENT_MASK_ENTER_WINDOW, (const char *)&ev);
+
+ err = xcb_request_check(_ecore_xcb_conn, vcookie);
+ if (err)
+ {
+ _ecore_xcb_error_handle(err);
+ free(err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_out_send(Ecore_X_Window win, int x, int y)
+{
+ xcb_translate_coordinates_cookie_t cookie;
+ xcb_translate_coordinates_reply_t *reply;
+ xcb_leave_notify_event_t ev;
+ xcb_void_cookie_t vcookie;
+ xcb_generic_error_t *err;
+ Ecore_X_Window root = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ memset(&ev, 0, sizeof(xcb_leave_notify_event_t));
+
+ ev.response_type = XCB_LEAVE_NOTIFY;
+ ev.event = win;
+ ev.child = win;
+ ev.root = root;
+ ev.event_x = x;
+ ev.event_y = y;
+ ev.same_screen_focus = 1;
+ ev.mode = XCB_NOTIFY_MODE_NORMAL;
+ ev.detail = XCB_NOTIFY_DETAIL_NONLINEAR;
+ /* ev.focus = 0; */
+ ev.state = 0;
+ ev.root_x = reply->dst_x;
+ ev.root_y = reply->dst_y;
+ ev.time = ecore_x_current_time_get();
+ free(reply);
+
+ vcookie = xcb_send_event(_ecore_xcb_conn, 1, win,
+ XCB_EVENT_MASK_LEAVE_WINDOW, (const char *)&ev);
+
+ err = xcb_request_check(_ecore_xcb_conn, vcookie);
+ if (err)
+ {
+ _ecore_xcb_error_handle(err);
+ free(err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_keyboard_grab(Ecore_X_Window win)
+{
+ xcb_grab_keyboard_cookie_t cookie;
+ xcb_grab_keyboard_reply_t *reply;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+}
+
+EAPI void
+ecore_x_keyboard_ungrab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_ungrab_keyboard(_ecore_xcb_conn, XCB_CURRENT_TIME);
+}
+
+EAPI void
+ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y)
+{
+ xcb_query_pointer_cookie_t cookie;
+ xcb_query_pointer_reply_t *reply;
+
+// LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+// if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ if (x) *x = -1;
+ if (y) *y = -1;
+
+ cookie = xcb_query_pointer_unchecked(_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)
+{
+ xcb_void_cookie_t vcookie;
+ xcb_generic_error_t *err;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ vcookie =
+ xcb_change_pointer_control_checked(_ecore_xcb_conn,
+ accel_num, accel_denom, threshold,
+ 1, 1);
+ err = xcb_request_check(_ecore_xcb_conn, vcookie);
+ if (err)
+ {
+ _ecore_xcb_error_handle(err);
+ free(err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (accel_num) *accel_num = 0;
+ if (accel_denom) *accel_denom = 0;
+ if (threshold) *threshold = 0;
+
+ 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 (accel_num) *accel_num = reply->acceleration_numerator;
+ if (accel_denom) *accel_denom = reply->acceleration_denominator;
+ if (threshold) *threshold = reply->threshold;
+ free(reply);
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_pointer_mapping_set(unsigned char *map, int nmap)
+{
+ xcb_set_pointer_mapping_cookie_t cookie;
+ xcb_set_pointer_mapping_reply_t *reply;
+ Eina_Bool ret = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ if (reply->status == XCB_MAPPING_STATUS_SUCCESS)
+ ret = EINA_TRUE;
+
+ 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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 EINA_FALSE;
+
+ nmap = xcb_get_pointer_mapping_map_length(reply);
+ if (nmap <= 0)
+ {
+ free(reply);
+ return EINA_FALSE;
+ }
+
+ if (map)
+ {
+ uint8_t *tmp;
+ int i = 0;
+
+ tmp = xcb_get_pointer_mapping_map(reply);
+ for (i = 0; i < nmap; i++)
+ map[i] = tmp[i];
+ }
+
+ free(reply);
+ return EINA_TRUE;
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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 EINA_FALSE;
+
+ ret = (reply->status == XCB_GRAB_STATUS_SUCCESS) ? EINA_TRUE : EINA_FALSE;
+
+ free(reply);
+ return ret;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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 EINA_FALSE;
+
+ ret = (reply->status == XCB_GRAB_STATUS_SUCCESS) ? EINA_TRUE : EINA_FALSE;
+
+ free(reply);
+ return ret;
+}
+
+EAPI void
+ecore_x_pointer_ungrab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_ungrab_pointer(_ecore_xcb_conn, XCB_CURRENT_TIME);
+}
+
+EAPI Eina_Bool
+ecore_x_pointer_warp(Ecore_X_Window win, int x, int y)
+{
+ xcb_void_cookie_t vcookie;
+ xcb_generic_error_t *err;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ vcookie =
+ xcb_warp_pointer_checked(_ecore_xcb_conn, XCB_NONE, win, 0, 0, 0, 0, x, y);
+ err = xcb_request_check(_ecore_xcb_conn, vcookie);
+ if (err)
+ {
+ _ecore_xcb_error_handle(err);
+ free(err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+/**
+ * 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).
+ *
+ * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_bell(int percent)
+{
+ xcb_void_cookie_t cookie;
+ xcb_generic_error_t *err;
+
+ CHECK_XCB_CONN;
+
+ // 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 EINA_TRUE;
+}
+
+EAPI void
+ecore_x_display_size_get(Ecore_X_Display *dsp EINA_UNUSED, int *w, int *h)
+{
+ xcb_screen_t *screen;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ /* grab the default screen */
+ screen = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data;
+ if (w) *w = screen->width_in_pixels;
+ if (h) *h = screen->height_in_pixels;
+}
+
+EAPI unsigned long
+ecore_x_display_black_pixel_get(Ecore_X_Display *dsp EINA_UNUSED)
+{
+ xcb_screen_t *screen;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ /* grab the default screen */
+ screen = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data;
+ return screen->black_pixel;
+}
+
+EAPI unsigned long
+ecore_x_display_white_pixel_get(Ecore_X_Display *dsp EINA_UNUSED)
+{
+ xcb_screen_t *screen;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ /* grab the default screen */
+ screen = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data;
+ return screen->white_pixel;
+}
+
+EAPI void
+ecore_x_pointer_last_xy_get(int *x, int *y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (x) *x = _ecore_xcb_event_last_root_x;
+ if (y) *y = _ecore_xcb_event_last_root_y;
+}
+
+EAPI void
+ecore_x_focus_reset(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_POINTER_ROOT,
+ ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ XCB_CURRENT_TIME);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_events_allow_all(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_allow_events(_ecore_xcb_conn, XCB_ALLOW_ASYNC_BOTH, XCB_CURRENT_TIME);
+// ecore_x_flush();
+}
+
+/**
+ * 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_kill_client(_ecore_xcb_conn, win);
+// ecore_x_flush();
+}
+
+/**
+ * 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 screens = 0, i = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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)
+ {
+ xcb_query_tree_cookie_t cookie;
+ xcb_query_tree_reply_t *reply;
+
+ 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, 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_ungrab();
+ ecore_x_sync(); // needed
+}
+
+/**
+ * Return the screen DPI
+ *
+ * This is a simplistic call to get DPI. It does not account for differing
+ * DPI in the x amd y axes nor does it account for multihead or xinerama and
+ * xrander where different parts of the screen may have differen DPI etc.
+ *
+ * @return the general screen DPI (dots/pixels per inch).
+ */
+EAPI int
+ecore_x_dpi_get(void)
+{
+ uint16_t mw = 0, w = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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;
+}
+
+/**
+ * @defgroup Ecore_X_Display_Attr_Group X Display Attributes
+ *
+ * Functions that set and retrieve X display attributes.
+ */
+
+/**
+ * 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)
+{
+ char *gl = NULL;
+
+ CHECK_XCB_CONN;
+
+ /* if we have the 'dont use xlib' env var, then we are not using
+ * XLib and thus cannot return a real XDisplay.
+ *
+ * NB: This may break EFL in some places and needs lots of testing !!! */
+ if ((gl = getenv("ECORE_X_NO_XLIB")))
+ return (Ecore_X_Display *)_ecore_xcb_conn;
+ else /* we can safely return an XDisplay var */
+ return (Ecore_X_Display *)_ecore_xcb_display;
+}
+
+/**
+ * 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__);
+ CHECK_XCB_CONN;
+ return xcb_get_file_descriptor(_ecore_xcb_conn);
+}
+
+EAPI void
+ecore_x_passive_grab_replay_func_set(Eina_Bool (*func)(void *data, int type, void *event),
+ void *data)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _ecore_xcb_window_grab_replay_func = func;
+ _ecore_xcb_window_grab_replay_data = data;
+}
+
+/**
+ * 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_screen_t *s;
+
+ 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;
+}
+
+/**
+ * Retrieves the count of screens.
+ *
+ * @return The count of screens.
+ * @ingroup Ecore_X_Display_Attr_Group
+ *
+ * @since 1.1
+ */
+EAPI int
+ecore_x_screen_count_get(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ return xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn));
+}
+
+/**
+ * Retrieves the index number of the given screen.
+ *
+ * @param screen The screen for which index will be gotten.
+ * @return The index number of the screen.
+ * @ingroup Ecore_X_Display_Attr_Group
+ *
+ * @since 1.1
+ */
+EAPI int
+ecore_x_screen_index_get(const Ecore_X_Screen *screen)
+{
+ xcb_screen_iterator_t iter;
+ int i = 0;
+
+ CHECK_XCB_CONN;
+
+ iter =
+ xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
+ for (; iter.rem; xcb_screen_next(&iter))
+ {
+ if (iter.data == (xcb_screen_t *)screen)
+ return i;
+ i++;
+ }
+
+ return 0;
+}
+
+/**
+ * Retrieves the screen based on index number.
+ *
+ * @param idx The index that will be used to retrieve the screen.
+ * @return The Ecore_X_Screen at this index.
+ * @ingroup Ecore_X_Display_Attr_Group
+ *
+ * @since 1.1
+ */
+EAPI Ecore_X_Screen *
+ecore_x_screen_get(int idx)
+{
+ xcb_screen_iterator_t iter;
+ int i = 0;
+
+ CHECK_XCB_CONN;
+
+ iter =
+ xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
+ for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
+ if (i == idx) return iter.data;
+
+ return NULL;
+}
+
+EAPI unsigned int
+ecore_x_visual_id_get(Ecore_X_Visual visual)
+{
+ return ((xcb_visualtype_t *)visual)->visual_id;
+}
+
+/**
+ * Retrieve the default Visual.
+ *
+ * @param disp The Display to get the Default Visual from
+ * @param screen The Screen.
+ *
+ * @return The default visual.
+ * @since 1.1.0
+ */
+EAPI Ecore_X_Visual
+ecore_x_default_visual_get(Ecore_X_Display *disp EINA_UNUSED, Ecore_X_Screen *screen)
+{
+ xcb_screen_t *s;
+ xcb_depth_iterator_t diter;
+ xcb_visualtype_iterator_t viter;
+
+ CHECK_XCB_CONN;
+
+ s = (xcb_screen_t *)screen;
+ diter = xcb_screen_allowed_depths_iterator(s);
+ 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 == s->root_visual)
+ return viter.data;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Retrieve the default Colormap.
+ *
+ * @param disp The Display to get the Default Colormap from
+ * @param screen The Screen.
+ *
+ * @return The default colormap.
+ * @since 1.1.0
+ */
+EAPI Ecore_X_Colormap
+ecore_x_default_colormap_get(Ecore_X_Display *disp EINA_UNUSED, Ecore_X_Screen *screen)
+{
+ xcb_screen_t *s;
+
+ s = (xcb_screen_t *)screen;
+ return s->default_colormap;
+}
+
+/**
+ * Retrieve the default depth.
+ *
+ * @param disp The Display to get the Default Depth from
+ * @param screen The Screen.
+ *
+ * @return The default depth.
+ * @since 1.1.0
+ */
+EAPI int
+ecore_x_default_depth_get(Ecore_X_Display *disp EINA_UNUSED, Ecore_X_Screen *screen)
+{
+ xcb_screen_t *s;
+
+ s = (xcb_screen_t *)screen;
+ return s->root_depth;
+}
+
+EAPI void
+ecore_x_xkb_select_group(int group)
+{
+ // XXX: implement me */
+}
+
+/**
+ * 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)
+{
+ if (t < 0.0) t = 0.0;
+ _ecore_xcb_double_click_time = t;
+}
+
+/**
+ * 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ ecore_idle_enterer_del(_ecore_xcb_idle_enterer);
+ _ecore_xcb_idle_enterer = NULL;
+
+ if (_ecore_xcb_fd_handler)
+ ecore_main_fd_handler_del(_ecore_xcb_fd_handler);
+
+ /* disconnect from display server */
+ if (close_display)
+ xcb_disconnect(_ecore_xcb_conn);
+ else
+ {
+ close(xcb_get_file_descriptor(_ecore_xcb_conn));
+ _ecore_xcb_conn = NULL;
+ }
+
+ /* shutdown events */
+ _ecore_xcb_events_shutdown();
+
+ /* shutdown input extension */
+ _ecore_xcb_input_shutdown();
+
+ /* shutdown gesture extension */
+ _ecore_xcb_gesture_shutdown();
+
+ /* shutdown selection */
+ _ecore_xcb_selection_shutdown();
+
+ /* shutdown dnd */
+ _ecore_xcb_dnd_shutdown();
+
+ /* shutdown netwm */
+ ecore_x_netwm_shutdown();
+
+ /* shutdown keymap */
+ _ecore_xcb_keymap_shutdown();
+
+ /* shutdown ecore_event */
+ ecore_event_shutdown();
+
+ /* shutdown ecore */
+ ecore_shutdown();
+
+ /* unregister log domain */
+ eina_log_domain_unregister(_ecore_xcb_log_dom);
+ _ecore_xcb_log_dom = -1;
+
+ /* shutdown eina */
+ eina_shutdown();
+
+ return _ecore_xcb_init_count;
+}
+
+static Eina_Bool
+_ecore_xcb_fd_handle(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
+{
+ xcb_connection_t *conn;
+ xcb_generic_event_t *ev = NULL;
+
+ conn = (xcb_connection_t *)data;
+
+ if (_ecore_xcb_event_buffered)
+ {
+ _ecore_xcb_events_handle(_ecore_xcb_event_buffered);
+ free(_ecore_xcb_event_buffered);
+ _ecore_xcb_event_buffered = NULL;
+ }
+
+// xcb_flush(conn);
+
+ while ((ev = xcb_poll_for_event(conn)))
+ {
+ /* NB: Ecore Xlib uses filterevent for xim, but xcb does not support
+ * xim, so no need for it here */
+
+ /* check for errors first */
+ if (xcb_connection_has_error(conn))
+ {
+ xcb_generic_error_t *err;
+
+ err = (xcb_generic_error_t *)ev;
+ _ecore_xcb_io_error_handle(err);
+ }
+ else
+ {
+ /* FIXME: Filter event for XIM */
+ _ecore_xcb_events_handle(ev);
+ free(ev);
+ }
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_ecore_xcb_fd_handle_buff(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
+{
+ xcb_connection_t *conn;
+ xcb_generic_event_t *ev = NULL;
+
+ conn = (xcb_connection_t *)data;
+ ev = xcb_poll_for_event(conn);
+ if (ev)
+ {
+ /* check for errors first */
+ if (xcb_connection_has_error(conn))
+ {
+ xcb_generic_error_t *err;
+
+ err = (xcb_generic_error_t *)ev;
+ _ecore_xcb_io_error_handle(err);
+ return ECORE_CALLBACK_CANCEL;
+ }
+ _ecore_xcb_event_buffered = ev;
+ return ECORE_CALLBACK_RENEW;
+ }
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_ecore_xcb_idle_enter(void *data EINA_UNUSED)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_flush(_ecore_xcb_conn);
+ return ECORE_CALLBACK_RENEW;
+}
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_atoms.c b/src/lib/ecore_x/xcb/ecore_xcb_atoms.c
new file mode 100644
index 0000000000..c8c217eec7
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_atoms.c
@@ -0,0 +1,149 @@
+#include "ecore_xcb_private.h"
+#include "ecore_x_atoms_decl.h"
+
+/* NB: Increment if you add new atoms */
+#define ECORE_X_ATOMS_COUNT 199
+
+/* local function prototypes */
+
+/* local variables */
+static xcb_intern_atom_cookie_t cookies[ECORE_X_ATOMS_COUNT];
+
+void
+_ecore_xcb_atoms_init(void)
+{
+ int i = 0, num = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ num = (sizeof(atom_items) / sizeof(Atom_Item));
+ for (i = 0; i < num; i++)
+ {
+ cookies[i] =
+ xcb_intern_atom_unchecked(_ecore_xcb_conn, 0,
+ strlen(atom_items[i].name), atom_items[i].name);
+ }
+}
+
+void
+_ecore_xcb_atoms_finalize(void)
+{
+ int i = 0, num = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ num = (sizeof(atom_items) / sizeof(Atom_Item));
+ 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;
+ *(atom_items[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.
+ *
+ * @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__);
+ CHECK_XCB_CONN;
+
+ 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__);
+ CHECK_XCB_CONN;
+
+ 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';
+
+ free(reply);
+ 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__);
+ CHECK_XCB_CONN;
+
+ for (i = 0; i < num; i++)
+ {
+ cookies[i] =
+ xcb_intern_atom_unchecked(_ecore_xcb_conn, 0,
+ strlen(names[i]), names[i]);
+ }
+ for (i = 0; i < num; i++)
+ {
+ xcb_intern_atom_reply_t *reply = NULL;
+
+ if (!(reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], 0)))
+ continue;
+ atoms[i] = reply->atom;
+ free(reply);
+ }
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_composite.c b/src/lib/ecore_x/xcb/ecore_xcb_composite.c
new file mode 100644
index 0000000000..0d3b44e4aa
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_composite.c
@@ -0,0 +1,290 @@
+#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
+ */
+
+/**
+ * Return whether the Composite Extension is available
+ *
+ * @return @c EINA_TRUE is the Composite Extension is available, @c EINA_FALSE
+ * if not.
+ *
+ * @ingroup Ecore_X_Composite_Group
+ */
+EAPI Eina_Bool
+ecore_x_composite_query(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _composite_avail;
+}
+
+EAPI void
+ecore_x_composite_redirect_window(Ecore_X_Window win,
+ Ecore_X_Composite_Update_Type type)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_composite_avail) return;
+
+#ifdef ECORE_XCB_COMPOSITE
+ uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC;
+
+ 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);
+// ecore_x_flush();
+#endif
+}
+
+EAPI void
+ecore_x_composite_redirect_subwindows(Ecore_X_Window win,
+ Ecore_X_Composite_Update_Type type)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_composite_avail) return;
+
+#ifdef ECORE_XCB_COMPOSITE
+ uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC;
+
+ 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);
+// ecore_x_flush();
+#endif
+}
+
+EAPI void
+ecore_x_composite_unredirect_window(Ecore_X_Window win,
+ Ecore_X_Composite_Update_Type type)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_composite_avail) return;
+
+#ifdef ECORE_XCB_COMPOSITE
+ uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC;
+
+ 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_window(_ecore_xcb_conn, win, update);
+// ecore_x_flush();
+#endif
+}
+
+EAPI void
+ecore_x_composite_unredirect_subwindows(Ecore_X_Window win,
+ Ecore_X_Composite_Update_Type type)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_composite_avail) return;
+
+#ifdef ECORE_XCB_COMPOSITE
+ uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC;
+
+ 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);
+// ecore_x_flush();
+#endif
+}
+
+EAPI Ecore_X_Pixmap
+ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win)
+{
+#ifdef ECORE_XCB_COMPOSITE
+ Ecore_X_Pixmap pmap = XCB_NONE;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_composite_avail) return XCB_NONE;
+
+#ifdef ECORE_XCB_COMPOSITE
+ pmap = xcb_generate_id(_ecore_xcb_conn);
+ xcb_composite_name_window_pixmap(_ecore_xcb_conn, win, pmap);
+// ecore_x_flush();
+#endif
+
+ return pmap;
+}
+
+EAPI void
+ecore_x_composite_window_events_disable(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_composite_avail) return;
+
+#ifdef ECORE_XCB_SHAPE
+ ecore_x_window_shape_input_rectangle_set(win, -1, -1, 1, 1);
+// ecore_x_flush();
+#else
+ return;
+ win = 0;
+#endif
+}
+
+EAPI void
+ecore_x_composite_window_events_enable(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_composite_avail) return;
+
+#ifdef ECORE_XCB_SHAPE
+ ecore_x_window_shape_input_rectangle_set(win, 0, 0, 65535, 65535);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_composite_avail) return 0;
+
+#ifdef ECORE_XCB_COMPOSITE
+ cookie = xcb_composite_get_overlay_window_unchecked(_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);
+// ecore_x_flush();
+#endif
+
+ return win;
+}
+
+EAPI void
+ecore_x_composite_render_window_disable(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_composite_avail) return;
+
+#ifdef ECORE_XCB_COMPOSITE
+ xcb_composite_release_overlay_window(_ecore_xcb_conn, win);
+// ecore_x_flush();
+#endif
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_cursor.c b/src/lib/ecore_x/xcb/ecore_xcb_cursor.c
new file mode 100644
index 0000000000..755df04e4f
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_cursor.c
@@ -0,0 +1,400 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_CURSOR
+# include <xcb/render.h>
+# include <xcb/xcb_renderutil.h>
+#endif
+
+/* local function prototypes */
+#ifdef ECORE_XCB_CURSOR
+static xcb_render_pictforminfo_t *_ecore_xcb_cursor_format_get(void);
+#endif
+static void _ecore_xcb_cursor_default_size_get(void);
+static void _ecore_xcb_cursor_dpi_size_get(void);
+static void _ecore_xcb_cursor_guess_size(void);
+#ifdef ECORE_XCB_CURSOR
+static Ecore_X_Cursor _ecore_xcb_cursor_image_load_cursor(xcb_image_t *img,
+ int hot_x,
+ int hot_y);
+#endif
+static void _ecore_xcb_cursor_image_destroy(xcb_image_t *img);
+
+/* local variables */
+static int _ecore_xcb_cursor_size = 0;
+static Eina_Bool _ecore_xcb_cursor = EINA_FALSE;
+#ifdef ECORE_XCB_CURSOR
+static uint32_t _ecore_xcb_cursor_format_id = 0;
+// static xcb_render_pictforminfo_t *_ecore_xcb_cursor_format = NULL;
+#endif
+
+void
+_ecore_xcb_cursor_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* NB: No-op */
+}
+
+void
+_ecore_xcb_cursor_finalize(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_CURSOR
+ _ecore_xcb_cursor = _ecore_xcb_render_argb_get();
+
+ /* find render pict format */
+ if (_ecore_xcb_cursor_format_id <= 0)
+ _ecore_xcb_cursor_format_id = _ecore_xcb_cursor_format_get()->id;
+#endif
+
+ /* try to grab cursor size from XDefaults */
+ _ecore_xcb_cursor_default_size_get();
+
+ /* if that failed, try to get it from Xft Dpi setting */
+ if (_ecore_xcb_cursor_size == 0)
+ _ecore_xcb_cursor_dpi_size_get();
+
+ /* if that failed, try to guess from display size */
+ if (_ecore_xcb_cursor_size == 0)
+ _ecore_xcb_cursor_guess_size();
+
+ /* NB: Would normally add theme stuff here, but E cursor does not support
+ * xcursor themes. Delay parsing that stuff out until such time if/when the
+ * user selects to use X Cursor, rather than E cursor */
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_CURSOR
+ if (_ecore_xcb_cursor)
+ {
+ img = _ecore_xcb_image_create_native(w, h, XCB_IMAGE_FORMAT_Z_PIXMAP,
+ 32, NULL, (w * h * sizeof(int)),
+ (uint8_t *)pixels);
+ cursor = _ecore_xcb_cursor_image_load_cursor(img, hot_x, hot_y);
+ _ecore_xcb_cursor_image_destroy(img);
+ return cursor;
+ }
+ else
+#endif
+ {
+ Ecore_X_GC gc;
+ xcb_pixmap_t pmap, mask;
+ 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}
+ };
+
+ img = _ecore_xcb_image_create_native(w, h, XCB_IMAGE_FORMAT_Z_PIXMAP,
+ 1, NULL, ~0, NULL);
+ if (img->data) free(img->data);
+ img->data = malloc(img->size);
+
+ pmap = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_pixmap(_ecore_xcb_conn, 1, pmap, win, w, h);
+ mask = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_pixmap(_ecore_xcb_conn, 1, mask, win, w, h);
+
+ 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++;
+ }
+ }
+
+ gc = ecore_x_gc_new(pmap, 0, NULL);
+ xcb_put_image(_ecore_xcb_conn, img->format, pmap, 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++;
+ }
+ }
+
+ gc = ecore_x_gc_new(mask, 0, NULL);
+ xcb_put_image(_ecore_xcb_conn, img->format, mask, gc, w, h,
+ 0, 0, 0, img->depth, img->size, img->data);
+ ecore_x_gc_free(gc);
+
+ if (img->data) free(img->data);
+ _ecore_xcb_cursor_image_destroy(img);
+
+ cursor = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_cursor(_ecore_xcb_conn, cursor, pmap, 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, pmap);
+ xcb_free_pixmap(_ecore_xcb_conn, mask);
+
+ return cursor;
+ }
+
+ return 0;
+}
+
+EAPI void
+ecore_x_cursor_free(Ecore_X_Cursor c)
+{
+// LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_free_cursor(_ecore_xcb_conn, c);
+}
+
+/*
+ * 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)
+{
+ Ecore_X_Cursor cursor = 0;
+ xcb_font_t font;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ font = xcb_generate_id(_ecore_xcb_conn);
+ xcb_open_font(_ecore_xcb_conn, font, strlen("cursor"), "cursor");
+
+ cursor = xcb_generate_id(_ecore_xcb_conn);
+ /* FIXME: Add request check ?? */
+ 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;
+}
+
+EAPI void
+ecore_x_cursor_size_set(int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _ecore_xcb_cursor_size = size;
+ /* NB: May need to adjust size of current cursors here */
+}
+
+EAPI int
+ecore_x_cursor_size_get(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return _ecore_xcb_cursor_size;
+}
+
+/* local functions */
+#ifdef ECORE_XCB_CURSOR
+static xcb_render_pictforminfo_t *
+_ecore_xcb_cursor_format_get(void)
+{
+ const xcb_render_query_pict_formats_reply_t *reply;
+ xcb_render_pictforminfo_t *ret = NULL;
+
+ CHECK_XCB_CONN;
+
+ reply = xcb_render_util_query_formats(_ecore_xcb_conn);
+ if (reply)
+ ret = xcb_render_util_find_standard_format(reply,
+ XCB_PICT_STANDARD_ARGB_32);
+
+ return ret;
+}
+
+#endif
+
+static void
+_ecore_xcb_cursor_default_size_get(void)
+{
+ char *s = NULL;
+ int v = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ s = getenv("XCURSOR_SIZE");
+ if (!s)
+ {
+ _ecore_xcb_xdefaults_init();
+ v = _ecore_xcb_xdefaults_int_get("Xcursor", "size");
+ _ecore_xcb_xdefaults_shutdown();
+ }
+ else
+ v = atoi(s);
+ if (v) _ecore_xcb_cursor_size = ((v * 16) / 72);
+}
+
+static void
+_ecore_xcb_cursor_dpi_size_get(void)
+{
+ int v = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _ecore_xcb_xdefaults_init();
+ v = _ecore_xcb_xdefaults_int_get("Xft", "dpi");
+ if (v) _ecore_xcb_cursor_size = ((v * 16) / 72);
+ _ecore_xcb_xdefaults_shutdown();
+}
+
+static void
+_ecore_xcb_cursor_guess_size(void)
+{
+ int w = 0, h = 0, s = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_screen_size_get(_ecore_xcb_screen, &w, &h);
+ if (h < w) s = h;
+ else s = w;
+ _ecore_xcb_cursor_size = (s / 48);
+}
+
+#ifdef ECORE_XCB_CURSOR
+static Ecore_X_Cursor
+_ecore_xcb_cursor_image_load_cursor(xcb_image_t *img,
+ int hot_x,
+ int hot_y)
+{
+ Ecore_X_Cursor cursor = 0;
+ Ecore_X_GC gc;
+ xcb_pixmap_t pmap;
+ xcb_render_picture_t pict;
+
+ CHECK_XCB_CONN;
+
+ pmap = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_pixmap(_ecore_xcb_conn, img->depth, pmap,
+ ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ img->width, img->height);
+
+ gc = ecore_x_gc_new(pmap, 0, NULL);
+ xcb_put_image(_ecore_xcb_conn, img->format, pmap, gc,
+ img->width, img->height, 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, pmap,
+ _ecore_xcb_cursor_format_id, 0, NULL);
+ xcb_free_pixmap(_ecore_xcb_conn, pmap);
+
+ 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;
+}
+
+#endif
+
+static void
+_ecore_xcb_cursor_image_destroy(xcb_image_t *img)
+{
+ CHECK_XCB_CONN;
+ if (img) xcb_image_destroy(img);
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_damage.c b/src/lib/ecore_x/xcb/ecore_xcb_damage.c
new file mode 100644
index 0000000000..deb3b9cb49
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_damage.c
@@ -0,0 +1,155 @@
+#include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_DAMAGE
+# include <xcb/damage.h>
+# endif
+
+/* local variables */
+static Eina_Bool _damage_avail = EINA_FALSE;
+
+/* external variables */
+int _ecore_xcb_event_damage = -1;
+
+void
+_ecore_xcb_damage_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_DAMAGE
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_damage_id);
+#endif
+}
+
+void
+_ecore_xcb_damage_finalize(void)
+{
+#ifdef ECORE_XCB_DAMAGE
+ const xcb_query_extension_reply_t *ext_reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#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)
+ {
+ _damage_avail = EINA_TRUE;
+ free(reply);
+ }
+
+ if (_damage_avail)
+ _ecore_xcb_event_damage = ext_reply->first_event;
+ }
+#endif
+}
+
+/**
+ * @defgroup Ecore_X_Damage_Group X Damage Extension Functions
+ *
+ * Functions related to the X Damage Extension.
+ */
+
+EAPI Eina_Bool
+ecore_x_damage_query(void)
+{
+ return _damage_avail;
+}
+
+/**
+ * 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)
+{
+ Ecore_X_Damage damage = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_damage_avail) return 0;
+
+#ifdef ECORE_XCB_DAMAGE
+ damage = xcb_generate_id(_ecore_xcb_conn);
+ xcb_damage_create(_ecore_xcb_conn, damage, drawable, level);
+// ecore_x_flush();
+#endif
+
+ return damage;
+}
+
+/**
+ * Destroy a damage object
+ *
+ * @param damage 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_damage_avail) return;
+
+#ifdef ECORE_XCB_DAMAGE
+ xcb_damage_destroy(_ecore_xcb_conn, damage);
+// ecore_x_flush();
+#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 regions in the following manner:
+ * If @p repair is @c XCB_NONE:
+ * 1) parts = damage
+ * 2) damage = \<empty\>
+ * Otherwise:
+ * 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_damage_avail) return;
+
+#ifdef ECORE_XCB_DAMAGE
+ xcb_damage_subtract(_ecore_xcb_conn, damage, repair, parts);
+// ecore_x_flush();
+#endif
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_dnd.c b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c
new file mode 100644
index 0000000000..80ae6b4c5d
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c
@@ -0,0 +1,688 @@
+#include "ecore_xcb_private.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 EINA_UNUSED,
+ void *data,
+ int size,
+ void **data_ret,
+ int *size_ret,
+ Ecore_X_Atom *tprop EINA_UNUSED,
+ int *count EINA_UNUSED);
+
+/* local variables */
+static int _ecore_xcb_dnd_init_count = 0;
+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;
+EAPI int ECORE_X_EVENT_XDND_LEAVE = 0;
+EAPI int ECORE_X_EVENT_XDND_DROP = 0;
+EAPI int ECORE_X_EVENT_XDND_FINISHED = 0;
+
+void
+_ecore_xcb_dnd_init(void)
+{
+ 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;
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ _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;
+
+ ECORE_X_EVENT_XDND_ENTER = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_POSITION = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_STATUS = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_LEAVE = ecore_event_type_new();
+ 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_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;
+}
+
+EAPI void
+ecore_x_dnd_send_status(Eina_Bool will_accept,
+ Eina_Bool suppress,
+ Ecore_X_Rectangle rect,
+ Ecore_X_Atom action)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (_target->state == ECORE_X_DND_TARGET_IDLE) return;
+
+ memset(&ev, 0, sizeof(xcb_client_message_event_t));
+
+ _target->will_accept = will_accept;
+
+ 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;
+
+ 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 (will_accept)
+ ev.data.data32[4] = action;
+ else
+ ev.data.data32[4] = XCB_NONE;
+ _target->accepted_action = action;
+
+ xcb_send_event(_ecore_xcb_conn, 0, _target->source,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+// ecore_x_flush();
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_drop(void)
+{
+ xcb_client_message_event_t ev;
+ Eina_Bool status = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ memset(&ev, 0, sizeof(xcb_client_message_event_t));
+
+ if (_source->dest)
+ {
+ 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,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+// ecore_x_flush();
+ _source->state = ECORE_X_DND_SOURCE_DROPPED;
+ status = EINA_TRUE;
+ }
+ 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,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+// ecore_x_flush();
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ }
+ else
+ {
+ ecore_x_selection_xdnd_clear();
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+
+ ecore_x_window_ignore_set(_source->win, 0);
+ _source->prev.window = 0;
+
+ return status;
+}
+
+EAPI void
+ecore_x_dnd_aware_set(Ecore_X_Window win,
+ Eina_Bool on)
+{
+ Ecore_X_Atom prop_data = ECORE_X_DND_VERSION;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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);
+}
+
+EAPI int
+ecore_x_dnd_version_get(Ecore_X_Window win)
+{
+ unsigned char *data;
+ int num = 0;
+ Version_Cache_Item *t;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
+ {
+ if (_version_cache)
+ {
+ int i = 0;
+
+ for (i = 0; i < _version_cache_num; i++)
+ {
+ if (_version_cache[i].win == win)
+ return _version_cache[i].ver;
+ }
+ }
+ }
+
+ 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);
+ 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;
+ }
+
+ 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;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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 (atom == atoms[i])
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+ }
+
+ free(data);
+ return ret;
+}
+
+EAPI void
+ecore_x_dnd_type_set(Ecore_X_Window win,
+ const char *type,
+ Eina_Bool on)
+{
+ Ecore_X_Atom atom, *oldset = NULL, *newset = NULL;
+ int i = 0, j = 0, num = 0;
+ unsigned char *data = NULL, *old_data = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ atom = ecore_x_atom_get(type);
+ 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 (ecore_x_dnd_type_isset(win, type))
+ {
+ free(old_data);
+ return;
+ }
+ 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];
+ 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
+ {
+ if (!ecore_x_dnd_type_isset(win, type))
+ {
+ free(old_data);
+ return;
+ }
+ newset = calloc(num - 1, sizeof(Ecore_X_Atom));
+ 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(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM, 32, data, num - 1);
+ }
+ free(oldset);
+ free(newset);
+}
+
+EAPI void
+ecore_x_dnd_types_set(Ecore_X_Window win,
+ const char **types,
+ unsigned int num_types)
+{
+ Ecore_X_Atom *newset = NULL;
+ unsigned int i;
+ unsigned char *data = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!num_types)
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_TYPE_LIST);
+ else
+ {
+ newset = calloc(num_types, sizeof(Ecore_X_Atom));
+ if (!newset) return;
+
+ data = (unsigned char *)newset;
+ for (i = 0; i < num_types; i++)
+ {
+ newset[i] = ecore_x_atom_get(types[i]);
+ ecore_x_selection_converter_atom_add(newset[i],
+ _ecore_xcb_dnd_converter_copy);
+ }
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM, 32, data,
+ num_types);
+ free(newset);
+ }
+}
+
+EAPI void
+ecore_x_dnd_actions_set(Ecore_X_Window win,
+ Ecore_X_Atom *actions,
+ unsigned int num_actions)
+{
+ unsigned int i;
+ unsigned char *data = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+ }
+}
+
+/**
+ * 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_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *data),
+ const void *data)
+{
+ _posupdatecb = cb;
+ _posupdatedata = (void *)data;
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_begin(Ecore_X_Window source,
+ unsigned char *data,
+ int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!ecore_x_dnd_version_get(source)) return EINA_FALSE;
+
+ /* Take ownership of XdndSelection */
+ if (!ecore_x_selection_xdnd_set(source, data, size)) return EINA_FALSE;
+
+ if (_version_cache)
+ {
+ free(_version_cache);
+ _version_cache = NULL;
+ _version_cache_num = 0;
+ _version_cache_alloc = 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_events_last_time_get();
+ _source->prev.window = 0;
+
+ /* Default Accepted Action: move */
+ _source->action = ECORE_X_ATOM_XDND_ACTION_MOVE;
+ _source->accepted_action = XCB_NONE;
+ _source->dest = XCB_NONE;
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_dnd_send_finished(void)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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.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)
+ {
+ ev.data.data32[1] |= 0x1UL;
+ ev.data.data32[2] = _target->accepted_action;
+ }
+
+ xcb_send_event(_ecore_xcb_conn, 0, _target->source,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+// ecore_x_flush();
+ _target->state = ECORE_X_DND_TARGET_IDLE;
+}
+
+EAPI void
+ecore_x_dnd_source_action_set(Ecore_X_Atom action)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _source->action = action;
+ if (_source->prev.window)
+ _ecore_xcb_dnd_drag(_source->prev.window,
+ _source->prev.x, _source->prev.y);
+}
+
+Ecore_X_DND_Source *
+_ecore_xcb_dnd_source_get(void)
+{
+ return _source;
+}
+
+Ecore_X_DND_Target *
+_ecore_xcb_dnd_target_get(void)
+{
+ return _target;
+}
+
+void
+_ecore_xcb_dnd_drag(Ecore_X_Window root,
+ int x,
+ int y)
+{
+ xcb_client_message_event_t ev;
+ Ecore_X_Window win, *skip;
+ Ecore_X_Xdnd_Position pos;
+ int num = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (_source->state != ECORE_X_DND_SOURCE_DRAGGING) return;
+
+ memset(&ev, 0, sizeof(xcb_client_message_event_t));
+
+ ev.response_type = XCB_CLIENT_MESSAGE;
+ ev.format = 32;
+
+ skip = ecore_x_window_ignore_list(&num);
+ win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num);
+ while ((win) && !(ecore_x_dnd_version_get(win)))
+ win = ecore_x_window_shadow_parent_get(root, win);
+
+ 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,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+// ecore_x_flush();
+ _source->suppress = 0;
+ }
+
+ if (win)
+ {
+ int x1, x2, y1, y2;
+
+ _source->version = MIN(ECORE_X_DND_VERSION,
+ ecore_x_dnd_version_get(win));
+ if (win != _source->dest)
+ {
+ int i = 0;
+ unsigned char *data;
+ Ecore_X_Atom *types;
+
+ 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;
+ 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;
+ else
+ 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;
+ for (i = 0; i < MIN(num, 3); ++i)
+ ev.data.data32[i + 2] = types[i];
+ free(data);
+
+ xcb_send_event(_ecore_xcb_conn, 0, win,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+// ecore_x_flush();
+ _source->await_status = 0;
+ _source->will_accept = 0;
+ }
+
+ 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)))
+ {
+ ev.window = win;
+ ev.type = ECORE_X_ATOM_XDND_POSITION;
+ ev.data.data32[0] = _source->win;
+ ev.data.data32[1] = 0;
+ ev.data.data32[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+ 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);
+// ecore_x_flush();
+ _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;
+}
+
+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 EINA_UNUSED,
+ void *data,
+ int size,
+ void **data_ret,
+ int *size_ret,
+ Ecore_X_Atom *tprop EINA_UNUSED,
+ int *count EINA_UNUSED)
+{
+ Ecore_Xcb_Textproperty text_prop;
+ Ecore_Xcb_Encoding_Style style = XcbTextStyle;
+ char *mystr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if ((!data) || (!size)) return EINA_FALSE;
+
+ mystr = calloc(1, size + 1);
+ if (!mystr) return EINA_FALSE;
+
+ memcpy(mystr, data, size);
+ if (_ecore_xcb_mb_textlist_to_textproperty(&mystr, 1, style, &text_prop))
+ {
+ int len;
+
+ len = strlen((char *)text_prop.value) + 1;
+ if (!(*data_ret = malloc(len)))
+ {
+ free(mystr);
+ return EINA_FALSE;
+ }
+ memcpy(*data_ret, text_prop.value, len);
+ *size_ret = len;
+ free(text_prop.value);
+ free(mystr);
+ return EINA_TRUE;
+ }
+ else
+ {
+ free(mystr);
+ return EINA_FALSE;
+ }
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_dpms.c b/src/lib/ecore_x/xcb/ecore_xcb_dpms.c
new file mode 100644
index 0000000000..39ef589dd1
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_dpms.c
@@ -0,0 +1,320 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_DAMAGE
+# include <xcb/dpms.h>
+#endif
+
+/* local variables */
+static Eina_Bool _dpms_avail = EINA_FALSE;
+
+void
+_ecore_xcb_dpms_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_DPMS
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_dpms_id);
+#endif
+}
+
+void
+_ecore_xcb_dpms_finalize(void)
+{
+#ifdef ECORE_XCB_DPMS
+ const xcb_query_extension_reply_t *ext_reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_DPMS
+ ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_dpms_id);
+ if ((ext_reply) && (ext_reply->present))
+ {
+ 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
+}
+
+/**
+ * @defgroup Ecore_X_DPMS_Group X DPMS Extension Functions
+ *
+ * Functions related to the X DPMS Extension
+ */
+
+/**
+ * Checks if the DPMS extension is available or not.
+ *
+ * @return @c EINA_TRUE if the DPMS extension is available,
+ * @c EINA_FALSE otherwise.
+ *
+ * Return @c EINA_TRUE if the X server supports the DPMS Extension version 1.0,
+ * @c EINA_FALSE otherwise.
+ *
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI Eina_Bool
+ecore_x_dpms_query(void)
+{
+// LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI Eina_Bool
+ecore_x_dpms_capable_get(void)
+{
+ Eina_Bool ret = EINA_FALSE;
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_capable_cookie_t cookie;
+ xcb_dpms_capable_reply_t *reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_dpms_avail) return EINA_FALSE;
+
+#ifdef ECORE_XCB_DPMS
+ 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
+
+ return ret;
+}
+
+/**
+ * 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 Eina_Bool
+ecore_x_dpms_enabled_get(void)
+{
+ Eina_Bool ret = EINA_FALSE;
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_info_cookie_t cookie;
+ xcb_dpms_info_reply_t *reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_dpms_avail) return EINA_FALSE;
+
+#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 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_dpms_avail) return;
+
+#ifdef ECORE_XCB_DPMS
+ if (enabled)
+ xcb_dpms_enable(_ecore_xcb_conn);
+ else
+ xcb_dpms_disable(_ecore_xcb_conn);
+#endif
+}
+
+/**
+ * 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.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeouts_get(unsigned int *standby,
+ unsigned int *suspend,
+ unsigned int *off)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_cookie_t cookie;
+ xcb_dpms_get_timeouts_reply_t *reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (standby) *standby = 0;
+ if (suspend) *suspend = 0;
+ if (off) *off = 0;
+
+ if (!_dpms_avail) return;
+
+#ifdef ECORE_XCB_DPMS
+ cookie = xcb_dpms_get_timeouts_unchecked(_ecore_xcb_conn);
+ reply = xcb_dpms_get_timeouts_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply) return;
+ if (standby) *standby = reply->standby_timeout;
+ if (suspend) *suspend = reply->suspend_timeout;
+ if (off) *off = reply->off_timeout;
+ free(reply);
+#endif
+}
+
+/**
+ * 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.
+ * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI Eina_Bool
+ecore_x_dpms_timeouts_set(unsigned int standby,
+ unsigned int suspend,
+ unsigned int off)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_dpms_avail) return EINA_FALSE;
+
+#ifdef ECORE_XCB_DPMS
+ // FIXME: Add request check
+ xcb_dpms_set_timeouts(_ecore_xcb_conn, standby, suspend, off);
+ return EINA_TRUE;
+#endif
+
+ return EINA_FALSE;
+}
+
+/**
+ * Returns the amount of time of inactivity before standby mode is invoked.
+ * @return The standby timeout value.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_standby_get(void)
+{
+ unsigned int standby = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_dpms_timeouts_get(&standby, NULL, NULL);
+ return standby;
+}
+
+/**
+ * Returns the amount of time of inactivity before the second level of
+ * power saving is invoked.
+ * @return The suspend timeout value.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_suspend_get(void)
+{
+ unsigned int suspend = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_dpms_timeouts_get(NULL, &suspend, NULL);
+ return suspend;
+}
+
+/**
+ * Returns the amount of time of inactivity before the third and final
+ * level of power saving is invoked.
+ * @return The off timeout value.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_off_get(void)
+{
+ unsigned int off = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_dpms_timeouts_get(NULL, NULL, &off);
+ return off;
+}
+
+/**
+ * Sets the standby timeout (in unit of seconds).
+ * @param new_timeout Amount of time of inactivity before standby mode will be invoked.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_standby_set(unsigned int new_timeout)
+{
+ unsigned int standby = 0, suspend = 0, off = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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 new_timeout Amount of time of inactivity before the screen is placed into suspend mode.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_suspend_set(unsigned int new_timeout)
+{
+ unsigned int standby = 0, suspend = 0, off = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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 new_timeout Amount of time of inactivity before the monitor is shut off.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_off_set(unsigned int new_timeout)
+{
+ unsigned int standby = 0, suspend = 0, off = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_dpms_timeouts_get(&standby, &suspend, &off);
+ ecore_x_dpms_timeouts_set(standby, suspend, new_timeout);
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_drawable.c b/src/lib/ecore_x/xcb/ecore_xcb_drawable.c
new file mode 100644
index 0000000000..4e9a3564ce
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_drawable.c
@@ -0,0 +1,123 @@
+#include "ecore_xcb_private.h"
+
+/**
+ * @defgroup Ecore_X_Drawable_Group X Drawable Functions
+ *
+ * Functions that operate on drawables.
+ */
+
+/**
+ * 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 draw,
+ Ecore_X_GC gc,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ xcb_rectangle_t rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+/**
+ * Retrieves the geometry of the given drawable.
+ * @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 draw,
+ int *x,
+ int *y,
+ int *w,
+ int *h)
+{
+ xcb_get_geometry_cookie_t cookie;
+ xcb_get_geometry_reply_t *reply;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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 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 d)
+{
+ xcb_get_geometry_cookie_t cookie;
+ xcb_get_geometry_reply_t *reply;
+ int ret = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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 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 d)
+{
+ xcb_get_geometry_cookie_t cookie;
+ xcb_get_geometry_reply_t *reply;
+ int ret = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, d);
+ reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply) return 0;
+ ret = (int)reply->depth;
+ free(reply);
+ return ret;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_e.c b/src/lib/ecore_x/xcb/ecore_xcb_e.c
new file mode 100644
index 0000000000..82d94b634f
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_e.c
@@ -0,0 +1,1576 @@
+#include "ecore_xcb_private.h"
+
+/* 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);
+static Ecore_X_Atom _ecore_xcb_e_indicator_atom_get(Ecore_X_Illume_Indicator_State state);
+static Ecore_X_Illume_Indicator_State _ecore_xcb_e_indicator_state_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__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+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_window_profile_list_set(Ecore_X_Window win,
+ const char **profiles,
+ unsigned int num_profiles)
+{
+ Ecore_X_Atom *atoms;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!win)
+ return;
+
+ if (!num_profiles)
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE_LIST);
+ else
+ {
+ atoms = alloca(num_profiles * sizeof(Ecore_X_Atom));
+ ecore_x_atoms_get(profiles, num_profiles, atoms);
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_E_PROFILE_LIST,
+ ECORE_X_ATOM_ATOM, 32, (void *)atoms,
+ num_profiles);
+ }
+}
+
+EAPI Eina_Bool
+ecore_x_e_window_profile_list_get(Ecore_X_Window win,
+ const char ***profiles,
+ int *ret_num)
+{
+ unsigned char *data = NULL;
+ Ecore_X_Atom *atoms;
+ int num, i;
+
+ if (ret_num)
+ *ret_num = 0;
+
+ if (profiles)
+ *profiles = NULL;
+
+ if (!win)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_E_PROFILE_LIST,
+ ECORE_X_ATOM_ATOM, 32, &data, &num))
+ return EINA_FALSE;
+
+ if (ret_num)
+ *ret_num = num;
+
+ if (profiles)
+ {
+ (*profiles) = calloc(num, sizeof(char *));
+ if (!(*profiles))
+ {
+ if (ret_num)
+ *ret_num = 0;
+
+ if (data)
+ free(data);
+
+ return EINA_FALSE;
+ }
+
+ atoms = (Ecore_X_Atom *)data;
+ for (i = 0; i < num; i++)
+ (*profiles)[i] = ecore_x_atom_name_get(atoms[i]);
+ }
+
+ if (data)
+ free(data);
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_e_window_profile_set(Ecore_X_Window win,
+ const char *profile)
+{
+ Ecore_X_Atom atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!win)
+ return;
+
+ if (!profile)
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE);
+ else
+ {
+ atom = ecore_x_atom_get(profile);
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_PROFILE,
+ ECORE_X_ATOM_ATOM, 32, (void *)&atom, 1);
+ }
+}
+
+EAPI char *
+ecore_x_e_window_profile_get(Ecore_X_Window win)
+{
+ Ecore_X_Atom *atom = NULL;
+ unsigned char *data;
+ char *profile = NULL;
+ int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_PROFILE,
+ ECORE_X_ATOM_ATOM, 32, &data, &num))
+ return NULL;
+
+ if (data)
+ atom = (Ecore_X_Atom *)data;
+
+ if (atom)
+ profile = ecore_x_atom_name_get(atom[0]);
+
+ return profile;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_e_comp_sync_end_send(Ecore_X_Window win)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_e_comp_flush_send(Ecore_X_Window win)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_e_comp_dump_send(Ecore_X_Window win)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+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;
+ 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);
+}
+
+static Ecore_X_Atom
+_ecore_xcb_e_clipboard_atom_get(Ecore_X_Illume_Clipboard_State state)
+{
+ switch (state)
+ {
+ case ECORE_X_ILLUME_CLIPBOARD_STATE_ON:
+ return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON;
+ case ECORE_X_ILLUME_CLIPBOARD_STATE_OFF:
+ return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Ecore_X_Illume_Clipboard_State
+_ecore_xcb_e_clipboard_state_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON)
+ return ECORE_X_ILLUME_CLIPBOARD_STATE_ON;
+
+ if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF)
+ return ECORE_X_ILLUME_CLIPBOARD_STATE_OFF;
+
+ return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN;
+}
+
+EAPI void
+ecore_x_e_illume_clipboard_state_set(Ecore_X_Window win,
+ Ecore_X_Illume_Clipboard_State state)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_xcb_e_clipboard_atom_get(state);
+
+ ecore_x_window_prop_atom_set(win,
+ ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Clipboard_State
+ecore_x_e_illume_clipboard_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_CLIPBOARD_STATE,
+ &atom, 1))
+ return ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN;
+ return _ecore_xcb_e_clipboard_state_get(atom);
+}
+
+EAPI void
+ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY,
+ geom, 4);
+}
+
+EAPI Eina_Bool
+ecore_x_e_illume_clipboard_geometry_get(Ecore_X_Window win,
+ int *x, int *y, int *w, int *h)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_CLIPBOARD_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];
+
+ return EINA_TRUE;
+}
+
+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_access_action_next_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_read_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_up_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_down_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN,
+ 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;
+}
+
+static Ecore_X_Atom
+_ecore_xcb_e_indicator_atom_get(Ecore_X_Illume_Indicator_State state)
+{
+ switch (state)
+ {
+ case ECORE_X_ILLUME_INDICATOR_STATE_ON:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_ON;
+
+ case ECORE_X_ILLUME_INDICATOR_STATE_OFF:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Ecore_X_Illume_Indicator_State
+_ecore_xcb_e_indicator_state_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_ON)
+ return ECORE_X_ILLUME_INDICATOR_STATE_ON;
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF)
+ return ECORE_X_ILLUME_INDICATOR_STATE_OFF;
+
+ return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN;
+}
+
+EAPI void
+ecore_x_e_illume_indicator_state_set(Ecore_X_Window win,
+ Ecore_X_Illume_Indicator_State state)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ atom = _ecore_xcb_e_indicator_atom_get(state);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Indicator_State
+ecore_x_e_illume_indicator_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_INDICATOR_STATE,
+ &atom, 1))
+ return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN;
+
+ return _ecore_xcb_e_indicator_state_get(atom);
+}
+
+EAPI void
+ecore_x_e_illume_indicator_state_send(Ecore_X_Window win,
+ Ecore_X_Illume_Indicator_State state)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ _ecore_xcb_e_indicator_atom_get(state),
+ 0, 0, 0, 0);
+}
+
+static Ecore_X_Atom
+_ecore_x_e_indicator_opacity_atom_get(Ecore_X_Illume_Indicator_Opacity_Mode mode)
+{
+ switch (mode)
+ {
+ case ECORE_X_ILLUME_INDICATOR_OPAQUE:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE;
+
+ case ECORE_X_ILLUME_INDICATOR_TRANSLUCENT:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT;
+
+ case ECORE_X_ILLUME_INDICATOR_TRANSPARENT:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Ecore_X_Illume_Indicator_Opacity_Mode
+_ecore_x_e_indicator_opacity_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE)
+ return ECORE_X_ILLUME_INDICATOR_OPAQUE;
+
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT)
+ return ECORE_X_ILLUME_INDICATOR_TRANSLUCENT;
+
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT)
+ return ECORE_X_ILLUME_INDICATOR_TRANSPARENT;
+
+ return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN;
+}
+
+EAPI void
+ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win,
+ Ecore_X_Illume_Indicator_Opacity_Mode mode)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_e_indicator_opacity_atom_get(mode);
+ ecore_x_window_prop_atom_set(win,
+ ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Indicator_Opacity_Mode
+ecore_x_e_illume_indicator_opacity_get(Ecore_X_Window win)
+{
+ Ecore_X_Atom atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_atom_get(win,
+ ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE,
+ &atom, 1))
+ return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN;
+
+ return _ecore_x_e_indicator_opacity_get(atom);
+}
+
+EAPI void
+ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win,
+ Ecore_X_Illume_Indicator_Opacity_Mode mode)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win,
+ ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ _ecore_x_e_indicator_opacity_atom_get(mode),
+ 0, 0, 0, 0);
+}
+
+static Ecore_X_Atom
+_ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state)
+{
+ switch (state)
+ {
+ case ECORE_X_ILLUME_WINDOW_STATE_NORMAL:
+ return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL;
+
+ case ECORE_X_ILLUME_WINDOW_STATE_FLOATING:
+ return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Ecore_X_Illume_Window_State
+_ecore_x_e_illume_window_state_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL)
+ return ECORE_X_ILLUME_WINDOW_STATE_NORMAL;
+
+ if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING)
+ return ECORE_X_ILLUME_WINDOW_STATE_FLOATING;
+
+ return ECORE_X_ILLUME_WINDOW_STATE_NORMAL;
+}
+
+EAPI void
+ecore_x_e_illume_window_state_set(Ecore_X_Window win,
+ Ecore_X_Illume_Window_State state)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_e_illume_window_state_atom_get(state);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_WINDOW_STATE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Window_State
+ecore_x_e_illume_window_state_get(Ecore_X_Window win)
+{
+ Ecore_X_Atom atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_atom_get(win,
+ ECORE_X_ATOM_E_ILLUME_WINDOW_STATE,
+ &atom, 1))
+ return ECORE_X_ILLUME_WINDOW_STATE_NORMAL;
+
+ return _ecore_x_e_illume_window_state_get(atom);
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_error.c b/src/lib/ecore_x/xcb/ecore_xcb_error.c
new file mode 100644
index 0000000000..fc329265d5
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_error.c
@@ -0,0 +1,123 @@
+#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;
+static Ecore_X_ID _error_resource_id = 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;
+}
+
+/**
+ * Get the resource id that caused the error.
+ * @return The resource id causing the X error
+ *
+ * Return the X resource id that caused the last X error
+ */
+EAPI Ecore_X_ID
+ecore_x_error_resource_id_get(void)
+{
+ return _error_resource_id;
+}
+
+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));
+
+#ifdef OLD_XCB_VERSION
+ 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);
+#else
+ if (err->error_code == XCB_VALUE)
+ WRN("\tBad Value: %d", ((xcb_value_error_t *)err)->bad_value);
+ else if (err->error_code == XCB_WINDOW)
+ WRN("\tBad Window: %d", ((xcb_window_error_t *)err)->bad_value);
+#endif
+
+ _error_request_code = err->sequence;
+ _error_code = err->error_code;
+ _error_resource_id = err->resource_id;
+ if (_error_func)
+ _error_func(_error_data);
+
+ return 0;
+}
+
+int
+_ecore_xcb_io_error_handle(xcb_generic_error_t *err)
+{
+ CRIT("IO Error:");
+ if (err)
+ {
+ CRIT("\tRequest: %d", err->sequence);
+ CRIT("\tCode: %d", err->error_code);
+ }
+ if (_io_error_func)
+ _io_error_func(_io_error_data);
+ else
+ exit(-1);
+
+ return 0;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_events.c b/src/lib/ecore_x/xcb/ecore_xcb_events.c
new file mode 100644
index 0000000000..9cc86f62a8
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_events.c
@@ -0,0 +1,2824 @@
+#include "ecore_xcb_private.h"
+//#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
+# ifdef ECORE_XCB_XGESTURE
+# include <xcb/gesture.h>
+# endif
+
+#ifndef CODESET
+# define CODESET "INVALID"
+#endif
+
+typedef struct _Ecore_X_Mouse_Down_Info
+{
+ EINA_INLIST;
+ int dev;
+ Ecore_X_Time last_time;
+ Ecore_X_Time last_last_time;
+ Ecore_X_Window last_win;
+ Ecore_X_Window last_last_win;
+ Ecore_X_Window last_event_win;
+ Ecore_X_Window last_last_event_win;
+ Eina_Bool did_double : 1;
+ Eina_Bool did_triple : 1;
+} Ecore_X_Mouse_Down_Info;
+
+/* 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_XGESTURE
+static void _ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event);
+static void _ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event);
+static void _ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event);
+static void _ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event);
+static void _ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event);
+static void _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event);
+static void _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event);
+#endif
+#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 EINA_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_free(void *data EINA_UNUSED,
+ void *event);
+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 EINA_UNUSED,
+ void *event);
+static void _ecore_xcb_event_selection_notify_free(void *data EINA_UNUSED,
+ void *event);
+static void _ecore_xcb_event_generic_event_free(void *data,
+ void *event);
+static void _ecore_xcb_event_mouse_down_info_clear(void);
+static Ecore_X_Mouse_Down_Info *_ecore_xcb_event_mouse_down_info_get(int dev);
+
+/* local variables */
+static Eina_Bool _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+//static Ecore_Event *_ecore_xcb_event_last_mouse_move_event = NULL;
+static Eina_Inlist *_ecore_xcb_mouse_down_info_list = NULL;
+static Ecore_X_Time _ecore_xcb_event_last_time;
+static Ecore_X_Window _ecore_xcb_event_last_window = 0;
+
+/* 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_FIXES_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_GESTURE_NOTIFY_FLICK = 0;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN = 0;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = 0;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP = 0;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = 0;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = 0;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 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_XKB_STATE_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_GENERIC = 0;
+
+EAPI int ECORE_X_RAW_BUTTON_PRESS = 0;
+EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0;
+EAPI int ECORE_X_RAW_MOTION = 0;
+
+void
+_ecore_xcb_events_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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_FIXES_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_GESTURE_NOTIFY_FLICK = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_PAN = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_TAP = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 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_XKB_STATE_NOTIFY = ecore_event_type_new();
+ ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new();
+ ECORE_X_EVENT_GENERIC = ecore_event_type_new();
+
+ ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new();
+ ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new();
+ ECORE_X_RAW_MOTION = ecore_event_type_new();
+ }
+}
+
+void
+_ecore_xcb_events_shutdown(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _ecore_xcb_event_mouse_down_info_clear();
+
+ _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;
+// }
+}
+
+void
+_ecore_xcb_events_handle(xcb_generic_event_t *ev)
+{
+ uint8_t response = 0;
+
+// LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ /* strip highest bit (set if event is generated) */
+ response = (ev->response_type & ~0x80);
+ if (response == 0)
+ {
+ xcb_generic_error_t *err;
+
+ 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 */
+#ifdef OLD_XCB_VERSION
+ 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;
+ }
+#else
+ if (err->error_code == XCB_WINDOW) return;
+ else if (err->error_code == XCB_MATCH)
+ {
+ if ((err->major_code == XCB_SET_INPUT_FOCUS) ||
+ (err->major_code == XCB_CONFIGURE_WINDOW))
+ return;
+ }
+ else if (err->error_code == XCB_VALUE)
+ {
+ if ((err->major_code == XCB_KILL_CLIENT) ||
+ (err->major_code == XCB_GRAB_BUTTON) ||
+ (err->major_code == XCB_UNGRAB_BUTTON))
+ return;
+ }
+#endif
+ 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 == 2) // bad value
+ WRN("\tValue: %d", ((xcb_value_error_t *)err)->bad_value);
+ else if (err->error_code == 8) // 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: Filter event for xim when xcb supports xim */
+
+ _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_XGESTURE
+ else if ((_ecore_xcb_event_gesture >= 0) &&
+ (response ==
+ _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_FLICK))
+ _ecore_xcb_event_handle_gesture_notify_flick(ev);
+ else if ((_ecore_xcb_event_gesture >= 0) &&
+ (response ==
+ _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_PAN))
+ _ecore_xcb_event_handle_gesture_notify_pan(ev);
+ else if ((_ecore_xcb_event_gesture >= 0) &&
+ (response ==
+ _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_PINCH_ROTATION))
+ _ecore_xcb_event_handle_gesture_notify_pinchrotation(ev);
+ else if ((_ecore_xcb_event_gesture >= 0) &&
+ (response ==
+ _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_TAP))
+ _ecore_xcb_event_handle_gesture_notify_tap(ev);
+ else if ((_ecore_xcb_event_gesture >= 0) &&
+ (response ==
+ _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_TAP_N_HOLD))
+ _ecore_xcb_event_handle_gesture_notify_tapnhold(ev);
+ else if ((_ecore_xcb_event_gesture >= 0) &&
+ (response ==
+ _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_HOLD))
+ _ecore_xcb_event_handle_gesture_notify_hold(ev);
+ else if ((_ecore_xcb_event_gesture >= 0) &&
+ (response ==
+ _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_GROUP))
+ _ecore_xcb_event_handle_gesture_notify_group(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 list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ list = (mask | reply->your_event_mask);
+ free(reply);
+ xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_EVENT_MASK, &list);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_event_mask_unset(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 list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ list = (reply->your_event_mask & ~mask);
+ free(reply);
+ xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_EVENT_MASK, &list);
+// ecore_x_flush();
+}
+
+unsigned int
+_ecore_xcb_events_modifiers_get(unsigned int state)
+{
+ unsigned int modifiers = 0;
+
+ 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;
+ if (state & ECORE_X_MODIFIER_ALT)
+ modifiers |= ECORE_EVENT_MODIFIER_ALT;
+ if (state & ECORE_X_MODIFIER_WIN)
+ modifiers |= ECORE_EVENT_MODIFIER_WIN;
+ if (state & ECORE_X_MODIFIER_ALTGR)
+ modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
+ if (state & ECORE_X_LOCK_SCROLL)
+ modifiers |= ECORE_EVENT_LOCK_SCROLL;
+ if (state & ECORE_X_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;
+}
+
+/* local functions */
+static void
+_ecore_xcb_event_handle_any_event(xcb_generic_event_t *event)
+{
+ xcb_generic_event_t *ev;
+
+// LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ev = malloc(sizeof(xcb_generic_event_t));
+ if (!ev) return;
+
+ memcpy(ev, event, sizeof(xcb_generic_event_t));
+ ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL);
+}
+
+static void
+_ecore_xcb_event_handle_key_press(xcb_generic_event_t *event)
+{
+ _ecore_xcb_event_key_press(event);
+}
+
+static void
+_ecore_xcb_event_handle_key_release(xcb_generic_event_t *event)
+{
+ _ecore_xcb_event_key_release(event);
+}
+
+static void
+_ecore_xcb_event_handle_button_press(xcb_generic_event_t *event)
+{
+ xcb_button_press_event_t *ev;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+
+ ev = (xcb_button_press_event_t *)event;
+ if ((ev->detail > 3) && (ev->detail < 8))
+ {
+ Ecore_Event_Mouse_Wheel *e;
+
+ if (!(e = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return;
+
+ e->timestamp = ev->time;
+ 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;
+ }
+ 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;
+ else
+ 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);
+
+ _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);
+
+ 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);
+ }
+}
+
+static void
+_ecore_xcb_event_handle_button_release(xcb_generic_event_t *event)
+{
+ xcb_button_release_event_t *ev;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_button_release_event_t *)event;
+ if ((ev->detail <= 3) || (ev->detail > 7))
+ {
+ _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);
+ }
+}
+
+static void
+_ecore_xcb_event_handle_motion_notify(xcb_generic_event_t *event)
+{
+ xcb_motion_notify_event_t *ev;
+
+ ev = (xcb_motion_notify_event_t *)event;
+
+ /* 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_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_enter_notify_event_t *)event;
+
+ _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;
+
+ ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_enter_notify_event_t *)event;
+
+ _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);
+
+ 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);
+}
+
+static void
+_ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event EINA_UNUSED)
+{
+// LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ // FIXME: handle this event type
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+}
+
+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;
+
+ _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;
+
+ e->win = ev->event;
+ e->mode = _ecore_xcb_event_mode_get(ev->mode);
+ e->detail = _ecore_xcb_event_detail_get(ev->detail);
+
+ 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);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_focus_out_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out)))) return;
+
+ e->win = ev->event;
+ e->mode = _ecore_xcb_event_mode_get(ev->mode);
+ e->detail = _ecore_xcb_event_detail_get(ev->detail);
+
+ 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);
+}
+
+static void
+_ecore_xcb_event_handle_expose(xcb_generic_event_t *event)
+{
+ xcb_expose_event_t *ev;
+ Ecore_X_Event_Window_Damage *e;
+
+ _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;
+ 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);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_graphics_exposure_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)))) return;
+
+ e->win = ev->drawable;
+ e->x = ev->x;
+ e->y = ev->y;
+ e->w = ev->width;
+ e->h = ev->height;
+ e->count = ev->count;
+ e->time = _ecore_xcb_event_last_time;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+}
+
+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;
+
+ _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;
+
+ 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_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_create_notify_event_t *)event;
+ 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;
+ else
+ 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);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_destroy_notify_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy)))) return;
+
+ e->win = ev->window;
+ e->event_win = ev->event;
+ if (e->win == _ecore_xcb_event_last_window)
+ _ecore_xcb_event_last_window = 0;
+ e->time = _ecore_xcb_event_last_time;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
+}
+
+static void
+_ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event)
+{
+ xcb_map_notify_event_t *ev;
+ Ecore_X_Event_Window_Show *e;
+
+ _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_SHOW, e, NULL, NULL);
+}
+
+static void
+_ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event)
+{
+ xcb_unmap_notify_event_t *ev;
+ Ecore_X_Event_Window_Hide *e;
+
+ _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_HIDE, e, NULL, NULL);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_map_request_event_t *)event;
+ 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);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_reparent_notify_event_t *)event;
+ 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);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_configure_notify_event_t *)event;
+ 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;
+ e->w = ev->width;
+ e->h = ev->height;
+ 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->time = _ecore_xcb_event_last_time;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_configure_request_event_t *)event;
+ 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;
+ e->w = ev->width;
+ e->h = ev->height;
+ e->border = ev->border_width;
+ e->value_mask = ev->value_mask;
+ switch (ev->stack_mode)
+ {
+ case XCB_STACK_MODE_ABOVE:
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ break;
+
+ case XCB_STACK_MODE_BELOW:
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+ break;
+
+ case XCB_STACK_MODE_TOP_IF:
+ e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
+ break;
+
+ case XCB_STACK_MODE_BOTTOM_IF:
+ e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
+ break;
+
+ case XCB_STACK_MODE_OPPOSITE:
+ 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);
+}
+
+static void
+_ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event EINA_UNUSED)
+{
+/*
+ xcb_gravity_notify_event_t *ev;
+ Ecore_X_Event_Window_Gravity *e;
+
+ _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;
+
+ 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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_resize_request_event_t *)event;
+ 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);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_circulate_notify_event_t *)event;
+ 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;
+ else
+ 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);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_circulate_request_event_t *)event;
+ 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;
+ else
+ 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);
+}
+
+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;
+
+ _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;
+
+ 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);
+}
+
+static void
+_ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event)
+{
+ xcb_selection_clear_event_t *ev;
+ 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;
+ if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Clear)))) return;
+
+ e->win = ev->owner;
+ e->atom = sel = ev->selection;
+ if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+ e->time = ev->time;
+
+ ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_selection_request_event_t *)event;
+ if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Request)))) return;
+
+ e->owner = ev->owner;
+ e->requestor = ev->requestor;
+ 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_xcb_selection_get(ev->selection)) &&
+ (sd->win == ev->owner))
+ {
+ Ecore_X_Selection_Intern *si;
+
+ si = _ecore_xcb_selection_get(ev->selection);
+ if (si->data)
+ {
+ Ecore_X_Atom property = XCB_NONE, type;
+ void *data = NULL;
+ int len = 0, typesize = 0;
+
+ type = ev->target;
+ typesize = 8;
+ len = sd->length;
+
+ if (!ecore_x_selection_convert(ev->selection, ev->target,
+ &data, &len, &type, &typesize))
+ property = XCB_NONE;
+ else if (data)
+ {
+ 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);
+ }
+ }
+}
+
+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 = 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)
+ {
+ format =
+ ecore_x_window_prop_property_get(ev->requestor, ev->property,
+ XCB_ATOM_ATOM, 32, &data, &num);
+ if (!format)
+ {
+ /* fallback if targets handling is not working and try get the
+ * selection directly */
+ xcb_convert_selection(_ecore_xcb_conn, ev->requestor,
+ selection, selection,
+ ECORE_X_ATOM_UTF8_STRING, XCB_CURRENT_TIME);
+ return;
+ }
+ }
+ else
+ format = ecore_x_window_prop_property_get(ev->requestor, ev->property,
+ XCB_GET_PROPERTY_TYPE_ANY, 8,
+ &data, &num);
+
+ e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
+ if (!e) return;
+ e->win = ev->requestor;
+ e->time = ev->time;
+ e->atom = selection;
+ e->target = _ecore_xcb_selection_target_get(ev->target);
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ e->selection = ECORE_X_SELECTION_XDND;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+
+ e->data = _ecore_xcb_selection_parse(e->target, data, num, format);
+
+ ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e,
+ _ecore_xcb_event_selection_notify_free, NULL);
+}
+
+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;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ ev = (xcb_colormap_notify_event_t *)event;
+ 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;
+ else
+ e->installed = 0;
+ e->time = _ecore_xcb_event_last_time;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
+}
+
+static void
+_ecore_xcb_event_handle_client_message(xcb_generic_event_t *event)
+{
+ xcb_client_message_event_t *ev;
+
+ _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 */
+
+ 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;
+
+ 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) && (ev->data.data32[2] < 9))
+ {
+ Ecore_X_Event_Window_Move_Resize_Request *e;
+
+ 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];
+ e->direction = ev->data.data32[2];
+ e->button = ev->data.data32[3];
+ e->source = ev->data.data32[4];
+ ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
+ }
+ else if (ev->type == ECORE_X_ATOM_XDND_ENTER)
+ {
+ Ecore_X_Event_Xdnd_Enter *e;
+ Ecore_X_DND_Target *target;
+
+ DBG("Got Xdnd Enter Event");
+ 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->source = ev->data.data32[0];
+ target->win = ev->window;
+ target->version = (int)(ev->data.data32[1] >> 24);
+ if (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;
+ }
+ if (ev->data.data32[1] & 0x1UL)
+ {
+ unsigned char *data;
+ Ecore_X_Atom *types;
+ 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))
+ {
+ 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)
+ {
+ int i = 0;
+
+ for (i = 0; i < num_ret; i++)
+ e->types[i] = ecore_x_atom_name_get(types[i]);
+ }
+ e->num_types = num_ret;
+ }
+ else
+ {
+ int i = 0;
+
+ e->types = calloc(3, sizeof(char *));
+ if (e->types)
+ {
+ while ((i < 3) && (ev->data.data32[i + 2]))
+ {
+ 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_xcb_event_xdnd_enter_free, NULL);
+ }
+ else if (ev->type == ECORE_X_ATOM_XDND_POSITION)
+ {
+ Ecore_X_Event_Xdnd_Position *e;
+ Ecore_X_DND_Target *target;
+
+ DBG("Got Xdnd Position Event");
+ 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] : XCB_CURRENT_TIME;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
+ if (!e) return;
+ e->win = target->win;
+ e->source = target->source;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ e->action = target->action;
+ ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
+ }
+ else if (ev->type == ECORE_X_ATOM_XDND_STATUS)
+ {
+ Ecore_X_Event_Xdnd_Status *e;
+ Ecore_X_DND_Source *source;
+
+ DBG("Got Xdnd Status Event");
+ 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 = 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;
+ e->win = source->win;
+ e->target = source->dest;
+ e->will_accept = source->will_accept;
+ e->rectangle.x = source->rectangle.x;
+ e->rectangle.y = source->rectangle.y;
+ e->rectangle.width = source->rectangle.width;
+ e->rectangle.height = source->rectangle.height;
+ e->action = source->accepted_action;
+
+ ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
+ }
+ else if (ev->type == ECORE_X_ATOM_XDND_LEAVE)
+ {
+ Ecore_X_Event_Xdnd_Leave *e;
+ Ecore_X_DND_Target *target;
+
+ DBG("Got Xdnd Leave Event");
+ 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;
+ e->win = ev->window;
+ e->source = (Ecore_X_Window)ev->data.data32[0];
+ ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
+ }
+ else if (ev->type == ECORE_X_ATOM_XDND_DROP)
+ {
+ Ecore_X_Event_Xdnd_Drop *e;
+ Ecore_X_DND_Target *target;
+
+ DBG("Got Xdnd Drop Event");
+ 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) ?
+ (Ecore_X_Time)ev->data.data32[2] : _ecore_xcb_event_last_time;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
+ if (!e) return;
+ e->win = target->win;
+ e->source = target->source;
+ e->action = target->action;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
+ }
+ else if (ev->type == ECORE_X_ATOM_XDND_FINISHED)
+ {
+ Ecore_X_Event_Xdnd_Finished *e;
+ Ecore_X_DND_Source *source;
+ Eina_Bool completed = EINA_TRUE;
+
+ DBG("Got Xdnd Finished Event");
+ 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))
+ {
+ ecore_x_selection_xdnd_clear();
+ source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ else if (source->version >= 5)
+ {
+ completed = EINA_FALSE;
+ source->state = ECORE_X_DND_SOURCE_CONVERTING;
+ /* FIXME: Probably need to add a timer to switch back to idle
+ * and discard the selection data */
+ }
+
+ 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)
+ {
+ source->accepted_action = ev->data.data32[2];
+ e->action = source->accepted_action;
+ }
+ 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)
+ {
+ Ecore_X_Event_Window_State_Request *e;
+
+ 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;
+ else if (ev->data.data32[0] == 1)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
+ else if (ev->data.data32[0] == 2)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
+ else
+ {
+ free(e);
+ return;
+ }
+ e->state[0] = _ecore_xcb_netwm_window_state_get(ev->data.data32[1]);
+ if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+ /* FIXME */
+ }
+ e->state[1] = _ecore_xcb_netwm_window_state_get(ev->data.data32[2]);
+ if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+ /* FIXME */
+ }
+ e->source = ev->data.data32[3];
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
+ }
+#ifdef OLD_XCB_VERSION
+ else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) &&
+ (ev->format == 32) && (ev->data.data32[0] == XCB_WM_STATE_ICONIC))
+#else
+ else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) && (ev->format == 32) &&
+ (ev->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC))
+#endif
+ {
+ Ecore_X_Event_Window_State_Request *e;
+
+ 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))
+ {
+ Ecore_X_Event_Desktop_Change *e;
+
+ 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)
+ {
+ Ecore_X_Event_Frame_Extents_Request *e;
+
+ 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))
+ {
+ Ecore_X_Event_Ping *e;
+ Ecore_X_Window root = 0;
+ int count = 0;
+
+ 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);
+
+ CHECK_XCB_CONN;
+
+ 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)
+ {
+ ev->window = root;
+ xcb_send_event(_ecore_xcb_conn, 0, root,
+ (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY),
+ (const char *)&ev);
+// ecore_x_flush();
+ }
+ }
+ else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
+ (ev->format == 8))
+ {
+ _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))
+ {
+ _ecore_xcb_netwm_startup_info(ev->window, ev->data.data8[0]);
+ }
+ else if ((ev->type == 27777) && (ev->data.data32[0] == 0x7162534) &&
+ (ev->format == 32)) // && (ev->window = _private_window))
+ {
+ if (ev->data.data32[1] == 0x10000001)
+ _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
+ {
+ Ecore_X_Event_Client_Message *e;
+ int i = 0;
+
+ 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];
+ 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;
+
+ _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);
+ _ecore_xcb_modifiers_get();
+
+ 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)
+{
+#ifdef ECORE_XCB_DAMAGE
+ xcb_damage_notify_event_t *ev;
+ Ecore_X_Event_Damage *e;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+#ifdef ECORE_XCB_DAMAGE
+ 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;
+
+ ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
+#endif
+}
+
+static void
+_ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_screen_change_notify_event_t *ev;
+ Ecore_X_Event_Screen_Change *e;
+#endif
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+#ifdef ECORE_XCB_RANDR
+ 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;
+
+ ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
+#endif
+}
+
+static void
+_ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_notify_event_t *ev;
+#endif
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+#ifdef ECORE_XCB_RANDR
+ 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
+}
+
+static void
+_ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_notify_event_t *ev;
+ Ecore_X_Event_Randr_Crtc_Change *e;
+#endif
+
+#ifdef ECORE_XCB_RANDR
+ 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)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_notify_event_t *ev;
+ Ecore_X_Event_Randr_Output_Change *e;
+#endif
+
+#ifdef ECORE_XCB_RANDR
+ ev = (xcb_randr_notify_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_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)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_notify_event_t *ev;
+ Ecore_X_Event_Randr_Output_Property_Notify *e;
+#endif
+
+#ifdef ECORE_XCB_RANDR
+ 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)
+{
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_screensaver_notify_event_t *ev;
+ Ecore_X_Event_Screensaver_Notify *e;
+#endif
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+#ifdef ECORE_XCB_SCREENSAVER
+ ev = (xcb_screensaver_notify_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify)))) return;
+
+ e->win = ev->window;
+ e->on = EINA_FALSE;
+ if ((ev->state == XCB_SCREENSAVER_STATE_ON) ||
+ (ev->state == XCB_SCREENSAVER_STATE_CYCLE)) e->on = EINA_TRUE;
+ e->time = ev->time;
+
+ ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
+#endif
+}
+
+#ifdef ECORE_XCB_XGESTURE
+static void
+_ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event)
+{
+ xcb_gesture_notify_flick_event_t *ev;
+ Ecore_X_Event_Gesture_Notify_Flick *e;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
+
+ ev = (xcb_gesture_notify_flick_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Flick)))) return;
+
+ e->win = ev->window;
+ e->time = ev->time;
+ e->subtype = ev->kind;
+ e->num_fingers = ev->num_finger;
+ e->distance = ev->distance;
+ e->duration = ev->duration;
+ e->direction = ev->direction;
+ e->angle = XFixedToDouble(ev->angle);
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_FLICK, e, NULL, NULL);
+}
+
+static void
+_ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event)
+{
+ xcb_gesture_notify_pan_event_t *ev;
+ Ecore_X_Event_Gesture_Notify_Pan *e;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
+
+ ev = (xcb_gesture_notify_pan_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Pan)))) return;
+
+ e->win = ev->window;
+ e->time = ev->time;
+ e->subtype = ev->kind;
+ e->num_fingers = ev->num_finger;
+ e->dx = ev->dx;
+ e->dy = ev->dy;
+ e->distance = ev->distance;
+ e->duration = ev->duration;
+ e->direction = ev->direction;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PAN, e, NULL, NULL);
+}
+
+static void
+_ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event)
+{
+ xcb_gesture_notify_pinch_rotation_event_t *ev;
+ Ecore_X_Event_Gesture_Notify_PinchRotation *e;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
+
+ ev = (xcb_gesture_notify_pinch_rotation_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_PinchRotation)))) return;
+
+ e->win = ev->window;
+ e->time = ev->time;
+ e->subtype = ev->kind;
+ e->num_fingers = ev->num_finger;
+ e->distance = ev->distance;
+ e->cx = ev->cx;
+ e->cy = ev->cy;
+ e->zoom = XFixedToDouble(ev->zoom);
+ e->angle = XFixedToDouble(ev->angle);
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION, e, NULL, NULL);
+}
+
+static void
+_ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event)
+{
+ xcb_gesture_notify_tap_event_t *ev;
+ Ecore_X_Event_Gesture_Notify_Tap *e;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
+
+ ev = (xcb_gesture_notify_tap_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Tap)))) return;
+
+ e->win = ev->window;
+ e->time = ev->time;
+ e->subtype = ev->kind;
+ e->num_fingers = ev->num_finger;
+ e->cx = ev->cx;
+ e->cy = ev->cy;
+ e->tap_repeat = ev->tap_repeat;
+ e->interval = ev->interval;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAP, e, NULL, NULL);
+}
+
+static void
+_ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event)
+{
+ xcb_gesture_notify_tap_n_hold_event_t *ev;
+ Ecore_X_Event_Gesture_Notify_TapNHold *e;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
+
+ ev = (xcb_gesture_notify_tap_n_hold_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_TapNHold)))) return;
+
+ e->win = ev->window;
+ e->time = ev->time;
+ e->subtype = ev->kind;
+ e->num_fingers = ev->num_finger;
+ e->cx = ev->cx;
+ e->cy = ev->cy;
+ e->interval = ev->interval;
+ e->hold_time = ev->holdtime;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD, e, NULL, NULL);
+}
+
+static void
+ _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event)
+{
+ xcb_gesture_notify_hold_event_t *ev;
+ Ecore_X_Event_Gesture_Notify_Hold *e;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
+
+ ev = (xcb_gesture_notify_hold_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Hold)))) return;
+
+ e->win = ev->window;
+ e->time = ev->time;
+ e->subtype = ev->kind;
+ e->num_fingers = ev->num_finger;
+ e->cx = ev->cx;
+ e->cy = ev->cy;
+ e->hold_time = ev->holdtime;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, e, NULL, NULL);
+}
+
+static void
+ _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event)
+{
+ xcb_gesture_notify_group_event_t *ev;
+ Ecore_X_Event_Gesture_Notify_Group *e;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+ fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
+
+ ev = (xcb_gesture_notify_group_event_t *)event;
+ if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Group)))) return;
+
+ e->win = ev->window;
+ e->time = ev->time;
+ e->subtype = ev->kind;
+ e->num_groups = ev->num_group;
+ e->group_id = ev->groupid;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_GROUP, e, NULL, NULL);
+}
+#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;
+
+ _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;
+
+ 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_XCB_SYNC
+ xcb_sync_counter_notify_event_t *ev;
+ Ecore_X_Event_Sync_Counter *e;
+#endif
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+
+#ifdef ECORE_XCB_SYNC
+ ev = (xcb_sync_counter_notify_event_t *)event;
+ 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
+}
+
+static void
+_ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event)
+{
+#ifdef ECORE_XCB_SYNC
+ xcb_sync_alarm_notify_event_t *ev;
+ Ecore_X_Event_Sync_Alarm *e;
+#endif
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+#ifdef ECORE_XCB_SYNC
+ ev = (xcb_sync_alarm_notify_event_t *)event;
+ 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
+}
+
+static void
+_ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event)
+{
+#ifdef ECORE_XCB_XFIXES
+ Ecore_X_Event_Fixes_Selection_Notify *e;
+ Ecore_X_Atom sel;
+ xcb_xfixes_selection_notify_event_t *ev;
+#endif
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+#ifdef ECORE_XCB_XFIXES
+ ev = (xcb_xfixes_selection_notify_event_t *)event;
+
+ if (!(e = calloc(1, sizeof(*e)))) return;
+
+ e->win = ev->window;
+ e->owner = ev->owner;
+ e->time = ev->timestamp;
+ e->selection_time = ev->selection_timestamp;
+ e->atom = sel = ev->selection;
+ if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+ e->reason = ev->subtype;
+
+ ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
+#endif
+}
+
+static void
+_ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event EINA_UNUSED)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+// FIXME: TBD
+}
+
+static void
+_ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event)
+{
+ xcb_ge_event_t *ev;
+ Ecore_X_Event_Generic *e;
+
+ ev = (xcb_ge_event_t *)event;
+
+ /* pad0 *IS* extension - bug in xcb */
+ if (ev->pad0 == _ecore_xcb_event_input)
+ {
+ _ecore_xcb_event_handle_input_event(event);
+// FIXME: should we generate generic events as WELL as input events?
+// return;
+ }
+
+ 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; */
+ if (ev->length > 0)
+ {
+ int len = ev->length * sizeof(int);
+ e->data = malloc(len);
+ if (e->data) memcpy(e->data, &(event[1]), len);
+ }
+
+ e->evtype = ev->event_type;
+
+ ecore_event_add(ECORE_X_EVENT_GENERIC, e,
+ _ecore_xcb_event_generic_event_free, e->data);
+}
+
+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;
+ char compose_buffer[256];
+ int val = 0;
+
+ _ecore_xcb_event_last_mouse_move = EINA_FALSE;
+
+ 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)
+ {
+ char buff[256];
+
+ snprintf(buff, sizeof(buff), "Keycode-%i", keycode);
+ keyname = buff;
+ }
+
+ 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);
+ if (!compose)
+ ERR("Ecore_X cannot convert input key string '%s' to UTF-8. "
+ "Is Eina built with iconv support?", compose_buffer);
+ }
+
+ 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);
+
+ 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;
+
+ DBG("Sending Key Down Event: %s", e->keyname);
+ 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;
+ char compose_buffer[256];
+ int val = 0;
+
+ _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;
+ }
+
+ 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);
+
+ 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_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)
+{
+ Ecore_Event_Mouse_Move *e;
+ Ecore_Event *event;
+
+ if (!(e = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
+
+ 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 EINA_UNUSED,
+ void *event)
+{
+ Ecore_Event_Mouse_Move *ev;
+
+ 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_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;
+ Ecore_X_Mouse_Down_Info *info = NULL;
+
+ 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 ((info = _ecore_xcb_event_mouse_down_info_get(dev)))
+ {
+ if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
+ (info->did_triple))
+ {
+ info->last_win = 0;
+ info->last_last_win = 0;
+ info->last_event_win = 0;
+ info->last_time = 0;
+ info->last_last_time = 0;
+ }
+ if (event_win == win)
+ {
+ if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN)
+ {
+ if (((int)(timestamp - info->last_time) <=
+ (int)(1000 * _ecore_xcb_double_click_time)) &&
+ (win == info->last_win) &&
+ (event_win == info->last_event_win))
+ {
+ e->double_click = 1;
+ info->did_double = EINA_TRUE;
+ }
+ else
+ {
+ info->did_double = EINA_FALSE;
+ info->did_triple = EINA_FALSE;
+ }
+ if (((int)(timestamp - info->last_last_time) <=
+ (int)(2 * 1000 * _ecore_xcb_double_click_time)) &&
+ (win == info->last_win) &&
+ (win == info->last_last_win) &&
+ (event_win == info->last_event_win) &&
+ (event_win == info->last_last_event_win))
+ {
+ e->triple_click = 1;
+ info->did_triple = EINA_TRUE;
+ }
+ else
+ info->did_triple = EINA_FALSE;
+ }
+ else
+ {
+ if (info->did_double) e->double_click = 1;
+ if (info->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; */
+
+ 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);
+
+ if ((info) && (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
+ (win == event_win) && (!info->did_triple))
+ {
+ info->last_last_win = info->last_win;
+ info->last_win = win;
+ info->last_last_event_win = info->last_event_win;
+ info->last_event_win = event_win;
+ info->last_last_time = info->last_time;
+ info->last_time = timestamp;
+ }
+
+ 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 EINA_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 EINA_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);
+}
+
+static void
+_ecore_xcb_event_mouse_down_info_clear(void)
+{
+ Eina_Inlist *l;
+ Ecore_X_Mouse_Down_Info *info = NULL;
+
+ l = _ecore_xcb_mouse_down_info_list;
+ while (l)
+ {
+ info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info);
+ l = eina_inlist_remove(l, l);
+ free(info);
+ }
+ _ecore_xcb_mouse_down_info_list = NULL;
+}
+
+static Ecore_X_Mouse_Down_Info *
+_ecore_xcb_event_mouse_down_info_get(int dev)
+{
+ Eina_Inlist *l;
+ Ecore_X_Mouse_Down_Info *info = NULL;
+
+ l = _ecore_xcb_mouse_down_info_list;
+ EINA_INLIST_FOREACH(l, info)
+ if (info->dev == dev) return info;
+
+ if (!(info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info)))) return NULL;
+
+ info->dev = dev;
+ l = eina_inlist_append(l, (Eina_Inlist *)info);
+ _ecore_xcb_mouse_down_info_list = l;
+
+ return info;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_extensions.c b/src/lib/ecore_x/xcb/ecore_xcb_extensions.c
new file mode 100644
index 0000000000..40c10ac05b
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_extensions.c
@@ -0,0 +1,148 @@
+#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_GESTURE
+ _ecore_xcb_gesture_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_GESTURE
+ _ecore_xcb_gesture_finalize();
+#endif
+
+/* #ifdef ECORE_XCB_DRI */
+/* _ecore_xcb_dri_finalize(); */
+/* #endif */
+
+#ifdef ECORE_XCB_XTEST
+ _ecore_xcb_xtest_finalize();
+#endif
+
+ xcb_get_maximum_request_length(_ecore_xcb_conn);
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_gc.c b/src/lib/ecore_x/xcb/ecore_xcb_gc.c
new file mode 100644
index 0000000000..d811b54594
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_gc.c
@@ -0,0 +1,173 @@
+#include "ecore_xcb_private.h"
+
+/**
+ * Creates a new default graphics context associated with the given
+ * drawable.
+ * @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.
+ */
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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, vmask, value_list);
+
+// ecore_x_flush();
+ return gc;
+}
+
+/**
+ * Deletes and frees the given graphics context.
+ * @param gc The given graphics context.
+ */
+EAPI void
+ecore_x_gc_free(Ecore_X_GC gc)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_free_gc(_ecore_xcb_conn, gc);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_gc_foreground_set(Ecore_X_GC gc,
+ unsigned long foreground)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ list = foreground;
+ xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_gc_background_set(Ecore_X_GC gc,
+ unsigned long background)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ list = background;
+ xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_BACKGROUND, &list);
+// ecore_x_flush();
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_gesture.c b/src/lib/ecore_x/xcb/ecore_xcb_gesture.c
new file mode 100644
index 0000000000..27c13167af
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_gesture.c
@@ -0,0 +1,203 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_XGESTURE
+# include <xcb/gesture.h>
+# include <xcb/xcb_event.h>
+#endif
+
+/* local variables */
+static Eina_Bool _gesture_available = EINA_FALSE;
+
+/* external variables */
+int _ecore_xcb_event_gesture = -1;
+
+void
+_ecore_xcb_gesture_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_XGESTURE
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_gesture_id);
+#endif
+}
+
+void
+_ecore_xcb_gesture_finalize(void)
+{
+#ifdef ECORE_XCB_XGESTURE
+ xcb_gesture_query_version_cookie_t cookie;
+ xcb_gesture_query_version_reply_t *reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_XGESTURE
+ cookie =
+ xcb_gesture_query_version_unchecked(_ecore_xcb_conn);
+ reply =
+ xcb_gesture_query_version_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply)
+ {
+ _gesture_available = EINA_TRUE;
+ free(reply);
+ }
+
+ if (_gesture_available)
+ {
+ const xcb_query_extension_reply_t *ext_reply;
+
+ ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_gesture_id);
+ if (ext_reply)
+ _ecore_xcb_event_gesture = ext_reply->first_event;
+ }
+#endif
+}
+
+void
+_ecore_xcb_gesture_shutdown(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+}
+
+EAPI Eina_Bool
+ecore_x_gesture_supported(void)
+{
+ return _gesture_available;
+}
+
+#ifdef ECORE_XCB_XGESTURE
+EAPI Eina_Bool
+ecore_x_gesture_events_select(Ecore_X_Window win,
+ Ecore_X_Gesture_Event_Mask mask)
+#else
+EAPI Eina_Bool
+ecore_x_gesture_events_select(Ecore_X_Window win EINA_UNUSED,
+ Ecore_X_Gesture_Event_Mask mask EINA_UNUSED)
+#endif
+
+{
+#ifdef ECORE_XCB_XGESTURE
+ if (!_gesture_available) return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN
+
+ xcb_gesture_select_events(_ecore_xcb_conn, win, mask);
+
+ return EINA_TRUE;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+#ifdef ECORE_XCB_XGESTURE
+EAPI Ecore_X_Gesture_Event_Mask
+ecore_x_gesture_events_selected_get(Ecore_X_Window win)
+#else
+EAPI Ecore_X_Gesture_Event_Mask
+ecore_x_gesture_events_selected_get(Ecore_X_Window win EINA_UNUSED)
+#endif
+{
+#ifdef ECORE_XCB_XGESTURE
+ xcb_gesture_get_selected_events_cookie_t ecookie;
+ xcb_gesture_get_selected_events_reply_t *ereply;
+ Ecore_X_Gesture_Event_Mask mask = ECORE_X_GESTURE_EVENT_MASK_NONE;
+
+ if (!_gesture_available) return mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN
+
+ ecookie = xcb_gesture_get_selected_events(_ecore_xcb_conn, win);
+ ereply =
+ xcb_gesture_get_selected_events_reply(_ecore_xcb_conn, ecookie, NULL);
+ if (ereply)
+ {
+ mask = ereply->mask;
+ free(ereply);
+ }
+
+ return mask;
+#else
+ return ECORE_X_GESTURE_EVENT_MASK_NONE;
+#endif
+}
+
+#ifdef ECORE_XCB_XGESTURE
+EAPI Eina_Bool
+ecore_x_gesture_event_grab(Ecore_X_Window win,
+ Ecore_X_Gesture_Event_Type type,
+ int num_fingers)
+#else
+EAPI Eina_Bool
+ecore_x_gesture_event_grab(Ecore_X_Window win EINA_UNUSED,
+ Ecore_X_Gesture_Event_Type type EINA_UNUSED,
+ int num_fingers EINA_UNUSED)
+#endif
+{
+#ifdef ECORE_XCB_XGESTURE
+ Eina_Bool status = EINA_TRUE;
+ xcb_gesture_grab_event_cookie_t ecookie;
+ xcb_gesture_grab_event_reply_t *ereply;
+
+ if (!_gesture_available) return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN
+
+ ecookie =
+ xcb_gesture_grab_event(_ecore_xcb_conn, win, type, num_fingers, 0L);
+ ereply = xcb_gesture_grab_event_reply(_ecore_xcb_conn, ecookie, NULL);
+
+ if (ereply)
+ {
+ if (ereply->status) status = EINA_FALSE;
+ free(ereply);
+ }
+ else
+ status = EINA_FALSE;
+
+ return status;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+#ifdef ECORE_XCB_XGESTURE
+EAPI Eina_Bool
+ecore_x_gesture_event_ungrab(Ecore_X_Window win,
+ Ecore_X_Gesture_Event_Type type,
+ int num_fingers)
+#else
+EAPI Eina_Bool
+ecore_x_gesture_event_ungrab(Ecore_X_Window win EINA_UNUSED,
+ Ecore_X_Gesture_Event_Type type EINA_UNUSED,
+ int num_fingers EINA_UNUSED)
+#endif
+{
+#ifdef ECORE_XCB_XGESTURE
+ Eina_Bool status = EINA_TRUE;
+ xcb_gesture_ungrab_event_cookie_t ecookie;
+ xcb_gesture_ungrab_event_reply_t *ereply;
+
+ if (!_gesture_available) return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN
+
+ ecookie =
+ xcb_gesture_ungrab_event(_ecore_xcb_conn, win, type, num_fingers, 0L);
+ ereply = xcb_gesture_ungrab_event_reply(_ecore_xcb_conn, ecookie, NULL);
+
+ if (ereply)
+ {
+ if (ereply->status) status = EINA_FALSE;
+ free(ereply);
+ }
+ else
+ status = EINA_FALSE;
+
+ return status;
+#else
+ return EINA_FALSE;
+#endif
+}
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_icccm.c b/src/lib/ecore_x/xcb/ecore_xcb_icccm.c
new file mode 100644
index 0000000000..8dea8617d1
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_icccm.c
@@ -0,0 +1,1569 @@
+#include "ecore_xcb_private.h"
+#include <xcb/xcb_icccm.h>
+
+EAPI void
+ecore_x_icccm_init(void)
+{
+}
+
+/**
+ * Sets the WM_COMMAND property for @a win.
+ *
+ * @param win The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ */
+EAPI void
+ecore_x_icccm_command_set(Ecore_X_Window win,
+ int argc,
+ char **argv)
+{
+ void *buf;
+ char *b;
+ int nbytes, i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ for (i = 0, nbytes = 0; i < argc; i++)
+ if (argv[i]) nbytes += strlen(argv[i]) + 1;
+
+ buf = malloc(sizeof(char) * nbytes);
+ if (!buf) return;
+
+ b = (char *)buf;
+ for (i = 0; i < argc; i++)
+ {
+ if (argv[i])
+ {
+ strcpy(b, argv[i]);
+ b += strlen(argv[i]) + 1;
+ }
+ else
+ *b++ = '\0';
+ }
+ 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);
+}
+
+/**
+ * Get the WM_COMMAND property for @a win.
+ *
+ * Return the command of a window. String must be free'd when done with.
+ *
+ * @param win The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ */
+EAPI void
+ecore_x_icccm_command_get(Ecore_X_Window win,
+ int *argc,
+ char ***argv)
+{
+ 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (argc) *argc = 0;
+ if (argv) *argv = NULL;
+
+ 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 ((reply->type != ECORE_X_ATOM_STRING) || (reply->format != 8))
+ {
+ free(reply);
+ return;
+ }
+
+ len = reply->value_len;
+ if (len < 1)
+ {
+ free(reply);
+ return;
+ }
+
+ data = (char *)xcb_get_property_value(reply);
+ if (len && (data[len - 1] == '\0'))
+ len--;
+
+ c = 1;
+ for (cp = (char *)data, i = len; i > 0; cp++, i--)
+ if (*cp == '\0') c++;
+
+ v = (char **)malloc((c + 1) * sizeof(char *));
+ if (!v)
+ {
+ free(reply);
+ return;
+ }
+
+ start = (char *)malloc((len + 1) * sizeof(char));
+ if (!start)
+ {
+ free(reply);
+ free(v);
+ return;
+ }
+
+ memcpy(start, (char *)data, len);
+ start[len] = '\0';
+ for (cp = start, i = len + 1, j = 0; i > 0; cp++, i--)
+ {
+ if (*cp == '\0')
+ {
+ v[j] = start;
+ start = (cp + 1);
+ j++;
+ }
+ }
+
+ if (c < 1)
+ {
+ free(reply);
+ free(v);
+ return;
+ }
+
+ if (argc) *argc = c;
+
+ if (argv)
+ {
+ (*argv) = malloc(c * sizeof(char *));
+ if (!*argv)
+ {
+ free(reply);
+ free(v);
+ if (argc) *argc = 0;
+ return;
+ }
+
+ for (i = 0; i < c; i++)
+ {
+ if (v[i])
+ (*argv)[i] = strdup(v[i]);
+ else
+ (*argv)[i] = strdup("");
+ }
+ }
+
+ free(reply);
+ free(v);
+}
+
+EAPI char *
+ecore_x_icccm_title_get(Ecore_X_Window win)
+{
+ xcb_get_property_cookie_t cookie;
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_t prop;
+#else
+ xcb_icccm_get_text_property_reply_t prop;
+#endif
+ uint8_t ret = 0;
+ char *title = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) return NULL;
+#ifdef OLD_XCB_VERSION
+ cookie = xcb_get_wm_name_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
+#else
+ cookie = xcb_icccm_get_wm_name_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_icccm_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
+#endif
+ if (ret == 0) return NULL;
+ if (prop.name_len < 1)
+ {
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_wipe(&prop);
+#else
+ xcb_icccm_get_text_property_reply_wipe(&prop);
+#endif
+ return NULL;
+ }
+
+ if (!(title = malloc((prop.name_len + 1) * sizeof(char *))))
+ {
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_wipe(&prop);
+#else
+ xcb_icccm_get_text_property_reply_wipe(&prop);
+#endif
+ return NULL;
+ }
+ memcpy(title, prop.name, sizeof(char *) * prop.name_len);
+ title[prop.name_len] = '\0';
+
+ 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]);
+
+ if (list) free(list);
+ }
+ }
+
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_wipe(&prop);
+#else
+ xcb_icccm_get_text_property_reply_wipe(&prop);
+#endif
+ return title;
+}
+
+EAPI void
+ecore_x_icccm_title_set(Ecore_X_Window win,
+ const char *title)
+{
+ Ecore_Xcb_Textproperty prop;
+ char *list[1];
+ Eina_Bool ret = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!title) return;
+
+ prop.value = NULL;
+ list[0] = strdup(title);
+
+#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 (ret)
+ {
+#ifdef OLD_XCB_VERSION
+ xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
+ strlen(prop.value), prop.value);
+#else
+ xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8,
+ strlen(prop.value), prop.value);
+#endif
+ if (prop.value) free(prop.value);
+ }
+ else
+#ifdef OLD_XCB_VERSION
+ xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
+ strlen(title), title);
+#else
+ xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8,
+ strlen(title), title);
+#endif
+ free(list[0]);
+}
+
+/**
+ * Get a window name & class.
+ * @param win The window
+ * @param n The name string
+ * @param c The class string
+ *
+ * Get a window name * class
+ */
+EAPI void
+ecore_x_icccm_name_class_get(Ecore_X_Window win,
+ char **name,
+ char **class)
+{
+ xcb_get_property_cookie_t cookie;
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_class_reply_t prop;
+#else
+ xcb_icccm_get_wm_class_reply_t prop;
+#endif
+ uint8_t ret = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (name) *name = NULL;
+ if (class) *class = NULL;
+
+#ifdef OLD_XCB_VERSION
+ cookie = xcb_get_wm_class_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL);
+#else
+ cookie = xcb_icccm_get_wm_class_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_icccm_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL);
+#endif
+ if (ret == 0) return;
+
+ if (name) *name = strdup(prop.instance_name);
+ if (class) *class = strdup(prop.class_name);
+
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_class_reply_wipe(&prop);
+#else
+ xcb_icccm_get_wm_class_reply_wipe(&prop);
+#endif
+}
+
+/**
+ * Set a window name & class.
+ * @param win The window
+ * @param n The name string
+ * @param c The class string
+ *
+ * Set a window name * class
+ */
+EAPI void
+ecore_x_icccm_name_class_set(Ecore_X_Window win,
+ const char *name,
+ const char *class)
+{
+ char *class_string, *s;
+ int length_name, length_class;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ length_name = strlen(name);
+ length_class = strlen(class);
+ class_string =
+ (char *)malloc(sizeof(char) * (length_name + length_class + 2));
+ if (!class_string) return;
+
+ s = class_string;
+ if (length_name)
+ {
+ strcpy(s, name);
+ s += length_name + 1;
+ }
+ else
+ *s++ = '\0';
+
+ if (length_class)
+ strcpy(s, class);
+ else
+ *s = '\0';
+
+ 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);
+}
+
+/**
+ * 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_transient_for_set(Ecore_X_Window win,
+ Ecore_X_Window forwindow)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+}
+
+/**
+ * Remove the transient_for setting from a window.
+ * @param win The window
+ */
+EAPI void
+ecore_x_icccm_transient_for_unset(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_TRANSIENT_FOR);
+}
+
+/**
+ * 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 Ecore_X_Window
+ecore_x_icccm_transient_for_get(Ecore_X_Window win)
+{
+ Ecore_X_Window forwin = 0;
+ xcb_get_property_cookie_t cookie;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef OLD_XCB_VERSION
+ cookie = xcb_get_wm_transient_for_unchecked(_ecore_xcb_conn, win);
+ xcb_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL);
+#else
+ cookie = xcb_icccm_get_wm_transient_for_unchecked(_ecore_xcb_conn, win);
+ xcb_icccm_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL);
+#endif
+
+ return forwin;
+}
+
+/**
+ * Get the window role.
+ * @param win The window
+ * @return The window's role string.
+ */
+EAPI char *
+ecore_x_icccm_window_role_get(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE);
+}
+
+/**
+ * Set the window role hint.
+ * @param win The window
+ * @param role The role string
+ */
+EAPI void
+ecore_x_icccm_window_role_set(Ecore_X_Window win,
+ const char *role)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE, role);
+}
+
+/**
+ * Get the window's client leader.
+ * @param win The window
+ * @return The window's client leader window, or 0 if unset
+ */
+EAPI Ecore_X_Window
+ecore_x_icccm_client_leader_get(Ecore_X_Window win)
+{
+ 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;
+
+ return 0;
+}
+
+/**
+ * Set the window's client leader.
+ * @param win The window
+ * @param l 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.
+ */
+EAPI void
+ecore_x_icccm_client_leader_set(Ecore_X_Window win,
+ Ecore_X_Window leader)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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__);
+ CHECK_XCB_CONN;
+
+ 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))
+ {
+ free(reply);
+ return hint;
+ }
+
+ prop = (uint8_t *)xcb_get_property_value(reply);
+#ifdef OLD_XCB_VERSION
+ 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:
+ break;
+ }
+#else
+ switch (prop[0])
+ {
+ case XCB_ICCCM_WM_STATE_WITHDRAWN:
+ hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ break;
+
+ case XCB_ICCCM_WM_STATE_NORMAL:
+ hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ break;
+
+ case XCB_ICCCM_WM_STATE_ICONIC:
+ hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ break;
+
+ default:
+ break;
+ }
+#endif
+
+ free(reply);
+ return hint;
+}
+
+EAPI void
+ecore_x_icccm_state_set(Ecore_X_Window win,
+ Ecore_X_Window_State_Hint state)
+{
+#ifdef OLD_XCB_VERSION
+ xcb_wm_hints_t hints;
+#else
+ xcb_icccm_wm_hints_t hints;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef OLD_XCB_VERSION
+ xcb_wm_hints_set_none(&hints);
+
+ hints.flags = XCB_WM_HINT_STATE;
+
+ 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);
+#else
+ xcb_icccm_wm_hints_set_none(&hints);
+
+ hints.flags = XCB_ICCCM_WM_HINT_STATE;
+
+ if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ xcb_icccm_wm_hints_set_withdrawn(&hints);
+ else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ xcb_icccm_wm_hints_set_normal(&hints);
+ else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ xcb_icccm_wm_hints_set_iconic(&hints);
+
+ xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints);
+#endif
+}
+
+EAPI void
+ecore_x_icccm_delete_window_send(Ecore_X_Window win,
+ Ecore_X_Time t)
+{
+ 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)
+{
+#ifdef OLD_XCB_VERSION
+ xcb_wm_hints_t hints;
+#else
+ xcb_icccm_wm_hints_t hints;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef OLD_XCB_VERSION
+ xcb_wm_hints_set_none(&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, win, &hints);
+#else
+ xcb_icccm_wm_hints_set_none(&hints);
+ xcb_icccm_wm_hints_set_input(&hints, accepts_focus);
+
+ if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ xcb_icccm_wm_hints_set_withdrawn(&hints);
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ xcb_icccm_wm_hints_set_normal(&hints);
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ xcb_icccm_wm_hints_set_iconic(&hints);
+
+ if (icon_pixmap != 0)
+ xcb_icccm_wm_hints_set_icon_pixmap(&hints, icon_pixmap);
+ if (icon_mask != 0)
+ xcb_icccm_wm_hints_set_icon_mask(&hints, icon_mask);
+ if (icon_window != 0)
+ xcb_icccm_wm_hints_set_icon_window(&hints, icon_window);
+ if (window_group != 0)
+ xcb_icccm_wm_hints_set_window_group(&hints, window_group);
+ if (is_urgent)
+ xcb_icccm_wm_hints_set_urgency(&hints);
+
+ xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints);
+#endif
+}
+
+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;
+#ifdef OLD_XCB_VERSION
+ xcb_wm_hints_t hints;
+#else
+ xcb_icccm_wm_hints_t hints;
+#endif
+ uint8_t ret = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+#ifdef OLD_XCB_VERSION
+ 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);
+#else
+ xcb_icccm_wm_hints_set_none(&hints);
+ cookie = xcb_icccm_get_wm_hints_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_icccm_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL);
+#endif
+ if (!ret) return EINA_FALSE;
+
+#ifdef OLD_XCB_VERSION
+ if ((hints.flags & XCB_WM_HINT_INPUT) && (accepts_focus))
+#else
+ if ((hints.flags & XCB_ICCCM_WM_HINT_INPUT) && (accepts_focus))
+#endif
+ {
+ if (hints.input)
+ *accepts_focus = EINA_TRUE;
+ else
+ *accepts_focus = EINA_FALSE;
+ }
+
+#ifdef OLD_XCB_VERSION
+ 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;
+ }
+
+ 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;
+#else
+ if ((hints.flags & XCB_ICCCM_WM_HINT_STATE) && (initial_state))
+ {
+ if (hints.initial_state == XCB_ICCCM_WM_STATE_WITHDRAWN)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else if (hints.initial_state == XCB_ICCCM_WM_STATE_NORMAL)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ else if (hints.initial_state == XCB_ICCCM_WM_STATE_ICONIC)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ }
+
+ if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_PIXMAP) && (icon_pixmap))
+ *icon_pixmap = hints.icon_pixmap;
+
+ if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_MASK) && (icon_mask))
+ *icon_mask = hints.icon_mask;
+
+ if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_WINDOW) && (icon_window))
+ *icon_window = hints.icon_window;
+
+ if ((hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) && (window_group))
+ *window_group = hints.window_group;
+
+ if ((hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) && (is_urgent))
+ *is_urgent = EINA_TRUE;
+#endif
+
+ 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;
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_t prop;
+#else
+ xcb_icccm_get_text_property_reply_t prop;
+#endif
+ uint8_t ret = 0;
+ char *tmp = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) return NULL;
+
+#ifdef OLD_XCB_VERSION
+ cookie = xcb_get_wm_icon_name_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
+#else
+ cookie = xcb_icccm_get_wm_icon_name_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_icccm_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
+#endif
+ if (ret == 0) return NULL;
+
+ if (prop.name_len < 1)
+ {
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_wipe(&prop);
+#else
+ xcb_icccm_get_text_property_reply_wipe(&prop);
+#endif
+ return NULL;
+ }
+
+ if (!(tmp = malloc((prop.name_len + 1) * sizeof(char *))))
+ {
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_wipe(&prop);
+#else
+ xcb_icccm_get_text_property_reply_wipe(&prop);
+#endif
+ return NULL;
+ }
+ memcpy(tmp, prop.name, sizeof(char *) * prop.name_len);
+ tmp[prop.name_len] = '\0';
+
+ 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(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)
+ {
+ if (count > 0)
+ tmp = strdup(list[0]);
+
+ if (list) free(list);
+ }
+ }
+
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_wipe(&prop);
+#else
+ xcb_icccm_get_text_property_reply_wipe(&prop);
+#endif
+ return tmp;
+}
+
+/**
+ * Set a window icon name.
+ * @param win The window
+ * @param t The icon name string
+ *
+ * Set a window icon name
+ */
+EAPI void
+ecore_x_icccm_icon_name_set(Ecore_X_Window win,
+ const char *name)
+{
+ Ecore_Xcb_Textproperty prop;
+ char *list[1];
+ Eina_Bool ret = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if ((!win) || (!name)) return;
+
+ prop.value = NULL;
+ list[0] = strdup(name);
+
+#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 (ret)
+ {
+#ifdef OLD_XCB_VERSION
+ xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
+ strlen(prop.value), prop.value);
+#else
+ xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
+ 8, strlen(prop.value), prop.value);
+#endif
+ if (prop.value) free(prop.value);
+ }
+ else
+#ifdef OLD_XCB_VERSION
+ xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
+ strlen(name), name);
+#else
+ xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
+ 8, strlen(name), name);
+#endif
+
+ free(list[0]);
+}
+
+EAPI void
+ecore_x_icccm_iconic_request_send(Ecore_X_Window win,
+ Ecore_X_Window root)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+#ifdef OLD_XCB_VERSION
+ ev.data.data32[0] = XCB_WM_STATE_ICONIC;
+#else
+ ev.data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC;
+#endif
+
+ xcb_send_event(_ecore_xcb_conn, 0, root,
+ (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT),
+ (const char *)&ev);
+// ecore_x_flush();
+}
+
+/**
+ * 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_protocol_set(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol,
+ Eina_Bool on)
+{
+ Ecore_X_Atom proto;
+ xcb_get_property_cookie_t cookie;
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_t protos;
+#else
+ xcb_icccm_get_wm_protocols_reply_t protos;
+#endif
+ int i = 0, count = 0, set = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return;
+ proto = _ecore_xcb_atoms_wm_protocol[protocol];
+#ifdef OLD_XCB_VERSION
+ cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
+ if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL))
+#else
+ cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
+ if (!xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL))
+#endif
+ count = 0;
+ else
+ count = protos.atoms_len;
+
+ for (i = 0; i < count; i++)
+ {
+ if (protos.atoms[i] == proto)
+ {
+ set = 1;
+ break;
+ }
+ }
+
+ if (on)
+ {
+ if (!set)
+ {
+ Ecore_X_Atom *atoms = NULL;
+
+ atoms = malloc((count + 1) * sizeof(Ecore_X_Atom));
+ if (atoms)
+ {
+ for (i = 0; i < count; i++)
+ atoms[i] = protos.atoms[i];
+ atoms[count] = proto;
+#ifdef OLD_XCB_VERSION
+ xcb_set_wm_protocols(_ecore_xcb_conn,
+ ECORE_X_ATOM_WM_PROTOCOLS,
+ win, count, atoms);
+#else
+ xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win,
+ ECORE_X_ATOM_WM_PROTOCOLS,
+ count, atoms);
+#endif
+ free(atoms);
+ }
+ }
+ }
+ else
+ {
+ if (set)
+ {
+ for (i = 0; i < count; i++)
+ {
+ 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)
+#ifdef OLD_XCB_VERSION
+ xcb_set_wm_protocols(_ecore_xcb_conn,
+ ECORE_X_ATOM_WM_PROTOCOLS,
+ win, count - 1, protos.atoms);
+#else
+ xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win,
+ ECORE_X_ATOM_WM_PROTOCOLS,
+ count - 1, protos.atoms);
+#endif
+ else
+ ecore_x_window_prop_property_del(win,
+ ECORE_X_ATOM_WM_PROTOCOLS);
+ break;
+ }
+ }
+ }
+ }
+
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_wipe(&protos);
+#else
+ xcb_icccm_get_wm_protocols_reply_wipe(&protos);
+#endif
+}
+
+/**
+ * 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 Eina_Bool
+ecore_x_icccm_protocol_isset(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol)
+{
+ Ecore_X_Atom proto;
+ Eina_Bool ret = EINA_FALSE;
+ xcb_get_property_cookie_t cookie;
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_t reply;
+#else
+ xcb_icccm_get_wm_protocols_reply_t reply;
+#endif
+ uint8_t val = 0;
+ unsigned int i = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE;
+
+ proto = _ecore_xcb_atoms_wm_protocol[protocol];
+#ifdef OLD_XCB_VERSION
+ cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
+ val = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL);
+#else
+ cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
+ val = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL);
+#endif
+ if (!val) return EINA_FALSE;
+
+ for (i = 0; i < reply.atoms_len; i++)
+ if (reply.atoms[i] == proto)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_wipe(&reply);
+#else
+ xcb_icccm_get_wm_protocols_reply_wipe(&reply);
+#endif
+
+ return ret;
+}
+
+/**
+ * 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_protocol_atoms_set(Ecore_X_Window win,
+ Ecore_X_Atom *protos,
+ int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (num > 0)
+#ifdef OLD_XCB_VERSION
+ xcb_set_wm_protocols(_ecore_xcb_conn, ECORE_X_ATOM_WM_PROTOCOLS,
+ win, num, protos);
+#else
+ xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win,
+ ECORE_X_ATOM_WM_PROTOCOLS, num, protos);
+#endif
+ else
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_PROTOCOLS);
+}
+
+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;
+ 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__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+#ifdef OLD_XCB_VERSION
+ cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL);
+#else
+ cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie,
+ &hints, NULL);
+#endif
+ if (!ret) return EINA_FALSE;
+
+#ifdef OLD_XCB_VERSION
+ if ((hints.flags & XCB_SIZE_HINT_US_POSITION) ||
+ (hints.flags & XCB_SIZE_HINT_P_POSITION))
+#else
+ if ((hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION) ||
+ (hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION))
+#endif
+ {
+ if (request_pos) *request_pos = EINA_TRUE;
+ }
+
+#ifdef OLD_XCB_VERSION
+ if (hints.flags & XCB_SIZE_HINT_P_WIN_GRAVITY)
+#else
+ if (hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY)
+#endif
+ {
+ if (gravity) *gravity = hints.win_gravity;
+ }
+
+#ifdef OLD_XCB_VERSION
+ if (hints.flags & XCB_SIZE_HINT_P_MIN_SIZE)
+#else
+ if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE)
+#endif
+ {
+ minw = hints.min_width;
+ minh = hints.min_height;
+ }
+
+#ifdef OLD_XCB_VERSION
+ if (hints.flags & XCB_SIZE_HINT_P_MAX_SIZE)
+#else
+ if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE)
+#endif
+ {
+ maxw = hints.max_width;
+ maxh = hints.max_height;
+ if (maxw < minw) maxw = minw;
+ if (maxh < minh) maxh = minh;
+ }
+
+#ifdef OLD_XCB_VERSION
+ if (hints.flags & XCB_SIZE_HINT_BASE_SIZE)
+#else
+ if (hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE)
+#endif
+ {
+ basew = hints.base_width;
+ baseh = hints.base_height;
+ if (basew > minw) minw = basew;
+ if (baseh > minh) minh = baseh;
+ }
+
+#ifdef OLD_XCB_VERSION
+ if (hints.flags & XCB_SIZE_HINT_P_RESIZE_INC)
+#else
+ if (hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC)
+#endif
+ {
+ stepx = hints.width_inc;
+ stepy = hints.height_inc;
+ if (stepx < 1) stepx = 1;
+ if (stepy < 1) stepy = 1;
+ }
+
+#ifdef OLD_XCB_VERSION
+ if (hints.flags & XCB_SIZE_HINT_P_ASPECT)
+#else
+ if (hints.flags & XCB_ICCCM_SIZE_HINT_P_ASPECT)
+#endif
+ {
+ if (hints.min_aspect_den > 0)
+ mina = ((double)hints.min_aspect_num) / ((double)hints.min_aspect_den);
+
+ 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;
+}
+
+EAPI void
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef OLD_XCB_VERSION
+ cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL);
+#else
+ cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie,
+ &hints, NULL);
+#endif
+ if (!ret) memset(&hints, 0, sizeof(xcb_size_hints_t));
+
+ hints.flags = 0;
+
+#ifdef OLD_XCB_VERSION
+ 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);
+#else
+ if (request_pos)
+ hints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION;
+
+ if (gravity != ECORE_X_GRAVITY_NW)
+ xcb_icccm_size_hints_set_win_gravity(&hints, gravity);
+ if ((min_w > 0) || (min_h > 0))
+ xcb_icccm_size_hints_set_min_size(&hints, min_w, min_h);
+ if ((max_w > 0) || (max_h > 0))
+ xcb_icccm_size_hints_set_max_size(&hints, max_w, max_h);
+ if ((base_w > 0) || (base_h > 0))
+ xcb_icccm_size_hints_set_base_size(&hints, base_w, base_h);
+ if ((step_x > 1) || (step_y > 1))
+ xcb_icccm_size_hints_set_resize_inc(&hints, step_x, step_y);
+ if ((min_aspect > 0.0) || (max_aspect > 0.0))
+ xcb_icccm_size_hints_set_aspect(&hints,
+ (int32_t)(min_aspect * 10000), 10000,
+ (int32_t)(max_aspect * 10000), 10000);
+
+ xcb_icccm_set_wm_normal_hints(_ecore_xcb_conn, win, &hints);
+#endif
+}
+
+EAPI void
+ecore_x_icccm_move_resize_send(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ xcb_configure_notify_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+/**
+ * Get a window client machine string.
+ * @param win The window
+ * @return The windows client machine string
+ *
+ * Return the client machine of a window. String must be free'd when done with.
+ */
+EAPI char *
+ecore_x_icccm_client_machine_get(Ecore_X_Window win)
+{
+ xcb_get_property_cookie_t cookie;
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_t prop;
+#else
+ xcb_icccm_get_text_property_reply_t prop;
+#endif
+ uint8_t ret = 0;
+ char *tmp = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef OLD_XCB_VERSION
+ cookie = xcb_get_wm_client_machine_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_get_wm_client_machine_reply(_ecore_xcb_conn, cookie, &prop, NULL);
+#else
+ cookie = xcb_icccm_get_wm_client_machine_unchecked(_ecore_xcb_conn, win);
+ ret = xcb_icccm_get_wm_client_machine_reply(_ecore_xcb_conn, cookie,
+ &prop, NULL);
+#endif
+ if (ret == 0) return NULL;
+
+ tmp = malloc((prop.name_len + 1) * sizeof(char *));
+ if (!tmp)
+ {
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_wipe(&prop);
+#else
+ xcb_icccm_get_text_property_reply_wipe(&prop);
+#endif
+ return NULL;
+ }
+ memcpy(tmp, prop.name, sizeof(char *) * prop.name_len);
+ tmp[prop.name_len] = '\0';
+
+#ifdef OLD_XCB_VERSION
+ xcb_get_text_property_reply_wipe(&prop);
+#else
+ xcb_icccm_get_text_property_reply_wipe(&prop);
+#endif
+
+ return tmp;
+}
+
+EAPI void
+ecore_x_icccm_take_focus_send(Ecore_X_Window win,
+ Ecore_X_Time t)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+}
+
+/**
+ * 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 void
+ecore_x_icccm_colormap_window_set(Ecore_X_Window win,
+ Ecore_X_Window subwin)
+{
+ int num = 0, i = 0;
+ unsigned char *odata = NULL, *data = NULL;
+ Ecore_X_Window *newset = NULL, *oldset = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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);
+}
+
+/**
+ * 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_colormap_window_unset(Ecore_X_Window win,
+ Ecore_X_Window subwin)
+{
+ int num = 0, i = 0, j = 0, k = 0;
+ unsigned char *odata = NULL, *data = NULL;
+ Ecore_X_Window *newset = NULL, *oldset = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ ECORE_X_ATOM_WINDOW, 32, &odata, &num))
+ return;
+
+ 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];
+
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ ECORE_X_ATOM_WINDOW, 32, data, k);
+ if (odata) free(odata);
+ odata = NULL;
+ free(newset);
+ return;
+ }
+ }
+ }
+ if (odata) free(odata);
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_image.c b/src/lib/ecore_x/xcb/ecore_xcb_image.c
new file mode 100644
index 0000000000..8e221101b0
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_image.c
@@ -0,0 +1,738 @@
+#include "ecore_xcb_private.h"
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <xcb/xcb_event.h>
+#include <xcb/shm.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_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__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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();
+ ecore_x_sync(); // needed
+
+ 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__);
+ CHECK_XCB_CONN;
+
+ 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_shm_put_image(_ecore_xcb_conn, draw, gc, im->xim->width,
+ im->xim->height, sx, sy, w, h, x, y,
+ im->xim->depth, im->xim->format, 0,
+ im->shminfo.shmseg,
+ im->xim->data - im->shminfo.shmaddr);
+// 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);
+ ecore_x_sync();
+}
+
+EAPI Eina_Bool
+ecore_x_image_is_argb32_get(Ecore_X_Image *im)
+{
+ xcb_visualtype_t *vis;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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_MSB_FIRST) return EINA_TRUE;
+#else
+ if (im->xim->byte_order == XCB_IMAGE_ORDER_LSB_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__);
+ CHECK_XCB_CONN;
+
+ 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;
+ CHECK_XCB_CONN;
+
+ /* 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)
+{
+ CHECK_XCB_CONN;
+
+ 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));
+ 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;
+}
+
+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 uint8_t dpth = 0;
+ static xcb_format_t *fmt = NULL;
+ const xcb_setup_t *setup;
+ xcb_image_format_t xif;
+
+ CHECK_XCB_CONN;
+
+ /* NB: We cannot use xcb_image_create_native as it only creates images
+ * using MSB_FIRST, so this routine recreates that function and uses
+ * the endian-ness of the server setup */
+ setup = xcb_get_setup(_ecore_xcb_conn);
+ xif = format;
+
+ if ((xif == XCB_IMAGE_FORMAT_Z_PIXMAP) && (depth == 1))
+ xif = XCB_IMAGE_FORMAT_XY_PIXMAP;
+
+ if (dpth != depth)
+ {
+ dpth = depth;
+ 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:
+ 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;
+
+ CHECK_XCB_CONN;
+
+ fmt = xcb_setup_pixmap_formats(setup);
+ fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
+ for (; fmt != fmtend; ++fmt)
+ if (fmt->depth == depth)
+ return fmt;
+
+ return 0;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_input.c b/src/lib/ecore_x/xcb/ecore_xcb_input.c
new file mode 100644
index 0000000000..6cf3ebf6e6
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_input.c
@@ -0,0 +1,274 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_XINPUT
+# include <xcb/xinput.h>
+# include <xcb/xcb_event.h>
+#endif
+
+/* FIXME: this is a guess. can't find defines for touch events in xcb libs
+ * online */
+/* these are not yet defined in xcb support for xi2 - so manually create */
+#ifndef XCB_INPUT_DEVICE_TOUCH_BEGIN
+#define XCB_INPUT_DEVICE_TOUCH_BEGIN 18
+#endif
+#ifndef XCB_INPUT_DEVICE_TOUCH_END
+#define XCB_INPUT_DEVICE_TOUCH_END 19
+#endif
+#ifndef XCB_INPUT_DEVICE_TOUCH_UPDATE
+#define XCB_INPUT_DEVICE_TOUCH_UPDATE 21
+#endif
+
+#ifndef XCB_INPUT_POINTER_EMULATED_MASK
+#define XCB_INPUT_POINTER_EMULATED_MASK (1 << 16)
+#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 EINA_UNUSED)
+#endif
+{
+#ifdef ECORE_XCB_XINPUT
+ xcb_ge_event_t *ev;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ /* FIXME: look at xlib ecore_x_xi2.c to copy logic in when i can find an
+ * xcb-input lib to test with */
+#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;
+
+ case XCB_INPUT_DEVICE_TOUCH_UPDATE:
+ {
+ 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_TOUCH_BEGIN:
+ {
+ 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_TOUCH_END:
+ {
+ 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__);
+ CHECK_XCB_CONN;
+
+ if (!_input_avail) return EINA_FALSE;
+
+ /* FIXME: i can't seemingly test this! no xcb input lib so can't look and
+ * test and look at types etc. - look at xlib code and copy logic over
+ * when we can */
+#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,
+ XCB_INPUT_DEVICE_TOUCH_BEGIN,
+ XCB_INPUT_DEVICE_TOUCH_END,
+ XCB_INPUT_DEVICE_TOUCH_UPDATE
+ };
+
+ 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);
+
+ xcb_input_select_extension_event(_ecore_xcb_conn, win,
+ sizeof(iclass) / sizeof(xcb_input_event_class_t),
+ iclass);
+ find = EINA_TRUE;
+ }
+ xcb_input_device_info_next(&diter);
+ }
+ free(dreply);
+#endif
+
+ return find;
+ win = 0;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_keymap.c b/src/lib/ecore_x/xcb/ecore_xcb_keymap.c
new file mode 100644
index 0000000000..6c112464b0
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_keymap.c
@@ -0,0 +1,491 @@
+#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_MODIFIER_ALTGR = 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__);
+ CHECK_XCB_CONN;
+
+ 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_Meta_L);
+
+ ECORE_X_MODIFIER_ALTGR = _ecore_xcb_keymap_mask_get(reply, XK_Mode_switch);
+
+ 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_modifiers_get(void)
+{
+ _ecore_xcb_keymap_finalize();
+}
+
+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)
+{
+ CHECK_XCB_CONN;
+ 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;
+
+ CHECK_XCB_CONN;
+ 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)
+{
+ CHECK_XCB_CONN;
+ 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;
+
+ CHECK_XCB_CONN;
+ 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;
+
+ CHECK_XCB_CONN;
+
+ 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;
+
+ CHECK_XCB_CONN;
+ 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);
+}
+
+EAPI int
+ecore_x_keysym_keycode_get(const char *keyname)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return _ecore_xcb_keymap_string_to_keycode(keyname);
+}
+
+/* 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__);
+ CHECK_XCB_CONN;
+
+ rep = (xcb_get_modifier_mapping_reply_t *)reply;
+ if ((rep) && (rep->keycodes_per_modifier > 0))
+ {
+ int i = 0;
+ xcb_keycode_t *modmap;
+
+ modmap = xcb_get_modifier_mapping_keycodes(rep);
+ for (i = 0; i < (8 * rep->keycodes_per_modifier); i++)
+ {
+ int j = 0;
+
+ for (j = 0; j < 8; j++)
+ {
+ sym2 =
+ xcb_key_symbols_get_keysym(_ecore_xcb_keysyms,
+ modmap[i], j);
+ if (sym2 != 0) break;
+ }
+ if (sym2 == sym)
+ {
+ mask = masks[i / rep->keycodes_per_modifier];
+ break;
+ }
+ }
+ }
+
+ return mask;
+}
+
+static xcb_keysym_t
+_ecore_xcb_keymap_string_to_keysym(const char *str)
+{
+ int i = 0, n = 0, h = 0;
+ unsigned long sig = 0;
+ const char *p = NULL;
+ int c = 0, idx = 0;
+ const unsigned char *entry;
+ unsigned char sig1, sig2;
+ long unsigned int val;
+
+ p = str;
+ while ((c = *p++))
+ sig = (sig << 1) + c;
+
+ i = (sig % KTABLESIZE);
+ h = i + 1;
+ sig1 = (sig >> 8) & 0xff;
+ sig2 = sig & 0xff;
+ n = KMAXHASH;
+
+ while ((idx = hashString[i]))
+ {
+ entry = &_ecore_xcb_keytable[idx];
+ if ((entry[0] == sig1) && (entry[1] == sig2) &&
+ !strcmp(str, (char *)entry + 6))
+ {
+ val = ((entry[2] << 24) | (entry[3] << 16) |
+ (entry[4] << 8) | (entry[5]));
+ if (!val) val = 0xffffff;
+ return val;
+ }
+ if (!--n) break;
+ i += h;
+ if (i >= KTABLESIZE) i -= KTABLESIZE;
+ }
+
+ if (*str == 'U')
+ {
+ val = 0;
+ for (p = &str[1]; *p; p++)
+ {
+ c = *p;
+ if (('0' <= c) && (c <= '9'))
+ val = (val << 4) + c - '0';
+ else if (('a' <= c) && (c <= 'f'))
+ val = (val << 4) + c - 'a' + 10;
+ else if (('A' <= c) && (c <= 'F'))
+ val = (val << 4) + c - 'A' + 10;
+ else
+ return XCB_NO_SYMBOL;
+ if (val > 0x10ffff) return XCB_NO_SYMBOL;
+ }
+ if ((val < 0x20) || ((val > 0x7e) && (val < 0xa0)))
+ return XCB_NO_SYMBOL;
+ if (val < 0x100) return val;
+ return val | 0x01000000;
+ }
+
+ if ((strlen(str) > 2) && (str[0] == '0') && (str[1] == 'x'))
+ {
+ char *tmp = NULL;
+
+ val = strtoul(str, &tmp, 16);
+ if ((val == ULONG_MAX) || ((tmp) && (*tmp != '\0')))
+ return XCB_NO_SYMBOL;
+ else
+ return val;
+ }
+
+ if (!strncmp(str, "XF86_", 5))
+ {
+ long unsigned int ret;
+ char *tmp;
+
+ tmp = strdup(str);
+ if (!tmp) return XCB_NO_SYMBOL;
+ memmove(&tmp[4], &tmp[5], strlen(str) - 5 + 1);
+ ret = _ecore_xcb_keymap_string_to_keysym(tmp);
+ free(tmp);
+ return ret;
+ }
+
+ return XCB_NO_SYMBOL;
+}
+
+static int
+_ecore_xcb_keymap_translate_key(xcb_keycode_t keycode,
+ unsigned int modifiers,
+ unsigned int *modifiers_return,
+ xcb_keysym_t *keysym_return)
+{
+ xcb_keysym_t sym;
+
+ if (!_ecore_xcb_keysyms) return 0;
+
+ sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, modifiers);
+
+ if (modifiers_return)
+ *modifiers_return = ((XCB_MOD_MASK_SHIFT | XCB_MOD_MASK_LOCK) |
+ _ecore_xcb_mode_switch | ECORE_X_LOCK_NUM);
+ if (keysym_return)
+ *keysym_return = sym;
+
+ return 1;
+}
+
+static int
+_ecore_xcb_keymap_translate_keysym(xcb_keysym_t keysym,
+ unsigned int modifiers,
+ char *buffer,
+ int bytes)
+{
+ unsigned long hbytes = 0;
+ unsigned char c;
+
+ if (!keysym) return 0;
+ hbytes = (keysym >> 8);
+
+ if (!(bytes &&
+ ((hbytes == 0) ||
+ ((hbytes == 0xFF) &&
+ (((keysym >= XK_BackSpace) && (keysym <= XK_Clear)) ||
+ (keysym == XK_Return) || (keysym == XK_Escape) ||
+ (keysym == XK_KP_Space) || (keysym == XK_KP_Tab) ||
+ (keysym == XK_KP_Enter) ||
+ ((keysym >= XK_KP_Multiply) && (keysym <= XK_KP_9)) ||
+ (keysym == XK_KP_Equal) || (keysym == XK_Delete))))))
+ return 0;
+
+ if (keysym == XK_KP_Space)
+ c = (XK_space & 0x7F);
+ else if (hbytes == 0xFF)
+ c = (keysym & 0x7F);
+ else
+ c = (keysym & 0xFF);
+
+ if (modifiers & ECORE_X_MODIFIER_CTRL)
+ {
+ if (((c >= '@') && (c < '\177')) || c == ' ')
+ c &= 0x1F;
+ else if (c == '2')
+ c = '\000';
+ else if ((c >= '3') && (c <= '7'))
+ c -= ('3' - '\033');
+ else if (c == '8')
+ c = '\177';
+ else if (c == '/')
+ c = '_' & 0x1F;
+ }
+ buffer[0] = c;
+ return 1;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_mwm.c b/src/lib/ecore_x/xcb/ecore_xcb_mwm.c
new file mode 100644
index 0000000000..6c9533136f
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_mwm.c
@@ -0,0 +1,104 @@
+#include "ecore_xcb_private.h"
+//#include "Ecore_X_Atoms.h"
+
+#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)
+
+typedef struct _mwmhints
+{
+ uint32_t flags;
+ uint32_t functions;
+ uint32_t decorations;
+ int32_t inputmode;
+ uint32_t status;
+} MWMHints;
+
+/**
+ * @defgroup Ecore_X_MWM_Group MWM related functions.
+ *
+ * Functions related to MWM.
+ */
+
+/**
+ * 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_borderless_set(Ecore_X_Window win,
+ Eina_Bool borderless)
+{
+ uint32_t data[5] = { 0, 0, 0, 0, 0 };
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ data[0] = 2;
+ data[2] = !borderless;
+
+ ecore_x_window_prop_property_set(win,
+ 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)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+ MWMHints *mwmhints = NULL;
+ int ret = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ cookie =
+ xcb_get_property_unchecked(_ecore_xcb_conn, 0, win,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ ECORE_X_ATOM_MOTIF_WM_HINTS, 0, UINT_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 (dhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_DECORATIONS)
+ *dhint = mwmhints->decorations;
+ else
+ *dhint = ECORE_X_MWM_HINT_DECOR_ALL;
+ }
+ if (fhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_FUNCTIONS)
+ *fhint = mwmhints->functions;
+ else
+ *fhint = ECORE_X_MWM_HINT_FUNC_ALL;
+ }
+ if (ihint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_INPUT_MODE)
+ *ihint = mwmhints->inputmode;
+ else
+ *ihint = ECORE_X_MWM_HINT_INPUT_MODELESS;
+ }
+ ret = EINA_TRUE;
+ }
+ free(reply);
+ return ret;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_netwm.c b/src/lib/ecore_x/xcb/ecore_xcb_netwm.c
new file mode 100644
index 0000000000..ae801d3407
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_netwm.c
@@ -0,0 +1,1604 @@
+#include "ecore_xcb_private.h"
+
+/* 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);
+
+/* local variables */
+//static Eina_Hash *_startup_info = NULL;
+
+/* 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;
+
+ /* sequence info fields */
+ char *id, *name;
+ int screen;
+ char *bin, *icon;
+ int desktop, timestamp;
+ char *description, *wmclass;
+ int silent;
+};
+
+EAPI void
+ecore_x_netwm_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+// _startup_info =
+// eina_hash_string_superfast_new(_ecore_xcb_netwm_startup_info_free);
+}
+
+EAPI void
+ecore_x_netwm_shutdown(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+// if (_startup_info) eina_hash_free(_startup_info);
+// _startup_info = NULL;
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_pid_get(Ecore_X_Window win,
+ int *pid)
+{
+ uint32_t tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID, &tmp, 1))
+ return EINA_FALSE;
+
+ if (pid) *pid = tmp;
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_pid_set(Ecore_X_Window win,
+ int pid)
+{
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ tmp = pid;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_PID, &tmp, 1);
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (type) *type = ECORE_X_WINDOW_TYPE_NORMAL;
+
+ 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]);
+
+ if (atoms) free(atoms);
+
+ 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;
+ }
+
+ atoms2 = malloc(num * sizeof(Ecore_X_Window_Type));
+ if (!atoms2)
+ {
+ if (atoms) free(atoms);
+ return 0;
+ }
+
+ for (i = 0; i < num; i++)
+ atoms2[i] = _ecore_xcb_netwm_window_type_type_get(atoms[i]);
+ if (atoms) free(atoms);
+
+ if (types)
+ *types = atoms2;
+ else
+ free(atoms2);
+
+ return num;
+}
+
+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;
+}
+
+EAPI void
+ecore_x_netwm_name_set(Ecore_X_Window win,
+ const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_NAME, name);
+}
+
+EAPI void
+ecore_x_netwm_opacity_set(Ecore_X_Window win,
+ unsigned int opacity)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &opacity, 1);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_opacity_get(Ecore_X_Window win,
+ unsigned int *opacity)
+{
+ unsigned int tmp = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &tmp, 1))
+ return EINA_FALSE;
+
+ if (opacity) *opacity = tmp;
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_wm_identify(Ecore_X_Window root,
+ Ecore_X_Window check,
+ const char *wm_name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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);
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK,
+ &check, 1);
+}
+
+EAPI void
+ecore_x_netwm_supported_set(Ecore_X_Window root,
+ Ecore_X_Atom *supported,
+ int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_atom_set(root, ECORE_X_ATOM_NET_SUPPORTED,
+ supported, num);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_supported_get(Ecore_X_Window root,
+ Ecore_X_Atom **supported,
+ int *num)
+{
+ int num_ret = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (num) *num = 0;
+ if (supported) *supported = NULL;
+
+ 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;
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_desk_count_set(Ecore_X_Window root,
+ unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
+ &n_desks, 1);
+}
+
+EAPI void
+ecore_x_netwm_desk_roots_set(Ecore_X_Window root,
+ Ecore_X_Window *vroots,
+ unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_VIRTUAL_ROOTS,
+ vroots, n_desks);
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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;
+ }
+
+ l = strlen(s) + 1;
+ t = realloc(buf, len + 1);
+ if (t)
+ {
+ buf = t;
+ memcpy(buf + len, s, l);
+ }
+ len += l;
+ }
+
+ 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);
+// ecore_x_flush();
+ free(buf);
+}
+
+EAPI void
+ecore_x_netwm_desk_size_set(Ecore_X_Window root,
+ unsigned int width,
+ unsigned int height)
+{
+ uint32_t size[2];
+
+ 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
+ origins, (2 * n_desks));
+}
+
+EAPI void
+ecore_x_netwm_desk_layout_set(Ecore_X_Window root,
+ int orientation,
+ int columns,
+ int rows,
+ int starting_corner)
+{
+ unsigned int 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);
+}
+
+EAPI void
+ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
+ unsigned int *areas,
+ unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_WORKAREA, areas,
+ 4 * n_desks);
+}
+
+EAPI unsigned int *
+ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, unsigned int *n_desks)
+{
+ int ret;
+ unsigned int *areas = NULL;
+
+ if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ ret = ecore_x_window_prop_card32_list_get(root, ECORE_X_ATOM_NET_WORKAREA,
+ &areas);
+ if (!areas)
+ {
+ if (n_desks) *n_desks = 0;
+ return 0;
+ }
+ if (n_desks) *n_desks = ret / 4;
+ return areas;
+}
+
+EAPI void
+ecore_x_netwm_desk_current_set(Ecore_X_Window root,
+ unsigned int desk)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_CURRENT_DESKTOP,
+ &desk, 1);
+}
+
+EAPI void
+ecore_x_netwm_showing_desktop_set(Ecore_X_Window root,
+ Eina_Bool on)
+{
+ unsigned int val = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ val = ((on) ? 1 : 0);
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP,
+ &val, 1);
+}
+
+EAPI int
+ecore_x_netwm_startup_id_get(Ecore_X_Window win,
+ char **id)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (id)
+ {
+ *id =
+ ecore_x_window_prop_string_get(win, ECORE_X_ATOM_NET_STARTUP_ID);
+ }
+
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_startup_id_set(Ecore_X_Window win,
+ const char *id)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id);
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_netwm_window_state_set(Ecore_X_Window win,
+ Ecore_X_Window_State *state,
+ unsigned int num)
+{
+ Ecore_X_Atom *set;
+ unsigned int i = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!num)
+ {
+ 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_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);
+}
+
+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 ret = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (num) *num = 0;
+ if (state) *state = NULL;
+
+ ret =
+ ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_STATE, &atoms);
+
+ if (ret <= 0) return EINA_FALSE;
+
+ if (state)
+ {
+ *state = malloc(ret * sizeof(Ecore_X_Window_State));
+ if (*state)
+ {
+ int i = 0;
+
+ for (i = 0; i < ret; i++)
+ (*state)[i] = _ecore_xcb_netwm_window_state_get(atoms[i]);
+ if (num) *num = ret;
+ }
+ }
+
+ free(atoms);
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_client_active_set(Ecore_X_Window root,
+ Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_window_set(root,
+ ECORE_X_ATOM_NET_ACTIVE_WINDOW, &win, 1);
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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_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;
+
+ xcb_send_event(_ecore_xcb_conn, 0, root,
+ (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev);
+// ecore_x_flush();
+}
+
+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__);
+
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST,
+ p_clients, n_clients);
+}
+
+EAPI void
+ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root,
+ Ecore_X_Window *p_clients,
+ unsigned int n_clients)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST_STACKING,
+ p_clients, n_clients);
+}
+
+EAPI Eina_Bool
+ecore_x_screen_is_composited(int screen)
+{
+ 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__);
+ CHECK_XCB_CONN;
+
+ snprintf(buff, sizeof(buff), "_NET_WM_CM_S%i", screen);
+
+ if (atom == XCB_NONE)
+ {
+ 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;
+
+ 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);
+
+ return (win != XCB_NONE) ? EINA_TRUE : EINA_FALSE;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ snprintf(buff, sizeof(buff), "_NET_WM_CM_S%i", screen);
+ if (atom == XCB_NONE)
+ {
+ 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());
+}
+
+EAPI void
+ecore_x_netwm_ping_send(Ecore_X_Window win)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) return;
+
+ 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);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_netwm_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;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_FRAME_EXTENTS,
+ frames, 4);
+}
+
+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];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_FRAME_EXTENTS,
+ frames, 4);
+ if (ret != 4) return EINA_FALSE;
+
+ if (fl) *fl = frames[0];
+ if (fr) *fr = frames[1];
+ if (ft) *ft = frames[2];
+ if (fb) *fb = frames[3];
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_sync_request_send(Ecore_X_Window win,
+ unsigned int serial)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) return;
+
+ /* FIXME: Maybe need XSyncIntToValue ?? */
+ 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);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_netwm_desktop_set(Ecore_X_Window win,
+ unsigned int desk)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_desktop_get(Ecore_X_Window win,
+ unsigned int *desk)
+{
+ unsigned int tmp = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP,
+ &tmp, 1))
+ return EINA_FALSE;
+
+ 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)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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_NET_WM_DESKTOP;
+ ev.data.data32[0] = desktop;
+
+ xcb_send_event(_ecore_xcb_conn, 0, root,
+ (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_netwm_moveresize_request_send(Ecore_X_Window win,
+ int x,
+ int y,
+ Ecore_X_Netwm_Direction direction,
+ unsigned int button)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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_NET_WM_MOVERESIZE;
+ ev.data.data32[0] = x;
+ ev.data.data32[1] = y;
+ ev.data.data32[2] = direction;
+ ev.data.data32[3] = button;
+ ev.data.data32[4] = 1;
+
+ xcb_send_event(_ecore_xcb_conn, 0, win,
+ (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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_handled_icons_get(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0))
+ return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+EAPI int
+ecore_x_netwm_icon_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_ICON_NAME);
+ }
+
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_icon_name_set(Ecore_X_Window win,
+ const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME, name);
+}
+
+EAPI void
+ecore_x_netwm_icons_set(Ecore_X_Window win,
+ Ecore_X_Icon *icon,
+ int num)
+{
+ unsigned int *data, *p, *p2;
+ unsigned int i, size, x, y;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ size = 0;
+ for (i = 0; i < (unsigned int)num; i++)
+ {
+ size += 2 + (icon[i].width * icon[i].height);
+ }
+ data = malloc(size * sizeof(unsigned int));
+ if (!data) return;
+ p = data;
+ for (i = 0; i < (unsigned int)num; i++)
+ {
+ p[0] = icon[i].width;
+ p[1] = icon[i].height;
+ p += 2;
+ p2 = icon[i].data;
+ for (y = 0; y < icon[i].height; y++)
+ {
+ for (x = 0; x < icon[i].width; x++)
+ {
+ unsigned int r, g, b, a;
+
+ a = (*p2 >> 24) & 0xff;
+ r = (*p2 >> 16) & 0xff;
+ g = (*p2 >> 8 ) & 0xff;
+ b = (*p2 ) & 0xff;
+ if ((a > 0) && (a < 255))
+ {
+ r = (r * 255) / a;
+ g = (g * 255) / a;
+ b = (b * 255) / a;
+ }
+ *p = (a << 24) | (r << 16) | (g << 8) | b;
+ p++;
+ p2++;
+ }
+ }
+ }
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON,
+ data, size);
+ free(data);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_icons_get(Ecore_X_Window win,
+ Ecore_X_Icon **icon,
+ int *num)
+{
+ int num_ret = 0;
+ unsigned int i = 0, len = 0, icons = 0;
+ unsigned int *data, *p, *src;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (num) *num = 0;
+ if (icon) *icon = NULL;
+
+ num_ret =
+ ecore_x_window_prop_card32_list_get(win, ECORE_X_ATOM_NET_WM_ICON, &data);
+
+ if ((num_ret <= 0) || (!data))
+ {
+ if (data) free(data);
+ return EINA_FALSE;
+ }
+ if (num_ret < 2)
+ {
+ if (data) free(data);
+ return EINA_FALSE;
+ }
+
+ 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;
+ }
+
+ *icon = malloc(icons * sizeof(Ecore_X_Icon));
+ if (!(*icon))
+ {
+ if (data) free(data);
+ return EINA_FALSE;
+ }
+
+ /* Fetch the icons */
+ p = data;
+ for (i = 0; i < icons; i++)
+ {
+ unsigned int *ps, *pd, *pe;
+
+ 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;
+ }
+
+ pd = ((*icon)[i]).data;
+ ps = src;
+ pe = ps + len;
+ for (; ps < pe; ps++)
+ {
+ unsigned int 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++;
+ }
+ p += (len + 2);
+ }
+
+ if (data) free(data);
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_icon_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_NET_WM_ICON_GEOMETRY,
+ geom, 4);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_icon_geometry_get(Ecore_X_Window win,
+ int *x,
+ int *y,
+ int *w,
+ int *h)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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];
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_strut_set(Ecore_X_Window win,
+ int l,
+ int r,
+ int t,
+ int b)
+{
+ unsigned int strut[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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);
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ret =
+ ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
+ if (ret != 4) return EINA_FALSE;
+
+ if (l) *l = strut[0];
+ if (r) *r = strut[1];
+ if (t) *t = strut[2];
+ if (b) *b = strut[3];
+
+ return EINA_TRUE;
+}
+
+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];
+
+ 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(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
+ strut, 12);
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ret =
+ ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
+ strut, 12);
+ if (ret != 12) return EINA_FALSE;
+
+ 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];
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_user_time_set(Ecore_X_Window win,
+ unsigned int t)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME, &t, 1);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_user_time_get(Ecore_X_Window win,
+ unsigned int *t)
+{
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME,
+ &tmp, 1))
+ return EINA_FALSE;
+
+ if (t) *t = tmp;
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_visible_name_set(Ecore_X_Window win,
+ const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
+ name);
+}
+
+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;
+}
+
+EAPI void
+ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win,
+ const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
+ name);
+}
+
+EAPI int
+ecore_x_netwm_visible_icon_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_ICON_NAME);
+ }
+
+ return 1;
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_sync_counter_get(Ecore_X_Window win,
+ Ecore_X_Sync_Counter *counter)
+{
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
+ &tmp, 1))
+ return EINA_FALSE;
+
+ if (counter) *counter = tmp;
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_allowed_action_isset(Ecore_X_Window win,
+ Ecore_X_Action action)
+{
+ int num = 0, i = 0;
+ Ecore_X_Atom *atoms, atom;
+ Eina_Bool ret = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ num =
+ ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atoms);
+ if (num <= 0) return EINA_FALSE;
+
+ atom = _ecore_xcb_netwm_action_atom_get(action);
+ for (i = 0; i < num; i++)
+ {
+ if (atoms[i] == atom)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+ }
+
+ if (atoms) free(atoms);
+ return ret;
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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)
+ {
+ 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;
+ }
+ free(atoms);
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_allowed_action_set(Ecore_X_Window win,
+ Ecore_X_Action *action,
+ unsigned int num)
+{
+ Ecore_X_Atom *set;
+ unsigned int i = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!num)
+ {
+ ecore_x_window_prop_property_del(win,
+ ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
+ return;
+ }
+
+ set = malloc(num * sizeof(Ecore_X_Atom));
+ if (!set) return;
+
+ for (i = 0; i < num; i++)
+ set[i] = _ecore_xcb_netwm_action_atom_get(action[i]);
+
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
+ set, num);
+ free(set);
+}
+
+/* local functions */
+int
+_ecore_xcb_netwm_startup_info_begin(Ecore_X_Window win EINA_UNUSED,
+ uint8_t data EINA_UNUSED)
+{
+ // TODO: TBD
+ return 1;
+}
+
+int
+_ecore_xcb_netwm_startup_info(Ecore_X_Window win EINA_UNUSED,
+ uint8_t data EINA_UNUSED)
+{
+ // TODO: TBD
+ return 1;
+}
+
+/* static void */
+/* _ecore_xcb_netwm_startup_info_free(void *data) */
+/* { */
+/* Ecore_Xcb_Startup_Info *info; */
+
+/* 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); */
+/* } */
+
+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;
+ }
+}
+
+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 if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
+ return ECORE_X_WINDOW_TYPE_DROPDOWN_MENU;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU)
+ return ECORE_X_WINDOW_TYPE_POPUP_MENU;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP)
+ return ECORE_X_WINDOW_TYPE_TOOLTIP;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION)
+ return ECORE_X_WINDOW_TYPE_NOTIFICATION;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO)
+ return ECORE_X_WINDOW_TYPE_COMBO;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND)
+ return ECORE_X_WINDOW_TYPE_DND;
+ else
+ return ECORE_X_WINDOW_TYPE_UNKNOWN;
+}
+
+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;
+ }
+}
+
+Ecore_X_Window_State
+_ecore_xcb_netwm_window_state_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_NET_WM_STATE_MODAL)
+ return ECORE_X_WINDOW_STATE_MODAL;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_STICKY)
+ return ECORE_X_WINDOW_STATE_STICKY;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
+ return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
+ return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_SHADED)
+ return ECORE_X_WINDOW_STATE_SHADED;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
+ return ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
+ return ECORE_X_WINDOW_STATE_SKIP_PAGER;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
+ return ECORE_X_WINDOW_STATE_HIDDEN;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
+ return ECORE_X_WINDOW_STATE_FULLSCREEN;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
+ return ECORE_X_WINDOW_STATE_ABOVE;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_BELOW)
+ return ECORE_X_WINDOW_STATE_BELOW;
+ else if (atom == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
+ return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION;
+ else
+ return ECORE_X_WINDOW_STATE_UNKNOWN;
+}
+
+static Ecore_X_Atom
+_ecore_xcb_netwm_action_atom_get(Ecore_X_Action action)
+{
+ switch (action)
+ {
+ case ECORE_X_ACTION_MOVE:
+ return ECORE_X_ATOM_NET_WM_ACTION_MOVE;
+
+ case ECORE_X_ACTION_RESIZE:
+ return ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
+
+ case ECORE_X_ACTION_MINIMIZE:
+ return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
+
+ case ECORE_X_ACTION_SHADE:
+ return ECORE_X_ATOM_NET_WM_ACTION_SHADE;
+
+ case ECORE_X_ACTION_STICK:
+ return ECORE_X_ATOM_NET_WM_ACTION_STICK;
+
+ case ECORE_X_ACTION_MAXIMIZE_HORZ:
+ return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
+
+ case ECORE_X_ACTION_MAXIMIZE_VERT:
+ return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
+
+ case ECORE_X_ACTION_FULLSCREEN:
+ return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
+
+ case ECORE_X_ACTION_CHANGE_DESKTOP:
+ return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
+
+ case ECORE_X_ACTION_CLOSE:
+ return ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
+
+ case ECORE_X_ACTION_ABOVE:
+ return ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
+
+ case ECORE_X_ACTION_BELOW:
+ return ECORE_X_ATOM_NET_WM_ACTION_BELOW;
+
+ default:
+ return 0;
+ }
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c b/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c
new file mode 100644
index 0000000000..f9bf525f7a
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c
@@ -0,0 +1,128 @@
+#include "ecore_xcb_private.h"
+
+/**
+ * @defgroup Ecore_X_Pixmap_Group X Pixmap Functions
+ *
+ * Functions that operate on pixmaps.
+ */
+
+/**
+ * Creates a new pixmap.
+ * @param win Window used to determine which screen of the display the
+ * pixmap should be created on. If 0, the default root window
+ * is used.
+ * @param w Width of the new pixmap.
+ * @param h Height of the new pixmap.
+ * @param dep Depth of the pixmap. If 0, the default depth of the default
+ * screen is used.
+ * @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)
+{
+ Ecore_X_Pixmap pmap;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+
+// ecore_x_flush();
+ return pmap;
+}
+
+/**
+ * Deletes the reference to the given pixmap.
+ *
+ * If no other clients have a reference to the given pixmap, the server
+ * will destroy it.
+ *
+ * @param pmap The given pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI void
+ecore_x_pixmap_free(Ecore_X_Pixmap pmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_free_pixmap(_ecore_xcb_conn, pmap);
+// ecore_x_flush();
+}
+
+/**
+ * Pastes a rectangular area of the given pixmap onto the given drawable.
+ * @param pmap The given pixmap.
+ * @param dest The given drawable.
+ * @param gc The graphics context which governs which operation will
+ * be used to paste the area onto the drawable.
+ * @param sx The X position of the area on the pixmap.
+ * @param sy The Y position of the area on the pixmap.
+ * @param w The width of the area.
+ * @param h The height of the area.
+ * @param dx The X position at which to paste the area on @p dest.
+ * @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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_copy_area(_ecore_xcb_conn, pmap, dest, gc, sx, sy, dx, dy, w, h);
+// ecore_x_flush();
+}
+
+/**
+ * Retrieves the size of the given pixmap.
+ * @param pmap The given pixmap.
+ * @param x Pointer to an integer in which to store the X position.
+ * @param y Pointer to an integer in which to store the Y position.
+ * @param w Pointer to an integer in which to store the width.
+ * @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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (pmap)
+ ecore_x_drawable_geometry_get(pmap, x, y, w, h);
+}
+
+/**
+ * Retrieves the depth of the given pixmap.
+ * @param pmap The given pixmap.
+ * @return The depth of the pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI int
+ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return ecore_x_drawable_depth_get(pmap);
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_private.h b/src/lib/ecore_x/xcb/ecore_xcb_private.h
new file mode 100644
index 0000000000..240210ca0d
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_private.h
@@ -0,0 +1,468 @@
+#ifndef __ECORE_XCB_PRIVATE_H__
+# define __ECORE_XCB_PRIVATE_H__
+
+//# define LOGFNS 1
+
+# ifdef HAVE_CONFIG_H
+# include "config.h"
+# endif
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif !defined alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# elif !defined HAVE_ALLOCA
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+#endif
+
+# include <unistd.h> // included for close & gethostname functions
+
+/* generic xcb includes */
+# include <xcb/xcb.h>
+# include <xcb/bigreq.h>
+# include <xcb/shm.h>
+# include <xcb/xcb_image.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
+
+#define CHECK_XCB_CONN \
+ { \
+ if (xcb_connection_has_error(_ecore_xcb_conn)) \
+ { \
+ DBG("XCB Connection Has Error !!"); \
+ _ecore_xcb_io_error_handle(NULL); \
+ } \
+ }
+
+/* enums */
+typedef enum _Ecore_Xcb_Encoding_Style Ecore_Xcb_Encoding_Style;
+
+enum _Ecore_Xcb_Encoding_Style
+{
+ XcbStringStyle,
+ XcbCompoundTextStyle,
+ XcbTextStyle,
+ XcbStdICCTextStyle,
+ XcbUTF8StringStyle
+};
+
+/* 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;
+
+struct _Ecore_X_DND_Source
+{
+ 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;
+
+ Ecore_X_Time time;
+
+ Ecore_X_Atom action, accepted_action;
+
+ int will_accept, suppress;
+ int await_status;
+};
+
+struct _Ecore_X_DND_Target
+{
+ int version;
+ Ecore_X_Window win, source;
+
+ enum
+ {
+ ECORE_X_DND_TARGET_IDLE,
+ ECORE_X_DND_TARGET_ENTERED
+ } state;
+
+ struct
+ {
+ int x, y;
+ } pos;
+
+ Ecore_X_Time time;
+
+ Ecore_X_Atom action, accepted_action;
+ int will_accept;
+};
+
+struct _Ecore_X_Selection_Intern
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom selection;
+ unsigned char *data;
+ int length;
+ Ecore_X_Time time;
+};
+
+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;
+};
+
+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 int16_t _ecore_xcb_event_last_root_x;
+extern int16_t _ecore_xcb_event_last_root_y;
+
+/* 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_xcb_event_gesture;
+
+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_gesture_init(void);
+void _ecore_xcb_gesture_finalize(void);
+void _ecore_xcb_gesture_shutdown(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);
+# 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,
+ uint8_t data);
+int _ecore_xcb_netwm_startup_info(Ecore_X_Window win,
+ uint8_t data);
+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);
+
+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);
+
+void _ecore_xcb_xdefaults_init(void);
+void _ecore_xcb_xdefaults_shutdown(void);
+char *_ecore_xcb_xdefaults_string_get(const char *prog,
+ const char *param);
+int _ecore_xcb_xdefaults_int_get(const char *prog,
+ const char *param);
+
+void _ecore_xcb_modifiers_get(void);
+
+#endif
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_randr.c b/src/lib/ecore_x/xcb/ecore_xcb_randr.c
new file mode 100644
index 0000000000..a2a4e6271f
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_randr.c
@@ -0,0 +1,3807 @@
+/* TODO: List of missing functions
+ *
+ * ecore_x_randr_crtc_clone_set
+ * ecore_x_randr_output_crtc_set
+ * ecore_x_randr_edid_version_get
+ * ecore_x_randr_edid_info_has_valid_checksum
+ * ecore_x_randr_edid_manufacturer_name_get
+ * ecore_x_randr_edid_display_ascii_get
+ * ecore_x_randr_edid_display_serial_get
+ * ecore_x_randr_edid_model_get
+ * ecore_x_randr_edid_manufacturer_serial_number_get
+ * ecore_x_randr_edid_manufacturer_model_get
+ * ecore_x_randr_edid_dpms_available_get
+ * ecore_x_randr_edid_dpms_standby_available_get
+ * ecore_x_randr_edid_dpms_suspend_available_get
+ * ecore_x_randr_edid_dpms_off_available_get
+ * ecore_x_randr_edid_display_aspect_ratio_preferred_get
+ * ecore_x_randr_edid_display_aspect_ratios_get
+ * ecore_x_randr_edid_display_colorscheme_get
+ * ecore_x_randr_edid_display_type_digital_get
+ * ecore_x_randr_edid_display_interface_type_get
+ * ecore_x_randr_screen_backlight_level_set
+ * ecore_x_randr_output_subpixel_order_get
+ * ecore_x_randr_output_wired_clones_get
+ * ecore_x_randr_output_compatibility_list_get
+ * ecore_x_randr_output_signal_formats_get
+ * ecore_x_randr_output_signal_format_set
+ * ecore_x_randr_output_signal_properties_get
+ * ecore_x_randr_output_connector_number_get
+ * ecore_x_randr_output_connector_type_get
+ * ecore_x_randr_crtc_panning_area_get
+ * ecore_x_randr_crtc_panning_area_set
+ * ecore_x_randr_crtc_tracking_area_get
+ * ecore_x_randr_crtc_tracking_area_set
+ * ecore_x_randr_crtc_border_area_get
+ * ecore_x_randr_crtc_border_area_set
+ */
+
+#include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_RANDR
+# include <xcb/randr.h>
+# endif
+
+#define Ecore_X_Randr_None 0
+#define Ecore_X_Randr_Unset -1
+
+#define RANDR_1_1 ((1 << 16) | 1)
+#define RANDR_1_2 ((1 << 16) | 2)
+#define RANDR_1_3 ((1 << 16) | 3)
+
+#define RANDR_CHECK_1_1_RET(ret) if (_randr_version < RANDR_1_1) return ret
+#define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) return ret
+#define RANDR_CHECK_1_3_RET(ret) if (_randr_version < RANDR_1_3) return ret
+
+#define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3)
+#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12
+#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13
+#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36
+#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3
+#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5
+#define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13
+
+#define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \
+ for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3 * 18)); block += 18)
+
+#define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \
+ _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \
+ if ((block[0] == 0) && (block[1] == 0))
+
+/* 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);
+#ifdef ECORE_XCB_RANDR
+static xcb_randr_get_screen_resources_reply_t *_ecore_xcb_randr_12_get_resources(Ecore_X_Window win);
+static xcb_randr_get_screen_resources_current_reply_t *_ecore_xcb_randr_13_get_resources(Ecore_X_Window win);
+#endif
+static xcb_timestamp_t _ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win);
+static xcb_timestamp_t _ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win);
+
+static Ecore_X_Randr_Mode *_ecore_xcb_randr_12_output_modes_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *num,
+ int *npreferred);
+static Ecore_X_Randr_Mode *_ecore_xcb_randr_13_output_modes_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *num,
+ int *npreferred);
+static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_12_mode_info_get(Ecore_X_Window root,
+ Ecore_X_Randr_Mode mode);
+static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_13_mode_info_get(Ecore_X_Window root,
+ Ecore_X_Randr_Mode mode);
+static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root,
+ int *num);
+static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root,
+ int *num);
+static void _ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root,
+ Ecore_X_Randr_Mode mode,
+ int *w,
+ int *h);
+static void _ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root,
+ Ecore_X_Randr_Mode mode,
+ int *w,
+ int *h);
+static Ecore_X_Randr_Output *_ecore_xcb_randr_12_output_clones_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *num);
+static Ecore_X_Randr_Output *_ecore_xcb_randr_13_output_clones_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *num);
+static Ecore_X_Randr_Crtc *_ecore_xcb_randr_12_output_possible_crtcs_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *num);
+static Ecore_X_Randr_Crtc *_ecore_xcb_randr_13_output_possible_crtcs_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *num);
+static char *_ecore_xcb_randr_12_output_name_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *len);
+static char *_ecore_xcb_randr_13_output_name_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *len);
+static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_12_output_connection_status_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output);
+static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_13_output_connection_status_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output);
+static Ecore_X_Randr_Output *_ecore_xcb_randr_12_outputs_get(Ecore_X_Window root,
+ int *num);
+static Ecore_X_Randr_Output *_ecore_xcb_randr_13_outputs_get(Ecore_X_Window root,
+ int *num);
+static Ecore_X_Randr_Crtc _ecore_xcb_randr_12_output_crtc_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output);
+static Ecore_X_Randr_Crtc _ecore_xcb_randr_13_output_crtc_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output);
+
+/* local variables */
+static Eina_Bool _randr_avail = EINA_FALSE;
+static int _randr_version = -1;
+
+/* external variables */
+int _ecore_xcb_event_randr = -1;
+
+void
+_ecore_xcb_randr_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_RANDR
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_randr_id);
+#endif
+}
+
+void
+_ecore_xcb_randr_finalize(void)
+{
+#ifdef ECORE_XCB_RANDR
+ const xcb_query_extension_reply_t *ext_reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_RANDR
+ ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_randr_id);
+ if ((ext_reply) && (ext_reply->present))
+ {
+ 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;
+
+ _randr_version =
+ ((reply->major_version << 16) | reply->minor_version);
+
+ free(reply);
+ }
+
+ if (_randr_avail)
+ _ecore_xcb_event_randr = ext_reply->first_event;
+ }
+#endif
+}
+
+static Eina_Bool
+#ifdef ECORE_XCB_RANDR
+_ecore_xcb_randr_root_validate(Ecore_X_Window root)
+#else
+_ecore_xcb_randr_root_validate(Ecore_X_Window root EINA_UNUSED)
+#endif
+{
+#ifdef ECORE_XCB_RANDR
+ 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
+
+ return EINA_FALSE;
+}
+
+static int
+_ecore_xcb_randr_root_to_screen(Ecore_X_Window root)
+{
+ int count = 0, num = 0;
+
+ CHECK_XCB_CONN;
+
+ 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 -1;
+}
+
+/* public functions */
+
+/*
+ * @brief Query whether RandR is available or not.
+ *
+ * @return @c EINA_TRUE if extension is available, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_randr_query(void)
+{
+ return _randr_avail;
+}
+
+/*
+ * @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 int
+ecore_x_randr_version_get(void)
+{
+ return _randr_version;
+}
+
+/*
+ * @param root window which's primary output will be queried
+ */
+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__);
+ CHECK_XCB_CONN;
+
+#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->rotations;
+ free(reply);
+ }
+#endif
+
+ return ret;
+}
+
+/*
+ * @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
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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
+
+ return ret;
+}
+
+/*
+ * @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 @c 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
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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
+
+ return ret;
+}
+
+/*
+ * @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;
+ Ecore_X_Randr_Screen_Size_MM *ret = NULL;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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;
+
+ 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;
+ }
+
+ free(reply);
+ }
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
+/*
+ * @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)
+{
+#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__);
+ CHECK_XCB_CONN;
+
+#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, 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 @c EINA_TRUE on success, @c 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__);
+ CHECK_XCB_CONN;
+
+#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;
+}
+
+/*
+ * @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)
+{
+#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
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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
+}
+
+/*
+ * @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_Randr_Refresh_Rate *ret = NULL;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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;
+
+ len = xcb_randr_get_screen_info_rates_length(reply);
+ if (num) *num = len;
+
+ ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * len);
+ if (ret)
+ {
+ xcb_randr_refresh_rates_iterator_t iter;
+ int i = 0;
+
+ iter = xcb_randr_get_screen_info_rates_iterator(reply);
+ while (i++ < size_index)
+ xcb_randr_refresh_rates_next(&iter);
+
+ memcpy(ret, xcb_randr_refresh_rates_rates(iter.data),
+ sizeof(Ecore_X_Randr_Refresh_Rate) * len);
+ }
+ free(reply);
+ }
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
+/*
+ * @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 @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ */
+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_get_screen_info_cookie_t cookie;
+ xcb_randr_get_screen_info_reply_t *reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ if (_randr_version < RANDR_1_1) 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)
+ {
+ 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
+
+ return ret;
+}
+
+/*
+ * @brief Free detailed mode information. The pointer handed in will be set to
+ * @c 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__);
+ CHECK_XCB_CONN;
+
+ RANDR_CHECK_1_2_RET();
+
+ if (!mode_info) return;
+
+ if (mode_info->name) free(mode_info->name);
+ free(mode_info);
+ mode_info = NULL;
+}
+
+/*
+ * @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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_3_RET(Ecore_X_Randr_None);
+
+ 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;
+}
+
+/*
+ * @param root window which's screen should be queried
+ * @param output that should be set as given root window's screen primary output
+ */
+EAPI void
+ecore_x_randr_primary_output_set(Ecore_X_Window root,
+ Ecore_X_Randr_Output output)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_3_RET();
+
+ if ((output) && (_ecore_xcb_randr_root_validate(root)))
+ xcb_randr_set_output_primary(_ecore_xcb_conn, root, output);
+#endif
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (_randr_version >= RANDR_1_3)
+ {
+ modes =
+ _ecore_xcb_randr_13_output_modes_get(root, output, num, npreferred);
+ }
+ else if (_randr_version == RANDR_1_2)
+ {
+ modes =
+ _ecore_xcb_randr_12_output_modes_get(root, output, num, npreferred);
+ }
+#endif
+
+ return modes;
+}
+
+EAPI Eina_Bool
+ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
+ return EINA_FALSE;
+
+ xcb_randr_add_output_mode(_ecore_xcb_conn, output, mode);
+ return EINA_TRUE;
+#endif
+ return EINA_FALSE;
+}
+
+/*
+ * @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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (!_ecore_xcb_randr_root_validate(root)) return NULL;
+
+ if (_randr_version >= RANDR_1_3)
+ ret = _ecore_xcb_randr_13_mode_info_get(root, mode);
+ else if (_randr_version == RANDR_1_2)
+ ret = _ecore_xcb_randr_12_mode_info_get(root, mode);
+#endif
+ return ret;
+}
+
+/*
+ * @brief add a mode to a display
+ * @param root window to which's screen's ressources are added
+ * @param mode_info
+ * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode
+ * adding failed.
+ * @since 1.2.0
+ */
+EAPI Ecore_X_Randr_Mode
+ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info)
+{
+ Ecore_X_Randr_Mode mode = Ecore_X_Randr_None;
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_create_mode_cookie_t cookie;
+ xcb_randr_create_mode_reply_t *reply;
+ xcb_randr_mode_info_t info;
+ int namelen = 0;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if (!mode_info) return Ecore_X_Randr_None;
+ if (!_ecore_xcb_randr_root_validate(root)) return Ecore_X_Randr_None;
+
+ namelen = strlen(mode_info->name);
+
+ memset(&info, 0, sizeof(info));
+ info.width = mode_info->width;
+ info.height = mode_info->height;
+ info.dot_clock = mode_info->dotClock;
+ info.hsync_start = mode_info->hSyncStart;
+ info.hsync_end = mode_info->hSyncEnd;
+ info.htotal = mode_info->hTotal;
+ info.hskew = mode_info->hSkew;
+ info.vsync_start = mode_info->vSyncStart;
+ info.vsync_end = mode_info->vSyncEnd;
+ info.vtotal = mode_info->vTotal;
+ info.mode_flags = mode_info->modeFlags;
+ info.name_len = namelen;
+
+ cookie =
+ xcb_randr_create_mode_unchecked(_ecore_xcb_conn, root, info,
+ namelen, mode_info->name);
+ reply = xcb_randr_create_mode_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply)
+ {
+ mode = mode_info->xid;
+ free(reply);
+ }
+#endif
+ return mode;
+}
+
+/*
+ * @brief get detailed information for all modes related to a root window's screen
+ * @param root window which's screen's ressources are queried
+ * @param num number of modes returned
+ * @return modes' information
+ */
+EAPI Ecore_X_Randr_Mode_Info **
+ecore_x_randr_modes_info_get(Ecore_X_Window root,
+ int *num)
+{
+ Ecore_X_Randr_Mode_Info **ret = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (num) *num = 0;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (!_ecore_xcb_randr_root_validate(root)) return NULL;
+
+ if (_randr_version >= RANDR_1_3)
+ ret = _ecore_xcb_randr_13_modes_info_get(root, num);
+ else if (_randr_version == RANDR_1_2)
+ ret = _ecore_xcb_randr_12_modes_info_get(root, num);
+#endif
+ return ret;
+}
+
+/**
+ * @brief Gets the width and hight of a given mode.
+ *
+ * @param root Window which's screen's ressources are queried.
+ * @param mode The mode which's size is to be looked up.
+ * @param w Width of given mode in px.
+ * @param h Height of given mode in px.
+ */
+EAPI void
+ecore_x_randr_mode_size_get(Ecore_X_Window root,
+ Ecore_X_Randr_Mode mode,
+ int *w,
+ int *h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET();
+
+ if (mode == Ecore_X_Randr_None) return;
+
+ if (_randr_version >= RANDR_1_3)
+ _ecore_xcb_randr_13_mode_size_get(root, mode, w, h);
+ else if (_randr_version == RANDR_1_2)
+ _ecore_xcb_randr_12_mode_size_get(root, mode, w, h);
+#endif
+}
+
+/**
+ * @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 @c NULL, request will fail.
+ * @return EDID information of the output.
+ */
+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
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ 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;
+}
+
+/**
+ * @brief Gets the outputs which might be used simultaneously 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.
+ * @return The existing outputs, @c NULL otherwise.
+ */
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (output == Ecore_X_Randr_None) return NULL;
+
+ if (_randr_version >= RANDR_1_3)
+ outputs = _ecore_xcb_randr_13_output_clones_get(root, output, num);
+ else if (_randr_version == RANDR_1_2)
+ outputs = _ecore_xcb_randr_12_output_clones_get(root, output, num);
+#endif
+ return outputs;
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (output == Ecore_X_Randr_None) return NULL;
+
+ if (_randr_version >= RANDR_1_3)
+ crtcs = _ecore_xcb_randr_13_output_possible_crtcs_get(root, output, num);
+ else if (_randr_version == RANDR_1_2)
+ crtcs = _ecore_xcb_randr_12_output_possible_crtcs_get(root, output, num);
+#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 output The output name given to be reported.
+ * @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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (output == Ecore_X_Randr_None) return NULL;
+
+ if (_randr_version >= RANDR_1_3)
+ return _ecore_xcb_randr_13_output_name_get(root, output, len);
+ else if (_randr_version == RANDR_1_2)
+ return _ecore_xcb_randr_12_output_name_get(root, output, len);
+#endif
+
+ return NULL;
+}
+
+EAPI Ecore_X_Randr_Connection_Status
+ecore_x_randr_output_connection_status_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN);
+
+ if (output == Ecore_X_Randr_None)
+ return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
+
+ if (_randr_version >= RANDR_1_3)
+ return _ecore_xcb_randr_13_output_connection_status_get(root, output);
+ else if (_randr_version == RANDR_1_2)
+ return _ecore_xcb_randr_12_output_connection_status_get(root, output);
+#endif
+
+ return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
+}
+
+EAPI Ecore_X_Randr_Output *
+ecore_x_randr_outputs_get(Ecore_X_Window root,
+ int *num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (_randr_version >= RANDR_1_3)
+ return _ecore_xcb_randr_13_outputs_get(root, num);
+ else if (_randr_version == RANDR_1_2)
+ return _ecore_xcb_randr_12_outputs_get(root, num);
+#endif
+
+ return NULL;
+}
+
+EAPI Ecore_X_Randr_Crtc
+ecore_x_randr_output_crtc_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
+
+ if (output == Ecore_X_Randr_None) return Ecore_X_Randr_None;
+
+ if (_randr_version >= RANDR_1_3)
+ return _ecore_xcb_randr_13_output_crtc_get(root, output);
+ else if (_randr_version == RANDR_1_2)
+ return _ecore_xcb_randr_12_output_crtc_get(root, output);
+#endif
+
+ return Ecore_X_Randr_None;
+}
+
+EAPI void
+ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w_mm, int *h_mm)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_output_info_cookie_t ocookie;
+ xcb_randr_get_output_info_reply_t *oreply;
+ xcb_timestamp_t timestamp = 0;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (w_mm) *w_mm = 0;
+ if (h_mm) *h_mm = 0;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET();
+
+ if ((output != Ecore_X_Randr_None) && (_randr_version >= RANDR_1_3))
+ {
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ timestamp = reply->config_timestamp;
+ free(reply);
+ }
+ else if ((output != Ecore_X_Randr_None) && (_randr_version == RANDR_1_2))
+ {
+ xcb_randr_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ timestamp = reply->config_timestamp;
+ free(reply);
+ }
+
+ ocookie =
+ xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, timestamp);
+ oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL);
+ if (oreply)
+ {
+ if (w_mm) *w_mm = oreply->mm_width;
+ if (h_mm) *h_mm = oreply->mm_height;
+ free(oreply);
+ }
+#endif
+}
+
+/**
+ * @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
+ * coordinate will be assumed.
+ * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y
+ * coordinate 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 @c EINA_TRUE if the configuration alteration was successful,
+ * @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_randr_crtc_settings_set(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ Ecore_X_Randr_Output *outputs,
+ int noutputs,
+ int x,
+ int y,
+ Ecore_X_Randr_Mode mode,
+ Ecore_X_Randr_Orientation orientation)
+{
+ Eina_Bool ret = EINA_FALSE;
+#ifdef ECORE_XCB_RANDR
+ xcb_timestamp_t stamp = 0;
+ xcb_randr_get_crtc_info_cookie_t ccookie;
+ xcb_randr_get_crtc_info_reply_t *creply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
+
+ if (_randr_version >= RANDR_1_3)
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+ else if (_randr_version == RANDR_1_2)
+ stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
+
+ ccookie =
+ xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
+ 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) ||
+ (noutputs == Ecore_X_Randr_None))
+ {
+ outputs = NULL;
+ noutputs = 0;
+ }
+ else if (noutputs == (int)Ecore_X_Randr_Unset)
+ {
+ outputs = xcb_randr_get_crtc_info_outputs(creply);
+ noutputs = 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, stamp,
+ x, y, mode, orientation,
+ noutputs, 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);
+ }
+#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
+ * @c NULL CRTC will be disabled.
+ * @param noutputs Number of outputs in array to be used. Use
+ * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs.
+ * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be
+ * disabled. If set to @c -1 the call will fail.
+ * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE
+ * otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_randr_crtc_mode_set(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ Ecore_X_Randr_Output *outputs,
+ int noutputs,
+ Ecore_X_Randr_Mode mode)
+{
+ Eina_Bool ret = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if ((int)mode == Ecore_X_Randr_Unset) return ret;
+ ret =
+ ecore_x_randr_crtc_settings_set(root, crtc, outputs, noutputs,
+ 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_timestamp_t stamp = 0;
+ xcb_randr_get_crtc_info_cookie_t ocookie;
+ xcb_randr_get_crtc_info_reply_t *oreply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset);
+
+ if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
+
+ if (_randr_version >= RANDR_1_3)
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+ else if (_randr_version == RANDR_1_2)
+ stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
+
+ ocookie =
+ xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
+ oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL);
+ if (oreply)
+ {
+ ret = oreply->mode;
+ free(oreply);
+ }
+#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_timestamp_t stamp = 0;
+ xcb_randr_get_crtc_info_cookie_t ocookie;
+ xcb_randr_get_crtc_info_reply_t *oreply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
+
+ if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
+
+ if (_randr_version >= RANDR_1_3)
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+ else if (_randr_version == RANDR_1_2)
+ stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
+
+ ocookie =
+ xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
+ oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL);
+ if (oreply)
+ {
+ ret = oreply->rotation;
+ free(oreply);
+ }
+#endif
+
+ return ret;
+}
+
+EAPI Eina_Bool
+ecore_x_randr_crtc_orientation_set(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ Ecore_X_Randr_Orientation orientation)
+{
+ Eina_Bool ret = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if (orientation != Ecore_X_Randr_None)
+ {
+ ret =
+ ecore_x_randr_crtc_settings_set(root, crtc, NULL,
+ Ecore_X_Randr_Unset, Ecore_X_Randr_Unset,
+ Ecore_X_Randr_Unset, Ecore_X_Randr_Unset,
+ orientation);
+ }
+#endif
+ return ret;
+}
+
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_crtc_orientations_get(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc)
+{
+ Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
+#ifdef ECORE_XCB_RANDR
+ xcb_timestamp_t stamp = 0;
+ xcb_randr_get_crtc_info_cookie_t ocookie;
+ xcb_randr_get_crtc_info_reply_t *oreply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
+
+ if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
+
+ if (_randr_version >= RANDR_1_3)
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+ else if (_randr_version == RANDR_1_2)
+ stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
+
+ ocookie =
+ xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
+ oreply =
+ xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL);
+ if (oreply)
+ {
+ ret = oreply->rotations;
+ free(oreply);
+ }
+#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_timestamp_t stamp = 0;
+ xcb_randr_get_crtc_info_cookie_t ocookie;
+ xcb_randr_get_crtc_info_reply_t *oreply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
+
+ if (_randr_version >= RANDR_1_3)
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+ else if (_randr_version == RANDR_1_2)
+ stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
+
+ ocookie =
+ xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
+ 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);
+ }
+#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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (_randr_version >= RANDR_1_3)
+ {
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ 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_current_crtcs(reply),
+ sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs);
+ free(reply);
+ }
+ }
+ else if (_randr_version == RANDR_1_2)
+ {
+ xcb_randr_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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;
+}
+
+/*
+ * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead.
+ * @brief Get the CRTCs, which display a certain window.
+ *
+ * @param window Window the displaying CRTCs shall be found for.
+ * @param num The number of CRTCs displaying the window.
+ * @return Array of CRTCs that display a certain window. @c NULL if no CRTCs
+ * was found that displays the specified window.
+ */
+EAPI Ecore_X_Randr_Crtc *
+ecore_x_randr_current_crtc_get(Ecore_X_Window window,
+ int *num)
+{
+ return ecore_x_randr_window_crtcs_get(window, num);
+}
+
+/*
+ * @brief Get the CRTCs, which display a certain window.
+ *
+ * @param window Window the displaying crtcs shall be found for.
+ * @param num The number of crtcs displaying the window.
+ * @return Array of crtcs that display a certain window. @c NULL if no crtcs
+ * was found that displays the specified window.
+ * @since 1.2.0
+ */
+EAPI Ecore_X_Randr_Crtc *
+ecore_x_randr_window_crtcs_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, *ret = NULL;
+ Ecore_X_Randr_Mode mode;
+ int ncrtcs, i, nret = 0;
+ xcb_translate_coordinates_cookie_t cookie;
+ xcb_translate_coordinates_reply_t *trans;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(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) goto _ecore_x_randr_window_crtcs_get_fail;
+
+ /* now get window RELATIVE to root window - thats what matters. */
+ cookie = xcb_translate_coordinates(_ecore_xcb_conn, window, root, 0, 0);
+ trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL);
+ w_geo.x = trans->dst_x;
+ w_geo.y = trans->dst_y;
+ free(trans);
+
+ ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc));
+ if (!ret)
+ {
+ free(crtcs);
+ goto _ecore_x_randr_window_crtcs_get_fail;
+ }
+ for (i = 0, nret = 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))
+ {
+ ret[nret] = crtcs[i];
+ nret++;
+ }
+ }
+ free(crtcs);
+
+ if (num) *num = nret;
+ return ret;
+
+_ecore_x_randr_window_crtcs_get_fail:
+#endif
+ if (num) *num = 0;
+ return NULL;
+}
+
+/*
+ * @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_timestamp_t stamp = 0;
+ xcb_randr_get_crtc_info_cookie_t ocookie;
+ xcb_randr_get_crtc_info_reply_t *oreply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(NULL);
+
+ if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
+
+ if (_randr_version >= RANDR_1_3)
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+ else if (_randr_version == RANDR_1_2)
+ stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
+
+ ocookie =
+ xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
+ 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);
+ }
+#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_timestamp_t stamp = 0;
+ xcb_randr_get_crtc_info_cookie_t ocookie;
+ xcb_randr_get_crtc_info_reply_t *oreply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET();
+
+ if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return;
+
+ if (_randr_version >= RANDR_1_3)
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+ else if (_randr_version == RANDR_1_2)
+ stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
+
+ ocookie =
+ xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
+ 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);
+ }
+#endif
+}
+
+/**
+ * @brief Sets a CRTC relative to another one.
+ *
+ * @param root The window on which CRTC's position will be set.
+ * @param crtc_r1 The CRTC to be positioned.
+ * @param crtc_r2 The CRTC the position should be relative to.
+ * @param policy The relation between the crtcs.
+ * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at
+ * CRTC2's borders.
+ * @return @c EINA_TRUE if crtc could be successfully positioned, @c 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 crtc_r1,
+ Ecore_X_Randr_Crtc crtc_r2,
+ 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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == 0) ||
+ (ecore_x_randr_crtc_mode_get(root, crtc_r2) == 0))
+ return EINA_FALSE;
+
+ if ((!_ecore_xcb_randr_crtc_validate(root, crtc_r1) ||
+ (!(crtc_r1 != crtc_r2) && (!_ecore_xcb_randr_crtc_validate(root, crtc_r2)))))
+ return EINA_FALSE;
+
+ ecore_x_randr_crtc_geometry_get(root, crtc_r1, &r1.x, &r1.y, &r1.w, &r1.h);
+ ecore_x_randr_crtc_geometry_get(root, crtc_r2, &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, crtc_r1, r2.x, r2.y);
+ break;
+
+ case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
+ break;
+ default:
+ return EINA_FALSE;
+ }
+
+ 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, crtc_r1, 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__);
+ CHECK_XCB_CONN;
+
+#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;
+}
+
+EAPI void
+ecore_x_randr_crtc_pos_get(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ int *x,
+ int *y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET();
+
+ ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL);
+#endif
+}
+
+/*
+ * @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 @c 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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ 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;
+}
+
+EAPI void
+ecore_x_randr_crtc_size_get(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ int *w,
+ int *h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET();
+ ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h);
+#endif
+}
+
+EAPI Ecore_X_Randr_Refresh_Rate
+ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ Ecore_X_Randr_Mode mode)
+{
+ Ecore_X_Randr_Refresh_Rate ret = 0.0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(0.0);
+
+ if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return 0.0;
+
+ if (_randr_version >= RANDR_1_3)
+ {
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ if (reply)
+ {
+ xcb_randr_mode_info_iterator_t miter;
+
+ miter =
+ xcb_randr_get_screen_resources_current_modes_iterator(reply);
+ while (miter.rem)
+ {
+ xcb_randr_mode_info_t *minfo;
+
+ minfo = miter.data;
+ if (minfo->id == mode)
+ {
+ if ((minfo->htotal) && (minfo->vtotal))
+ {
+ ret = ((double)minfo->dot_clock /
+ ((double)minfo->htotal *
+ (double)minfo->vtotal));
+ }
+ break;
+ }
+ xcb_randr_mode_info_next(&miter);
+ }
+ free(reply);
+ }
+ }
+ else if (_randr_version == RANDR_1_2)
+ {
+ xcb_randr_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ if (reply)
+ {
+ xcb_randr_mode_info_iterator_t miter;
+
+ miter = xcb_randr_get_screen_resources_modes_iterator(reply);
+ while (miter.rem)
+ {
+ xcb_randr_mode_info_t *minfo;
+
+ minfo = miter.data;
+ if (minfo->id == mode)
+ {
+ if ((minfo->htotal) && (minfo->vtotal))
+ {
+ ret = ((double)minfo->dot_clock /
+ ((double)minfo->htotal *
+ (double)minfo->vtotal));
+ }
+ break;
+ }
+ xcb_randr_mode_info_next(&miter);
+ }
+ free(reply);
+ }
+ }
+#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 @c 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_timestamp_t stamp = 0;
+ 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;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if (!_ecore_xcb_randr_root_validate(root)) return EINA_FALSE;
+
+ if (_randr_version >= RANDR_1_3)
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+ else if (_randr_version == RANDR_1_2)
+ stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
+
+ 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],
+ stamp);
+ 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))
+ {
+ continue;
+ }
+ nw = MAX((int)(oreply[i]->x + oreply[i]->width + dx), nw);
+ nh = MAX((int)(oreply[i]->y + oreply[i]->height + dy), nh);
+ }
+ }
+
+ 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__);
+ CHECK_XCB_CONN;
+
+#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_timestamp_t stamp = 0;
+ 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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ if (!_ecore_xcb_randr_root_validate(root)) return;
+ crtcs = ecore_x_randr_crtcs_get(root, &total);
+
+ if (_randr_version >= RANDR_1_3)
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+ else if (_randr_version == RANDR_1_2)
+ stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
+
+ /* I hate declaring variables inside code like this, but we need the
+ * value of 'total' before we can */
+ Ecore_X_Randr_Crtc enabled[total];
+
+ 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], stamp);
+ 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(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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET();
+
+ 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
+ Ecore_X_Randr_Screen scr = 0;
+ xcb_screen_t *s;
+# define RANDR_VALIDATE_ROOT(screen, root) \
+ ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1)
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET();
+
+ if (!RANDR_VALIDATE_ROOT(scr, root)) return;
+
+ s = ecore_x_screen_get(scr);
+ if (w) *w = s->width_in_pixels;
+ if (h) *h = s->height_in_pixels;
+ if (w_mm) *w_mm = s->width_in_millimeters;
+ if (h_mm) *h_mm = s->height_in_millimeters;
+#endif
+}
+
+/*
+ * @param root Window which's screen's size should be set. If invalid (e.g.
+ * @c 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 @c 0, current
+ * aspect is assumed.
+ * @param h_mm Height in mm the screen should be set to. If @c 0, current
+ * aspect is assumed.
+ * @return @c EINA_TRUE if request was successfully sent or screen is already
+ * in requested size, @c 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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ 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;
+
+ /* NB: Hmmmm, xlib version divides w_mm by width ... that seems wrong */
+ 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;
+}
+
+/*
+ * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead.
+ * @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. @c NULL if no
+ * outputs was found that displays the specified window.
+ */
+
+Ecore_X_Randr_Output *
+ecore_x_randr_current_output_get(Ecore_X_Window window,
+ int *num)
+{
+ return ecore_x_randr_window_outputs_get(window, num);
+}
+
+/*
+ * @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. @c 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;
+ Ecore_X_Randr_Crtc *crtcs;
+ Ecore_X_Randr_Output *outputs, *ret = NULL, *tret;
+ int ncrtcs, noutputs, i, nret = 0;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (num) *num = 0;
+
+#ifdef ECORE_XCB_RANDR
+ if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail;
+
+ root = ecore_x_window_root_get(window);
+ if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs)))
+ goto _ecore_x_randr_current_output_get_fail;
+
+ for (i = 0, nret = 0; i < ncrtcs; i++)
+ {
+
+ outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i],
+ &noutputs);
+ if (!outputs)
+ goto _ecore_x_randr_current_output_get_fail_free;
+ tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output)));
+ if (!tret) goto _ecore_x_randr_current_output_get_fail_free;
+ ret = tret;
+ memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output)));
+ nret += noutputs;
+ free(outputs);
+ outputs = NULL;
+ }
+ free(crtcs);
+
+ if (num)
+ *num = nret;
+
+ return ret;
+
+_ecore_x_randr_current_output_get_fail_free:
+ free(outputs);
+ free(crtcs);
+ free(ret);
+_ecore_x_randr_current_output_get_fail:
+#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;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(-1);
+
+ 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 @c 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;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ 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;
+}
+
+/*
+ * @brief Check if a backlight is available.
+ *
+ * @return Whether a backlight is available.
+ */
+EAPI Eina_Bool
+ecore_x_randr_output_backlight_available(void)
+{
+#ifdef ECORE_XCB_RANDR
+ Ecore_X_Atom _backlight;
+ xcb_intern_atom_cookie_t acookie;
+ xcb_intern_atom_reply_t *areply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(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)
+ {
+ ERR("Backlight property is not suppported on this server or driver");
+ return EINA_FALSE;
+ }
+ else
+ {
+ _backlight = areply->atom;
+ free(areply);
+ return EINA_TRUE;
+ }
+#endif
+ return EINA_FALSE;
+}
+
+EAPI int
+ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length)
+{
+ if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) &&
+ (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
+ return (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) |
+ edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR];
+ return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+}
+
+EAPI char *
+ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length)
+{
+ unsigned char *block = NULL;
+ int version = 0;
+
+ version = ecore_x_randr_edid_version_get(edid, edid_length);
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL;
+
+ _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+ {
+ if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfc)
+ {
+ char *name, *p;
+ const char *edid_name;
+
+ edid_name = (const char *)block +
+ _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT;
+ name =
+ malloc(sizeof(char) *
+ _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
+ if (!name) return NULL;
+
+ strncpy(name, edid_name,
+ (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
+ name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0;
+ for (p = name; *p; p++)
+ if ((*p < ' ') || (*p > '~')) *p = 0;
+
+ return name;
+ }
+ }
+ return NULL;
+}
+
+EAPI Eina_Bool
+ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length)
+{
+ const unsigned char header[] =
+ {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
+ };
+
+ if ((!edid) || (edid_length < 8)) return EINA_FALSE;
+ if (!memcmp(edid, header, 8)) return EINA_TRUE;
+ 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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if ((output) && (_ecore_xcb_randr_root_validate(root)))
+ {
+ if (_randr_version >= RANDR_1_3)
+ {
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ if (reply)
+ {
+ int len = 0, i = 0;
+ xcb_randr_output_t *outputs;
+
+ len =
+ xcb_randr_get_screen_resources_current_outputs_length(reply);
+ outputs =
+ xcb_randr_get_screen_resources_current_outputs(reply);
+ for (i = 0; i < len; i++)
+ {
+ if (outputs[i] == output)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+ }
+ free(reply);
+ }
+ }
+ else if (_randr_version == RANDR_1_2)
+ {
+ xcb_randr_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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 @c EINA_TRUE will be returned, else
+ * @c 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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if (((int)crtc == Ecore_X_Randr_None) || ((int)crtc == Ecore_X_Randr_Unset))
+ return ret;
+
+ if ((crtc) && (_ecore_xcb_randr_root_validate(root)))
+ {
+ if (_randr_version >= RANDR_1_3)
+ {
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ if (reply)
+ {
+ int i = 0;
+ xcb_randr_crtc_t *crtcs;
+
+ crtcs = xcb_randr_get_screen_resources_current_crtcs(reply);
+ for (i = 0; i < reply->num_crtcs; i++)
+ {
+ if (crtcs[i] == crtc)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+ }
+ free(reply);
+ }
+ }
+ else if (_randr_version == RANDR_1_2)
+ {
+ xcb_randr_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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;
+}
+
+static Ecore_X_Randr_Mode *
+_ecore_xcb_randr_12_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_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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_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);
+ }
+#endif
+ return modes;
+}
+
+static Ecore_X_Randr_Mode *
+_ecore_xcb_randr_13_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_timestamp_t stamp = 0;
+ xcb_randr_get_output_info_cookie_t ocookie;
+ xcb_randr_get_output_info_reply_t *oreply;
+
+ stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
+
+ ocookie =
+ xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, stamp);
+ oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL);
+ if (oreply)
+ {
+ 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);
+ }
+#endif
+ return modes;
+}
+
+static Ecore_X_Randr_Mode_Info *
+_ecore_xcb_randr_12_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_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ if (reply)
+ {
+ if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
+ {
+ 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;
+}
+
+static Ecore_X_Randr_Mode_Info *
+_ecore_xcb_randr_13_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_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ if (reply)
+ {
+ if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
+ {
+ uint8_t *nbuf;
+ xcb_randr_mode_info_iterator_t miter;
+
+ nbuf = xcb_randr_get_screen_resources_current_names(reply);
+ miter =
+ xcb_randr_get_screen_resources_current_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;
+}
+
+static Ecore_X_Randr_Mode_Info **
+_ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root,
+ int *num)
+{
+ Ecore_X_Randr_Mode_Info **ret = NULL;
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ if (reply)
+ {
+ if (num) *num = reply->num_modes;
+ ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes);
+ if (ret)
+ {
+ xcb_randr_mode_info_iterator_t miter;
+ int i = 0;
+ uint8_t *nbuf;
+
+ 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 ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
+ {
+ ret[i]->xid = minfo->id;
+ ret[i]->width = minfo->width;
+ ret[i]->height = minfo->height;
+ ret[i]->dotClock = minfo->dot_clock;
+ ret[i]->hSyncStart = minfo->hsync_start;
+ ret[i]->hSyncEnd = minfo->hsync_end;
+ ret[i]->hTotal = minfo->htotal;
+ ret[i]->vSyncStart = minfo->vsync_start;
+ ret[i]->vSyncEnd = minfo->vsync_end;
+ ret[i]->vTotal = minfo->vtotal;
+ ret[i]->modeFlags = minfo->mode_flags;
+
+ ret[i]->name = NULL;
+ ret[i]->nameLength = minfo->name_len;
+ if (ret[i]->nameLength > 0)
+ {
+ ret[i]->name = malloc(ret[i]->nameLength + 1);
+ if (ret[i]->name)
+ memcpy(ret[i]->name, nbuf,
+ ret[i]->nameLength + 1);
+ }
+ }
+ else
+ {
+ while (i > 0)
+ free(ret[--i]);
+ free(ret);
+ ret = NULL;
+ break;
+ }
+ i++;
+ xcb_randr_mode_info_next(&miter);
+ }
+ }
+ free(reply);
+ }
+#endif
+ return ret;
+}
+
+static Ecore_X_Randr_Mode_Info **
+_ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root,
+ int *num)
+{
+ Ecore_X_Randr_Mode_Info **ret = NULL;
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ if (reply)
+ {
+ if (num) *num = reply->num_modes;
+ ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes);
+ if (ret)
+ {
+ xcb_randr_mode_info_iterator_t miter;
+ int i = 0;
+ uint8_t *nbuf;
+
+ nbuf = xcb_randr_get_screen_resources_current_names(reply);
+ miter =
+ xcb_randr_get_screen_resources_current_modes_iterator(reply);
+ while (miter.rem)
+ {
+ xcb_randr_mode_info_t *minfo;
+
+ minfo = miter.data;
+ nbuf += minfo->name_len;
+ if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
+ {
+ ret[i]->xid = minfo->id;
+ ret[i]->width = minfo->width;
+ ret[i]->height = minfo->height;
+ ret[i]->dotClock = minfo->dot_clock;
+ ret[i]->hSyncStart = minfo->hsync_start;
+ ret[i]->hSyncEnd = minfo->hsync_end;
+ ret[i]->hTotal = minfo->htotal;
+ ret[i]->vSyncStart = minfo->vsync_start;
+ ret[i]->vSyncEnd = minfo->vsync_end;
+ ret[i]->vTotal = minfo->vtotal;
+ ret[i]->modeFlags = minfo->mode_flags;
+
+ ret[i]->name = NULL;
+ ret[i]->nameLength = minfo->name_len;
+ if (ret[i]->nameLength > 0)
+ {
+ ret[i]->name = malloc(ret[i]->nameLength + 1);
+ if (ret[i]->name)
+ memcpy(ret[i]->name, nbuf,
+ ret[i]->nameLength + 1);
+ }
+ }
+ else
+ {
+ while (i > 0)
+ free(ret[--i]);
+ free(ret);
+ ret = NULL;
+ break;
+ }
+ i++;
+ xcb_randr_mode_info_next(&miter);
+ }
+ }
+ free(reply);
+ }
+#endif
+ return ret;
+}
+
+static void
+_ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root,
+ Ecore_X_Randr_Mode mode,
+ int *w,
+ int *h)
+{
+ if (w) *w = 0;
+ if (h) *h = 0;
+
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ if (reply)
+ {
+ xcb_randr_mode_info_iterator_t miter;
+
+ miter = xcb_randr_get_screen_resources_modes_iterator(reply);
+ while (miter.rem)
+ {
+ xcb_randr_mode_info_t *minfo;
+
+ minfo = miter.data;
+ if (minfo->id == mode)
+ {
+ if (w) *w = minfo->width;
+ if (h) *h = minfo->height;
+ break;
+ }
+ xcb_randr_mode_info_next(&miter);
+ }
+ free(reply);
+ }
+#endif
+}
+
+static void
+_ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root,
+ Ecore_X_Randr_Mode mode,
+ int *w,
+ int *h)
+{
+ if (w) *w = 0;
+ if (h) *h = 0;
+
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ if (reply)
+ {
+ xcb_randr_mode_info_iterator_t miter;
+
+ miter = xcb_randr_get_screen_resources_current_modes_iterator(reply);
+ while (miter.rem)
+ {
+ xcb_randr_mode_info_t *minfo;
+
+ minfo = miter.data;
+ if (minfo->id == mode)
+ {
+ if (w) *w = minfo->width;
+ if (h) *h = minfo->height;
+ break;
+ }
+ xcb_randr_mode_info_next(&miter);
+ }
+ free(reply);
+ }
+#endif
+}
+
+static Ecore_X_Randr_Output *
+_ecore_xcb_randr_12_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_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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_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);
+ }
+#endif
+ return outputs;
+}
+
+static Ecore_X_Randr_Output *
+_ecore_xcb_randr_13_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_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ 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_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);
+ }
+#endif
+ return outputs;
+}
+
+static Ecore_X_Randr_Crtc *
+_ecore_xcb_randr_12_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_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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;
+}
+
+static Ecore_X_Randr_Crtc *
+_ecore_xcb_randr_13_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_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ 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;
+}
+
+static char *
+_ecore_xcb_randr_12_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_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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;
+}
+
+static char *
+_ecore_xcb_randr_13_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_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ 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;
+}
+
+static Ecore_X_Randr_Connection_Status
+_ecore_xcb_randr_12_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_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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;
+}
+
+static Ecore_X_Randr_Connection_Status
+_ecore_xcb_randr_13_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_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ 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;
+}
+
+static Ecore_X_Randr_Output *
+_ecore_xcb_randr_12_outputs_get(Ecore_X_Window root,
+ int *num)
+{
+ Ecore_X_Randr_Output *ret = NULL;
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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;
+}
+
+static Ecore_X_Randr_Output *
+_ecore_xcb_randr_13_outputs_get(Ecore_X_Window root,
+ int *num)
+{
+ Ecore_X_Randr_Output *ret = NULL;
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ 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_current_outputs(reply),
+ sizeof(Ecore_X_Randr_Output) * reply->num_outputs);
+ free(reply);
+ }
+#endif
+ return ret;
+}
+
+static Ecore_X_Randr_Crtc
+_ecore_xcb_randr_12_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_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(root);
+ 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;
+}
+
+static Ecore_X_Randr_Crtc
+_ecore_xcb_randr_13_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_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(root);
+ 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;
+}
+
+static xcb_randr_get_screen_resources_reply_t *
+_ecore_xcb_randr_12_get_resources(Ecore_X_Window win)
+{
+ 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, win);
+ reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL);
+ return reply;
+}
+
+static xcb_randr_get_screen_resources_current_reply_t *
+_ecore_xcb_randr_13_get_resources(Ecore_X_Window win)
+{
+ xcb_randr_get_screen_resources_current_cookie_t cookie;
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ cookie =
+ xcb_randr_get_screen_resources_current_unchecked(_ecore_xcb_conn, win);
+ reply =
+ xcb_randr_get_screen_resources_current_reply(_ecore_xcb_conn,
+ cookie, NULL);
+ return reply;
+}
+
+static xcb_timestamp_t
+_ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win)
+{
+ xcb_timestamp_t stamp = 0;
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_resources_reply_t *reply;
+
+ reply = _ecore_xcb_randr_12_get_resources(win);
+ stamp = reply->config_timestamp;
+ free(reply);
+#endif
+ return stamp;
+}
+
+static xcb_timestamp_t
+_ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win)
+{
+ xcb_timestamp_t stamp = 0;
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_resources_current_reply_t *reply;
+
+ reply = _ecore_xcb_randr_13_get_resources(win);
+ stamp = reply->config_timestamp;
+ free(reply);
+#endif
+ return stamp;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_region.c b/src/lib/ecore_x/xcb/ecore_xcb_region.c
new file mode 100644
index 0000000000..a221d8fc37
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_region.c
@@ -0,0 +1,159 @@
+#include "ecore_xcb_private.h"
+#include <pixman.h>
+
+/*
+ * [ ] XPolygonRegion
+ * [ ] XShrinkRegion
+ * [ ] XClipBox
+ * [ ] XXorRegion
+ */
+
+EAPI Ecore_X_XRegion *
+ecore_x_xregion_new()
+{
+ pixman_region16_t *region;
+
+ region = (pixman_region16_t *)malloc(sizeof(pixman_region16_t));
+ if (!region) return NULL;
+
+ pixman_region_init(region);
+
+ return (Ecore_X_XRegion *)region;
+}
+
+EAPI void
+ecore_x_xregion_free(Ecore_X_XRegion *region)
+{
+ if (!region) return;
+
+ pixman_region_fini(region);
+ free(region);
+}
+
+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 = 0, i = 0;
+
+ CHECK_XCB_CONN;
+
+ if (!region) return EINA_FALSE;
+
+ 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 EINA_FALSE;
+
+ for (i = 0; i < num; i++)
+ {
+ rects[i].x = boxes[i].x1;
+ rects[i].y = boxes[i].y1;
+ rects[i].width = boxes[i].x2 - boxes[i].x1 + 1;
+ 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);
+
+// ecore_x_flush();
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_xregion_translate(Ecore_X_XRegion *region,
+ int x,
+ int y)
+{
+ if (!region) return;
+
+ pixman_region_translate((pixman_region16_t *)region, x, y);
+}
+
+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);
+}
+
+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);
+}
+
+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,
+ rect->x, rect->y, rect->width, rect->height);
+}
+
+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);
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_is_empty(Ecore_X_XRegion *region)
+{
+ if (!region) return EINA_TRUE;
+
+ return !pixman_region_not_empty((pixman_region16_t *)region);
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_is_equal(Ecore_X_XRegion *r1,
+ Ecore_X_XRegion *r2)
+{
+ if ((!r1) || (!r2)) return EINA_FALSE;
+
+ 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 EINA_FALSE;
+
+ return pixman_region_contains_point((pixman_region16_t *)region, x, y, NULL);
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_rect_contain(Ecore_X_XRegion *region,
+ Ecore_X_Rectangle *rect)
+{
+ pixman_box16_t box;
+
+ if ((!region) || (!rect)) return EINA_FALSE;
+
+ box.x1 = rect->x;
+ box.y1 = rect->y;
+ box.x2 = rect->x + rect->width - 1;
+ box.y2 = rect->y + rect->height - 1;
+
+ return pixman_region_contains_rectangle((pixman_region16_t *)region, &box);
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_render.c b/src/lib/ecore_x/xcb/ecore_xcb_render.c
new file mode 100644
index 0000000000..f36b4d2489
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_render.c
@@ -0,0 +1,225 @@
+#include "ecore_xcb_private.h"
+#include <ctype.h> // for isupper/tolower
+#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);
+
+/* 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;
+ _ecore_xcb_xdefaults_init();
+ if ((reply->major_version > 0) || (reply->minor_version >= 5))
+ {
+ _render_argb = EINA_TRUE;
+ v = getenv("XCURSOR_CORE");
+ if (!v)
+ v = _ecore_xcb_xdefaults_string_get("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)
+ v = _ecore_xcb_xdefaults_string_get("Xcursor", "anim");
+ if ((v) && (_ecore_xcb_render_parse_boolean(v)))
+ _render_anim = EINA_FALSE;
+ }
+ _ecore_xcb_xdefaults_shutdown();
+ }
+ }
+ 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__);
+ CHECK_XCB_CONN;
+
+ if (!visual) return EINA_FALSE;
+ if (!_render_avail) 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__);
+ CHECK_XCB_CONN;
+
+ if (!_render_avail) return 0;
+
+#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;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c b/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c
new file mode 100644
index 0000000000..6106450c88
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c
@@ -0,0 +1,370 @@
+#include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_SCREENSAVER
+# include <xcb/screensaver.h>
+# endif
+
+/* local variables */
+static Eina_Bool _screensaver_avail = EINA_FALSE;
+
+/* external variables */
+int _ecore_xcb_event_screensaver = -1;
+
+void
+_ecore_xcb_screensaver_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_screensaver_id);
+#endif
+}
+
+void
+_ecore_xcb_screensaver_finalize(void)
+{
+#ifdef ECORE_XCB_SCREENSAVER
+ const xcb_query_extension_reply_t *ext_reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_SCREENSAVER
+ ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_screensaver_id);
+ if ((ext_reply) && (ext_reply->present))
+ {
+ 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
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return 0;
+
+#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);
+ 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return;
+
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_set_screen_saver(_ecore_xcb_conn,
+ timeout, interval, prefer_blanking, allow_exposures);
+#endif
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return;
+
+#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;
+ 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
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return 0;
+
+#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;
+ timeout = reply->timeout;
+ free(reply);
+#endif
+
+ return timeout;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return;
+
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return 0;
+
+#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;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return;
+
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return 0;
+
+#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;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return;
+
+#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
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return 0;
+
+#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
+ Ecore_X_Window root;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_screensaver_avail) return;
+
+#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 |
+ XCB_SCREENSAVER_EVENT_CYCLE_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;
+}
+
+EAPI Eina_Bool
+ecore_x_screensaver_custom_blanking_enable(void)
+{
+#ifdef ECORE_XCB_SCREENSAVER
+ uint32_t mask_list[9];
+
+ xcb_screensaver_set_attributes_checked
+ (_ecore_xcb_conn,
+ ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ -9999, -9999, 1, 1, 0,
+ XCB_WINDOW_CLASS_INPUT_ONLY,
+ XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT,
+ 0, mask_list);
+ return EINA_TRUE;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_screensaver_custom_blanking_disable(void)
+{
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_screensaver_unset_attributes_checked
+ (_ecore_xcb_conn,
+ ((xcb_screen_t *)_ecore_xcb_screen)->root);
+ return EINA_TRUE;
+#else
+ return EINA_FALSE;
+#endif
+}
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_selection.c b/src/lib/ecore_x/xcb/ecore_xcb_selection.c
new file mode 100644
index 0000000000..6d5c5aca4c
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_selection.c
@@ -0,0 +1,1026 @@
+#include "ecore_xcb_private.h"
+//#include "Ecore_X_Atoms.h"
+
+#define ECORE_XCB_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x))
+
+/* local function prototypes */
+static void *_ecore_xcb_selection_parser_text(const char *target EINA_UNUSED,
+ void *data,
+ int size,
+ int format EINA_UNUSED);
+static void *_ecore_xcb_selection_parser_files(const char *target,
+ void *data,
+ int size,
+ int format EINA_UNUSED);
+static void *_ecore_xcb_selection_parser_targets(const char *target EINA_UNUSED,
+ void *data,
+ int size,
+ int format EINA_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_x_selection_converter_text);
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING,
+ ecore_x_selection_converter_text);
+ 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);
+
+ /* 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ /* free selection converters */
+ cnv = _converters;
+ while (cnv)
+ {
+ Ecore_X_Selection_Converter *tmp;
+
+ tmp = cnv->next;
+ free(cnv);
+ cnv = tmp;
+ }
+ _converters = NULL;
+
+ /* free parsers */
+ prs = _parsers;
+ while (prs)
+ {
+ Ecore_X_Selection_Parser *tmp;
+
+ tmp = prs;
+ prs = prs->next;
+ free(tmp->target);
+ free(tmp);
+ }
+ _parsers = NULL;
+}
+
+/* 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))
+{
+ Ecore_X_Selection_Converter *cnv;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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));
+ if (!cnv->next) return;
+ cnv = cnv->next;
+ }
+ else
+ {
+ _converters = calloc(1, sizeof(Ecore_X_Selection_Converter));
+ if (!_converters) return;
+ cnv = _converters;
+ }
+ cnv->target = target;
+ cnv->convert = func;
+}
+
+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))
+{
+ Ecore_X_Atom atarget;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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)
+{
+ Ecore_X_Atom atarget;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!target) return;
+ atarget = _ecore_xcb_selection_target_atom_get(target);
+ ecore_x_selection_converter_atom_del(atarget);
+}
+
+EAPI void
+ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
+{
+ Ecore_X_Selection_Converter *conv, *pconv = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ conv = _converters;
+ while (conv)
+ {
+ if (conv->target == target)
+ {
+ if (pconv)
+ pconv->next = conv->next;
+ else
+ _converters = conv->next;
+ free(conv);
+ return;
+ }
+ pconv = conv;
+ conv = conv->next;
+ }
+}
+
+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)
+ {
+ while (prs->next)
+ {
+ 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;
+}
+
+EAPI void
+ecore_x_selection_parser_del(const char *target)
+{
+ Ecore_X_Selection_Parser *prs, *pprs = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!target) return;
+
+ 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 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 win,
+ const void *data,
+ int size)
+{
+ 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.
+ */
+EAPI Eina_Bool
+ecore_x_selection_primary_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return _ecore_xcb_selection_set(XCB_NONE, NULL, 0,
+ ECORE_X_ATOM_SELECTION_PRIMARY);
+}
+
+EAPI void
+ecore_x_selection_primary_request(Ecore_X_Window win,
+ const char *target)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_PRIMARY, target);
+}
+
+/**
+ * Claim ownership of the SECONDARY selection and set its data.
+ * @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 win,
+ const void *data,
+ int size)
+{
+ 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.
+ */
+EAPI Eina_Bool
+ecore_x_selection_secondary_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return _ecore_xcb_selection_set(XCB_NONE, NULL, 0,
+ ECORE_X_ATOM_SELECTION_SECONDARY);
+}
+
+EAPI void
+ecore_x_selection_secondary_request(Ecore_X_Window win,
+ const char *target)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_SECONDARY, target);
+}
+
+/**
+ * Claim ownership of the XDND selection and set its data.
+ * @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 win,
+ const void *data,
+ int size)
+{
+ 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.
+ */
+EAPI Eina_Bool
+ecore_x_selection_xdnd_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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)
+{
+ Ecore_X_Atom atom;
+ Ecore_X_DND_Target *_target;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ _target = _ecore_xcb_dnd_target_get();
+ atom = _ecore_xcb_selection_target_atom_get(target);
+
+ 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 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.
+ */
+EAPI Eina_Bool
+ecore_x_selection_clipboard_set(Ecore_X_Window win,
+ const void *data,
+ int size)
+{
+ 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.
+ */
+EAPI Eina_Bool
+ecore_x_selection_clipboard_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return _ecore_xcb_selection_set(XCB_NONE, NULL, 0,
+ ECORE_X_ATOM_SELECTION_CLIPBOARD);
+}
+
+EAPI void
+ecore_x_selection_clipboard_request(Ecore_X_Window win,
+ const char *target)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_CLIPBOARD, 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)
+{
+ Ecore_X_Selection_Intern *sel;
+ Ecore_X_Selection_Converter *cnv;
+ void *data;
+ char *tgt_str;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ sel = _ecore_xcb_selection_get(selection);
+ tgt_str = _ecore_xcb_selection_target_get(target);
+
+ for (cnv = _converters; cnv; cnv = cnv->next)
+ {
+ if (cnv->target == target)
+ {
+ int r = 0;
+
+ 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;
+ }
+ }
+
+ 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 tim)
+{
+ xcb_selection_notify_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ memset(&ev, 0, sizeof(xcb_selection_notify_event_t));
+
+ ev.response_type = XCB_SELECTION_NOTIFY;
+ ev.requestor = requestor;
+ ev.selection = selection;
+ ev.target = target;
+ ev.property = property;
+ ev.time = tim;
+
+ xcb_send_event(_ecore_xcb_conn, 0, requestor,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+// ecore_x_flush();
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_selection_owner_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Time tim)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_set_selection_owner(_ecore_xcb_conn, win, atom, tim);
+}
+
+EAPI Ecore_X_Window
+ecore_x_selection_owner_get(Ecore_X_Atom atom)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+ xcb_get_selection_owner_reply_t *reply;
+ Ecore_X_Window ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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_Parser *prs;
+ Ecore_X_Selection_Data *sel;
+
+ for (prs = _parsers; prs; prs = prs->next)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ sel = prs->parse(target, data, size, format);
+ if (sel) return sel;
+ }
+ }
+
+ 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;
+
+ return sel;
+}
+
+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;
+}
+
+/* local functions */
+static Eina_Bool
+_ecore_xcb_selection_set(Ecore_X_Window win,
+ const void *data,
+ int size,
+ Ecore_X_Atom selection)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+ xcb_get_selection_owner_reply_t *reply;
+ int in = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_set_selection_owner(_ecore_xcb_conn, win, selection, XCB_CURRENT_TIME);
+
+ 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)
+ {
+ free(reply);
+ return EINA_FALSE;
+ }
+ free(reply);
+
+ 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;
+
+ if (data)
+ {
+ unsigned char *buff = NULL;
+
+ _selections[in].win = win;
+ _selections[in].selection = selection;
+ _selections[in].length = size;
+ _selections[in].time = _ecore_xcb_events_last_time_get();
+
+ buff = malloc(size);
+ if (!buff) return EINA_FALSE;
+ memcpy(buff, data, size);
+ _selections[in].data = buff;
+ }
+ else if (_selections[in].data)
+ {
+ free(_selections[in].data);
+ memset(&_selections[in], 0, sizeof(Ecore_X_Selection_Data));
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_ecore_xcb_selection_request(Ecore_X_Window win,
+ Ecore_X_Atom selection,
+ const char *target)
+{
+ Ecore_X_Atom atarget, prop;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ atarget = _ecore_xcb_selection_target_atom_get(target);
+
+ xcb_convert_selection(_ecore_xcb_conn, win, selection, atarget, prop,
+ XCB_CURRENT_TIME);
+}
+
+EAPI Eina_Bool
+ecore_x_selection_converter_text(char *target,
+ void *data,
+ int size,
+ void **data_ret,
+ int *size_ret,
+ Ecore_X_Atom *type EINA_UNUSED,
+ int *size_type EINA_UNUSED)
+{
+ Ecore_Xcb_Encoding_Style style;
+ Ecore_Xcb_Textproperty ret;
+ char *str;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if ((!data) || (!size)) return EINA_FALSE;
+
+ 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;
+#ifdef HAVE_ICONV
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
+ style = XcbUTF8StringStyle;
+#endif
+ else
+ return EINA_FALSE;
+
+ str = alloca(size + 1);
+ memcpy(str, data, size);
+ str[size] = '\0';
+
+#ifdef HAVE_ICONV
+ if (_ecore_xcb_utf8_textlist_to_textproperty(&str, 1, style, &ret))
+ {
+ int size = 0;
+
+ size = (strlen((char *)ret.value) + 1);
+ *data_ret = malloc(size);
+ if (!*data_ret) return EINA_FALSE;
+ memcpy(*data_ret, ret.value, size);
+ *size_ret = size;
+ if (ret.value) free(ret.value);
+ return EINA_TRUE;
+ }
+#else
+ if (_ecore_xcb_mb_textlist_to_textproperty(&str, 1, style, &ret))
+ {
+ int size = 0;
+
+ size = (strlen((char *)ret.value) + 1);
+ *data_ret = malloc(size);
+ if (!*data_ret) return EINA_FALSE;
+ memcpy(*data_ret, ret.value, size);
+ *size_ret = size;
+ if (ret.value) free(ret.value);
+ return EINA_TRUE;
+ }
+#endif
+ else
+ return EINA_TRUE;
+}
+
+static void *
+_ecore_xcb_selection_parser_text(const char *target EINA_UNUSED,
+ void *data,
+ int size,
+ int format EINA_UNUSED)
+{
+ Ecore_X_Selection_Data_Text *sel;
+ unsigned char *_data;
+ void *t;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(_data = data)) return NULL;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text));
+ if (!sel) return NULL;
+
+ if (_data && _data[size - 1])
+ {
+ size++;
+ t = realloc(_data, size);
+ if (!t)
+ {
+ free(sel);
+ return NULL;
+ }
+ _data = t;
+ _data[size - 1] = 0;
+ }
+ 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)->data = _data;
+ ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_text_free;
+ return sel;
+}
+
+static void *
+_ecore_xcb_selection_parser_files(const char *target,
+ void *data,
+ int size,
+ int format EINA_UNUSED)
+{
+ Ecore_X_Selection_Data_Files *sel;
+ char *_data, *tmp, *t, **t2;
+ int i = 0, is = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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));
+ if (!sel) return NULL;
+
+ ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_files_free;
+
+ if (_data && _data[size - 1])
+ {
+ size++;
+ t = realloc(_data, size);
+ if (!t)
+ {
+ free(sel);
+ return NULL;
+ }
+ _data = t;
+ _data[size - 1] = 0;
+ }
+
+ tmp = malloc(size);
+ if (!tmp)
+ {
+ free(sel);
+ return NULL;
+ }
+
+ while ((is < size) && (_data[is]))
+ {
+ if ((i == 0) && (_data[is] == '#'))
+ {
+ for (; ((_data[is]) && (_data[is] != '\n')); is++) ;
+ }
+ else
+ {
+ if ((_data[is] != '\r') && (_data[is] != '\n'))
+ tmp[i++] = _data[is++];
+ else
+ {
+ while ((_data[is] == '\r') || (_data[is] == '\n'))
+ is++;
+ tmp[i] = 0;
+ sel->num_files++;
+ t2 = realloc(sel->files, sel->num_files * sizeof(char *));
+ if (t2)
+ {
+ sel->files = t2;
+ sel->files[sel->num_files - 1] = strdup(tmp);
+ }
+ tmp[0] = 0;
+ i = 0;
+ }
+ }
+ }
+ if (i > 0)
+ {
+ tmp[i] = 0;
+ sel->num_files++;
+ t2 = realloc(sel->files, sel->num_files * sizeof(char *));
+ if (t2)
+ {
+ sel->files = t2;
+ 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);
+}
+
+static void *
+_ecore_xcb_selection_parser_targets(const char *target EINA_UNUSED,
+ void *data,
+ int size,
+ int format EINA_UNUSED)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+ unsigned long *targets;
+ int i = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!(targets = (unsigned long *)data)) return NULL;
+
+ 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 *));
+ if (!sel->targets)
+ {
+ free(sel);
+ return NULL;
+ }
+
+ for (i = 2; i < size; i++)
+ {
+ xcb_get_atom_name_cookie_t cookie;
+ xcb_get_atom_name_reply_t *reply;
+ char *name = NULL;
+ int len = 0;
+
+ cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, targets[i]);
+ reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply)
+ {
+ len = xcb_get_atom_name_name_length(reply);
+ name = (char *)malloc(sizeof(char) * (len + 1));
+ if (name)
+ {
+ memcpy(name, xcb_get_atom_name_name(reply), len);
+ name[len] = '\0';
+ sel->targets[i - 2] = name;
+ }
+ free(reply);
+ }
+ }
+
+ 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;
+ ECORE_XCB_SELECTION_DATA(sel)->data = data;
+
+ return sel;
+}
+
+/*
+ static int
+ _ecore_xcb_selection_data_free(void *data)
+ {
+ Ecore_X_Selection_Data *sel;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(sel = data)) return 0;
+ if (sel->data) free(sel->data);
+ free(sel);
+ return 1;
+ }
+ */
+
+static int
+_ecore_xcb_selection_data_text_free(void *data)
+{
+ Ecore_X_Selection_Data_Text *sel;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(sel = data)) return 0;
+ if (sel->text) free(sel->text);
+ free(sel);
+ return 1;
+}
+
+static int
+_ecore_xcb_selection_data_targets_free(void *data)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(sel = data)) return 0;
+ if (sel->targets) free(sel->targets);
+ free(ECORE_XCB_SELECTION_DATA(sel)->data);
+ free(sel);
+ return 1;
+}
+
+static int
+_ecore_xcb_selection_data_files_free(void *data)
+{
+ Ecore_X_Selection_Data_Files *sel;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(sel = data)) return 0;
+ if (sel->files)
+ {
+ 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 0;
+}
+
+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;
+}
+
+static Ecore_X_Atom
+_ecore_xcb_selection_target_atom_get(const char *target)
+{
+ Ecore_X_Atom x_target;
+
+ if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
+ x_target = ECORE_X_ATOM_TEXT;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
+ x_target = ECORE_X_ATOM_COMPOUND_TEXT;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
+ x_target = ECORE_X_ATOM_STRING;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
+ x_target = ECORE_X_ATOM_UTF8_STRING;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME))
+ x_target = ECORE_X_ATOM_FILE_NAME;
+ else
+ x_target = ecore_x_atom_get(target);
+
+ return x_target;
+}
+
+char *
+_ecore_xcb_selection_target_get(Ecore_X_Atom target)
+{
+ if (target == ECORE_X_ATOM_FILE_NAME)
+ return strdup(ECORE_X_SELECTION_TARGET_FILENAME);
+ else if (target == ECORE_X_ATOM_STRING)
+ return strdup(ECORE_X_SELECTION_TARGET_STRING);
+ else if (target == ECORE_X_ATOM_UTF8_STRING)
+ return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING);
+ else if (target == ECORE_X_ATOM_TEXT)
+ return strdup(ECORE_X_SELECTION_TARGET_TEXT);
+ else
+ return ecore_x_atom_name_get(target);
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_shape.c b/src/lib/ecore_x/xcb/ecore_xcb_shape.c
new file mode 100644
index 0000000000..913f1992b9
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_shape.c
@@ -0,0 +1,50 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_SHAPE
+# include <xcb/shape.h>
+#endif
+
+/* external variables */
+int _ecore_xcb_event_shape = -1;
+
+void
+_ecore_xcb_shape_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_SHAPE
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shape_id);
+#endif
+}
+
+void
+_ecore_xcb_shape_finalize(void)
+{
+#ifdef ECORE_XCB_SHAPE
+ const xcb_query_extension_reply_t *ext_reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_SHAPE
+ ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_shape_id);
+ if ((ext_reply) && (ext_reply->present))
+ {
+ xcb_shape_query_version_cookie_t cookie;
+ xcb_shape_query_version_reply_t *reply;
+ Eina_Bool _shape_avail;
+
+ _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)
+ {
+ _shape_avail = EINA_TRUE;
+ free(reply);
+ }
+
+ if (_shape_avail)
+ _ecore_xcb_event_shape = ext_reply->first_event;
+ }
+#endif
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_sync.c b/src/lib/ecore_x/xcb/ecore_xcb_sync.c
new file mode 100644
index 0000000000..75f4e4f2be
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_sync.c
@@ -0,0 +1,338 @@
+#include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_SYNC
+# include <xcb/sync.h>
+# endif
+
+/* local variables */
+static Eina_Bool _sync_avail = EINA_FALSE;
+
+/* external variables */
+int _ecore_xcb_event_sync = -1;
+
+void
+_ecore_xcb_sync_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_SYNC
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_sync_id);
+#endif
+}
+
+void
+_ecore_xcb_sync_finalize(void)
+{
+#ifdef ECORE_XCB_SYNC
+ const xcb_query_extension_reply_t *ext_reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_SYNC
+ ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_sync_id);
+ if ((ext_reply) && (ext_reply->present))
+ {
+ xcb_sync_initialize_cookie_t cookie;
+ xcb_sync_initialize_reply_t *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
+}
+
+void
+_ecore_xcb_sync_magic_send(int val,
+ Ecore_X_Window win)
+{
+ xcb_client_message_event_t ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ memset(&ev, 0, sizeof(xcb_client_message_event_t));
+ ev.response_type = XCB_CLIENT_MESSAGE;
+ ev.format = 32;
+ ev.window = win;
+ ev.type = 27777;
+ ev.data.data32[0] = 0x7162534;
+ ev.data.data32[1] = (0x10000000 + val);
+ ev.data.data32[2] = win;
+
+ xcb_send_event(_ecore_xcb_conn, 0, win, XCB_EVENT_MASK_NO_EVENT,
+ (const char *)&ev);
+// ecore_x_flush();
+}
+
+/* public functions */
+EAPI Ecore_X_Sync_Alarm
+ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter)
+{
+#ifdef ECORE_XCB_SYNC
+ uint32_t list[6], mask;
+ xcb_sync_int64_t init;
+ Ecore_X_Sync_Alarm alarm;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+
+ 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, mask, list);
+ ecore_x_sync(); // needed
+
+ return alarm;
+#endif
+ return 0;
+}
+
+EAPI Eina_Bool
+ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if ((!_sync_avail) || (!alarm)) return EINA_FALSE;
+
+#ifdef ECORE_XCB_SYNC
+ xcb_sync_destroy_alarm(_ecore_xcb_conn, alarm);
+// ecore_x_flush();
+ return EINA_TRUE;
+#endif
+
+ return EINA_FALSE;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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 (val) *val = (unsigned int)reply->counter_value.lo;
+ free(reply);
+ return EINA_TRUE;
+ }
+#endif
+ return EINA_FALSE;
+}
+
+EAPI void
+ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter,
+ int by)
+{
+#ifdef ECORE_XCB_SYNC
+ xcb_sync_int64_t v;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if ((!_sync_avail) || (!counter)) return;
+
+#ifdef ECORE_XCB_SYNC
+ v.hi = (by < 0) ? ~0 : 0;
+ v.lo = by;
+
+ xcb_sync_change_counter(_ecore_xcb_conn, counter, v);
+// ecore_x_flush();
+#endif
+}
+
+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, v2;
+ xcb_sync_waitcondition_t cond;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if ((!_sync_avail) || (!counter)) return;
+
+#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);
+
+ 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, &cond);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+
+ return counter;
+#endif
+
+ return 0;
+}
+
+EAPI void
+ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if ((!_sync_avail) || (!counter)) return;
+
+#ifdef ECORE_XCB_SYNC
+ xcb_sync_destroy_counter(_ecore_xcb_conn, counter);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if ((!_sync_avail) || (!counter)) return EINA_FALSE;
+
+#ifdef ECORE_XCB_SYNC
+ cookie =
+ xcb_sync_query_counter_unchecked(_ecore_xcb_conn,
+ (xcb_sync_counter_t)counter);
+ reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply) return EINA_FALSE;
+ value = reply->counter_value;
+ free(reply);
+ if (val_hi) *val_hi = (int)value.hi;
+ if (val_lo) *val_lo = (unsigned int)value.lo;
+ return EINA_TRUE;
+#endif
+
+ return EINA_FALSE;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_textlist.c b/src/lib/ecore_x/xcb/ecore_xcb_textlist.c
new file mode 100644
index 0000000000..2a5c854494
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_textlist.c
@@ -0,0 +1,509 @@
+#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
index 0000000000..7888796f9a
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_vsync.c
@@ -0,0 +1,375 @@
+#include "ecore_xcb_private.h"
+# include <fcntl.h>
+# include <dlfcn.h>
+# include <X11/Xlib-xcb.h>
+
+#define ECORE_XCB_VSYNC_DRI2 1
+#define DRM_EVENT_CONTEXT_VERSION 2
+
+#ifdef ECORE_XCB_VSYNC_DRI2
+
+/* 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;
+
+/* dri */
+static Bool (*sym_DRI2QueryExtension)(Display *display,
+ int *eventBase,
+ int *errorBase) = NULL;
+static Bool (*sym_DRI2QueryVersion)(Display *display,
+ int *major,
+ int *minor) = NULL;
+static Bool (*sym_DRI2Connect)(Display *display,
+ XID window,
+ char **driverName,
+ char **deviceName) = NULL;
+static Bool (*sym_DRI2Authenticate)(Display *display,
+ XID window,
+ drm_magic_t magic) = NULL;
+
+/* 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 EINA_UNUSED,
+ Ecore_Fd_Handler *fdh EINA_UNUSED);
+static void _ecore_xcb_dri_tick_begin(void *data EINA_UNUSED);
+static void _ecore_xcb_dri_tick_end(void *data EINA_UNUSED);
+static void _ecore_xcb_dri_tick_schedule(void);
+static void _ecore_xcb_dri_vblank_handler(int fd EINA_UNUSED,
+ unsigned int frame EINA_UNUSED,
+ unsigned int sec EINA_UNUSED,
+ unsigned int usec EINA_UNUSED,
+ void *data EINA_UNUSED);
+
+/* local variables */
+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;
+static void *_dri_lib = NULL;
+static drmEventContext _drm_evctx;
+#endif
+
+void
+_ecore_xcb_dri_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+}
+
+void
+_ecore_xcb_dri_finalize(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+}
+
+EAPI Eina_Bool
+ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win)
+{
+#ifdef ECORE_XCB_VSYNC_DRI2
+ Ecore_X_Window root;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_VSYNC_DRI2
+ 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 */
+#ifdef ECORE_XCB_VSYNC_DRI2
+static Eina_Bool
+_ecore_xcb_dri_link(void)
+{
+ const char *_drm_libs[] =
+ {
+ "libdrm.so.2",
+ "libdrm.so.1",
+ "libdrm.so.0",
+ "libdrm.so",
+ NULL,
+ };
+ const char *_dri_libs[] =
+ {
+ "libdri2.so.2",
+ "libdri2.so.1",
+ "libdri2.so.0",
+ "libdri2.so",
+ "libGL.so.4",
+ "libGL.so.3",
+ "libGL.so.2",
+ "libGL.so.1",
+ "libGL.so.0",
+ "libGL.so",
+ NULL,
+ };
+ int i = 0, fail = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+# 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;
+ for (i = 0; _dri_libs[i]; i++)
+ {
+ if ((_dri_lib = dlopen(_dri_libs[i], (RTLD_LOCAL | RTLD_LAZY))))
+ {
+ fail = 0;
+ SYM(_dri_lib, DRI2QueryExtension);
+ SYM(_dri_lib, DRI2QueryVersion);
+ SYM(_dri_lib, DRI2Connect);
+ SYM(_dri_lib, DRI2Authenticate);
+ if (fail)
+ {
+ dlclose(_dri_lib);
+ _dri_lib = NULL;
+ }
+ else
+ break;
+ }
+ }
+ if (!_dri_lib)
+ {
+ dlclose(_drm_lib);
+ _drm_lib = NULL;
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecore_xcb_dri_start(void)
+{
+ Ecore_X_Display *disp;
+ int _dri2_event = 0, _dri2_error = 0;
+ int _dri2_major = 0, _dri2_minor = 0;
+ char *device = NULL, *driver = NULL;
+
+ disp = ecore_x_display_get();
+ if (!sym_DRI2QueryExtension(disp, &_dri2_event, &_dri2_error))
+ return 0;
+ if (!sym_DRI2QueryVersion(disp, &_dri2_major, &_dri2_minor))
+ return 0;
+ if (_dri2_major < 2) return 0;
+ if (!sym_DRI2Connect(disp, _vsync_root, &driver, &device))
+ return 0;
+
+ _drm_fd = open(device, O_RDWR);
+ if (_drm_fd < 0) return 0;
+
+ sym_drmGetMagic(_drm_fd, &_drm_magic);
+ if (!sym_DRI2Authenticate(disp, _vsync_root, _drm_magic))
+ {
+ close(_drm_fd);
+ _drm_fd = -1;
+ return EINA_FALSE;
+ }
+
+ 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;
+}
+
+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 EINA_UNUSED,
+ Ecore_Fd_Handler *fdh EINA_UNUSED)
+{
+ sym_drmHandleEvent(_drm_fd, &_drm_evctx);
+ return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_ecore_xcb_dri_tick_begin(void *data EINA_UNUSED)
+{
+ _drm_event_busy = EINA_TRUE;
+ _ecore_xcb_dri_tick_schedule();
+}
+
+static void
+_ecore_xcb_dri_tick_end(void *data EINA_UNUSED)
+{
+ _drm_event_busy = EINA_FALSE;
+}
+
+static void
+_ecore_xcb_dri_tick_schedule(void)
+{
+ drmVBlank vbl;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ vbl.request.type = (DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT);
+ vbl.request.sequence = 1;
+ vbl.request.signal = 0;
+
+ sym_drmWaitVBlank(_drm_fd, &vbl);
+}
+
+static void
+_ecore_xcb_dri_vblank_handler(int fd EINA_UNUSED,
+ unsigned int frame EINA_UNUSED,
+ unsigned int sec EINA_UNUSED,
+ unsigned int usec EINA_UNUSED,
+ void *data EINA_UNUSED)
+{
+ ecore_animator_custom_tick();
+ if (_drm_event_busy) _ecore_xcb_dri_tick_schedule();
+}
+
+#endif
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window.c b/src/lib/ecore_x/xcb/ecore_xcb_window.c
new file mode 100644
index 0000000000..f8405fe1ec
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_window.c
@@ -0,0 +1,2238 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_RENDER
+# include <xcb/render.h>
+#endif
+#ifdef ECORE_XCB_SHAPE
+# include <xcb/shape.h>
+#endif
+#ifdef ECORE_XCB_XPRINT
+#include <xcb/xprint.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);
+#ifdef ECORE_XCB_XPRINT
+static xcb_screen_t *_ecore_xcb_window_screen_of_display(int screen);
+#endif
+
+/* local variables */
+static int ignore_num = 0;
+static Ecore_X_Window *ignore_list = NULL;
+
+/* 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
+ *
+ * Functions that can be used to create an X window.
+ */
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @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 w,
+ int h)
+{
+ Ecore_X_Window win;
+ uint32_t mask, mask_list[9];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ 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(win);
+
+ return win;
+}
+
+/**
+ * Creates a window with the override redirect attribute set to @c True.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @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_new(Ecore_X_Window parent,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ Ecore_X_Window win;
+ uint32_t mask, mask_list[9];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ 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);
+
+ return win;
+}
+
+/**
+ * Creates a new input window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @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 w,
+ int h)
+{
+ Ecore_X_Window win;
+ uint32_t mask, mask_list[3];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__)
+ CHECK_XCB_CONN;
+
+ 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_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;
+
+ 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 win;
+}
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @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 w,
+ int h)
+{
+ Ecore_X_Window win = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0);
+
+ return win;
+}
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @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 w,
+ int h)
+{
+ Ecore_X_Window win = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @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 w,
+ int h)
+{
+ Ecore_X_Window win = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ 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
+ *
+ * Functions to destroy X windows.
+ */
+
+/**
+ * Deletes the given window.
+ * @param win The given window.
+ * @ingroup Ecore_X_Window_Destroy_Group
+ */
+EAPI void
+ecore_x_window_free(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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_flush();
+ }
+}
+
+/**
+ * Sends a delete request to 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 win)
+{
+ 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);
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) return;
+
+ 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);
+// ecore_x_flush();
+}
+
+/**
+ * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
+ *
+ * Functions that change or retrieve the geometry of X windows.
+ */
+
+/**
+ * Moves a window to the position @p x, @p y.
+ *
+ * The position is relative to the upper left hand corner of the
+ * parent window.
+ *
+ * @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 win,
+ int x,
+ int y)
+{
+ uint32_t list[2], mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) return;
+
+ mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y);
+ list[0] = x;
+ list[1] = y;
+
+ xcb_configure_window(_ecore_xcb_conn, win, mask,
+ (const uint32_t *)&list);
+// ecore_x_flush();
+}
+
+/**
+ * Resizes a window.
+ * @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 win,
+ int w,
+ int h)
+{
+ uint32_t list[2], mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) return;
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+
+ mask = (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
+ list[0] = w;
+ list[1] = h;
+
+ xcb_configure_window(_ecore_xcb_conn, win, mask,
+ (const uint32_t *)&list);
+// ecore_x_flush();
+}
+
+/**
+ * Moves and resizes a window.
+ * @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 win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ uint32_t list[4], mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) return;
+ if (w < 1) w = 1;
+ if (h < 1) h = 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;
+
+ xcb_configure_window(_ecore_xcb_conn, win, mask,
+ (const uint32_t *)&list);
+// ecore_x_flush();
+}
+
+/**
+ * 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__);
+
+ if (!win) return 0;
+ return ecore_x_drawable_border_width_get(win);
+}
+
+/**
+ * Sets the width of the border of the given window.
+ * @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 win,
+ int border_width)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) return;
+
+ list = border_width;
+
+ xcb_configure_window(_ecore_xcb_conn, win,
+ XCB_CONFIG_WINDOW_BORDER_WIDTH, &list);
+// ecore_x_flush();
+}
+
+/**
+ * @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 win The window to raise.
+ * @ingroup Ecore_X_Window_Z_Order_Group
+ */
+EAPI void
+ecore_x_window_raise(Ecore_X_Window win)
+{
+ uint32_t list[] = { XCB_STACK_MODE_ABOVE };
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_configure_window(_ecore_xcb_conn, win,
+ XCB_CONFIG_WINDOW_STACK_MODE, list);
+// ecore_x_flush();
+}
+
+/**
+ * Lowers the given window.
+ * @param win The window to lower.
+ * @ingroup Ecore_X_Window_Z_Order_Group
+ */
+EAPI void
+ecore_x_window_lower(Ecore_X_Window win)
+{
+ uint32_t list[] = { XCB_STACK_MODE_BELOW };
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_configure_window(_ecore_xcb_conn, win,
+ XCB_CONFIG_WINDOW_STACK_MODE, list);
+// ecore_x_flush();
+}
+
+/**
+ * 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__);
+
+ return ecore_x_drawable_depth_get(win);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Properties_Group X Window Property Functions
+ *
+ * Functions that set window properties.
+ */
+
+/**
+ * Sets the default properties for the given window.
+ *
+ * The default properties set for the window are @c WM_CLIENT_MACHINE and
+ * @c _NET_WM_PID.
+ *
+ * @param win The given window.
+ * @ingroup Ecore_X_Window_Properties_Group
+ */
+EAPI void
+ecore_x_window_defaults_set(Ecore_X_Window win)
+{
+ char buff[MAXHOSTNAMELEN], **argv;
+ int argc;
+ pid_t pid;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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(win, argc, argv);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
+ *
+ * Functions to access and change the visibility of X windows.
+ */
+
+/**
+ * Shows a window.
+ *
+ * Synonymous to "mapping" a window in X Window System terminology.
+ *
+ * @param win The window to show.
+ * @ingroup Ecore_X_Window_Visibility
+ */
+EAPI void
+ecore_x_window_show(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (win)
+ xcb_map_window(_ecore_xcb_conn, win);
+}
+
+/**
+ * Hides a window.
+ *
+ * Synonymous to "unmapping" a window in X Window System terminology.
+ *
+ * @param win The window to hide.
+ * @ingroup Ecore_X_Window_Visibility
+ */
+EAPI void
+ecore_x_window_hide(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (win)
+ {
+ 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);
+ }
+
+ xcb_unmap_window(_ecore_xcb_conn, win);
+ memset(&ev, 0, sizeof(xcb_unmap_notify_event_t));
+
+ 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);
+
+// ecore_x_flush();
+ }
+}
+
+/**
+ * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions
+ *
+ * Functions that give the focus to an X Window.
+ */
+
+/**
+ * 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 win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ xcb_set_input_focus(_ecore_xcb_conn,
+ XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME);
+// ecore_x_flush();
+}
+
+/**
+ * Sets the focus to the given window at a specific time.
+ * @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 win,
+ Ecore_X_Time time EINA_UNUSED)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+ xcb_set_input_focus(_ecore_xcb_conn,
+ XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME);
+// ecore_x_flush();
+}
+
+/**
+ * @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 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_Parent_Group
+ */
+EAPI void
+ecore_x_window_reparent(Ecore_X_Window win,
+ Ecore_X_Window parent,
+ int x,
+ int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (parent == 0)
+ parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ xcb_reparent_window(_ecore_xcb_conn, win, parent, x, y);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_pixmap_set(Ecore_X_Window win,
+ Ecore_X_Pixmap pixmap)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ list = pixmap;
+
+ xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_BACK_PIXMAP, &list);
+// ecore_x_flush();
+}
+
+/**
+ * Sets the background color of the given window.
+ * @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 win,
+ unsigned short red,
+ unsigned short green,
+ unsigned short blue)
+{
+ xcb_alloc_color_cookie_t cookie;
+ xcb_alloc_color_reply_t *reply;
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_pixel_gravity_set(Ecore_X_Window win,
+ Ecore_X_Gravity gravity)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ list = gravity;
+
+ xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_BIT_GRAVITY, &list);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_gravity_set(Ecore_X_Window win,
+ Ecore_X_Gravity gravity)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ list = gravity;
+
+ xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_WIN_GRAVITY, &list);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_override_set(Ecore_X_Window win,
+ Eina_Bool override)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ list = override;
+
+ xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_OVERRIDE_REDIRECT, &list);
+// ecore_x_flush();
+}
+
+/**
+ * @brief Show the cursor on a window of type Ecore_X_Window.
+ * @param win The window for which the cursor will be showed.
+ * @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE.
+ */
+EAPI void
+ecore_x_window_cursor_show(Ecore_X_Window win,
+ Eina_Bool show)
+{
+ uint32_t list = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ if (!show)
+ {
+ Ecore_X_Cursor cursor;
+ Ecore_X_Pixmap p, m;
+ Ecore_X_GC gc;
+ xcb_point_t point;
+
+ 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, 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,
+ 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,
+ 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, m);
+ xcb_free_pixmap(_ecore_xcb_conn, p);
+ }
+ else
+ {
+ xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_CURSOR, &list);
+ }
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_cursor_set(Ecore_X_Window win,
+ Ecore_X_Cursor cursor)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ list = cursor;
+
+ xcb_change_window_attributes(_ecore_xcb_conn, win, XCB_CW_CURSOR, &list);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_container_manage(Ecore_X_Window win)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ list = (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
+
+ xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_EVENT_MASK, &list);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_client_manage(Ecore_X_Window win)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE);
+#endif
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_sniff(Ecore_X_Window win)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ list = (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_PROPERTY_CHANGE);
+
+ xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_EVENT_MASK, &list);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_client_sniff(Ecore_X_Window win)
+{
+ uint32_t list;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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, EINA_TRUE);
+#endif
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_area_clear(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_clear_area(_ecore_xcb_conn, 0, win, x, y, w, h);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_area_expose(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_clear_area(_ecore_xcb_conn, 1, win, x, y, w, h);
+// ecore_x_flush();
+}
+
+EAPI void
+ecore_x_window_save_set_add(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, win);
+}
+
+EAPI void
+ecore_x_window_save_set_del(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, win);
+}
+
+/**
+ * gets the window that has focus.
+ * @return The window that has focus.
+ * @ingroup Ecore_X_Window_Focus_Functions
+ */
+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 focus = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+// if (!win) return ret;
+
+#ifdef ECORE_XCB_RENDER
+ /* grab the window's visual */
+ visual = _ecore_xcb_window_visual_get(win);
+
+ /* check if this visual supports alpha */
+ ret = _ecore_xcb_render_visual_supports_alpha(visual);
+#endif
+
+ 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__);
+ CHECK_XCB_CONN;
+
+ cookie = xcb_get_window_attributes(_ecore_xcb_conn, win);
+ reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply) return EINA_FALSE;
+
+ ecore_x_sync(); // needed
+
+ 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);
+
+ change_cookie = xcb_change_window_attributes(_ecore_xcb_conn, win,
+ XCB_CW_EVENT_MASK, &list);
+
+ ecore_x_sync(); // needed
+
+ err = xcb_request_check(_ecore_xcb_conn, change_cookie);
+ if (err)
+ {
+ _ecore_xcb_error_handle(err);
+ free(err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
+
+ if (reply->map_state != XCB_MAP_STATE_UNMAPPED)
+ att_ret->visible = EINA_TRUE;
+
+ if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
+ att_ret->viewable = EINA_TRUE;
+
+ if (reply->override_redirect)
+ att_ret->override = EINA_TRUE;
+
+ if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY)
+ att_ret->input_only = EINA_TRUE;
+
+ if (reply->save_under)
+ att_ret->save_under = EINA_TRUE;
+
+ 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 = _ecore_xcb_window_find_visual_by_id(reply->visual);
+
+ free(reply);
+
+ gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
+ greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL);
+ if (!greply) return EINA_TRUE;
+
+ /* xcb_translate_coordinates_reply_t *trans; */
+ /* xcb_query_tree_cookie_t tcookie; */
+ /* xcb_query_tree_reply_t *treply; */
+
+ /* tcookie = xcb_query_tree(_ecore_xcb_conn, win); */
+ /* treply = xcb_query_tree_reply(_ecore_xcb_conn, tcookie, NULL); */
+
+ /* 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;
+
+// free(trans);
+
+ free(greply);
+ return EINA_TRUE;
+}
+
+/**
+ * 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_window_size_get(Ecore_X_Window win,
+ int *width,
+ int *height)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+ ecore_x_drawable_geometry_get(win, NULL, NULL, width, height);
+}
+
+/**
+ * Set if a window should be ignored.
+ * @param win The given window.
+ * @param ignore if to ignore
+ */
+EAPI void
+ecore_x_window_ignore_set(Ecore_X_Window win,
+ int ignore)
+{
+ int i = 0, j = 0, count = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (ignore)
+ {
+ if (ignore_list)
+ {
+ for (i = 0; i < ignore_num; i++)
+ if (win == ignore_list[i]) return;
+
+ ignore_list =
+ realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
+ if (!ignore_list) 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;
+ }
+
+ ignore_list =
+ realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
+ }
+}
+
+/**
+ * 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (num) *num = ignore_num;
+ return ignore_list;
+}
+
+/**
+ * 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;
+ uint8_t i, num;
+ Ecore_X_Window *roots = NULL;
+#ifdef ECORE_XCB_XPRINT
+ const xcb_query_extension_reply_t *ext_reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!num_ret) return NULL;
+ if (num_ret) *num_ret = 0;
+
+ /* if (xcb_connection_has_error(_ecore_xcb_conn)) */
+ /* { */
+ /* DBG("XCB Connection Has Error !!!"); */
+ /* return NULL; */
+ /* } */
+
+ num = ecore_x_screen_count_get();
+
+#ifdef ECORE_XCB_XPRINT
+ ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id);
+ if ((ext_reply) && (ext_reply->present))
+ {
+ xcb_x_print_print_query_screens_cookie_t cookie;
+ xcb_x_print_print_query_screens_reply_t *reply;
+
+ cookie = xcb_x_print_print_query_screens_unchecked(_ecore_xcb_conn);
+ reply =
+ xcb_x_print_print_query_screens_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply)
+ {
+ xcb_window_t *screens;
+ int psnum = 0, overlap = 0, j = 0, k = 0;
+
+ psnum = xcb_x_print_print_query_screens_roots_length(reply);
+ screens = xcb_x_print_print_query_screens_roots(reply);
+ for (i = 0; i < num; i++)
+ {
+ for (j = 0; j < psnum; j++)
+ {
+ xcb_screen_t *s;
+
+ if ((s = _ecore_xcb_window_screen_of_display(i)))
+ {
+ if (s->root == screens[j])
+ overlap++;
+ }
+ }
+ }
+ if (!(roots = malloc((num - overlap)
+ * sizeof(Ecore_X_Window)))) return NULL;
+ for (i = 0; i < num; i++)
+ {
+ Eina_Bool is_print = EINA_FALSE;
+
+ for (j = 0; j < psnum; j++)
+ {
+ xcb_screen_t *s;
+
+ if ((s = _ecore_xcb_window_screen_of_display(i)))
+ {
+ if (s->root == screens[j])
+ {
+ is_print = EINA_TRUE;
+ break;
+ }
+ }
+ }
+ if (!is_print)
+ {
+ xcb_screen_t *s;
+
+ if ((s = _ecore_xcb_window_screen_of_display(i)))
+ {
+ roots[k] = s->root;
+ k++;
+ }
+ }
+ }
+ if (num_ret) *num_ret = k;
+ free(reply);
+ }
+ else
+ {
+ /* Fallback to default method */
+ iter =
+ xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
+ if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
+ if (num_ret) *num_ret = num;
+ for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
+ roots[i] = iter.data->root;
+ }
+ }
+ else
+ {
+ /* Fallback to default method */
+ iter =
+ xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
+ if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
+ if (num_ret) *num_ret = num;
+ for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
+ roots[i] = iter.data->root;
+ }
+#else
+ iter =
+ xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
+ if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
+ if (num_ret) *num_ret = num;
+ for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
+ roots[i] = iter.data->root;
+#endif
+
+ return roots;
+}
+
+EAPI Ecore_X_Window *
+ecore_x_window_children_get(Ecore_X_Window win,
+ int *num)
+{
+ xcb_query_tree_cookie_t cookie;
+ xcb_query_tree_reply_t *reply;
+ Ecore_X_Window *windows = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (num) *num = 0;
+ cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, win);
+ reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply) return NULL;
+
+ if (num) *num = reply->children_len;
+ if (reply->children_len > 0)
+ {
+ windows = malloc(sizeof(Ecore_X_Window) * reply->children_len);
+ if (windows)
+ {
+ unsigned int i = 0;
+ xcb_window_t *w;
+
+ w = xcb_query_tree_children(reply);
+ for (i = 0; i < reply->children_len; i++)
+ windows[i] = w[i];
+ }
+ }
+
+ free(reply);
+ return windows;
+}
+
+/**
+ * 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;
+
+ /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
+ CHECK_XCB_CONN;
+
+ 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;
+}
+
+EAPI Ecore_X_Window
+ecore_x_window_root_first_get(void)
+{
+ return ((xcb_screen_t *)_ecore_xcb_screen)->root;
+}
+
+/**
+ * Retrieves the geometry of the given window.
+ *
+ * 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__);
+ CHECK_XCB_CONN;
+
+ 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.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_get(int x,
+ int y)
+{
+ Ecore_X_Window root, win = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ ecore_x_grab();
+ win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
+ ecore_x_ungrab();
+
+ 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.
+ * @param skip The list of windows to be skipped.
+ * @param skip_num The number of windows to be skipped.
+ * @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)
+{
+ Ecore_X_Window root, win = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ ecore_x_grab();
+ win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
+ ecore_x_ungrab();
+
+ return win ? win : root;
+}
+
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,
+ int x,
+ int y)
+{
+ Ecore_X_Window win = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ ecore_x_grab();
+ win = _ecore_xcb_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
+ ecore_x_ungrab();
+
+ return win ? win : begin;
+}
+
+/**
+ * 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)
+{
+ xcb_query_tree_cookie_t cookie;
+ xcb_query_tree_reply_t *reply;
+ Ecore_X_Window window = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+// 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);
+
+ return window;
+}
+
+/**
+ * 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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 (reply->map_state == XCB_MAP_STATE_VIEWABLE)
+ ret = EINA_TRUE;
+
+ free(reply);
+ return ret;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ 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__);
+ CHECK_XCB_CONN;
+
+ 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__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ CHECK_XCB_CONN;
+ 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;
+#ifdef ECORE_XCB_RENDER
+ uint32_t value_list[10];
+ uint32_t value_mask;
+ uint32_t vis;
+ Ecore_X_Colormap colormap;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_RENDER
+ 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);
+
+ 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_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[8] = XCB_EVENT_MASK_NO_EVENT;
+ value_list[9] = colormap;
+
+ win = xcb_generate_id(_ecore_xcb_conn);
+ 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);
+#endif
+
+ return 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)
+{
+ 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+
+ for (i = (num - 1); i >= 0; --i)
+ {
+ skipit = EINA_FALSE;
+
+ if (skip)
+ {
+ int j = 0;
+
+ for (j = 0; j < skip_num; j++)
+ {
+ if (windows[i] == skip[j])
+ {
+ 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;
+ }
+ }
+ }
+
+ if (reply) free(reply);
+ return base;
+}
+
+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;
+
+ CHECK_XCB_CONN;
+
+ 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (_ecore_xcb_button_grabs_num > 0)
+ {
+ int i = 0, shuffle = 0;
+
+ for (i = 0; i < _ecore_xcb_button_grabs_num; i++)
+ {
+ if (shuffle)
+ _ecore_xcb_button_grabs[i - 1] = _ecore_xcb_button_grabs[i];
+
+ if ((!shuffle) && (_ecore_xcb_button_grabs[i] == win))
+ shuffle = 1;
+ }
+
+ if (shuffle)
+ {
+ 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;
+ }
+ }
+}
+
+void
+_ecore_xcb_window_key_grab_remove(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (_ecore_xcb_key_grabs_num > 0)
+ {
+ int i = 0, shuffle = 0;
+
+ for (i = 0; i < _ecore_xcb_key_grabs_num; i++)
+ {
+ if (shuffle)
+ _ecore_xcb_key_grabs[i - 1] = _ecore_xcb_key_grabs[i];
+
+ if ((!shuffle) && (_ecore_xcb_key_grabs[i] == win))
+ shuffle = 1;
+ }
+
+ if (shuffle)
+ {
+ Ecore_X_Window *t;
+
+ _ecore_xcb_key_grabs_num--;
+ if (_ecore_xcb_key_grabs_num <= 0)
+ {
+ free(_ecore_xcb_key_grabs);
+ _ecore_xcb_key_grabs = NULL;
+ return;
+ }
+
+ t = realloc(_ecore_xcb_key_grabs,
+ _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window));
+ if (!t) return;
+ _ecore_xcb_key_grabs = t;
+ }
+ }
+}
+
+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 i = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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;
+
+ 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;
+ }
+ }
+}
+
+static int
+_ecore_xcb_window_modifiers_get(unsigned int state)
+{
+ 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_MODIFIER_ALTGR)
+ xmodifiers |= ECORE_X_MODIFIER_ALTGR;
+ 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;
+
+ CHECK_XCB_CONN;
+ 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;
+}
+
+#ifdef ECORE_XCB_XPRINT
+static xcb_screen_t *
+_ecore_xcb_window_screen_of_display(int screen)
+{
+ xcb_screen_iterator_t iter;
+
+ CHECK_XCB_CONN;
+ iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
+ for (; iter.rem; --screen, xcb_screen_next(&iter))
+ if (screen == 0)
+ return iter.data;
+
+ return NULL;
+}
+
+#endif
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c b/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c
new file mode 100644
index 0000000000..e00fdc1963
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c
@@ -0,0 +1,720 @@
+#include "ecore_xcb_private.h"
+#include <xcb/xcb_icccm.h>
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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 != ECORE_X_ATOM_CARDINAL) || (reply->format != 32))
+ num = -1;
+ else if (reply->value_len == 0)
+ num = 0;
+ else
+ {
+ if (reply->value_len < len)
+ len = reply->value_len;
+
+ if (val)
+ {
+ unsigned int i = 0;
+ unsigned char *v;
+
+ v = xcb_get_property_value(reply);
+ for (i = 0; i < len; i++)
+ val[i] = ((uint32_t *)v)[i];
+ num = len;
+ }
+ }
+
+ if (reply) free(reply);
+ return num;
+}
+
+EAPI void
+ecore_x_window_prop_card32_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ unsigned int *val,
+ unsigned int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#else
+ long *v2;
+ unsigned int i;
+
+ v2 = malloc(num * sizeof(long));
+ if (!v2) return;
+ for (i = 0; i < num; i++)
+ v2[i] = val[i];
+
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom,
+ ECORE_X_ATOM_CARDINAL, 32, num, (unsigned char *)v2);
+ free(v2);
+// ecore_x_flush();
+#endif
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (list) *list = NULL;
+
+ 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;
+
+ 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)
+ {
+ unsigned int *val;
+ void *data;
+ int i = 0;
+
+ val = malloc(num * sizeof(unsigned int));
+ if (!val)
+ {
+ free(reply);
+ return -1;
+ }
+ data = xcb_get_property_value(reply);
+ for (i = 0; i < num; i++)
+ val[i] = ((uint32_t *)data)[i];
+ *list = val;
+ }
+ }
+
+ free(reply);
+ return num;
+}
+
+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__);
+
+ return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_ATOM, list, len);
+}
+
+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__);
+
+ /* 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);
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+#if SIZEOF_INT == SIZEOF_LONG
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom,
+ type, 32, num, (unsigned char *)xids);
+// ecore_x_flush();
+#else
+ long *v2;
+ unsigned int i;
+
+ v2 = malloc(num * sizeof(long));
+ if (!v2) return;
+ for (i = 0; i < num; i++)
+ v2[i] = xids[i];
+
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom,
+ type, 32, num, (unsigned char *)v2);
+ free(v2);
+// ecore_x_flush();
+#endif
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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);
+ 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] = ((uint32_t *)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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, type,
+ ECORE_X_ATOM_UTF8_STRING, 8, strlen(str), str);
+// ecore_x_flush();
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ 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);
+ 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);
+}
+
+EAPI void
+ecore_x_window_prop_window_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Window *list,
+ unsigned int num)
+{
+ 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)
+{
+ 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)
+{
+ return XCB_ATOM_ANY;
+}
+
+EAPI void
+ecore_x_window_prop_property_del(Ecore_X_Window win,
+ Ecore_X_Atom property)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ xcb_delete_property(_ecore_xcb_conn, win, property);
+}
+
+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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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);
+// ecore_x_flush();
+ }
+ else
+ {
+ uint32_t *dat;
+ int i = 0, *ptr;
+
+ dat = malloc(sizeof(uint32_t) * 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);
+// ecore_x_flush();
+ }
+ }
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (num) *num = 0;
+
+ if (data)
+ *data = NULL;
+ else
+ return 0;
+
+ if (win == 0)
+ win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ cookie =
+ xcb_get_property_unchecked(_ecore_xcb_conn, 0, win,
+ property, type, 0, UINT_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;
+ }
+
+ if (!(*data = malloc(reply->value_len * reply->format / 8)))
+ {
+ free(reply);
+ return 0;
+ }
+
+ 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] = ((uint32_t *)value)[i];
+ break;
+ }
+
+ if (num) *num = reply->value_len;
+ format = reply->format;
+ free(reply);
+ return format;
+}
+
+EAPI int
+ecore_x_window_prop_atom_list_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom **list)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_ATOM, list);
+}
+
+EAPI void
+ecore_x_window_prop_atom_list_change(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom item,
+ int op)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_xid_list_change(win, atom, ECORE_X_ATOM_ATOM, item, op);
+}
+
+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_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+ int num = -1;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (xids) *xids = 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;
+
+ 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;
+
+ for (i = 0; i < num; i++)
+ alst[i] = ((uint32_t *)val)[i];
+ *xids = alst;
+ }
+ }
+
+ 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)
+{
+ Ecore_X_ID *lst;
+ int i = 0, num = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst);
+ if (num < 0) return;
+
+ for (i = 0; i < num; i++)
+ {
+ if (lst[i] == item) break;
+ }
+
+ if (i < num)
+ {
+ 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);
+
+done:
+ if (lst) free(lst);
+}
+
+EAPI Eina_Bool
+ecore_x_window_prop_protocol_isset(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol)
+{
+ Eina_Bool ret = EINA_FALSE;
+ Ecore_X_Atom proto;
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_t protos;
+#else
+ xcb_icccm_get_wm_protocols_reply_t protos;
+#endif
+ xcb_get_property_cookie_t cookie;
+ uint8_t reply;
+ uint32_t count = 0, i = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE;
+
+ proto = _ecore_xcb_atoms_wm_protocol[protocol];
+#ifdef OLD_XCB_VERSION
+ 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);
+#else
+ cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win,
+ ECORE_X_ATOM_WM_PROTOCOLS);
+ reply = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie,
+ &protos, NULL);
+#endif
+ if (!reply) return EINA_FALSE;
+
+ count = protos.atoms_len;
+ for (i = 0; i < count; i++)
+ {
+ if (protos.atoms[i] == proto)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+ }
+
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_wipe(&protos);
+#else
+ xcb_icccm_get_wm_protocols_reply_wipe(&protos);
+#endif
+ return ret;
+}
+
+EAPI Ecore_X_WM_Protocol *
+ecore_x_window_prop_protocol_list_get(Ecore_X_Window win,
+ int *num_ret)
+{
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_t protos;
+#else
+ xcb_icccm_get_wm_protocols_reply_t protos;
+#endif
+ xcb_get_property_cookie_t cookie;
+ uint8_t reply;
+ uint32_t count = 0, i = 0;
+ Ecore_X_WM_Protocol *prot_ret = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!num_ret) return NULL;
+
+ *num_ret = 0;
+
+#ifdef OLD_XCB_VERSION
+ 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);
+#else
+ cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win,
+ ECORE_X_ATOM_WM_PROTOCOLS);
+ reply = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie,
+ &protos, NULL);
+#endif
+ if (!reply) return NULL;
+
+ count = protos.atoms_len;
+ if (count <= 0)
+ {
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_wipe(&protos);
+#else
+ xcb_icccm_get_wm_protocols_reply_wipe(&protos);
+#endif
+ return NULL;
+ }
+
+ prot_ret = calloc(1, count * sizeof(Ecore_X_WM_Protocol));
+ if (!prot_ret)
+ {
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_wipe(&protos);
+#else
+ xcb_icccm_get_wm_protocols_reply_wipe(&protos);
+#endif
+ return NULL;
+ }
+
+ 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++)
+ {
+ if (_ecore_xcb_atoms_wm_protocol[j] == protos.atoms[i])
+ prot_ret[i] = j;
+ }
+ }
+
+ if (num_ret) *num_ret = count;
+
+#ifdef OLD_XCB_VERSION
+ xcb_get_wm_protocols_reply_wipe(&protos);
+#else
+ xcb_icccm_get_wm_protocols_reply_wipe(&protos);
+#endif
+ return prot_ret;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ if (num) *num = 0;
+
+ cookie = xcb_list_properties_unchecked(_ecore_xcb_conn, win);
+ reply = xcb_list_properties_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply) return NULL;
+
+ atoms = (Ecore_X_Atom *)malloc(reply->atoms_len * sizeof(Ecore_X_Atom));
+ if (!atoms)
+ {
+ free(reply);
+ return NULL;
+ }
+
+ atm = xcb_list_properties_atoms(reply);
+ for (i = 0; i < reply->atoms_len; i++)
+ atoms[i] = atm[i];
+
+ if (num) *num = reply->atoms_len;
+ free(reply);
+
+ return atoms;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c b/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c
new file mode 100644
index 0000000000..d46e306c8d
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c
@@ -0,0 +1,410 @@
+#include "ecore_xcb_private.h"
+
+typedef struct _Shadow Shadow;
+struct _Shadow
+{
+ Shadow *parent, **children;
+ Ecore_X_Window win;
+ int children_num;
+ short x, y;
+ unsigned short w, h;
+};
+
+static Eina_Bool _inside_rects(Shadow *s,
+ int x,
+ int y,
+ int bx,
+ int by,
+ Ecore_X_Rectangle *rects,
+ int num);
+
+//static int shadow_count = 0;
+static Shadow **shadow_base = NULL;
+static int shadow_num = 0;
+
+/* FIXME: round trips */
+static Shadow *
+_ecore_x_window_tree_walk(Ecore_X_Window window)
+{
+ 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, j;
+
+ CHECK_XCB_CONN;
+
+ cookie_attr = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
+ reply_attr = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_attr, NULL);
+ if (!reply_attr) return NULL;
+ if (reply_attr->map_state != XCB_MAP_STATE_VIEWABLE)
+ {
+ free(reply_attr);
+ return NULL;
+ }
+
+ free(reply_attr);
+
+ 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 NULL;
+
+ if (!(s = calloc(1, sizeof(Shadow))))
+ {
+ free(reply_geom);
+ return NULL;
+ }
+
+ s->win = window;
+ s->x = reply_geom->x;
+ s->y = reply_geom->y;
+ s->w = reply_geom->width;
+ s->h = reply_geom->height;
+
+ 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)
+ {
+ xcb_window_t *list;
+ int num;
+
+ num = xcb_query_tree_children_length(reply_tree);
+ list = xcb_query_tree_children(reply_tree);
+
+ s->children = calloc(1, sizeof(Shadow *) * num);
+ if (s->children)
+ {
+ s->children_num = num;
+ for (i = 0; i < num; i++)
+ {
+ s->children[i] = _ecore_x_window_tree_walk(list[i]);
+ if (s->children[i])
+ s->children[i]->parent = s;
+ }
+ /* compress list down */
+ j = 0;
+ for (i = 0; i < num; i++)
+ {
+ if (s->children[i])
+ {
+ s->children[j] = s->children[i];
+ j++;
+ }
+ }
+ if (j == 0)
+ {
+ free(s->children);
+ s->children = NULL;
+ s->children_num = 0;
+ }
+ else
+ {
+ s->children_num = j;
+ sl = realloc(s->children, sizeof(Shadow *) * j);
+ if (sl) s->children = sl;
+ }
+ }
+
+ free(reply_tree);
+ }
+
+ return s;
+}
+
+static void
+_ecore_x_window_tree_shadow_free1(Shadow *s)
+{
+ 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]);
+ }
+ free(s->children);
+ }
+
+ free(s);
+}
+
+static void
+_ecore_x_window_tree_shadow_free(void)
+{
+ int i = 0;
+
+ if (!shadow_base) return;
+
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i]) continue;
+ _ecore_x_window_tree_shadow_free1(shadow_base[i]);
+ }
+ free(shadow_base);
+ shadow_base = NULL;
+ shadow_num = 0;
+}
+
+static void
+_ecore_x_window_tree_shadow_populate(void)
+{
+ Ecore_X_Window *roots = NULL;
+ int i = 0, num = 0;
+
+ 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]);
+ }
+
+ free(roots);
+ }
+}
+
+/*
+ static void
+ _ecore_x_window_tree_shadow_start(void)
+ {
+ shadow_count++;
+ if (shadow_count > 1) return;
+ _ecore_x_window_tree_shadow_populate();
+ }
+
+ static void
+ _ecore_x_window_tree_shadow_stop(void)
+ {
+ shadow_count--;
+ if (shadow_count != 0) return;
+ _ecore_x_window_tree_shadow_free();
+ }
+ */
+
+Shadow *
+_ecore_x_window_shadow_tree_find_shadow(Shadow *s,
+ Ecore_X_Window win)
+{
+ Shadow *ss;
+ int i = 0;
+
+ if (s->win == win) return s;
+
+ if (s->children)
+ {
+ for (i = 0; i < s->children_num; i++)
+ {
+ if (!s->children[i]) continue;
+
+ if ((ss =
+ _ecore_x_window_shadow_tree_find_shadow(s->children[i], win)))
+ return ss;
+ }
+ }
+
+ return NULL;
+}
+
+Shadow *
+_ecore_x_window_shadow_tree_find(Ecore_X_Window base)
+{
+ Shadow *s;
+ int i = 0;
+
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i]) continue;
+
+ if ((s =
+ _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], base)))
+ return s;
+ }
+ return NULL;
+}
+
+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 child;
+ Ecore_X_Rectangle *rects;
+ int i = 0, j = 0, wx = 0, wy = 0, num = 0;
+
+ wx = s->x + bx;
+ wy = s->y + by;
+ if (!((x >= wx) && (y >= wy) && (x < (wx + s->w)) && (y < (wy + s->h))))
+ return 0;
+
+ rects = ecore_x_window_shape_rectangles_get(s->win, &num);
+ if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0;
+ num = 0;
+ rects = ecore_x_window_shape_input_rectangles_get(s->win, &num);
+ if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0;
+
+ if (s->children)
+ {
+ int skipit = 0;
+
+ for (i = s->children_num - 1; i >= 0; --i)
+ {
+ if (!s->children[i]) continue;
+
+ skipit = 0;
+ if (skip)
+ {
+ for (j = 0; j < skip_num; j++)
+ {
+ if (s->children[i]->win == skip[j])
+ {
+ skipit = 1;
+ goto onward;
+ }
+ }
+ }
+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;
+ }
+ }
+ }
+
+ return s->win;
+}
+
+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)
+{
+ Shadow *s;
+
+ if (!shadow_base)
+ {
+ _ecore_x_window_tree_shadow_populate();
+ if (!shadow_base) return 0;
+ }
+
+ s = _ecore_x_window_shadow_tree_find(base);
+ if (!s) return 0;
+
+ return _ecore_x_window_shadow_tree_at_xy_get_shadow(s, bx, by, x, y, skip, skip_num);
+}
+
+static Eina_Bool
+_inside_rects(Shadow *s,
+ int x,
+ int y,
+ int bx,
+ int by,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+ Eina_Bool inside = EINA_FALSE;
+ int i = 0;
+
+ if (!rects) return EINA_FALSE;
+ for (i = 0; i < num; i++)
+ {
+ if ((x >= s->x + bx + rects[i].x) &&
+ (y >= s->y + by + rects[i].y) &&
+ (x < (int)(s->x + bx + rects[i].x + rects[i].width)) &&
+ (y < (int)(s->y + by + rects[i].y + rects[i].height)))
+ {
+ inside = EINA_TRUE;
+ break;
+ }
+ }
+ free(rects);
+ return inside;
+}
+
+/**
+ * Retrieves the top, visible window at the given location,
+ * but skips the windows in the list. This uses a shadow tree built from the
+ * window tree that is only updated the first time
+ * ecore_x_window_shadow_tree_at_xy_with_skip_get() is called, or the next time
+ * it is called after a ecore_x_window_shadow_tree_flush()
+ * @param base The base window to start searching from (normally root).
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @param skip The list of windows to be skipped.
+ * @param skip_num The number of windows to be skipped.
+ * @return The window at the desired position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+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);
+}
+
+/**
+ * Retrieves the parent window a given window has. This uses the shadow window
+ * tree.
+ * @param root The root window of @p win - if 0, this will be automatically determined with extra processing overhead
+ * @param win The window to get the parent window of
+ * @return The parent window of @p win
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_shadow_parent_get(Ecore_X_Window root EINA_UNUSED,
+ Ecore_X_Window win)
+{
+ Shadow *s;
+ int i = 0;
+
+ if (!shadow_base)
+ {
+ _ecore_x_window_tree_shadow_populate();
+ if (!shadow_base) return 0;
+ }
+
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i]) continue;
+
+ s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], win);
+ if (s)
+ {
+ if (!s->parent) return 0;
+ return s->parent->win;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Flushes the window shadow tree so nothing is stored.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_shadow_tree_flush(void)
+{
+ _ecore_x_window_tree_shadow_free();
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c b/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c
new file mode 100644
index 0000000000..6206a51833
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c
@@ -0,0 +1,790 @@
+#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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT,
+ win, 0, 0, mask);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING,
+ win, 0, 0, mask);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#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)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t rect;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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_SET,
+ XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
+ win, 0, 0, 1, &rect);
+// ecore_x_flush();
+#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)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t *rect = NULL;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!rects) return;
+
+#ifdef ECORE_XCB_SHAPE
+ if (num > 0)
+ {
+ int i = 0;
+
+ if (!(rect = malloc(sizeof(xcb_rectangle_t) * num)))
+ return;
+
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+ 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 *)rect);
+
+ if (rect) free(rect);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#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)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t rect;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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_UNION,
+ XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
+ win, 0, 0, 1, &rect);
+// ecore_x_flush();
+#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)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t rect;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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_SUBTRACT,
+ XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
+ win, 0, 0, 1, &rect);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#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)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t *rect = NULL;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_SHAPE
+ if (num > 0)
+ {
+ int i = 0;
+
+ if (!(rect = malloc(sizeof(xcb_rectangle_t) * num)))
+ return;
+
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+
+ 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 *)&rect);
+
+ if (rect) free(rect);
+// ecore_x_flush();
+#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;
+#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;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (num_ret) *num_ret = 0;
+
+#ifdef ECORE_XCB_SHAPE
+ 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__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_select_input(_ecore_xcb_conn, win, on);
+// ecore_x_flush();
+#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;
+#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;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (num_ret) *num_ret = 0;
+
+#ifdef ECORE_XCB_SHAPE
+ 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
+ xcb_get_geometry_cookie_t cookie;
+ xcb_get_geometry_reply_t *reply;
+
+ if (!(rects = malloc(sizeof(Ecore_X_Rectangle))))
+ return NULL;
+
+ /* get geometry */
+ cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
+ reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply)
+ {
+ rects[0].x = reply->x;
+ rects[0].y = reply->y;
+ rects[0].width = reply->width;
+ rects[0].height = reply->height;
+ free(reply);
+ }
+ if (num_ret) *num_ret = 1;
+ return rects;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t *rect = NULL;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!rects) return;
+
+#ifdef ECORE_XCB_SHAPE
+ if (num > 0)
+ {
+ int i = 0;
+
+ if (!(rect = malloc(sizeof(xcb_rectangle_t) * num)))
+ return;
+
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+ 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 *)rect);
+
+ if (rect) free(rect);
+// ecore_x_flush();
+#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)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t rect;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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_SUBTRACT,
+ XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED,
+ win, 0, 0, 1, &rect);
+// ecore_x_flush();
+#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)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t rect;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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_UNION,
+ XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED,
+ win, 0, 0, 1, &rect);
+// ecore_x_flush();
+#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)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t rect;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#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_SET,
+ XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED,
+ win, 0, 0, 1, &rect);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+#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);
+// ecore_x_flush();
+#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)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t *rect = NULL;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+#ifdef ECORE_XCB_SHAPE
+ if (num > 0)
+ {
+ int i = 0;
+
+ if (!(rect = malloc(sizeof(xcb_rectangle_t) * num)))
+ return;
+
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+
+ 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 *)&rect);
+
+ if (rect) free(rect);
+// ecore_x_flush();
+#else
+ return;
+ win = 0;
+ num = 0;
+ rects = NULL;
+#endif
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c b/src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c
new file mode 100644
index 0000000000..e0e56102e2
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c
@@ -0,0 +1,116 @@
+#include "ecore_xcb_private.h"
+#include <fnmatch.h>
+
+/* local function prototypes */
+static Eina_Bool _ecore_xcb_xdefaults_glob_match(const char *str,
+ const char *glob);
+
+/* local variables */
+static Eina_File *_ecore_xcb_xdefaults_file = NULL;
+static char *_ecore_xcb_xdefaults_data = NULL;
+
+void
+_ecore_xcb_xdefaults_init(void)
+{
+ char buff[PATH_MAX];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ snprintf(buff, sizeof(buff), "%s/.Xdefaults", getenv("HOME"));
+ if ((_ecore_xcb_xdefaults_file = eina_file_open(buff, EINA_FALSE)))
+ {
+ eina_mmap_safety_enabled_set(EINA_TRUE);
+
+ _ecore_xcb_xdefaults_data =
+ eina_file_map_all(_ecore_xcb_xdefaults_file, EINA_FILE_SEQUENTIAL);
+ }
+}
+
+void
+_ecore_xcb_xdefaults_shutdown(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!_ecore_xcb_xdefaults_file) return;
+ if (_ecore_xcb_xdefaults_data)
+ eina_file_map_free(_ecore_xcb_xdefaults_file, _ecore_xcb_xdefaults_data);
+ if (_ecore_xcb_xdefaults_file) eina_file_close(_ecore_xcb_xdefaults_file);
+}
+
+char *
+_ecore_xcb_xdefaults_string_get(const char *prog,
+ const char *param)
+{
+ char buff[1024], ret[1024];
+ char *str = NULL;
+ char **ea = NULL;
+ unsigned int count = 0, i = 0;
+
+ if ((!_ecore_xcb_xdefaults_data) || (!_ecore_xcb_xdefaults_file))
+ return NULL;
+
+ snprintf(buff, sizeof(buff), "*%s*.*%s*", prog, param);
+
+ str = _ecore_xcb_xdefaults_data;
+ ea = eina_str_split_full(str, "\n", -1, &count);
+ for (i = 0; i < count; i++)
+ {
+ if (_ecore_xcb_xdefaults_glob_match(ea[i], buff))
+ sscanf(ea[i], "%*[^:]:%*[ ]%s", ret);
+ }
+ if ((ea) && (ea[0]))
+ {
+ free(ea[0]);
+ free(ea);
+ }
+
+ return strdup(ret);
+}
+
+int
+_ecore_xcb_xdefaults_int_get(const char *prog,
+ const char *param)
+{
+ char buff[1024];
+ char *str = NULL;
+ char **ea = NULL;
+ unsigned int count = 0, i = 0;
+ int ret = -1;
+
+ if ((!_ecore_xcb_xdefaults_data) || (!_ecore_xcb_xdefaults_file))
+ return 0;
+
+ snprintf(buff, sizeof(buff), "*%s*.*%s*", prog, param);
+
+ str = _ecore_xcb_xdefaults_data;
+ ea = eina_str_split_full(str, "\n", -1, &count);
+ for (i = 0; i < count; i++)
+ {
+ if (_ecore_xcb_xdefaults_glob_match(ea[i], buff))
+ sscanf(ea[i], "%*[^:]:%*[ ]%d", &ret);
+ }
+ if ((ea) && (ea[0]))
+ {
+ free(ea[0]);
+ free(ea);
+ }
+
+ return ret;
+}
+
+/* local functions */
+static Eina_Bool
+_ecore_xcb_xdefaults_glob_match(const char *str,
+ const char *glob)
+{
+ if ((!str) || (!glob)) return EINA_FALSE;
+ if (glob[0] == 0)
+ {
+ if (str[0] == 0) return EINA_TRUE;
+ return EINA_FALSE;
+ }
+ if (!strcmp(glob, "*")) return EINA_TRUE;
+ if (!fnmatch(glob, str, 0)) return EINA_TRUE;
+ return EINA_FALSE;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c b/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c
new file mode 100644
index 0000000000..58444cdf1f
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c
@@ -0,0 +1,744 @@
+#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)
+ {
+ /* NB: XFixes Extension >= 3 needed for shape stuff.
+ * for now, I am removing this check so that it matches the
+ * xlib code closer. If the extension version ends up being
+ * that important, then re-enable this */
+
+ /* if (reply->major_version >= 3) */
+ _xfixes_avail = EINA_TRUE;
+ free(reply);
+ }
+
+ if (_xfixes_avail)
+ _ecore_xcb_event_xfixes = ext_reply->first_event;
+ }
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection)
+{
+#ifdef ECORE_XCB_XFIXES
+ Ecore_X_Window root = 0;
+ xcb_void_cookie_t cookie;
+ xcb_generic_error_t *err;
+ int mask = 0;
+#endif
+
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return EINA_FALSE;
+
+#ifdef ECORE_XCB_XFIXES
+ root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ mask = (XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
+ XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
+ XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE);
+
+ cookie =
+ xcb_xfixes_select_selection_input_checked(_ecore_xcb_conn, root,
+ selection, mask);
+ err = xcb_request_check(_ecore_xcb_conn, cookie);
+ if (err)
+ {
+ free(err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+#endif
+ return EINA_FALSE;
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return 0;
+
+#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);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return 0;
+
+#ifdef ECORE_XCB_XFIXES
+ region = xcb_generate_id(_ecore_xcb_conn);
+ xcb_xfixes_create_region_from_bitmap(_ecore_xcb_conn, region, bitmap);
+// ecore_x_flush();
+#endif
+
+ return region;
+}
+
+/**
+ * Create a region from a window.
+ * @param win 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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return 0;
+
+#ifdef ECORE_XCB_XFIXES
+ region = xcb_generate_id(_ecore_xcb_conn);
+ xcb_xfixes_create_region_from_window(_ecore_xcb_conn, region, win, type);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return 0;
+
+#ifdef ECORE_XCB_XFIXES
+ region = xcb_generate_id(_ecore_xcb_conn);
+ xcb_xfixes_create_region_from_gc(_ecore_xcb_conn, region, gc);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return 0;
+
+#ifdef ECORE_XCB_XFIXES
+ region = xcb_generate_id(_ecore_xcb_conn);
+ xcb_xfixes_create_region_from_picture(_ecore_xcb_conn, region, picture);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_destroy_region(_ecore_xcb_conn, region);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xrects = _ecore_xcb_rect_to_xcb(rects, num);
+ xcb_xfixes_set_region(_ecore_xcb_conn, region, num, xrects);
+ free(xrects);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+ // NB: Hmmmm...this may need converting to/fro xcb_rectangle_t
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_copy_region(_ecore_xcb_conn, source, dest);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_union_region(_ecore_xcb_conn, source1, source2, dest);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_intersect_region(_ecore_xcb_conn, source1, source2, dest);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_subtract_region(_ecore_xcb_conn, source1, source2, dest);
+// ecore_x_flush();
+#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;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xrects.x = bounds->x;
+ xrects.y = bounds->y;
+ xrects.width = bounds->width;
+ xrects.height = bounds->height;
+
+ xcb_xfixes_invert_region(_ecore_xcb_conn, source, xrects, dest);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_translate_region(_ecore_xcb_conn, region, dx, dy);
+// ecore_x_flush();
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_region_extents(_ecore_xcb_conn, source, dest);
+// ecore_x_flush();
+#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.
+ *
+ * @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__);
+ CHECK_XCB_CONN;
+
+ if (num) *num = 0;
+ if (bounds) *bounds = extents;
+ if (!_xfixes_avail) return NULL;
+
+#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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_expand_region(_ecore_xcb_conn, source, dest, left, right, top, bottom);
+// ecore_x_flush();
+#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 The horizontal translation.
+ * @param y 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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_set_gc_clip_region(_ecore_xcb_conn, gc, region, x, y);
+// ecore_x_flush();
+#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 The horizontal offset.
+ * @param y 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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_set_window_shape_region(_ecore_xcb_conn, dest, type, x, y, region);
+// ecore_x_flush();
+#endif
+}
+
+/**
+ * Change clip-mask in picture to the specified region.
+ * @param region The region.
+ * @param picture The picture.
+ * @param x The X coordinate of the origin.
+ * @param y 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__);
+ CHECK_XCB_CONN;
+
+ if (!_xfixes_avail) return;
+
+#ifdef ECORE_XCB_XFIXES
+ xcb_xfixes_set_picture_clip_region(_ecore_xcb_conn, picture, region, x, y);
+// ecore_x_flush();
+#endif
+}
+
+/* local function prototypes */
+static xcb_rectangle_t *
+_ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects,
+ int num)
+{
+ xcb_rectangle_t *xrect;
+ int i = 0;
+
+ if (!num) return NULL;
+
+ xrect = malloc(sizeof(xcb_rectangle_t) * num);
+ if (!xrect) return NULL;
+
+ for (i = 0; i < num; i++)
+ {
+ xrect[i].x = rects[i].x;
+ xrect[i].y = rects[i].y;
+ xrect[i].width = rects[i].width;
+ xrect[i].height = rects[i].height;
+ }
+
+ return xrect;
+}
+
+static Ecore_X_Rectangle *
+_ecore_xcb_rect_to_ecore(xcb_rectangle_t *rects,
+ int num)
+{
+ Ecore_X_Rectangle *erect;
+ int i = 0;
+
+ if (!num) return NULL;
+
+ erect = malloc(sizeof(Ecore_X_Rectangle) * num);
+ if (!erect) return NULL;
+
+ for (i = 0; i < num; i++)
+ {
+ erect[i].x = rects[i].x;
+ erect[i].y = rects[i].y;
+ erect[i].width = rects[i].width;
+ erect[i].height = rects[i].height;
+ }
+
+ return erect;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c b/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c
new file mode 100644
index 0000000000..37a2339e9b
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c
@@ -0,0 +1,139 @@
+#include "ecore_xcb_private.h"
+#ifdef ECORE_XCB_XINERAMA
+# include <xcb/xinerama.h>
+#endif
+
+/* local variables */
+static Eina_Bool _xinerama_avail = EINA_FALSE;
+static Eina_Bool _xinerama_active = EINA_FALSE;
+
+void
+_ecore_xcb_xinerama_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_XINERAMA
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xinerama_id);
+#endif
+}
+
+void
+_ecore_xcb_xinerama_finalize(void)
+{
+#ifdef ECORE_XCB_XINERAMA
+ const xcb_query_extension_reply_t *ext_reply;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_XINERAMA
+ ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xinerama_id);
+ if ((ext_reply) && (ext_reply->present))
+ {
+ 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);
+ }
+
+ 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
+}
+
+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__);
+ CHECK_XCB_CONN;
+
+ if (!_xinerama_avail) 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 0;
+ count = reply->number;
+#endif
+
+ return count;
+}
+
+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_query_screens_cookie_t cookie;
+ xcb_xinerama_query_screens_reply_t *reply;
+ xcb_xinerama_screen_info_t *info;
+#endif
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ CHECK_XCB_CONN;
+
+ 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 (!_xinerama_avail) return EINA_FALSE;
+
+#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;
+
+ info = xcb_xinerama_query_screens_screen_info(reply);
+ if (!info)
+ {
+ free(reply);
+ return EINA_FALSE;
+ }
+
+ 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;
+
+ free(reply);
+ return EINA_TRUE;
+#endif
+
+ return EINA_FALSE;
+}
+
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xtest.c b/src/lib/ecore_x/xcb/ecore_xcb_xtest.c
new file mode 100644
index 0000000000..7f76b2ccb5
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_xtest.c
@@ -0,0 +1,215 @@
+#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 EINA_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__);
+ CHECK_XCB_CONN;
+
+ 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 EINA_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__);
+ CHECK_XCB_CONN;
+
+ 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 EINA_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__);
+ CHECK_XCB_CONN;
+
+ 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;
+}
diff --git a/src/lib/ecore_x/xlib/ecore_x.c b/src/lib/ecore_x/xlib/ecore_x.c
new file mode 100644
index 0000000000..d9b81bc0f8
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x.c
@@ -0,0 +1,2242 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif !defined alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# elif !defined HAVE_ALLOCA
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+//#define LOGRT 1
+
+#ifdef LOGRT
+#include <dlfcn.h>
+#endif /* ifdef LOGRT */
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+#include "Ecore_Input.h"
+
+static Eina_Bool _ecore_x_fd_handler(void *data,
+ Ecore_Fd_Handler *fd_handler);
+static Eina_Bool _ecore_x_fd_handler_buf(void *data,
+ Ecore_Fd_Handler *fd_handler);
+static int _ecore_x_key_mask_get(KeySym sym);
+static int _ecore_x_event_modifier(unsigned int state);
+
+static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL;
+
+static const int AnyXEvent = 0; /* 0 can be used as there are no event types
+ * with index 0 and 1 as they are used for
+ * errors
+ */
+
+static int _ecore_x_event_shape_id = 0;
+static int _ecore_x_event_screensaver_id = 0;
+static int _ecore_x_event_sync_id = 0;
+int _ecore_xlib_log_dom = -1;
+
+#ifdef ECORE_XRANDR
+static int _ecore_x_event_randr_id = 0;
+#endif /* ifdef ECORE_XRANDR */
+#ifdef ECORE_XFIXES
+static int _ecore_x_event_fixes_selection_id = 0;
+#endif /* ifdef ECORE_XFIXES */
+#ifdef ECORE_XDAMAGE
+static int _ecore_x_event_damage_id = 0;
+#endif /* ifdef ECORE_XDAMAGE */
+#ifdef ECORE_XGESTURE
+static int _ecore_x_event_gesture_id = 0;
+#endif /* ifdef ECORE_XGESTURE */
+#ifdef ECORE_XKB
+static int _ecore_x_event_xkb_id = 0;
+#endif /* ifdef ECORE_XKB */
+static int _ecore_x_event_handlers_num = 0;
+static void (**_ecore_x_event_handlers) (XEvent * event) = NULL;
+
+static int _ecore_x_init_count = 0;
+static int _ecore_x_grab_count = 0;
+
+Display *_ecore_x_disp = NULL;
+double _ecore_x_double_click_time = 0.25;
+Time _ecore_x_event_last_time = 0;
+Window _ecore_x_event_last_win = 0;
+int _ecore_x_event_last_root_x = 0;
+int _ecore_x_event_last_root_y = 0;
+Eina_Bool _ecore_x_xcursor = EINA_FALSE;
+
+Ecore_X_Window _ecore_x_private_win = 0;
+
+Ecore_X_Atom _ecore_x_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_FIXES_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_GESTURE_NOTIFY_FLICK;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD;
+EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP;
+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_XKB_STATE_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0;
+
+
+EAPI int ECORE_X_EVENT_GENERIC = 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_MODIFIER_ALTGR = 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;
+
+EAPI int ECORE_X_RAW_BUTTON_PRESS = 0;
+EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0;
+EAPI int ECORE_X_RAW_MOTION = 0;
+
+#ifdef LOGRT
+static double t0 = 0.0;
+static Status (*_logrt_real_reply)(Display *disp,
+ void *rep,
+ int extra,
+ Bool discard) = NULL;
+static void
+_logrt_init(void)
+{
+ void *lib;
+
+ lib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
+ if (!lib)
+ lib = dlopen("libX11.so.6", RTLD_GLOBAL | RTLD_LAZY);
+
+ if (!lib)
+ lib = dlopen("libX11.so.6.3", RTLD_GLOBAL | RTLD_LAZY);
+
+ if (!lib)
+ lib = dlopen("libX11.so.6.3.0", RTLD_GLOBAL | RTLD_LAZY);
+
+ _logrt_real_reply = dlsym(lib, "_XReply");
+ t0 = ecore_time_get();
+}
+
+Status
+_XReply(Display *disp,
+ void *rep,
+ int extra,
+ Bool discard)
+{
+ void *bt[128];
+ int i, n;
+ char **sym;
+
+ n = backtrace(bt, 128);
+ if (n > 0)
+ {
+ sym = backtrace_symbols(bt, n);
+ printf("ROUNDTRIP: %4.4f :", ecore_time_get() - t0);
+ if (sym)
+ {
+ for (i = n - 1; i > 0; i--)
+ {
+ char *fname = strchr(sym[i], '(');
+ if (fname)
+ {
+ char *tsym = alloca(strlen(fname) + 1);
+ char *end;
+ strcpy(tsym, fname + 1);
+ end = strchr(tsym, '+');
+ if (end)
+ {
+ *end = 0;
+ printf("%s", tsym);
+ }
+ else
+ printf("???");
+ }
+ else
+ printf("???");
+
+ if (i > 1)
+ printf(" > ");
+ }
+ printf("\n");
+ }
+ }
+
+ // fixme: logme
+ return _logrt_real_reply(disp, rep, extra, discard);
+}
+
+#endif /* ifdef LOGRT */
+
+/* wrapper to use XkbKeycodeToKeysym when possible */
+KeySym
+_ecore_x_XKeycodeToKeysym(Display *display, KeyCode keycode, int idx)
+{
+#ifdef ECORE_XKB
+ return XkbKeycodeToKeysym(display, keycode, 0, idx);
+#else
+ return XKeycodeToKeysym(display, keycode, idx);
+#endif
+}
+
+void
+_ecore_x_modifiers_get(void)
+{
+ /* everything has these... unless its like a pda... :) */
+ ECORE_X_MODIFIER_SHIFT = _ecore_x_key_mask_get(XK_Shift_L);
+ ECORE_X_MODIFIER_CTRL = _ecore_x_key_mask_get(XK_Control_L);
+
+ /* apple's xdarwin has no alt!!!! */
+ ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Alt_L);
+ if (!ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Meta_L);
+
+ if (!ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Super_L);
+
+ /* the windows key... a valid modifier :) */
+ ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Super_L);
+ if (!ECORE_X_MODIFIER_WIN)
+ ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Meta_L);
+
+ ECORE_X_MODIFIER_ALTGR = _ecore_x_key_mask_get(XK_Mode_switch);
+
+ 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_x_key_mask_get(XK_Scroll_Lock);
+ ECORE_X_LOCK_NUM = _ecore_x_key_mask_get(XK_Num_Lock);
+ ECORE_X_LOCK_CAPS = _ecore_x_key_mask_get(XK_Caps_Lock);
+ ECORE_X_LOCK_SHIFT = _ecore_x_key_mask_get(XK_Shift_Lock);
+}
+
+/**
+ * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions
+ *
+ * Functions that start and shut down the Ecore X Library.
+ */
+
+/**
+ * Initialize the X display connection to the given display.
+ *
+ * @param name Display target name. If @c NULL, the default display is
+ * assumed.
+ * @return The number of times the library has been initialized without
+ * being shut down. 0 is returned if an error occurs.
+ * @ingroup Ecore_X_Init_Group
+ */
+EAPI int
+ecore_x_init(const char *name)
+{
+ int shape_base = 0;
+ int shape_err_base = 0;
+#ifdef ECORE_XSS
+ int screensaver_base = 0;
+ int screensaver_err_base = 0;
+#endif /* ifdef ECORE_XSS */
+ int sync_base = 0;
+ int sync_err_base = 0;
+#ifdef ECORE_XRANDR
+ int randr_base = 0;
+ int randr_err_base = 0;
+#endif /* ifdef ECORE_XRANDR */
+#ifdef ECORE_XFIXES
+ int fixes_base = 0;
+ int fixes_err_base = 0;
+#endif /* ifdef ECORE_XFIXES */
+#ifdef ECORE_XDAMAGE
+ int damage_base = 0;
+ int damage_err_base = 0;
+#endif /* ifdef ECORE_XDAMAGE */
+#ifdef ECORE_XGESTURE
+ int gesture_base = 0;
+ int gesture_err_base = 0;
+#endif /* ifdef ECORE_XGESTURE */
+#ifdef ECORE_XKB
+ int xkb_base = 0;
+#endif /* ifdef ECORE_XKB */
+ if (++_ecore_x_init_count != 1)
+ return _ecore_x_init_count;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+#ifdef LOGRT
+ _logrt_init();
+#endif /* ifdef LOGRT */
+
+ eina_init();
+ _ecore_xlib_log_dom = eina_log_domain_register
+ ("ecore_x", ECORE_XLIB_DEFAULT_LOG_COLOR);
+ if (_ecore_xlib_log_dom < 0)
+ {
+ EINA_LOG_ERR(
+ "Impossible to create a log domain for the Ecore Xlib module.");
+ return --_ecore_x_init_count;
+ }
+
+ if (!ecore_init())
+ goto shutdown_eina;
+ if (!ecore_event_init())
+ goto shutdown_ecore;
+
+#ifdef EVAS_FRAME_QUEUING
+ XInitThreads();
+#endif /* ifdef EVAS_FRAME_QUEUING */
+ _ecore_x_disp = XOpenDisplay((char *)name);
+ if (!_ecore_x_disp)
+ goto shutdown_ecore_event;
+
+ _ecore_x_error_handler_init();
+ _ecore_x_event_handlers_num = LASTEvent;
+
+#define ECORE_X_EVENT_HANDLERS_GROW(ext_base, ext_num_events) \
+ do { \
+ if (_ecore_x_event_handlers_num < (ext_base + ext_num_events)) { \
+ _ecore_x_event_handlers_num = (ext_base + ext_num_events); } \
+ } while (0)
+
+ if (XShapeQueryExtension(_ecore_x_disp, &shape_base, &shape_err_base))
+ _ecore_x_event_shape_id = shape_base;
+
+ ECORE_X_EVENT_HANDLERS_GROW(shape_base, ShapeNumberEvents);
+
+#ifdef ECORE_XSS
+ if (XScreenSaverQueryExtension(_ecore_x_disp, &screensaver_base,
+ &screensaver_err_base))
+ _ecore_x_event_screensaver_id = screensaver_base;
+
+ ECORE_X_EVENT_HANDLERS_GROW(screensaver_base, ScreenSaverNumberEvents);
+#endif /* ifdef ECORE_XSS */
+
+ if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base))
+ {
+ int major, minor;
+
+ _ecore_x_event_sync_id = sync_base;
+ if (!XSyncInitialize(_ecore_x_disp, &major, &minor))
+ _ecore_x_event_sync_id = 0;
+ }
+
+ ECORE_X_EVENT_HANDLERS_GROW(sync_base, XSyncNumberEvents);
+
+#ifdef ECORE_XRANDR
+ if (XRRQueryExtension(_ecore_x_disp, &randr_base, &randr_err_base))
+ _ecore_x_event_randr_id = randr_base;
+
+ ECORE_X_EVENT_HANDLERS_GROW(randr_base, RRNumberEvents);
+#endif /* ifdef ECORE_XRANDR */
+
+#ifdef ECORE_XFIXES
+ if (XFixesQueryExtension(_ecore_x_disp, &fixes_base, &fixes_err_base))
+ _ecore_x_event_fixes_selection_id = fixes_base;
+
+ ECORE_X_EVENT_HANDLERS_GROW(fixes_base, XFixesNumberEvents);
+#endif /* ifdef ECORE_XFIXES */
+
+#ifdef ECORE_XDAMAGE
+ if (XDamageQueryExtension(_ecore_x_disp, &damage_base, &damage_err_base))
+ _ecore_x_event_damage_id = damage_base;
+
+ ECORE_X_EVENT_HANDLERS_GROW(damage_base, XDamageNumberEvents);
+#endif /* ifdef ECORE_XDAMAGE */
+
+#ifdef ECORE_XGESTURE
+ if (XGestureQueryExtension(_ecore_x_disp, &gesture_base, &gesture_err_base))
+ _ecore_x_event_gesture_id = gesture_base;
+
+ ECORE_X_EVENT_HANDLERS_GROW(gesture_base, GestureNumberEvents);
+#endif /* ifdef ECORE_XGESTURE */
+#ifdef ECORE_XKB
+ {
+ int dummy;
+
+ if (XkbQueryExtension(_ecore_x_disp, &dummy, &xkb_base,
+ &dummy, &dummy, &dummy))
+ _ecore_x_event_xkb_id = xkb_base;
+ XkbSelectEventDetails(_ecore_x_disp, XkbUseCoreKbd, XkbStateNotify,
+ XkbAllStateComponentsMask, XkbGroupStateMask);
+ }
+ ECORE_X_EVENT_HANDLERS_GROW(xkb_base, XkbNumberEvents);
+#endif
+
+ _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *));
+ if (!_ecore_x_event_handlers)
+ goto close_display;
+
+#ifdef ECORE_XCURSOR
+ _ecore_x_xcursor = XcursorSupportsARGB(_ecore_x_disp) ? EINA_TRUE : EINA_FALSE;
+#endif /* ifdef ECORE_XCURSOR */
+ _ecore_x_event_handlers[AnyXEvent] = _ecore_x_event_handle_any_event;
+ _ecore_x_event_handlers[KeyPress] = _ecore_x_event_handle_key_press;
+ _ecore_x_event_handlers[KeyRelease] = _ecore_x_event_handle_key_release;
+ _ecore_x_event_handlers[ButtonPress] = _ecore_x_event_handle_button_press;
+ _ecore_x_event_handlers[ButtonRelease] =
+ _ecore_x_event_handle_button_release;
+ _ecore_x_event_handlers[MotionNotify] = _ecore_x_event_handle_motion_notify;
+ _ecore_x_event_handlers[EnterNotify] = _ecore_x_event_handle_enter_notify;
+ _ecore_x_event_handlers[LeaveNotify] = _ecore_x_event_handle_leave_notify;
+ _ecore_x_event_handlers[FocusIn] = _ecore_x_event_handle_focus_in;
+ _ecore_x_event_handlers[FocusOut] = _ecore_x_event_handle_focus_out;
+ _ecore_x_event_handlers[KeymapNotify] = _ecore_x_event_handle_keymap_notify;
+ _ecore_x_event_handlers[Expose] = _ecore_x_event_handle_expose;
+ _ecore_x_event_handlers[GraphicsExpose] =
+ _ecore_x_event_handle_graphics_expose;
+ _ecore_x_event_handlers[VisibilityNotify] =
+ _ecore_x_event_handle_visibility_notify;
+ _ecore_x_event_handlers[CreateNotify] = _ecore_x_event_handle_create_notify;
+ _ecore_x_event_handlers[DestroyNotify] =
+ _ecore_x_event_handle_destroy_notify;
+ _ecore_x_event_handlers[UnmapNotify] = _ecore_x_event_handle_unmap_notify;
+ _ecore_x_event_handlers[MapNotify] = _ecore_x_event_handle_map_notify;
+ _ecore_x_event_handlers[MapRequest] = _ecore_x_event_handle_map_request;
+ _ecore_x_event_handlers[ReparentNotify] =
+ _ecore_x_event_handle_reparent_notify;
+ _ecore_x_event_handlers[ConfigureNotify] =
+ _ecore_x_event_handle_configure_notify;
+ _ecore_x_event_handlers[ConfigureRequest] =
+ _ecore_x_event_handle_configure_request;
+ _ecore_x_event_handlers[GravityNotify] =
+ _ecore_x_event_handle_gravity_notify;
+ _ecore_x_event_handlers[ResizeRequest] =
+ _ecore_x_event_handle_resize_request;
+ _ecore_x_event_handlers[CirculateNotify] =
+ _ecore_x_event_handle_circulate_notify;
+ _ecore_x_event_handlers[CirculateRequest] =
+ _ecore_x_event_handle_circulate_request;
+ _ecore_x_event_handlers[PropertyNotify] =
+ _ecore_x_event_handle_property_notify;
+ _ecore_x_event_handlers[SelectionClear] =
+ _ecore_x_event_handle_selection_clear;
+ _ecore_x_event_handlers[SelectionRequest] =
+ _ecore_x_event_handle_selection_request;
+ _ecore_x_event_handlers[SelectionNotify] =
+ _ecore_x_event_handle_selection_notify;
+ _ecore_x_event_handlers[ColormapNotify] =
+ _ecore_x_event_handle_colormap_notify;
+ _ecore_x_event_handlers[ClientMessage] =
+ _ecore_x_event_handle_client_message;
+ _ecore_x_event_handlers[MappingNotify] =
+ _ecore_x_event_handle_mapping_notify;
+#ifdef GenericEvent
+ _ecore_x_event_handlers[GenericEvent] = _ecore_x_event_handle_generic_event;
+#endif /* ifdef GenericEvent */
+
+ if (_ecore_x_event_shape_id)
+ _ecore_x_event_handlers[_ecore_x_event_shape_id] =
+ _ecore_x_event_handle_shape_change;
+
+ if (_ecore_x_event_screensaver_id)
+ _ecore_x_event_handlers[_ecore_x_event_screensaver_id] =
+ _ecore_x_event_handle_screensaver_notify;
+
+ if (_ecore_x_event_sync_id)
+ {
+ _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncCounterNotify] =
+ _ecore_x_event_handle_sync_counter;
+ _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncAlarmNotify] =
+ _ecore_x_event_handle_sync_alarm;
+ }
+
+#ifdef ECORE_XRANDR
+ if (_ecore_x_event_randr_id)
+ {
+ _ecore_x_event_handlers[_ecore_x_event_randr_id +
+ RRScreenChangeNotify] =
+ _ecore_x_event_handle_randr_change;
+ _ecore_x_event_handlers[_ecore_x_event_randr_id +
+ RRNotify] = _ecore_x_event_handle_randr_notify;
+ }
+
+#endif /* ifdef ECORE_XRANDR */
+#ifdef ECORE_XFIXES
+ if (_ecore_x_event_fixes_selection_id)
+ _ecore_x_event_handlers[_ecore_x_event_fixes_selection_id] =
+ _ecore_x_event_handle_fixes_selection_notify;
+
+#endif /* ifdef ECORE_XFIXES */
+#ifdef ECORE_XDAMAGE
+ if (_ecore_x_event_damage_id)
+ _ecore_x_event_handlers[_ecore_x_event_damage_id] =
+ _ecore_x_event_handle_damage_notify;
+
+#endif /* ifdef ECORE_XDAMAGE */
+#ifdef ECORE_XKB
+ // set x autorepeat detection to on. that means instead of
+ // press-release-press-release-press-release
+ // you get
+ // press-press-press-press-press-release
+ do
+ {
+ Bool works = 0;
+ XkbSetDetectableAutoRepeat(_ecore_x_disp, 1, &works);
+ }
+ while (0);
+ if (_ecore_x_event_xkb_id)
+ _ecore_x_event_handlers[_ecore_x_event_xkb_id] = _ecore_x_event_handle_xkb;
+#endif /* ifdef ECORE_XKB */
+
+#ifdef ECORE_XGESTURE
+ if (_ecore_x_event_gesture_id)
+ {
+ _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyFlick] =
+ _ecore_x_event_handle_gesture_notify_flick;
+ _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyPan] =
+ _ecore_x_event_handle_gesture_notify_pan;
+ _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyPinchRotation] =
+ _ecore_x_event_handle_gesture_notify_pinchrotation;
+ _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyTap] =
+ _ecore_x_event_handle_gesture_notify_tap;
+ _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyTapNHold] =
+ _ecore_x_event_handle_gesture_notify_tapnhold;
+ _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyHold] =
+ _ecore_x_event_handle_gesture_notify_hold;
+ _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyGroup] =
+ _ecore_x_event_handle_gesture_notify_group;
+ }
+
+#endif /* ifdef ECORE_XGESTURE */
+
+ 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_GESTURE_NOTIFY_FLICK = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_PAN = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_TAP = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = ecore_event_type_new();
+ ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 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_XKB_STATE_NOTIFY = ecore_event_type_new();
+ ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new();
+
+ ECORE_X_EVENT_GENERIC = ecore_event_type_new();
+
+ ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new();
+ ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new();
+ ECORE_X_RAW_MOTION = ecore_event_type_new();
+ }
+
+ _ecore_x_modifiers_get();
+
+ _ecore_x_fd_handler_handle =
+ ecore_main_fd_handler_add(ConnectionNumber(_ecore_x_disp),
+ ECORE_FD_READ,
+ _ecore_x_fd_handler, _ecore_x_disp,
+ _ecore_x_fd_handler_buf, _ecore_x_disp);
+ if (!_ecore_x_fd_handler_handle)
+ goto free_event_handlers;
+
+ _ecore_x_atoms_init();
+
+ /* Set up the ICCCM hints */
+ ecore_x_icccm_init();
+
+ /* Set up the _NET_... hints */
+ ecore_x_netwm_init();
+
+ /* old e hints init */
+ ecore_x_e_init();
+
+ /* This is just to be anal about naming conventions */
+
+ _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] =
+ ECORE_X_ATOM_WM_DELETE_WINDOW;
+ _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] =
+ ECORE_X_ATOM_WM_TAKE_FOCUS;
+ _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] =
+ ECORE_X_ATOM_NET_WM_PING;
+ _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] =
+ ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+
+ _ecore_x_selection_data_init();
+ _ecore_x_dnd_init();
+ _ecore_x_fixes_init();
+ _ecore_x_damage_init();
+ _ecore_x_composite_init();
+ _ecore_x_dpms_init();
+ _ecore_x_randr_init();
+ _ecore_x_gesture_init();
+ _ecore_x_input_init();
+ _ecore_x_events_init();
+
+ _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456);
+
+ return _ecore_x_init_count;
+
+free_event_handlers:
+ free(_ecore_x_event_handlers);
+ _ecore_x_event_handlers = NULL;
+close_display:
+ XCloseDisplay(_ecore_x_disp);
+ _ecore_x_fd_handler_handle = NULL;
+ _ecore_x_disp = NULL;
+shutdown_ecore_event:
+ ecore_event_shutdown();
+shutdown_ecore:
+ ecore_shutdown();
+shutdown_eina:
+ eina_log_domain_unregister(_ecore_xlib_log_dom);
+ _ecore_xlib_log_dom = -1;
+ eina_shutdown();
+
+ return --_ecore_x_init_count;
+}
+
+static int
+_ecore_x_shutdown(int close_display)
+{
+ if (--_ecore_x_init_count != 0)
+ return _ecore_x_init_count;
+
+ if (!_ecore_x_disp)
+ return _ecore_x_init_count;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ecore_main_fd_handler_del(_ecore_x_fd_handler_handle);
+ if (close_display)
+ XCloseDisplay(_ecore_x_disp);
+ else
+ {
+ close(ConnectionNumber(_ecore_x_disp));
+ // FIXME: may have to clean up x display internal here
+// getting segv here? hmmm. odd. disable
+// XFree(_ecore_x_disp);
+ }
+
+ free(_ecore_x_event_handlers);
+ _ecore_x_fd_handler_handle = NULL;
+ _ecore_x_disp = NULL;
+ _ecore_x_event_handlers = NULL;
+ _ecore_x_events_shutdown();
+ _ecore_x_input_shutdown();
+ _ecore_x_selection_shutdown();
+ _ecore_x_dnd_shutdown();
+ ecore_x_netwm_shutdown();
+
+ ecore_event_shutdown();
+ ecore_shutdown();
+
+ eina_log_domain_unregister(_ecore_xlib_log_dom);
+ _ecore_xlib_log_dom = -1;
+ eina_shutdown();
+
+ return _ecore_x_init_count;
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * In shutting down the library, the X display connection is terminated
+ * and any event handlers for it are removed.
+ *
+ * @return The number of times the library has been initialized without
+ * being shut down. 0 is returned if an error occurs.
+ * @ingroup Ecore_X_Init_Group
+ */
+EAPI int
+ecore_x_shutdown(void)
+{
+ return _ecore_x_shutdown(1);
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * As ecore_x_shutdown, except do not close Display, only connection.
+ *
+ * @ingroup Ecore_X_Init_Group
+ */
+EAPI int
+ecore_x_disconnect(void)
+{
+ return _ecore_x_shutdown(0);
+}
+
+/**
+ * @defgroup Ecore_X_Display_Attr_Group X Display Attributes
+ *
+ * Functions that set and retrieve X display attributes.
+ */
+
+/**
+ * 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)
+{
+ return (Ecore_X_Display *)_ecore_x_disp;
+}
+
+/**
+ * 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 ConnectionNumber(_ecore_x_disp);
+}
+
+/**
+ * Retrieves the Ecore_X_Screen handle used for the current X connection.
+ * @return The current default screen.
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+EAPI Ecore_X_Screen *
+ecore_x_default_screen_get(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return (Ecore_X_Screen *)DefaultScreenOfDisplay(_ecore_x_disp);
+}
+
+/**
+ * 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)
+{
+ Screen *s = (Screen *)screen;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (w) *w = 0;
+ if (h) *h = 0;
+ if (!s) return;
+ if (w) *w = s->width;
+ if (h) *h = s->height;
+}
+
+/**
+ * Retrieves the number of screens.
+ *
+ * @return The count of the number of screens.
+ * @ingroup Ecore_X_Display_Attr_Group
+ *
+ * @since 1.1
+ */
+EAPI int
+ecore_x_screen_count_get(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ return ScreenCount(_ecore_x_disp);
+}
+
+/**
+ * Retrieves the index number of the given screen.
+ *
+ * @param screen The screen for which the index will be retrieved.
+ * @return The index number of the screen.
+ * @ingroup Ecore_X_Display_Attr_Group
+ *
+ * @since 1.1
+ */
+EAPI int
+ecore_x_screen_index_get(const Ecore_X_Screen *screen)
+{
+ return XScreenNumberOfScreen((Screen *)screen);
+}
+
+/**
+ * Retrieves the screen based on index number.
+ *
+ * @param idx The index that will be used to retrieve the screen.
+ * @return The Ecore_X_Screen at this index.
+ * @ingroup Ecore_X_Display_Attr_Group
+ *
+ * @since 1.1
+ */
+EAPI Ecore_X_Screen *
+ecore_x_screen_get(int idx)
+{
+ return XScreenOfDisplay(_ecore_x_disp, idx);
+}
+
+/**
+ * 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)
+{
+ if (t < 0.0)
+ t = 0.0;
+
+ _ecore_x_double_click_time = t;
+}
+
+/**
+ * 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_x_double_click_time;
+}
+
+/**
+ * @defgroup Ecore_X_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.
+ */
+
+/**
+ * Sends all X commands in the X Display buffer.
+ * @ingroup Ecore_X_Flush_Group
+ */
+EAPI void
+ecore_x_flush(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFlush(_ecore_x_disp);
+}
+
+/**
+ * Flushes the command buffer and waits until all requests have been
+ * processed by the server.
+ * @ingroup Ecore_X_Flush_Group
+ */
+EAPI void
+ecore_x_sync(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSync(_ecore_x_disp, False);
+}
+
+/**
+ * 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)
+{
+ unsigned int j;
+ Window root_r;
+ Window parent_r;
+ Window *children_r = NULL;
+ unsigned int num_children = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGrabServer(_ecore_x_disp);
+ /* Tranverse window tree starting from root, and drag each
+ * before the firing squad */
+ while (XQueryTree(_ecore_x_disp, root, &root_r, &parent_r,
+ &children_r, &num_children) && (num_children > 0))
+ {
+ for (j = 0; j < num_children; ++j)
+ {
+ XKillClient(_ecore_x_disp, children_r[j]);
+ }
+
+ XFree(children_r);
+ }
+ XUngrabServer(_ecore_x_disp);
+ XSync(_ecore_x_disp, False);
+}
+
+/**
+ * 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XKillClient(_ecore_x_disp, win);
+}
+
+/**
+ * Return the last event time
+ */
+EAPI Ecore_X_Time
+ecore_x_current_time_get(void)
+{
+ return _ecore_x_event_last_time;
+}
+
+/**
+ * Return the screen DPI
+ *
+ * This is a simplistic call to get DPI. It does not account for differing
+ * DPI in the x amd y axes nor does it account for multihead or xinerama and
+ * xrander where different parts of the screen may have different DPI etc.
+ *
+ * @return the general screen DPI (dots/pixels per inch).
+ */
+EAPI int
+ecore_x_dpi_get(void)
+{
+ Screen *s;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ s = DefaultScreenOfDisplay(_ecore_x_disp);
+ if (s->mwidth <= 0)
+ return 75;
+
+ return (((s->width * 254) / s->mwidth) + 5) / 10;
+}
+
+/**
+ * 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 @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_bell(int percent)
+{
+ int ret;
+
+ ret = XBell(_ecore_x_disp, percent);
+ if (ret == BadValue)
+ return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecore_x_fd_handler(void *data,
+ Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+ Display *d;
+
+ d = data;
+ while (XPending(d))
+ {
+ XEvent ev;
+
+ XNextEvent(d, &ev);
+#ifdef ENABLE_XIM
+ /* Filter event for XIM */
+ if (XFilterEvent(&ev, ev.xkey.window))
+ continue;
+
+#endif /* ifdef ENABLE_XIM */
+ if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num))
+ {
+ if (_ecore_x_event_handlers[AnyXEvent])
+ _ecore_x_event_handlers[AnyXEvent] (&ev);
+
+ if (_ecore_x_event_handlers[ev.type])
+ _ecore_x_event_handlers[ev.type] (&ev);
+ }
+ }
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_ecore_x_fd_handler_buf(void *data,
+ Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+ Display *d;
+
+ d = data;
+ if (XPending(d))
+ return ECORE_CALLBACK_RENEW;
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static int
+_ecore_x_key_mask_get(KeySym sym)
+{
+ XModifierKeymap *mod;
+ KeySym sym2;
+ int i, j;
+ const int masks[8] =
+ {
+ ShiftMask, LockMask, ControlMask,
+ Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
+ };
+
+ mod = XGetModifierMapping(_ecore_x_disp);
+ if ((mod) && (mod->max_keypermod > 0))
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ sym2 = _ecore_x_XKeycodeToKeysym(_ecore_x_disp,
+ mod->modifiermap[i], j);
+ if (sym2 != 0)
+ break;
+ }
+ if (sym2 == sym)
+ {
+ int mask;
+
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+
+ XFree(mod);
+ return mask;
+ }
+ }
+
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+
+ XFree(mod);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+/* FIXME: these funcs need categorising */
+/*****************************************************************************/
+
+/**
+ * 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)
+{
+ int num, i;
+ Ecore_X_Window *roots;
+#ifdef ECORE_XPRINT
+ int xp_base, xp_err_base;
+#endif /* ifdef ECORE_XPRINT */
+
+ if (!num_ret)
+ return NULL;
+
+ *num_ret = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+#ifdef ECORE_XPRINT
+ num = ScreenCount(_ecore_x_disp);
+ if (XpQueryExtension(_ecore_x_disp, &xp_base, &xp_err_base))
+ {
+ Screen **ps = NULL;
+ int psnum = 0;
+
+ ps = XpQueryScreens(_ecore_x_disp, &psnum);
+ if (ps)
+ {
+ int overlap, j;
+
+ overlap = 0;
+ for (i = 0; i < num; i++)
+ {
+ for (j = 0; j < psnum; j++)
+ {
+ if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
+ overlap++;
+ }
+ }
+ roots = malloc(MAX((num - overlap) * sizeof(Window), 1));
+ 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_x_disp, i) == ps[j])
+ {
+ is_print = 1;
+ break;
+ }
+ }
+ if (!is_print)
+ {
+ roots[k] = RootWindow(_ecore_x_disp, i);
+ k++;
+ }
+ }
+ *num_ret = k;
+ }
+
+ XFree(ps);
+ }
+ else
+ {
+ roots = malloc(num * sizeof(Window));
+ if (!roots)
+ return NULL;
+
+ *num_ret = num;
+ for (i = 0; i < num; i++)
+ roots[i] = RootWindow(_ecore_x_disp, i);
+ }
+ }
+ else
+ {
+ roots = malloc(num * sizeof(Window));
+ if (!roots)
+ return NULL;
+
+ *num_ret = num;
+ for (i = 0; i < num; i++)
+ roots[i] = RootWindow(_ecore_x_disp, i);
+ }
+
+#else /* ifdef ECORE_XPRINT */
+ num = ScreenCount(_ecore_x_disp);
+ roots = malloc(num * sizeof(Window));
+ if (!roots)
+ return NULL;
+
+ *num_ret = num;
+ for (i = 0; i < num; i++)
+ roots[i] = RootWindow(_ecore_x_disp, i);
+#endif /* ifdef ECORE_XPRINT */
+ return roots;
+}
+
+EAPI Ecore_X_Window
+ecore_x_window_root_first_get(void)
+{
+ return RootWindow(_ecore_x_disp, 0);
+/*
+ int num;
+ Ecore_X_Window root, *roots = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ roots = ecore_x_window_root_list(&num);
+ if (!(roots)) return 0;
+
+ if (num > 0)
+ root = roots[0];
+ else
+ root = 0;
+
+ free(roots);
+ return root;
+ */
+}
+
+static void _ecore_x_window_manage_error(void *data);
+
+static int _ecore_x_window_manage_failed = 0;
+static void
+_ecore_x_window_manage_error(void *data EINA_UNUSED)
+{
+ if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) &&
+ (ecore_x_error_code_get() == BadAccess))
+ _ecore_x_window_manage_failed = 1;
+}
+
+EAPI Eina_Bool
+ecore_x_window_manage(Ecore_X_Window win)
+{
+ XWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True)
+ return EINA_FALSE;
+
+ ecore_x_sync();
+ _ecore_x_window_manage_failed = 0;
+ ecore_x_error_handler_set(_ecore_x_window_manage_error, NULL);
+ XSelectInput(_ecore_x_disp, win,
+ EnterWindowMask |
+ LeaveWindowMask |
+ PropertyChangeMask |
+ ResizeRedirectMask |
+ SubstructureRedirectMask |
+ SubstructureNotifyMask |
+ StructureNotifyMask |
+ KeyPressMask |
+ KeyReleaseMask |
+ att.your_event_mask);
+ ecore_x_sync();
+ ecore_x_error_handler_set(NULL, NULL);
+ if (_ecore_x_window_manage_failed)
+ {
+ _ecore_x_window_manage_failed = 0;
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_window_container_manage(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSelectInput(_ecore_x_disp, win,
+ SubstructureRedirectMask |
+ SubstructureNotifyMask);
+}
+
+EAPI void
+ecore_x_window_client_manage(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSelectInput(_ecore_x_disp, win,
+ PropertyChangeMask |
+// ResizeRedirectMask |
+ FocusChangeMask |
+ ColormapChangeMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ SubstructureNotifyMask
+ );
+ XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
+}
+
+EAPI void
+ecore_x_window_sniff(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSelectInput(_ecore_x_disp, win,
+ PropertyChangeMask |
+ SubstructureNotifyMask);
+}
+
+EAPI void
+ecore_x_window_client_sniff(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSelectInput(_ecore_x_disp, win,
+ PropertyChangeMask |
+ FocusChangeMask |
+ ColormapChangeMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ SubstructureNotifyMask);
+ XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
+}
+
+EAPI Eina_Bool
+ecore_x_window_attributes_get(Ecore_X_Window win,
+ Ecore_X_Window_Attributes *att_ret)
+{
+ XWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWindowAttributes(_ecore_x_disp, win, &att))
+ return EINA_FALSE;
+
+ memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
+ att_ret->root = att.root;
+ att_ret->x = att.x;
+ att_ret->y = att.y;
+ att_ret->w = att.width;
+ att_ret->h = att.height;
+ att_ret->border = att.border_width;
+ att_ret->depth = att.depth;
+ if (att.map_state != IsUnmapped)
+ att_ret->visible = 1;
+
+ if (att.map_state == IsViewable)
+ att_ret->viewable = 1;
+
+ if (att.override_redirect)
+ att_ret->override = 1;
+
+ if (att.class == InputOnly)
+ att_ret->input_only = 1;
+
+ if (att.save_under)
+ att_ret->save_under = 1;
+
+ att_ret->event_mask.mine = att.your_event_mask;
+ att_ret->event_mask.all = att.all_event_masks;
+ att_ret->event_mask.no_propagate = att.do_not_propagate_mask;
+ att_ret->window_gravity = att.win_gravity;
+ att_ret->pixel_gravity = att.bit_gravity;
+ att_ret->colormap = att.colormap;
+ att_ret->visual = att.visual;
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_window_save_set_add(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XAddToSaveSet(_ecore_x_disp, win);
+}
+
+EAPI void
+ecore_x_window_save_set_del(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XRemoveFromSaveSet(_ecore_x_disp, win);
+}
+
+EAPI Ecore_X_Window *
+ecore_x_window_children_get(Ecore_X_Window win,
+ int *num)
+{
+ Ecore_X_Window *windows = NULL;
+ Window root_ret = 0, parent_ret = 0, *children_ret = NULL;
+ unsigned int children_ret_num = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XQueryTree(_ecore_x_disp, win, &root_ret, &parent_ret, &children_ret,
+ &children_ret_num))
+ return NULL;
+
+ if (children_ret)
+ {
+ windows = malloc(children_ret_num * sizeof(Ecore_X_Window));
+ if (windows)
+ {
+ unsigned int i;
+
+ for (i = 0; i < children_ret_num; i++)
+ windows[i] = children_ret[i];
+ *num = children_ret_num;
+ }
+
+ XFree(children_ret);
+ }
+
+ return windows;
+}
+
+EAPI Eina_Bool
+ecore_x_pointer_control_set(int accel_num,
+ int accel_denom,
+ int threshold)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XChangePointerControl(_ecore_x_disp, 1, 1,
+ accel_num, accel_denom, threshold) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_pointer_control_get(int *accel_num,
+ int *accel_denom,
+ int *threshold)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XGetPointerControl(_ecore_x_disp,
+ accel_num, accel_denom, threshold) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_pointer_mapping_set(unsigned char *map,
+ int nmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return (XSetPointerMapping(_ecore_x_disp, map, nmap) == MappingSuccess) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_pointer_mapping_get(unsigned char *map,
+ int nmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XGetPointerMapping(_ecore_x_disp, map, nmap) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_pointer_grab(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGrabPointer(_ecore_x_disp, win, False,
+ ButtonPressMask | ButtonReleaseMask |
+ EnterWindowMask | LeaveWindowMask | PointerMotionMask,
+ GrabModeAsync, GrabModeAsync,
+ None, None, CurrentTime) == GrabSuccess)
+ return EINA_TRUE;
+
+ return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_pointer_confine_grab(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGrabPointer(_ecore_x_disp, win, False,
+ ButtonPressMask | ButtonReleaseMask |
+ EnterWindowMask | LeaveWindowMask | PointerMotionMask,
+ GrabModeAsync, GrabModeAsync,
+ win, None, CurrentTime) == GrabSuccess)
+ return EINA_TRUE;
+
+ return EINA_FALSE;
+}
+
+EAPI void
+ecore_x_pointer_ungrab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XUngrabPointer(_ecore_x_disp, CurrentTime);
+}
+
+EAPI Eina_Bool
+ecore_x_pointer_warp(Ecore_X_Window win,
+ int x,
+ int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XWarpPointer(_ecore_x_disp, None, win, 0, 0, 0, 0, x, y) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_keyboard_grab(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGrabKeyboard(_ecore_x_disp, win, False,
+ GrabModeAsync, GrabModeAsync,
+ CurrentTime) == GrabSuccess)
+ return EINA_TRUE;
+
+ return EINA_FALSE;
+}
+
+EAPI void
+ecore_x_keyboard_ungrab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XUngrabKeyboard(_ecore_x_disp, CurrentTime);
+}
+
+EAPI void
+ecore_x_grab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_grab_count++;
+ if (_ecore_x_grab_count == 1)
+ XGrabServer(_ecore_x_disp);
+}
+
+EAPI void
+ecore_x_ungrab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_grab_count--;
+ if (_ecore_x_grab_count < 0)
+ _ecore_x_grab_count = 0;
+
+ if (_ecore_x_grab_count == 0)
+ XUngrabServer(_ecore_x_disp);
+}
+
+int _ecore_window_grabs_num = 0;
+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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_window_grab_replay_func = func;
+ _ecore_window_grab_replay_data = data;
+}
+
+EAPI void
+ecore_x_window_button_grab(Ecore_X_Window win,
+ int button,
+ Ecore_X_Event_Mask event_mask,
+ int mod,
+ int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i, ev;
+ Window *t;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ b = button;
+ if (b == 0)
+ b = AnyButton;
+
+ m = _ecore_x_event_modifier(mod);
+ if (any_mod)
+ m = AnyModifier;
+
+ 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++)
+ XGrabButton(_ecore_x_disp, b, m | locks[i],
+ win, False, ev, GrabModeSync, GrabModeAsync, None, None);
+ _ecore_window_grabs_num++;
+ t = realloc(_ecore_window_grabs,
+ _ecore_window_grabs_num * sizeof(Window));
+ if (!t) return;
+ _ecore_window_grabs = t;
+ _ecore_window_grabs[_ecore_window_grabs_num - 1] = win;
+}
+
+void
+_ecore_x_sync_magic_send(int val,
+ Ecore_X_Window swin)
+{
+ XEvent xev;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = _ecore_x_private_win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = 27777;
+ xev.xclient.data.l[0] = 0x7162534;
+ xev.xclient.data.l[1] = 0x10000000 + val;
+ xev.xclient.data.l[2] = swin;
+ XSendEvent(_ecore_x_disp, _ecore_x_private_win, False, NoEventMask, &xev);
+}
+
+void
+_ecore_x_window_grab_remove(Ecore_X_Window win)
+{
+ int i, shuffle = 0;
+ Window *t;
+
+ 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 ((!shuffle) && (_ecore_window_grabs[i] == win))
+ shuffle = 1;
+ }
+ if (shuffle)
+ {
+ _ecore_window_grabs_num--;
+ if (_ecore_window_grabs_num <= 0)
+ {
+ free(_ecore_window_grabs);
+ _ecore_window_grabs = NULL;
+ return;
+ }
+ t = realloc(_ecore_window_grabs,
+ _ecore_window_grabs_num *
+ sizeof(Window));
+ if (!t) return;
+ _ecore_window_grabs = t;
+ }
+ }
+}
+
+EAPI void
+ecore_x_window_button_ungrab(Ecore_X_Window win,
+ int button,
+ int mod,
+ int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ b = button;
+ if (b == 0)
+ b = AnyButton;
+
+ m = _ecore_x_event_modifier(mod);
+ if (any_mod)
+ m = AnyModifier;
+
+ 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++)
+ XUngrabButton(_ecore_x_disp, b, m | locks[i], win);
+ _ecore_x_sync_magic_send(1, win);
+}
+
+int _ecore_key_grabs_num = 0;
+Window *_ecore_key_grabs = NULL;
+
+EAPI void
+ecore_x_window_key_grab(Ecore_X_Window win,
+ const char *key,
+ int mod,
+ int any_mod)
+{
+ KeyCode keycode = 0;
+ KeySym keysym;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+ Window *t;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol)
+ return;
+
+ keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
+ }
+
+ if (keycode == 0)
+ return;
+
+ m = _ecore_x_event_modifier(mod);
+ if (any_mod)
+ m = AnyModifier;
+
+ 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++)
+ XGrabKey(_ecore_x_disp, keycode, m | locks[i],
+ win, False, GrabModeSync, GrabModeAsync);
+ _ecore_key_grabs_num++;
+ t = realloc(_ecore_key_grabs,
+ _ecore_key_grabs_num * sizeof(Window));
+ if (!t) return;
+ _ecore_key_grabs = t;
+ _ecore_key_grabs[_ecore_key_grabs_num - 1] = win;
+}
+
+void
+_ecore_x_key_grab_remove(Ecore_X_Window win)
+{
+ int i, shuffle = 0;
+ Window *t;
+
+ if (_ecore_key_grabs_num > 0)
+ {
+ for (i = 0; i < _ecore_key_grabs_num; i++)
+ {
+ if (shuffle)
+ _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
+
+ if ((!shuffle) && (_ecore_key_grabs[i] == win))
+ shuffle = 1;
+ }
+ if (shuffle)
+ {
+ _ecore_key_grabs_num--;
+ if (_ecore_key_grabs_num <= 0)
+ {
+ free(_ecore_key_grabs);
+ _ecore_key_grabs = NULL;
+ return;
+ }
+ t = realloc(_ecore_key_grabs,
+ _ecore_key_grabs_num * sizeof(Window));
+ if (!t) return;
+ _ecore_key_grabs = t;
+ }
+ }
+}
+
+EAPI void
+ecore_x_window_key_ungrab(Ecore_X_Window win,
+ const char *key,
+ int mod,
+ int any_mod)
+{
+ KeyCode keycode = 0;
+ KeySym keysym;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol)
+ return;
+
+ keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
+ }
+
+ if (keycode == 0)
+ return;
+
+ m = _ecore_x_event_modifier(mod);
+ if (any_mod)
+ m = AnyModifier;
+
+ 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++)
+ XUngrabKey(_ecore_x_disp, keycode, m | locks[i], win);
+ _ecore_x_sync_magic_send(2, win);
+}
+
+/**
+ * Send client message with given type and format 32.
+ *
+ * @param win The window the message is sent to.
+ * @param type The client message type.
+ * @param mask The mask of the message to be sent.
+ * @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
+ *
+ * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
+ */
+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)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.window = win;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.message_type = type;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = d0;
+ xev.xclient.data.l[1] = d1;
+ xev.xclient.data.l[2] = d2;
+ xev.xclient.data.l[3] = d3;
+ xev.xclient.data.l[4] = d4;
+
+ return XSendEvent(_ecore_x_disp, win, False, mask, &xev) ? EINA_TRUE : EINA_FALSE;
+}
+
+/**
+ * Send client message with given type and format 8.
+ *
+ * @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 @c 20.
+ *
+ * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_client_message8_send(Ecore_X_Window win,
+ Ecore_X_Atom type,
+ const void *data,
+ int len)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.window = win;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.message_type = type;
+ xev.xclient.format = 8;
+ if (len > 20)
+ len = 20;
+
+ memcpy(xev.xclient.data.b, data, len);
+ memset(xev.xclient.data.b + len, 0, 20 - len);
+
+ return XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_move_send(Ecore_X_Window win,
+ int x,
+ int y)
+{
+ XEvent xev;
+ XWindowAttributes att;
+ Window tw;
+ int rx, ry;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetWindowAttributes(_ecore_x_disp, win, &att);
+ XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
+ xev.xmotion.type = MotionNotify;
+ xev.xmotion.window = win;
+ xev.xmotion.root = att.root;
+ xev.xmotion.subwindow = win;
+ xev.xmotion.time = _ecore_x_event_last_time;
+ xev.xmotion.x = x;
+ xev.xmotion.y = y;
+ xev.xmotion.x_root = rx;
+ xev.xmotion.y_root = ry;
+ xev.xmotion.state = 0;
+ xev.xmotion.is_hint = 0;
+ xev.xmotion.same_screen = 1;
+ return XSendEvent(_ecore_x_disp, win, True, PointerMotionMask, &xev) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_down_send(Ecore_X_Window win,
+ int x,
+ int y,
+ int b)
+{
+ XEvent xev;
+ XWindowAttributes att;
+ Window tw;
+ int rx, ry;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetWindowAttributes(_ecore_x_disp, win, &att);
+ XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
+ xev.xbutton.type = ButtonPress;
+ xev.xbutton.window = win;
+ xev.xbutton.root = att.root;
+ xev.xbutton.subwindow = win;
+ xev.xbutton.time = _ecore_x_event_last_time;
+ xev.xbutton.x = x;
+ xev.xbutton.y = y;
+ xev.xbutton.x_root = rx;
+ xev.xbutton.y_root = ry;
+ xev.xbutton.state = 1 << b;
+ xev.xbutton.button = b;
+ xev.xbutton.same_screen = 1;
+ return XSendEvent(_ecore_x_disp, win, True, ButtonPressMask, &xev) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_up_send(Ecore_X_Window win,
+ int x,
+ int y,
+ int b)
+{
+ XEvent xev;
+ XWindowAttributes att;
+ Window tw;
+ int rx, ry;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetWindowAttributes(_ecore_x_disp, win, &att);
+ XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
+ xev.xbutton.type = ButtonRelease;
+ xev.xbutton.window = win;
+ xev.xbutton.root = att.root;
+ xev.xbutton.subwindow = win;
+ xev.xbutton.time = _ecore_x_event_last_time;
+ xev.xbutton.x = x;
+ xev.xbutton.y = y;
+ xev.xbutton.x_root = rx;
+ xev.xbutton.y_root = ry;
+ xev.xbutton.state = 0;
+ xev.xbutton.button = b;
+ xev.xbutton.same_screen = 1;
+ return XSendEvent(_ecore_x_disp, win, True, ButtonReleaseMask, &xev) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_in_send(Ecore_X_Window win,
+ int x,
+ int y)
+{
+ XEvent xev;
+ XWindowAttributes att;
+ Window tw;
+ int rx, ry;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetWindowAttributes(_ecore_x_disp, win, &att);
+ XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
+ xev.xcrossing.type = EnterNotify;
+ xev.xcrossing.window = win;
+ xev.xcrossing.root = att.root;
+ xev.xcrossing.subwindow = win;
+ xev.xcrossing.time = _ecore_x_event_last_time;
+ xev.xcrossing.x = x;
+ xev.xcrossing.y = y;
+ xev.xcrossing.x_root = rx;
+ xev.xcrossing.y_root = ry;
+ xev.xcrossing.mode = NotifyNormal;
+ xev.xcrossing.detail = NotifyNonlinear;
+ xev.xcrossing.same_screen = 1;
+ xev.xcrossing.focus = 0;
+ xev.xcrossing.state = 0;
+ return XSendEvent(_ecore_x_disp, win, True, EnterWindowMask, &xev) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_mouse_out_send(Ecore_X_Window win,
+ int x,
+ int y)
+{
+ XEvent xev;
+ XWindowAttributes att;
+ Window tw;
+ int rx, ry;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetWindowAttributes(_ecore_x_disp, win, &att);
+ XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
+ xev.xcrossing.type = LeaveNotify;
+ xev.xcrossing.window = win;
+ xev.xcrossing.root = att.root;
+ xev.xcrossing.subwindow = win;
+ xev.xcrossing.time = _ecore_x_event_last_time;
+ xev.xcrossing.x = x;
+ xev.xcrossing.y = y;
+ xev.xcrossing.x_root = rx;
+ xev.xcrossing.y_root = ry;
+ xev.xcrossing.mode = NotifyNormal;
+ xev.xcrossing.detail = NotifyNonlinear;
+ xev.xcrossing.same_screen = 1;
+ xev.xcrossing.focus = 0;
+ xev.xcrossing.state = 0;
+ return XSendEvent(_ecore_x_disp, win, True, LeaveWindowMask, &xev) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI void
+ecore_x_focus_reset(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetInputFocus(_ecore_x_disp, PointerRoot, RevertToPointerRoot, CurrentTime);
+}
+
+EAPI void
+ecore_x_events_allow_all(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XAllowEvents(_ecore_x_disp, AsyncBoth, CurrentTime);
+}
+
+EAPI void
+ecore_x_pointer_last_xy_get(int *x,
+ int *y)
+{
+ if (x)
+ *x = _ecore_x_event_last_root_x;
+
+ if (y)
+ *y = _ecore_x_event_last_root_y;
+}
+
+EAPI void
+ecore_x_pointer_xy_get(Ecore_X_Window win,
+ int *x,
+ int *y)
+{
+ Window rwin, cwin;
+ int rx, ry, wx, wy, ret;
+ unsigned int mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = XQueryPointer(_ecore_x_disp, win, &rwin, &cwin,
+ &rx, &ry, &wx, &wy, &mask);
+ if (!ret)
+ wx = wy = -1;
+
+ if (x) *x = wx;
+ if (y) *y = wy;
+}
+
+/**
+ * Retrieve the Visual ID from a given Visual.
+ *
+ * @param visual The Visual to get the ID for.
+ *
+ * @return The visual id.
+ * @since 1.1.0
+ */
+EAPI unsigned int
+ecore_x_visual_id_get(Ecore_X_Visual visual)
+{
+ return XVisualIDFromVisual(visual);
+}
+
+/**
+ * Retrieve the default Visual.
+ *
+ * @param disp The Display to get the Default Visual from
+ * @param screen The Screen.
+ *
+ * @return The default visual.
+ * @since 1.1.0
+ */
+EAPI Ecore_X_Visual
+ecore_x_default_visual_get(Ecore_X_Display *disp,
+ Ecore_X_Screen *screen)
+{
+ return DefaultVisual(disp, ecore_x_screen_index_get(screen));
+}
+
+/**
+ * Retrieve the default Colormap.
+ *
+ * @param disp The Display to get the Default Colormap from
+ * @param screen The Screen.
+ *
+ * @return The default colormap.
+ * @since 1.1.0
+ */
+EAPI Ecore_X_Colormap
+ecore_x_default_colormap_get(Ecore_X_Display *disp,
+ Ecore_X_Screen *screen)
+{
+ return DefaultColormap(disp, ecore_x_screen_index_get(screen));
+}
+
+/**
+ * Retrieve the default depth.
+ *
+ * @param disp The Display to get the Default Depth from
+ * @param screen The Screen.
+ *
+ * @return The default depth.
+ * @since 1.1.0
+ */
+EAPI int
+ecore_x_default_depth_get(Ecore_X_Display *disp,
+ Ecore_X_Screen *screen)
+{
+ return DefaultDepth(disp, ecore_x_screen_index_get(screen));
+}
+
+EAPI void
+ecore_x_xkb_select_group(int group)
+{
+#ifdef ECORE_XKB
+ XkbLockGroup(_ecore_x_disp, XkbUseCoreKbd, group);
+#endif
+}
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+static int
+_ecore_x_event_modifier(unsigned int state)
+{
+ 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_MODIFIER_ALTGR)
+ xmodifiers |= ECORE_X_MODIFIER_ALTGR;
+
+ 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;
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_atoms.c b/src/lib/ecore_x/xlib/ecore_x_atoms.c
new file mode 100644
index 0000000000..2aec7ce740
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_atoms.c
@@ -0,0 +1,109 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif !defined alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# elif !defined HAVE_ALLOCA
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+#endif
+
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+#include "ecore_x_atoms_decl.h"
+
+void
+_ecore_x_atoms_init(void)
+{
+ Atom *atoms;
+ char **names;
+ int i, num;
+
+ num = sizeof(atom_items) / sizeof(Atom_Item);
+ atoms = alloca(num * sizeof(Atom));
+ names = alloca(num * sizeof(char *));
+ for (i = 0; i < num; i++)
+ names[i] = (char *) atom_items[i].name;
+ XInternAtoms(_ecore_x_disp, names, num, False, atoms);
+ for (i = 0; i < num; i++)
+ *(atom_items[i].atom) = atoms[i];
+}
+
+/**
+ * Retrieves the atom value associated with the given name.
+ * @param name The given name.
+ * @return Associated atom value.
+ */
+EAPI Ecore_X_Atom
+ecore_x_atom_get(const char *name)
+{
+ if (!_ecore_x_disp)
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XInternAtom(_ecore_x_disp, name, False);
+}
+
+EAPI void
+ecore_x_atoms_get(const char **names,
+ int num,
+ Ecore_X_Atom *atoms)
+{
+ Atom *atoms_int;
+ int i;
+
+ if (!_ecore_x_disp)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atoms_int = alloca(num * sizeof(Atom));
+ XInternAtoms(_ecore_x_disp, (char **)names, num, False, atoms_int);
+ for (i = 0; i < num; i++)
+ atoms[i] = atoms_int[i];
+}
+
+EAPI char *
+ecore_x_atom_name_get(Ecore_X_Atom atom)
+{
+ char *name;
+ char *xname;
+
+ if (!_ecore_x_disp)
+ return NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xname = XGetAtomName(_ecore_x_disp, atom);
+ if (!xname)
+ return NULL;
+
+ name = strdup(xname);
+ XFree(xname);
+
+ return name;
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_composite.c b/src/lib/ecore_x/xlib/ecore_x_composite.c
new file mode 100644
index 0000000000..b919db96d2
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_composite.c
@@ -0,0 +1,176 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+static Eina_Bool _composite_available = EINA_FALSE;
+
+void
+_ecore_x_composite_init(void)
+{
+ _composite_available = EINA_FALSE;
+
+#ifdef ECORE_XCOMPOSITE
+ int major, minor;
+
+ if (XCompositeQueryVersion(_ecore_x_disp, &major, &minor))
+ {
+# ifdef ECORE_XRENDER
+ if (XRenderQueryExtension(_ecore_x_disp, &major, &minor))
+ {
+# ifdef ECORE_XFIXES
+ if (XFixesQueryVersion(_ecore_x_disp, &major, &minor))
+ {
+ _composite_available = EINA_TRUE;
+ }
+# endif
+ }
+# endif
+ }
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_composite_query(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _composite_available;
+}
+
+EAPI void
+ecore_x_composite_redirect_window(Ecore_X_Window win,
+ Ecore_X_Composite_Update_Type type)
+{
+#ifdef ECORE_XCOMPOSITE
+ int update = CompositeRedirectAutomatic;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch (type)
+ {
+ case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC:
+ update = CompositeRedirectAutomatic;
+ break;
+
+ case ECORE_X_COMPOSITE_UPDATE_MANUAL:
+ update = CompositeRedirectManual;
+ break;
+ }
+ XCompositeRedirectWindow(_ecore_x_disp, win, update);
+#endif /* ifdef ECORE_XCOMPOSITE */
+}
+
+EAPI void
+ecore_x_composite_redirect_subwindows(Ecore_X_Window win,
+ Ecore_X_Composite_Update_Type type)
+{
+#ifdef ECORE_XCOMPOSITE
+ int update = CompositeRedirectAutomatic;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch (type)
+ {
+ case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC:
+ update = CompositeRedirectAutomatic;
+ break;
+
+ case ECORE_X_COMPOSITE_UPDATE_MANUAL:
+ update = CompositeRedirectManual;
+ break;
+ }
+ XCompositeRedirectSubwindows(_ecore_x_disp, win, update);
+#endif /* ifdef ECORE_XCOMPOSITE */
+}
+
+EAPI void
+ecore_x_composite_unredirect_window(Ecore_X_Window win,
+ Ecore_X_Composite_Update_Type type)
+{
+#ifdef ECORE_XCOMPOSITE
+ int update = CompositeRedirectAutomatic;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch (type)
+ {
+ case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC:
+ update = CompositeRedirectAutomatic;
+ break;
+
+ case ECORE_X_COMPOSITE_UPDATE_MANUAL:
+ update = CompositeRedirectManual;
+ break;
+ }
+ XCompositeUnredirectWindow(_ecore_x_disp, win, update);
+#endif /* ifdef ECORE_XCOMPOSITE */
+}
+
+EAPI void
+ecore_x_composite_unredirect_subwindows(Ecore_X_Window win,
+ Ecore_X_Composite_Update_Type type)
+{
+#ifdef ECORE_XCOMPOSITE
+ int update = CompositeRedirectAutomatic;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch (type)
+ {
+ case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC:
+ update = CompositeRedirectAutomatic;
+ break;
+
+ case ECORE_X_COMPOSITE_UPDATE_MANUAL:
+ update = CompositeRedirectManual;
+ break;
+ }
+ XCompositeUnredirectSubwindows(_ecore_x_disp, win, update);
+#endif /* ifdef ECORE_XCOMPOSITE */
+}
+
+EAPI Ecore_X_Pixmap
+ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win)
+{
+ Ecore_X_Pixmap pixmap = None;
+#ifdef ECORE_XCOMPOSITE
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ pixmap = XCompositeNameWindowPixmap(_ecore_x_disp, win);
+#endif /* ifdef ECORE_XCOMPOSITE */
+ return pixmap;
+}
+
+EAPI void
+ecore_x_composite_window_events_disable(Ecore_X_Window win)
+{
+#ifdef ECORE_XCOMPOSITE
+ ecore_x_window_shape_input_rectangle_set(win, -1, -1, 1, 1);
+#endif /* ifdef ECORE_XCOMPOSITE */
+}
+
+EAPI void
+ecore_x_composite_window_events_enable(Ecore_X_Window win)
+{
+#ifdef ECORE_XCOMPOSITE
+ ecore_x_window_shape_input_rectangle_set(win, 0, 0, 65535, 65535);
+#endif /* ifdef ECORE_XCOMPOSITE */
+}
+
+EAPI Ecore_X_Window
+ecore_x_composite_render_window_enable(Ecore_X_Window root)
+{
+ Ecore_X_Window win = 0;
+#ifdef ECORE_XCOMPOSITE
+ win = XCompositeGetOverlayWindow(_ecore_x_disp, root);
+ ecore_x_composite_window_events_disable(win);
+#endif /* ifdef ECORE_XCOMPOSITE */
+ return win;
+}
+
+EAPI void
+ecore_x_composite_render_window_disable(Ecore_X_Window root)
+{
+#ifdef ECORE_XCOMPOSITE
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XCompositeReleaseOverlayWindow(_ecore_x_disp, root);
+#endif /* ifdef ECORE_XCOMPOSITE */
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_cursor.c b/src/lib/ecore_x/xlib/ecore_x_cursor.c
new file mode 100644
index 0000000000..a968c56af2
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_cursor.c
@@ -0,0 +1,246 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+
+#include "ecore_x_private.h"
+
+EAPI Eina_Bool
+ecore_x_cursor_color_supported_get(void)
+{
+ return _ecore_x_xcursor;
+}
+
+EAPI Ecore_X_Cursor
+ecore_x_cursor_new(Ecore_X_Window win,
+ int *pixels,
+ int w,
+ int h,
+ int hot_x,
+ int hot_y)
+{
+#ifdef ECORE_XCURSOR
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (_ecore_x_xcursor)
+ {
+ Cursor c;
+ XcursorImage *xci;
+
+ 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 /* ifdef ECORE_XCURSOR */
+ {
+ XColor c1, c2;
+ Cursor c;
+ Pixmap pmap, mask;
+ GC gc;
+ XGCValues gcv;
+ XImage *xim;
+ unsigned int *pix;
+ int fr, fg, fb, br, bg, bb;
+ int brightest = 0;
+ int darkest = 255 * 3;
+ int x, y;
+ const int dither[2][2] =
+ {
+ {0, 2},
+ {3, 1}
+ };
+
+ pmap = XCreatePixmap(_ecore_x_disp, win, w, h, 1);
+ mask = XCreatePixmap(_ecore_x_disp, win, w, h, 1);
+ xim = XCreateImage(_ecore_x_disp,
+ DefaultVisual(_ecore_x_disp, 0),
+ 1, ZPixmap, 0, NULL, w, h, 32, 0);
+ xim->data = malloc(xim->bytes_per_line * xim->height);
+
+ fr = 0x00; fg = 0x00; fb = 0x00;
+ br = 0xff; bg = 0xff; bb = 0xff;
+ pix = (unsigned int *)pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int 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 ((r + g + b) > brightest)
+ {
+ brightest = r + g + b;
+ br = r;
+ bg = g;
+ bb = b;
+ }
+
+ if ((r + g + b) < darkest)
+ {
+ darkest = r + g + b;
+ fr = r;
+ fg = g;
+ fb = b;
+ }
+ }
+
+ pix++;
+ }
+ }
+
+ pix = (unsigned int *)pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int v;
+ int r, g, b;
+ int 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;
+
+ XPutPixel(xim, x, y, v);
+ pix++;
+ }
+ }
+ gc = XCreateGC(_ecore_x_disp, pmap, 0, &gcv);
+ XPutImage(_ecore_x_disp, pmap, gc, xim, 0, 0, 0, 0, w, h);
+ XFreeGC(_ecore_x_disp, gc);
+
+ pix = (unsigned int *)pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int v;
+
+ v = (((pix[0] >> 24) & 0xff) * 5) / 256;
+ if (v > dither[x & 0x1][y & 0x1])
+ v = 1;
+ else
+ v = 0;
+
+ XPutPixel(xim, x, y, v);
+ pix++;
+ }
+ }
+ gc = XCreateGC(_ecore_x_disp, mask, 0, &gcv);
+ XPutImage(_ecore_x_disp, mask, gc, xim, 0, 0, 0, 0, w, h);
+ XFreeGC(_ecore_x_disp, gc);
+
+ free(xim->data);
+ xim->data = NULL;
+ XDestroyImage(xim);
+
+ c1.pixel = 0;
+ c1.red = fr << 8 | fr;
+ c1.green = fg << 8 | fg;
+ c1.blue = fb << 8 | fb;
+ c1.flags = DoRed | DoGreen | DoBlue;
+
+ c2.pixel = 0;
+ c2.red = br << 8 | br;
+ c2.green = bg << 8 | bg;
+ c2.blue = bb << 8 | bb;
+ c2.flags = DoRed | DoGreen | DoBlue;
+
+ c = XCreatePixmapCursor(_ecore_x_disp,
+ pmap, mask,
+ &c1, &c2,
+ hot_x, hot_y);
+ XFreePixmap(_ecore_x_disp, pmap);
+ XFreePixmap(_ecore_x_disp, mask);
+ return c;
+ }
+
+ return 0;
+}
+
+EAPI void
+ecore_x_cursor_free(Ecore_X_Cursor c)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFreeCursor(_ecore_x_disp, c);
+}
+
+/*
+ * 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* Shapes are defined in Ecore_X_Cursor.h */
+ return XCreateFontCursor(_ecore_x_disp, shape);
+}
+
+EAPI void
+ecore_x_cursor_size_set(int size)
+{
+#ifdef ECORE_XCURSOR
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XcursorSetDefaultSize(_ecore_x_disp, size);
+#else /* ifdef ECORE_XCURSOR */
+ size = 0;
+#endif /* ifdef ECORE_XCURSOR */
+}
+
+EAPI int
+ecore_x_cursor_size_get(void)
+{
+#ifdef ECORE_XCURSOR
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XcursorGetDefaultSize(_ecore_x_disp);
+#else /* ifdef ECORE_XCURSOR */
+ return 0;
+#endif /* ifdef ECORE_XCURSOR */
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_damage.c b/src/lib/ecore_x/xlib/ecore_x_damage.c
new file mode 100644
index 0000000000..b094f85235
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_damage.c
@@ -0,0 +1,71 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+static Eina_Bool _damage_available = EINA_FALSE;
+#ifdef ECORE_XDAMAGE
+static int _damage_major, _damage_minor;
+#endif /* ifdef ECORE_XDAMAGE */
+
+void
+_ecore_x_damage_init(void)
+{
+#ifdef ECORE_XDAMAGE
+ _damage_major = 1;
+ _damage_minor = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XDamageQueryVersion(_ecore_x_disp, &_damage_major, &_damage_minor))
+ _damage_available = EINA_TRUE;
+ else
+ _damage_available = EINA_FALSE;
+
+#else /* ifdef ECORE_XDAMAGE */
+ _damage_available = EINA_FALSE;
+#endif /* ifdef ECORE_XDAMAGE */
+}
+
+EAPI Eina_Bool
+ecore_x_damage_query(void)
+{
+ return _damage_available;
+}
+
+EAPI Ecore_X_Damage
+ecore_x_damage_new(Ecore_X_Drawable d,
+ Ecore_X_Damage_Report_Level level)
+{
+#ifdef ECORE_XDAMAGE
+ Ecore_X_Damage damage;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ damage = XDamageCreate(_ecore_x_disp, d, level);
+ return damage;
+#else /* ifdef ECORE_XDAMAGE */
+ return 0;
+#endif /* ifdef ECORE_XDAMAGE */
+}
+
+EAPI void
+ecore_x_damage_free(Ecore_X_Damage damage)
+{
+#ifdef ECORE_XDAMAGE
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XDamageDestroy(_ecore_x_disp, damage);
+#endif /* ifdef ECORE_XDAMAGE */
+}
+
+EAPI void
+ecore_x_damage_subtract(Ecore_X_Damage damage,
+ Ecore_X_Region repair,
+ Ecore_X_Region parts)
+{
+#ifdef ECORE_XDAMAGE
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XDamageSubtract(_ecore_x_disp, damage, repair, parts);
+#endif /* ifdef ECORE_XDAMAGE */
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_dnd.c b/src/lib/ecore_x/xlib/ecore_x_dnd.c
new file mode 100644
index 0000000000..e4f74a7257
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_dnd.c
@@ -0,0 +1,706 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+EAPI int ECORE_X_EVENT_XDND_ENTER = 0;
+EAPI int ECORE_X_EVENT_XDND_POSITION = 0;
+EAPI int ECORE_X_EVENT_XDND_STATUS = 0;
+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;
+
+typedef struct _Version_Cache_Item
+{
+ Ecore_X_Window win;
+ int ver;
+} Version_Cache_Item;
+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;
+
+void
+_ecore_x_dnd_init(void)
+{
+ if (!_ecore_x_dnd_init_count)
+ {
+ _source = calloc(1, sizeof(Ecore_X_DND_Source));
+ if (!_source) return;
+ _source->version = ECORE_X_DND_VERSION;
+ _source->win = None;
+ _source->dest = None;
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ _source->prev.window = 0;
+
+ _target = calloc(1, sizeof(Ecore_X_DND_Target));
+ if (!_target)
+ {
+ free(_source);
+ _source = NULL;
+ return;
+ }
+ _target->win = None;
+ _target->source = None;
+ _target->state = ECORE_X_DND_TARGET_IDLE;
+
+ ECORE_X_EVENT_XDND_ENTER = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_POSITION = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_STATUS = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_LEAVE = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_DROP = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_FINISHED = ecore_event_type_new();
+ }
+
+ _ecore_x_dnd_init_count++;
+}
+
+void
+_ecore_x_dnd_shutdown(void)
+{
+ _ecore_x_dnd_init_count--;
+ if (_ecore_x_dnd_init_count > 0)
+ return;
+
+ if (_source)
+ free(_source);
+
+ _source = NULL;
+
+ if (_target)
+ free(_target);
+
+ _target = NULL;
+
+ _ecore_x_dnd_init_count = 0;
+}
+
+static Eina_Bool
+_ecore_x_dnd_converter_copy(char *target EINA_UNUSED,
+ void *data,
+ int size,
+ void **data_ret,
+ int *size_ret,
+ Ecore_X_Atom *tprop EINA_UNUSED,
+ int *count EINA_UNUSED)
+{
+ XTextProperty text_prop;
+ char *mystr;
+ XICCEncodingStyle style = XTextStyle;
+
+ if (!data || !size)
+ return EINA_FALSE;
+
+ mystr = calloc(1, size + 1);
+ if (!mystr)
+ return EINA_FALSE;
+
+ memcpy(mystr, data, size);
+
+ if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style,
+ &text_prop) == Success)
+ {
+ int bufsize = strlen((char *)text_prop.value) + 1;
+ *data_ret = malloc(bufsize);
+ if (!*data_ret)
+ {
+ free(mystr);
+ return EINA_FALSE;
+ }
+ memcpy(*data_ret, text_prop.value, bufsize);
+ *size_ret = bufsize;
+ XFree(text_prop.value);
+ free(mystr);
+ return EINA_TRUE;
+ }
+ else
+ {
+ free(mystr);
+ return EINA_FALSE;
+ }
+}
+
+EAPI void
+ecore_x_dnd_aware_set(Ecore_X_Window win,
+ Eina_Bool on)
+{
+ Ecore_X_Atom prop_data = ECORE_X_DND_VERSION;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (on)
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_AWARE,
+ XA_ATOM, 32, &prop_data, 1);
+ else
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_AWARE);
+}
+
+EAPI int
+ecore_x_dnd_version_get(Ecore_X_Window win)
+{
+ unsigned char *prop_data;
+ int num;
+ Version_Cache_Item *t;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ // this looks hacky - and it is, but we need a way of caching info about
+ // a window while dragging, because we literally query this every mouse
+ // move and going to and from x multiple times per move is EXPENSIVE
+ // and slows things down, puts lots of load on x etc.
+ if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
+ if (_version_cache)
+ {
+ int i;
+
+ for (i = 0; i < _version_cache_num; i++)
+ {
+ if (_version_cache[i].win == win)
+ return _version_cache[i].ver;
+ }
+ }
+
+ if (ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_AWARE,
+ XA_ATOM, 32, &prop_data, &num))
+ {
+ int version = (int)*prop_data;
+ free(prop_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 = version;
+ }
+
+ return version;
+ }
+
+ 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;
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_type_isset(Ecore_X_Window win,
+ const char *type)
+{
+ int num, i, 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,
+ XA_ATOM, 32, &data, &num))
+ return ret;
+
+ atom = ecore_x_atom_get(type);
+ atoms = (Ecore_X_Atom *)data;
+
+ for (i = 0; i < num; ++i)
+ {
+ if (atom == atoms[i])
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+ }
+
+ XFree(data);
+ return ret;
+}
+
+EAPI void
+ecore_x_dnd_type_set(Ecore_X_Window win,
+ const char *type,
+ Eina_Bool on)
+{
+ Ecore_X_Atom atom;
+ Ecore_X_Atom *oldset = NULL, *newset = NULL;
+ int i, j = 0, num = 0;
+ unsigned char *data = NULL;
+ unsigned char *old_data = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = ecore_x_atom_get(type);
+ ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, &old_data, &num);
+ oldset = (Ecore_X_Atom *)old_data;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (on)
+ {
+ if (ecore_x_dnd_type_isset(win, type))
+ {
+ XFree(old_data);
+ return;
+ }
+
+ 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 */
+ newset[0] = atom;
+
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, data, num + 1);
+ }
+ else
+ {
+ if (!ecore_x_dnd_type_isset(win, type))
+ {
+ XFree(old_data);
+ return;
+ }
+
+ newset = calloc(num - 1, sizeof(Ecore_X_Atom));
+ if (!newset)
+ {
+ XFree(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(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, data, num - 1);
+ }
+
+ XFree(oldset);
+ free(newset);
+}
+
+EAPI void
+ecore_x_dnd_types_set(Ecore_X_Window win,
+ const char **types,
+ unsigned int num_types)
+{
+ Ecore_X_Atom *newset = NULL;
+ unsigned int i;
+ unsigned char *data = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!num_types)
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_TYPE_LIST);
+ else
+ {
+ newset = calloc(num_types, sizeof(Ecore_X_Atom));
+ if (!newset)
+ return;
+
+ data = (unsigned char *)newset;
+ for (i = 0; i < num_types; i++)
+ {
+ newset[i] = ecore_x_atom_get(types[i]);
+ ecore_x_selection_converter_atom_add(newset[i],
+ _ecore_x_dnd_converter_copy);
+ }
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, data, num_types);
+ free(newset);
+ }
+}
+
+EAPI void
+ecore_x_dnd_actions_set(Ecore_X_Window win,
+ Ecore_X_Atom *actions,
+ unsigned int num_actions)
+{
+ unsigned int i;
+ unsigned char *data = NULL;
+
+ 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_x_dnd_converter_copy);
+ }
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_ACTION_LIST,
+ XA_ATOM, 32, data, num_actions);
+ }
+}
+
+/**
+ * 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_callback_pos_update_set(
+ void (*cb)(void *,
+ Ecore_X_Xdnd_Position *data),
+ const void *data)
+{
+ _posupdatecb = cb;
+ _posupdatedata = (void *)data; /* Discard the const early */
+}
+
+Ecore_X_DND_Source *
+_ecore_x_dnd_source_get(void)
+{
+ return _source;
+}
+
+Ecore_X_DND_Target *
+_ecore_x_dnd_target_get(void)
+{
+ return _target;
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_begin(Ecore_X_Window source,
+ unsigned char *data,
+ int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_dnd_version_get(source))
+ return EINA_FALSE;
+
+ /* Take ownership of XdndSelection */
+ if (!ecore_x_selection_xdnd_set(source, data, size))
+ return EINA_FALSE;
+
+ if (_version_cache)
+ {
+ free(_version_cache);
+ _version_cache = NULL;
+ _version_cache_num = 0;
+ _version_cache_alloc = 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_x_event_last_time;
+ _source->prev.window = 0;
+
+ /* Default Accepted Action: move */
+ _source->action = ECORE_X_ATOM_XDND_ACTION_MOVE;
+ _source->accepted_action = None;
+ _source->dest = None;
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_drop(void)
+{
+ XEvent xev;
+ int status = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (_source->dest)
+ {
+ xev.xany.type = ClientMessage;
+ xev.xany.display = _ecore_x_disp;
+ xev.xclient.format = 32;
+ xev.xclient.window = _source->dest;
+
+ if (_source->will_accept)
+ {
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_DROP;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = _source->time;
+ XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
+ _source->state = ECORE_X_DND_SOURCE_DROPPED;
+ status = EINA_TRUE;
+ }
+ else
+ {
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+ XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
+ _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;
+
+ return status;
+}
+
+EAPI void
+ecore_x_dnd_send_status(Eina_Bool will_accept,
+ Eina_Bool suppress,
+ Ecore_X_Rectangle rectangle,
+ Ecore_X_Atom action)
+{
+ XEvent xev;
+
+ if (_target->state == ECORE_X_DND_TARGET_IDLE)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ memset(&xev, 0, sizeof(XEvent));
+
+ _target->will_accept = will_accept;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_STATUS;
+ xev.xclient.format = 32;
+ xev.xclient.window = _target->source;
+
+ xev.xclient.data.l[0] = _target->win;
+ xev.xclient.data.l[1] = 0;
+ if (will_accept)
+ xev.xclient.data.l[1] |= 0x1UL;
+
+ if (!suppress)
+ xev.xclient.data.l[1] |= 0x2UL;
+
+ /* Set rectangle information */
+ xev.xclient.data.l[2] = rectangle.x;
+ xev.xclient.data.l[2] <<= 16;
+ xev.xclient.data.l[2] |= rectangle.y;
+ xev.xclient.data.l[3] = rectangle.width;
+ xev.xclient.data.l[3] <<= 16;
+ xev.xclient.data.l[3] |= rectangle.height;
+
+ if (will_accept)
+ {
+ xev.xclient.data.l[4] = action;
+ _target->accepted_action = action;
+ }
+ else
+ {
+ xev.xclient.data.l[4] = None;
+ _target->accepted_action = action;
+ }
+
+ XSendEvent(_ecore_x_disp, _target->source, False, 0, &xev);
+}
+
+EAPI void
+ecore_x_dnd_send_finished(void)
+{
+ XEvent xev;
+
+ if (_target->state == ECORE_X_DND_TARGET_IDLE)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xany.type = ClientMessage;
+ xev.xany.display = _ecore_x_disp;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_FINISHED;
+ xev.xclient.format = 32;
+ xev.xclient.window = _target->source;
+
+ xev.xclient.data.l[0] = _target->win;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = 0;
+ if (_target->will_accept)
+ {
+ xev.xclient.data.l[1] |= 0x1UL;
+ xev.xclient.data.l[2] = _target->accepted_action;
+ }
+
+ XSendEvent(_ecore_x_disp, _target->source, False, 0, &xev);
+
+ _target->state = ECORE_X_DND_TARGET_IDLE;
+}
+
+EAPI void
+ecore_x_dnd_source_action_set(Ecore_X_Atom action)
+{
+ _source->action = action;
+ if (_source->prev.window)
+ _ecore_x_dnd_drag(_source->prev.window, _source->prev.x, _source->prev.y);
+}
+
+EAPI Ecore_X_Atom
+ecore_x_dnd_source_action_get(void)
+{
+ return _source->action;
+}
+
+void
+_ecore_x_dnd_drag(Ecore_X_Window root,
+ int x,
+ int y)
+{
+ XEvent xev;
+ Ecore_X_Window win;
+ Ecore_X_Window *skip;
+ Ecore_X_Xdnd_Position pos;
+ int num;
+
+ if (_source->state != ECORE_X_DND_SOURCE_DRAGGING)
+ return;
+
+ /* Preinitialize XEvent struct */
+ memset(&xev, 0, sizeof(XEvent));
+ xev.xany.type = ClientMessage;
+ xev.xany.display = _ecore_x_disp;
+ xev.xclient.format = 32;
+
+ /* Attempt to find a DND-capable window under the cursor */
+ skip = ecore_x_window_ignore_list(&num);
+// WARNING - this function is HEAVY. it goes to and from x a LOT walking the
+// window tree - use the SHADOW version - makes a 1-off tree copy, then uses
+// that instead.
+// 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);
+
+// NOTE: This now uses the shadow version to find parent windows
+// while ((win) && !(ecore_x_dnd_version_get(win)))
+// win = ecore_x_window_parent_get(win);
+ while ((win) && !(ecore_x_dnd_version_get(win)))
+ win = ecore_x_window_shadow_parent_get(root, win);
+
+ /* Send XdndLeave to current destination window if we have left it */
+ if ((_source->dest) && (win != _source->dest))
+ {
+ xev.xclient.window = _source->dest;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+
+ XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
+ _source->suppress = 0;
+ }
+
+ if (win)
+ {
+ int x1, x2, y1, y2;
+
+ _source->version = MIN(ECORE_X_DND_VERSION,
+ ecore_x_dnd_version_get(win));
+ if (win != _source->dest)
+ {
+ int i;
+ unsigned char *data;
+ Ecore_X_Atom *types;
+
+ ecore_x_window_prop_property_get(_source->win,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM,
+ 32,
+ &data,
+ &num);
+ types = (Ecore_X_Atom *)data;
+
+ /* Entered new window, send XdndEnter */
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_ENTER;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+ if (num > 3)
+ xev.xclient.data.l[1] |= 0x1UL;
+ else
+ xev.xclient.data.l[1] &= 0xfffffffeUL;
+
+ xev.xclient.data.l[1] |= ((unsigned long)_source->version) << 24;
+
+ for (i = 2; i < 5; i++)
+ xev.xclient.data.l[i] = 0;
+ for (i = 0; i < MIN(num, 3); ++i)
+ xev.xclient.data.l[i + 2] = types[i];
+ XFree(data);
+ XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+ _source->await_status = 0;
+ _source->will_accept = 0;
+ }
+
+ /* 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)))
+ {
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_POSITION;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0; /* Reserved */
+ xev.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+ xev.xclient.data.l[3] = _source->time; /* Version 1 */
+ xev.xclient.data.l[4] = _source->action; /* Version 2, Needs to be pre-set */
+ XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+
+ _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;
+}
+
+/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
diff --git a/src/lib/ecore_x/xlib/ecore_x_dpms.c b/src/lib/ecore_x/xlib/ecore_x_dpms.c
new file mode 100644
index 0000000000..23349f44e6
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_dpms.c
@@ -0,0 +1,247 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "ecore_x_private.h"
+
+static Eina_Bool _dpms_available = EINA_FALSE;
+
+void
+_ecore_x_dpms_init(void)
+{
+#ifdef ECORE_XDPMS
+ int _dpms_major, _dpms_minor;
+
+ _dpms_major = 1;
+ _dpms_minor = 0;
+
+ if (DPMSGetVersion(_ecore_x_disp, &_dpms_major, &_dpms_minor))
+ _dpms_available = EINA_TRUE;
+ else
+ _dpms_available = EINA_FALSE;
+
+#else /* ifdef ECORE_XDPMS */
+ _dpms_available = EINA_FALSE;
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * @defgroup Ecore_X_DPMS_Group X DPMS Extension Functions
+ *
+ * Functions related to the X DPMS extension.
+ */
+
+/**
+ * Checks if the X DPMS extension is available on the server.
+ * @return @c 1 if the X DPMS extension is available, @c 0 otherwise.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI Eina_Bool
+ecore_x_dpms_query(void)
+{
+ return _dpms_available;
+}
+
+/**
+ * Checks if the X server is capable of DPMS.
+ * @return @c 1 if the X server is capable of DPMS, @c 0 otherwise.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI Eina_Bool
+ecore_x_dpms_capable_get(void)
+{
+#ifdef ECORE_XDPMS
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return DPMSCapable(_ecore_x_disp) ? EINA_TRUE : EINA_FALSE;
+#else /* ifdef ECORE_XDPMS */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * Checks the DPMS state of the display.
+ * @return @c 1 if DPMS is enabled, @c 0 otherwise.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI Eina_Bool
+ecore_x_dpms_enabled_get(void)
+{
+#ifdef ECORE_XDPMS
+ unsigned char state;
+ unsigned short power_lvl;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSInfo(_ecore_x_disp, &power_lvl, &state);
+ return state ? EINA_TRUE : EINA_FALSE;
+#else /* ifdef ECORE_XDPMS */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * 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)
+{
+#ifdef ECORE_XDPMS
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (enabled)
+ DPMSEnable(_ecore_x_disp);
+ else
+ DPMSDisable(_ecore_x_disp);
+
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * 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.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeouts_get(unsigned int *standby,
+ unsigned int *suspend,
+ unsigned int *off)
+{
+#ifdef ECORE_XDPMS
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, (unsigned short *)standby,
+ (unsigned short *)suspend, (unsigned short *)off);
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * 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 Eina_Bool
+ecore_x_dpms_timeouts_set(unsigned int standby,
+ unsigned int suspend,
+ unsigned int off)
+{
+#ifdef ECORE_XDPMS
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return DPMSSetTimeouts(_ecore_x_disp, standby, suspend, off) ? EINA_TRUE : EINA_FALSE;
+#else /* ifdef ECORE_XDPMS */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * Returns the amount of time of inactivity before standby mode is invoked.
+ * @return The standby timeout value.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_standby_get(void)
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ return standby;
+#else /* ifdef ECORE_XDPMS */
+ return 0;
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * Returns the amount of time of inactivity before the second level of
+ * power saving is invoked.
+ * @return The suspend timeout value.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_suspend_get(void)
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ return suspend;
+#else /* ifdef ECORE_XDPMS */
+ return 0;
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * Returns the amount of time of inactivity before the third and final
+ * level of power saving is invoked.
+ * @return The off timeout value.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_off_get(void)
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ return off;
+#else /* ifdef ECORE_XDPMS */
+ return 0;
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * Sets the standby timeout (in unit of seconds).
+ * @param new_timeout Amount of time of inactivity before standby mode will be invoked.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_standby_set(unsigned int new_timeout)
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ DPMSSetTimeouts(_ecore_x_disp, new_timeout, suspend, off);
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * Sets the suspend timeout (in unit of seconds).
+ * @param new_timeout Amount of time of inactivity before the screen is placed into suspend mode.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_suspend_set(unsigned int new_timeout)
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ DPMSSetTimeouts(_ecore_x_disp, standby, new_timeout, off);
+#endif /* ifdef ECORE_XDPMS */
+}
+
+/**
+ * Sets the off timeout (in unit of seconds).
+ * @param new_timeout Amount of time of inactivity before the monitor is shut off.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_off_set(unsigned int new_timeout)
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ DPMSSetTimeouts(_ecore_x_disp, standby, suspend, new_timeout);
+#endif /* ifdef ECORE_XDPMS */
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_drawable.c b/src/lib/ecore_x/xlib/ecore_x_drawable.c
new file mode 100644
index 0000000000..d1b41114da
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_drawable.c
@@ -0,0 +1,118 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "ecore_x_private.h"
+
+/**
+ * @defgroup Ecore_X_Drawable_Group X Drawable Functions
+ *
+ * Functions that operate on drawables.
+ */
+
+/**
+ * Retrieves the geometry of the given drawable.
+ * @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 d,
+ int *x,
+ int *y,
+ int *w,
+ int *h)
+{
+ Window dummy_win;
+ int ret_x, ret_y;
+ unsigned int ret_w, ret_h, dummy_border, dummy_depth;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &ret_x, &ret_y,
+ &ret_w, &ret_h, &dummy_border, &dummy_depth))
+ {
+ ret_x = 0;
+ ret_y = 0;
+ ret_w = 0;
+ ret_h = 0;
+ }
+
+ if (x)
+ *x = ret_x;
+
+ if (y)
+ *y = ret_y;
+
+ if (w)
+ *w = (int)ret_w;
+
+ if (h)
+ *h = (int)ret_h;
+}
+
+/**
+ * Retrieves the width of the border of the given drawable.
+ * @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 d)
+{
+ Window dummy_win;
+ int dummy_x, dummy_y;
+ unsigned int dummy_w, dummy_h, border_ret, dummy_depth;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &dummy_x, &dummy_y,
+ &dummy_w, &dummy_h, &border_ret, &dummy_depth))
+ border_ret = 0;
+
+ return (int)border_ret;
+}
+
+/**
+ * Retrieves the depth of the given drawable.
+ * @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 d)
+{
+ Window dummy_win;
+ int dummy_x, dummy_y;
+ unsigned int dummy_w, dummy_h, dummy_border, depth_ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &dummy_x, &dummy_y,
+ &dummy_w, &dummy_h, &dummy_border, &depth_ret))
+ depth_ret = 0;
+
+ return (int)depth_ret;
+}
+
+/**
+ * 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFillRectangle(_ecore_x_disp, d, gc, x, y, width, height);
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_e.c b/src/lib/ecore_x/xlib/ecore_x_e.c
new file mode 100644
index 0000000000..430b24b117
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_e.c
@@ -0,0 +1,1670 @@
+/*
+ * OLD E hints
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif !defined alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# elif !defined HAVE_ALLOCA
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+#endif
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+EAPI void
+ecore_x_e_init(void)
+{
+}
+
+EAPI void
+ecore_x_e_frame_size_set(Ecore_X_Window win,
+ int fl,
+ int fr,
+ int ft,
+ int fb)
+{
+ unsigned int frames[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ frames[0] = fl;
+ frames[1] = fr;
+ frames[2] = ft;
+ frames[3] = fb;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_FRAME_SIZE, frames, 4);
+}
+
+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;
+
+ 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;
+}
+
+static Ecore_X_Virtual_Keyboard_State
+_ecore_x_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_x_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;
+}
+
+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_x_e_vkbd_atom_get(state);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE,
+ &atom, 1);
+}
+
+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_x_e_vkbd_state_get(atom);
+}
+
+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_x_e_vkbd_atom_get(state),
+ 0, 0, 0, 0);
+}
+
+static Ecore_X_Atom
+_ecore_x_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_x_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;
+}
+
+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 n_zones)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(win, ECORE_X_ATOM_E_ILLUME_ZONE_LIST,
+ zones, n_zones);
+}
+
+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 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_mode_set(Ecore_X_Window win,
+ Ecore_X_Illume_Mode mode)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_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_x_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_x_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_access_action_next_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_read_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_up_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP,
+ 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_access_action_down_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ win,
+ ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN,
+ 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 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_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 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_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)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_INDICATOR_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];
+
+ return EINA_TRUE;
+}
+
+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)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_SOFTKEY_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];
+
+ 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)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_KEYBOARD_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];
+
+ return EINA_TRUE;
+}
+
+static Ecore_X_Atom
+_ecore_x_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_x_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;
+}
+
+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_x_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_x_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_x_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_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_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_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 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_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);
+}
+
+static Ecore_X_Atom
+_ecore_x_e_clipboard_atom_get(Ecore_X_Illume_Clipboard_State state)
+{
+ switch (state)
+ {
+ case ECORE_X_ILLUME_CLIPBOARD_STATE_ON:
+ return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON;
+ case ECORE_X_ILLUME_CLIPBOARD_STATE_OFF:
+ return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Ecore_X_Illume_Clipboard_State
+_ecore_x_e_clipboard_state_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON)
+ return ECORE_X_ILLUME_CLIPBOARD_STATE_ON;
+
+ if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF)
+ return ECORE_X_ILLUME_CLIPBOARD_STATE_OFF;
+
+ return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN;
+}
+
+EAPI void
+ecore_x_e_illume_clipboard_state_set(Ecore_X_Window win,
+ Ecore_X_Illume_Clipboard_State state)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_e_clipboard_atom_get(state);
+
+ ecore_x_window_prop_atom_set(win,
+ ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Clipboard_State
+ecore_x_e_illume_clipboard_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_CLIPBOARD_STATE,
+ &atom, 1))
+ return ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN;
+ return _ecore_x_e_clipboard_state_get(atom);
+}
+
+EAPI void
+ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY,
+ geom, 4);
+}
+
+EAPI Eina_Bool
+ecore_x_e_illume_clipboard_geometry_get(Ecore_X_Window win,
+ int *x, int *y, int *w, int *h)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_CLIPBOARD_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];
+
+ return EINA_TRUE;
+}
+
+/* for sliding window */
+EAPI void
+ecore_x_e_illume_sliding_win_state_set(Ecore_X_Window win,
+ unsigned int is_visible)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win,
+ ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE,
+ &is_visible, 1);
+} /* ecore_x_e_illume_sliding_win_state_set */
+
+EAPI int
+ecore_x_e_illume_sliding_win_state_get(Ecore_X_Window win)
+{
+ unsigned int is_visible = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE,
+ &is_visible, 1))
+ return 0;
+
+ return is_visible;
+}
+
+EAPI void
+ecore_x_e_illume_sliding_win_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_SLIDING_WIN_GEOMETRY,
+ geom, 4);
+} /* ecore_x_e_illume_sliding_win_geometry_set */
+
+EAPI int
+ecore_x_e_illume_sliding_win_geometry_get(Ecore_X_Window win,
+ int *x,
+ int *y,
+ int *w,
+ int *h)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY,
+ geom, 4);
+ if (ret != 4)
+ return 0;
+
+ if (x)
+ *x = geom[0];
+
+ if (y)
+ *y = geom[1];
+
+ if (w)
+ *w = geom[2];
+
+ if (h)
+ *h = geom[3];
+
+ return 1;
+}/* ecore_x_e_illume_sliding_win_geometry_get */
+
+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)
+{
+ int ret = 0;
+ Ecore_X_Sync_Counter counter = 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 void
+ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window root,
+ Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root)
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // version
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_sync_draw_size_done_send(Ecore_X_Window root,
+ Ecore_X_Window win,
+ int w,
+ int h)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root)
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 1; // version
+ xev.xclient.data.l[2] = w; // win width at draw time
+ xev.xclient.data.l[3] = h; // win height at draw time
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+/*
+ * @since 1.3
+ *
+ */
+EAPI void
+ecore_x_e_window_profile_list_set(Ecore_X_Window win,
+ const char **profiles,
+ unsigned int num_profiles)
+{
+ Ecore_X_Atom *atoms;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!win)
+ return;
+
+ if (!num_profiles)
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE_LIST);
+ else
+ {
+ atoms = alloca(num_profiles * sizeof(Ecore_X_Atom));
+ ecore_x_atoms_get(profiles, num_profiles, atoms);
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_E_PROFILE_LIST,
+ XA_ATOM, 32, (void *)atoms,
+ num_profiles);
+ }
+}
+
+/*
+ * @since 1.3
+ */
+EAPI Eina_Bool
+ecore_x_e_window_profile_list_get(Ecore_X_Window win,
+ const char ***profiles,
+ int *ret_num)
+{
+ unsigned char *data;
+ Ecore_X_Atom *atoms;
+ int num, i;
+
+ if (ret_num)
+ *ret_num = 0;
+
+ if (profiles)
+ *profiles = NULL;
+
+ if (!win)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_E_PROFILE_LIST,
+ XA_ATOM, 32, &data, &num))
+ return EINA_FALSE;
+
+ if (ret_num)
+ *ret_num = num;
+
+ if (profiles)
+ {
+ (*profiles) = calloc(num, sizeof(char *));
+ if (!(*profiles))
+ {
+ if (ret_num)
+ *ret_num = 0;
+
+ if (data)
+ free(data);
+
+ return EINA_FALSE;
+ }
+
+ atoms = (Ecore_X_Atom *)data;
+ for (i = 0; i < num; i++)
+ (*profiles)[i] = ecore_x_atom_name_get(atoms[i]);
+ }
+
+ if (data)
+ XFree(data);
+
+ return EINA_TRUE;
+}
+
+/*
+ * @since 1.3
+ */
+EAPI void
+ecore_x_e_window_profile_set(Ecore_X_Window win,
+ const char *profile)
+{
+ Ecore_X_Atom atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!win)
+ return;
+
+ if (!profile)
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE);
+ else
+ {
+ atom = ecore_x_atom_get(profile);
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_PROFILE,
+ XA_ATOM, 32, (void *)&atom, 1);
+ }
+}
+
+/*
+ * @since 1.3
+ */
+EAPI char *
+ecore_x_e_window_profile_get(Ecore_X_Window win)
+{
+ Ecore_X_Atom *atom = NULL;
+ unsigned char *data;
+ char *profile = NULL;
+ int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_PROFILE,
+ XA_ATOM, 32, &data, &num))
+ return NULL;
+
+ if (data)
+ atom = (Ecore_X_Atom *)data;
+
+ if (atom)
+ profile = ecore_x_atom_name_get(atom[0]);
+
+ return profile;
+}
+
+EAPI void
+ecore_x_e_comp_sync_supported_set(Ecore_X_Window root,
+ Eina_Bool enabled)
+{
+ Ecore_X_Window win;
+
+ if (!root)
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ 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;
+
+ 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 Eina_Bool
+ecore_x_e_comp_sync_supported_get(Ecore_X_Window root)
+{
+ Ecore_X_Window win, win2;
+ int ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root)
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ 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_begin_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_BEGIN;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_sync_end_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_END;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_CANCEL;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_flush_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_FLUSH;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_dump_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_DUMP;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+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)
+{
+ int ret = 0;
+ Ecore_X_Pixmap pixmap = 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;
+}
+
+static Ecore_X_Atom
+_ecore_x_e_indicator_atom_get(Ecore_X_Illume_Indicator_State state)
+{
+ switch (state)
+ {
+ case ECORE_X_ILLUME_INDICATOR_STATE_ON:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_ON;
+
+ case ECORE_X_ILLUME_INDICATOR_STATE_OFF:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Ecore_X_Illume_Indicator_State
+_ecore_x_e_indicator_state_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_ON)
+ return ECORE_X_ILLUME_INDICATOR_STATE_ON;
+
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF)
+ return ECORE_X_ILLUME_INDICATOR_STATE_OFF;
+
+ return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN;
+}
+
+EAPI void
+ecore_x_e_illume_indicator_state_set(Ecore_X_Window win,
+ Ecore_X_Illume_Indicator_State state)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_e_indicator_atom_get(state);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Indicator_State
+ecore_x_e_illume_indicator_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_INDICATOR_STATE,
+ &atom, 1))
+ return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN;
+
+ return _ecore_x_e_indicator_state_get(atom);
+}
+
+EAPI void
+ecore_x_e_illume_indicator_state_send(Ecore_X_Window win,
+ Ecore_X_Illume_Indicator_State state)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ _ecore_x_e_indicator_atom_get(state),
+ 0, 0, 0, 0);
+}
+
+static Ecore_X_Atom
+_ecore_x_e_indicator_opacity_atom_get(Ecore_X_Illume_Indicator_Opacity_Mode mode)
+{
+ switch (mode)
+ {
+ case ECORE_X_ILLUME_INDICATOR_OPAQUE:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE;
+
+ case ECORE_X_ILLUME_INDICATOR_TRANSLUCENT:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT;
+
+ case ECORE_X_ILLUME_INDICATOR_TRANSPARENT:
+ return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Ecore_X_Illume_Indicator_Opacity_Mode
+_ecore_x_e_indicator_opacity_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE)
+ return ECORE_X_ILLUME_INDICATOR_OPAQUE;
+
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT)
+ return ECORE_X_ILLUME_INDICATOR_TRANSLUCENT;
+
+ if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT)
+ return ECORE_X_ILLUME_INDICATOR_TRANSPARENT;
+
+ return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN;
+}
+
+EAPI void
+ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win,
+ Ecore_X_Illume_Indicator_Opacity_Mode mode)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_e_indicator_opacity_atom_get(mode);
+ ecore_x_window_prop_atom_set(win,
+ ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Indicator_Opacity_Mode
+ecore_x_e_illume_indicator_opacity_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_INDICATOR_OPACITY_MODE,
+ &atom, 1))
+ return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN;
+
+ return _ecore_x_e_indicator_opacity_get(atom);
+}
+
+EAPI void
+ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win,
+ Ecore_X_Illume_Indicator_Opacity_Mode mode)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win,
+ ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ _ecore_x_e_indicator_opacity_atom_get(mode),
+ 0, 0, 0, 0);
+}
+
+static Ecore_X_Atom
+_ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state)
+{
+ switch (state)
+ {
+ case ECORE_X_ILLUME_WINDOW_STATE_NORMAL:
+ return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL;
+
+ case ECORE_X_ILLUME_WINDOW_STATE_FLOATING:
+ return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Ecore_X_Illume_Window_State
+_ecore_x_e_illume_window_state_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL)
+ return ECORE_X_ILLUME_WINDOW_STATE_NORMAL;
+
+ if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING)
+ return ECORE_X_ILLUME_WINDOW_STATE_FLOATING;
+
+ return ECORE_X_ILLUME_WINDOW_STATE_NORMAL;
+}
+
+EAPI void
+ecore_x_e_illume_window_state_set(Ecore_X_Window win,
+ Ecore_X_Illume_Window_State state)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_e_illume_window_state_atom_get(state);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_WINDOW_STATE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Window_State
+ecore_x_e_illume_window_state_get(Ecore_X_Window win)
+{
+ Ecore_X_Atom atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_atom_get(win,
+ ECORE_X_ATOM_E_ILLUME_WINDOW_STATE,
+ &atom, 1))
+ return ECORE_X_ILLUME_WINDOW_STATE_NORMAL;
+
+ return _ecore_x_e_illume_window_state_get(atom);
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_error.c b/src/lib/ecore_x/xlib/ecore_x_error.c
new file mode 100644
index 0000000000..f6eb075b54
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_error.c
@@ -0,0 +1,126 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+static int _ecore_x_error_handle(Display *d,
+ XErrorEvent *ev);
+static int _ecore_x_io_error_handle(Display *d);
+
+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;
+static Ecore_X_ID _error_resource_id = 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
+ */
+//FIXME: Use Ecore_X_Error_Code type when 2.0 is released
+EAPI int
+ecore_x_error_code_get(void)
+{
+ return _error_code;
+}
+
+/**
+ * Get the resource id that caused the error.
+ * @return The resource id causing the X error
+ *
+ * Return the X resource id that caused the last X error
+ */
+EAPI Ecore_X_ID
+ecore_x_error_resource_id_get(void)
+{
+ return _error_resource_id;
+}
+
+void
+_ecore_x_error_handler_init(void)
+{
+ XSetErrorHandler((XErrorHandler)_ecore_x_error_handle);
+ XSetIOErrorHandler((XIOErrorHandler)_ecore_x_io_error_handle);
+}
+
+static int
+_ecore_x_error_handle(Display *d,
+ XErrorEvent *ev)
+{
+ if (d == _ecore_x_disp)
+ {
+ _error_request_code = ev->request_code;
+ _error_code = ev->error_code;
+ _error_resource_id = ev->resourceid;
+ if (_error_func)
+ _error_func(_error_data);
+ }
+ return 0;
+}
+
+static int
+_ecore_x_io_error_handle(Display *d)
+{
+ if (d == _ecore_x_disp)
+ {
+ if (_io_error_func)
+ _io_error_func(_io_error_data);
+ else
+ exit(-1);
+ }
+
+ return 0;
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_events.c b/src/lib/ecore_x/xlib/ecore_x_events.c
new file mode 100644
index 0000000000..9ce7163d53
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_events.c
@@ -0,0 +1,2523 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <langinfo.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+/** OpenBSD does not define CODESET
+ * FIXME ??
+ */
+
+#ifndef CODESET
+#define CODESET "INVALID"
+#endif /* ifndef CODESET */
+
+typedef struct _Ecore_X_Mouse_Down_Info
+{
+ EINA_INLIST;
+ int dev;
+ Window last_win;
+ Window last_last_win;
+ Window last_event_win;
+ Window last_last_event_win;
+ Time last_time;
+ Time last_last_time;
+ Eina_Bool did_double : 1;
+ Eina_Bool did_triple : 1;
+} Ecore_X_Mouse_Down_Info;
+
+static int _ecore_x_last_event_mouse_move = 0;
+static Ecore_Event *_ecore_x_last_event_mouse_move_event = NULL;
+static Eina_Inlist *_ecore_x_mouse_down_info_list = NULL;
+
+static void
+_ecore_x_mouse_down_info_clear(void)
+{
+ Eina_Inlist *l = _ecore_x_mouse_down_info_list;
+ Ecore_X_Mouse_Down_Info *info = NULL;
+ while (l)
+ {
+ info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info);
+ l = eina_inlist_remove(l, l);
+ free(info);
+ }
+ _ecore_x_mouse_down_info_list = NULL;
+}
+
+void
+_ecore_x_events_init(void)
+{
+ //Actually, Nothing to do.
+}
+
+void
+_ecore_x_events_shutdown(void)
+{
+ _ecore_x_mouse_down_info_clear();
+}
+
+static Ecore_X_Mouse_Down_Info *
+_ecore_x_mouse_down_info_get(int dev)
+{
+ Eina_Inlist *l = _ecore_x_mouse_down_info_list;
+ Ecore_X_Mouse_Down_Info *info = NULL;
+
+ //Return the exist info
+ EINA_INLIST_FOREACH(l, info)
+ if (info->dev == dev) return info;
+
+ //New Device. Add it.
+ info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info));
+ if (!info) return NULL;
+
+ info->dev = dev;
+ l = eina_inlist_append(l, (Eina_Inlist *)info);
+ _ecore_x_mouse_down_info_list = l;
+ return info;
+}
+
+static void
+_ecore_x_event_free_mouse_move(void *data EINA_UNUSED,
+ void *ev)
+{
+ Ecore_Event_Mouse_Move *e;
+
+ e = ev;
+ if (_ecore_x_last_event_mouse_move)
+ {
+ _ecore_x_last_event_mouse_move_event = NULL;
+ _ecore_x_last_event_mouse_move = 0;
+ }
+
+ free(e);
+}
+
+EAPI void
+ecore_x_event_mask_set(Ecore_X_Window w,
+ Ecore_X_Event_Mask mask)
+{
+ XWindowAttributes attr;
+ XSetWindowAttributes s_attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!w)
+ w = DefaultRootWindow(_ecore_x_disp);
+
+ memset(&attr, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(_ecore_x_disp, w, &attr);
+ s_attr.event_mask = mask | attr.your_event_mask;
+ XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
+}
+
+EAPI void
+ecore_x_event_mask_unset(Ecore_X_Window w,
+ Ecore_X_Event_Mask mask)
+{
+ XWindowAttributes attr;
+ XSetWindowAttributes s_attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!w)
+ w = DefaultRootWindow(_ecore_x_disp);
+
+ memset(&attr, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(_ecore_x_disp, w, &attr);
+ s_attr.event_mask = attr.your_event_mask & ~mask;
+ XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
+}
+
+static void
+_ecore_x_event_free_xdnd_enter(void *data EINA_UNUSED,
+ void *ev)
+{
+ Ecore_X_Event_Xdnd_Enter *e;
+ int i;
+
+ e = ev;
+ for (i = 0; i < e->num_types; i++)
+ XFree(e->types[i]);
+ free(e->types);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_selection_notify(void *data EINA_UNUSED,
+ void *ev)
+{
+ Ecore_X_Event_Selection_Notify *e;
+ Ecore_X_Selection_Data *sel;
+
+ e = ev;
+ sel = e->data;
+ if (sel->free)
+ sel->free(sel);
+
+ free(e->target);
+ free(e);
+}
+
+static unsigned int
+_ecore_x_event_modifiers(unsigned int state)
+{
+ unsigned int modifiers = 0;
+
+ if (state & ECORE_X_MODIFIER_SHIFT)
+ modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+
+ if (state & ECORE_X_MODIFIER_CTRL)
+ modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+
+ if (state & ECORE_X_MODIFIER_ALT)
+ modifiers |= ECORE_EVENT_MODIFIER_ALT;
+
+ if (state & ECORE_X_MODIFIER_WIN)
+ modifiers |= ECORE_EVENT_MODIFIER_WIN;
+
+ if (state & ECORE_X_MODIFIER_ALTGR)
+ modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
+
+ if (state & ECORE_X_LOCK_SCROLL)
+ modifiers |= ECORE_EVENT_LOCK_SCROLL;
+
+ if (state & ECORE_X_LOCK_NUM)
+ modifiers |= ECORE_EVENT_LOCK_NUM;
+
+ if (state & ECORE_X_LOCK_CAPS)
+ modifiers |= ECORE_EVENT_LOCK_CAPS;
+
+ if (state & ECORE_X_LOCK_SHIFT)
+ modifiers |= ECORE_EVENT_LOCK_SHIFT;
+
+ return modifiers;
+}
+
+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,
+ int dev,
+ double radx,
+ double rady,
+ double pressure,
+ double angle,
+ double mx,
+ double my,
+ double mrx,
+ double mry)
+{
+ 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;
+
+ 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_x_event_free_mouse_move,
+ NULL);
+
+ _ecore_x_event_last_time = timestamp;
+ _ecore_x_event_last_win = window;
+ _ecore_x_event_last_root_x = x_root;
+ _ecore_x_event_last_root_y = y_root;
+
+ _ecore_x_last_event_mouse_move_event = event;
+}
+
+static void
+_ecore_key_press(int event,
+ XKeyEvent *xevent)
+{
+ Ecore_Event_Key *e;
+ 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_x_last_event_mouse_move = 0;
+ keyname = XKeysymToString(_ecore_x_XKeycodeToKeysym(xevent->display,
+ xevent->keycode, 0));
+ if (!keyname)
+ {
+ snprintf(keyname_buffer,
+ sizeof(keyname_buffer),
+ "Keycode-%i",
+ xevent->keycode);
+ keyname = keyname_buffer;
+ }
+
+ sym = 0;
+ key = NULL;
+ compose = NULL;
+ 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);
+ if (!compose)
+ ERR("Ecore_X cannot convert input key string '%s' to UTF-8. "
+ "Is Eina built with iconv support?", compose_buffer);
+ tmp = compose;
+ }
+
+ key = XKeysymToString(sym);
+ if (!key)
+ key = keyname;
+
+ 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_x_event_last_time = e->timestamp;
+
+on_error:
+ if (tmp)
+ free(tmp);
+}
+
+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,
+ int dev,
+ double radx,
+ double rady,
+ double pressure,
+ double angle,
+ double mx,
+ double my,
+ double mrx,
+ double mry)
+{
+ 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;
+
+ Ecore_X_Mouse_Down_Info *down_info = _ecore_x_mouse_down_info_get(dev);
+
+ if (down_info)
+ {
+ if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
+ down_info->did_triple)
+ {
+ down_info->last_win = 0;
+ down_info->last_last_win = 0;
+ down_info->last_event_win = 0;
+ down_info->last_last_event_win = 0;
+ down_info->last_time = 0;
+ down_info->last_last_time = 0;
+ }
+ if (event_window == window)
+ {
+ if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN)
+ {
+ //Check Double Clicked
+ if (((int)(timestamp - down_info->last_time) <=
+ (int)(1000 * _ecore_x_double_click_time)) &&
+ (window == down_info->last_win) &&
+ (event_window == down_info->last_event_win))
+ {
+ e->double_click = 1;
+ down_info->did_double = EINA_TRUE;
+ }
+ else
+ {
+ down_info->did_double = EINA_FALSE;
+ down_info->did_triple = EINA_FALSE;
+ }
+
+ //Check Triple Clicked
+ if (((int)(timestamp - down_info->last_last_time) <=
+ (int)(2 * 1000 * _ecore_x_double_click_time)) &&
+ (window == down_info->last_win) &&
+ (window == down_info->last_last_win) &&
+ (event_window == down_info->last_event_win) &&
+ (event_window == down_info->last_last_event_win)
+ )
+ {
+ e->triple_click = 1;
+ down_info->did_triple = EINA_TRUE;
+ }
+ else
+ {
+ down_info->did_triple = EINA_FALSE;
+ }
+ }
+ else
+ {
+ if (down_info->did_double)
+ e->double_click = 1;
+ if (down_info->did_triple)
+ e->triple_click = 1;
+ }
+ }
+ }
+
+ /* NB: Block commented out as _ecore_x_mouse_up_count appears to have
+ * no use. The variable is also commented out above. This code block is
+ * the only place that this variable is used, and appears to serve no
+ * purpose. - dh
+ if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN
+ && !e->double_click
+ && !e->triple_click)
+ _ecore_x_mouse_up_count = 0;
+ */
+
+ 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_x_event_last_time = e->timestamp;
+ _ecore_x_event_last_win = e->window;
+ _ecore_x_event_last_root_x = x_root;
+ _ecore_x_event_last_root_y = y_root;
+
+ ecore_event_add(event, e, NULL, NULL);
+
+ if ((down_info) &&
+ (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
+ (window == event_window) &&
+ (!down_info->did_triple))
+ {
+ down_info->last_last_win = down_info->last_win;
+ down_info->last_win = window;
+ down_info->last_last_event_win = down_info->last_event_win;
+ down_info->last_event_win = event_window;
+ down_info->last_last_time = down_info->last_time;
+ down_info->last_time = timestamp;
+ }
+
+ return e;
+}
+
+void
+_ecore_x_event_handle_any_event(XEvent *xevent)
+{
+ XEvent *ev = malloc(sizeof(XEvent));
+ if (!ev) return;
+ memcpy(ev, xevent, sizeof(XEvent));
+ ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_key_press(XEvent *xevent)
+{
+ _ecore_key_press(ECORE_EVENT_KEY_DOWN, (XKeyEvent *)xevent);
+}
+
+void
+_ecore_x_event_handle_key_release(XEvent *xevent)
+{
+ _ecore_key_press(ECORE_EVENT_KEY_UP, (XKeyEvent *)xevent);
+}
+
+void
+_ecore_x_event_handle_button_press(XEvent *xevent)
+{
+ int i;
+
+ _ecore_x_last_event_mouse_move = 0;
+ if ((xevent->xbutton.button > 3) && (xevent->xbutton.button < 8))
+ {
+ Ecore_Event_Mouse_Wheel *e;
+
+ e = malloc(sizeof(Ecore_Event_Mouse_Wheel));
+ if (!e)
+ return;
+
+ e->timestamp = xevent->xbutton.time;
+ e->modifiers = _ecore_x_event_modifiers(xevent->xbutton.state);
+ switch (xevent->xbutton.button)
+ {
+ 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 = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->root.x = xevent->xbutton.x_root;
+ e->root.y = xevent->xbutton.y_root;
+
+ if (xevent->xbutton.subwindow)
+ e->window = xevent->xbutton.subwindow;
+ else
+ e->window = xevent->xbutton.window;
+
+ e->event_window = xevent->xbutton.window;
+ e->same_screen = xevent->xbutton.same_screen;
+ e->root_window = xevent->xbutton.root;
+
+ _ecore_x_event_last_time = e->timestamp;
+ _ecore_x_event_last_win = e->window;
+ _ecore_x_event_last_root_x = xevent->xbutton.x_root;
+ _ecore_x_event_last_root_y = xevent->xbutton.y_root;
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
+
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if ((_ecore_window_grabs[i] == xevent->xbutton.window) ||
+ (_ecore_window_grabs[i] == xevent->xbutton.subwindow))
+ {
+ 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);
+
+ if (replay)
+ XAllowEvents(xevent->xbutton.display,
+ ReplayPointer, xevent->xbutton.time);
+ else
+ XAllowEvents(xevent->xbutton.display,
+ AsyncPointer, xevent->xbutton.time);
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ {
+ _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root,
+ xevent->xbutton.window,
+ (xevent->xbutton.subwindow ? xevent->xbutton.
+ subwindow : xevent->xbutton.window),
+ xevent->xbutton.root,
+ xevent->xbutton.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root);
+ }
+ {
+ Ecore_Event_Mouse_Button *e;
+ int event_window;
+ int window;
+
+ window =
+ (xevent->xbutton.subwindow ? xevent->xbutton.subwindow : xevent->
+ xbutton.window);
+ event_window = xevent->xbutton.window;
+
+ e = _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
+ xevent->xbutton.time,
+ xevent->xbutton.state,
+ xevent->xbutton.button,
+ xevent->xbutton.x,
+ xevent->xbutton.y,
+ xevent->xbutton.x_root,
+ xevent->xbutton.y_root,
+ event_window,
+ window,
+ xevent->xbutton.root,
+ xevent->xbutton.same_screen,
+ 0,
+ 1,
+ 1,
+ 1.0,
+// pressure
+ 0.0,
+// angle
+ xevent->xbutton.x,
+ xevent->xbutton.y,
+ xevent->xbutton.x_root,
+ xevent->xbutton.y_root);
+ if (e)
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if ((_ecore_window_grabs[i] == xevent->xbutton.window) ||
+ (_ecore_window_grabs[i] == xevent->xbutton.subwindow))
+ {
+ 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);
+
+ if (replay)
+ XAllowEvents(xevent->xbutton.display,
+ ReplayPointer, xevent->xbutton.time);
+ else
+ XAllowEvents(xevent->xbutton.display,
+ AsyncPointer, xevent->xbutton.time);
+
+ break;
+ }
+ }
+ }
+ }
+}
+
+void
+_ecore_x_event_handle_button_release(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ /* filter out wheel buttons */
+ if ((xevent->xbutton.button <= 3) || (xevent->xbutton.button > 7))
+ {
+ _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root,
+ xevent->xbutton.window,
+ (xevent->xbutton.subwindow ? xevent->xbutton.
+ subwindow : xevent->xbutton.window),
+ xevent->xbutton.root,
+ xevent->xbutton.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root);
+
+ _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP,
+ xevent->xbutton.time, xevent->xbutton.state,
+ xevent->xbutton.button,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root,
+ xevent->xbutton.window,
+ (xevent->xbutton.subwindow ? xevent->xbutton.
+ subwindow : xevent->xbutton.window),
+ xevent->xbutton.root,
+ xevent->xbutton.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root);
+ }
+}
+
+void
+_ecore_x_event_handle_motion_notify(XEvent *xevent)
+{
+/*
+ if (_ecore_x_last_event_mouse_move)
+ {
+ ecore_event_del(_ecore_x_last_event_mouse_move_event);
+ _ecore_x_last_event_mouse_move = 0;
+ _ecore_x_last_event_mouse_move_event = NULL;
+ }
+ */
+ _ecore_mouse_move(xevent->xmotion.time, xevent->xmotion.state,
+ xevent->xmotion.x, xevent->xmotion.y,
+ xevent->xmotion.x_root, xevent->xmotion.y_root,
+ xevent->xmotion.window,
+ (xevent->xmotion.subwindow ? xevent->xmotion.subwindow :
+ xevent->xmotion.window),
+ xevent->xmotion.root,
+ xevent->xmotion.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xmotion.x, xevent->xmotion.y,
+ xevent->xmotion.x_root, xevent->xmotion.y_root);
+
+ _ecore_x_last_event_mouse_move = 1;
+
+ /* Xdnd handling */
+ _ecore_x_dnd_drag(xevent->xmotion.root,
+ xevent->xmotion.x_root,
+ xevent->xmotion.y_root);
+}
+
+void
+_ecore_x_event_handle_enter_notify(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ {
+ _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
+ xevent->xcrossing.x, xevent->xcrossing.y,
+ xevent->xcrossing.x_root, xevent->xcrossing.y_root,
+ xevent->xcrossing.window,
+ (xevent->xcrossing.subwindow ? xevent->xcrossing.
+ subwindow : xevent->xcrossing.window),
+ xevent->xcrossing.root,
+ xevent->xcrossing.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xcrossing.x, xevent->xcrossing.y,
+ xevent->xcrossing.x_root, xevent->xcrossing.y_root);
+ }
+ {
+ Ecore_X_Event_Mouse_In *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
+ if (!e)
+ return;
+
+ e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->root.x = xevent->xcrossing.x_root;
+ e->root.y = xevent->xcrossing.y_root;
+ if (xevent->xcrossing.subwindow)
+ e->win = xevent->xcrossing.subwindow;
+ else
+ e->win = xevent->xcrossing.window;
+
+ e->same_screen = xevent->xcrossing.same_screen;
+ e->root_win = xevent->xcrossing.root;
+ e->event_win = xevent->xcrossing.window;
+
+ if (xevent->xcrossing.mode == NotifyNormal)
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xcrossing.mode == NotifyGrab)
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xcrossing.mode == NotifyUngrab)
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+
+ if (xevent->xcrossing.detail == NotifyAncestor)
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xcrossing.detail == NotifyVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xcrossing.detail == NotifyInferior)
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xcrossing.detail == NotifyNonlinear)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+
+ e->time = xevent->xcrossing.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_leave_notify(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ {
+ _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
+ xevent->xcrossing.x, xevent->xcrossing.y,
+ xevent->xcrossing.x_root, xevent->xcrossing.y_root,
+ xevent->xcrossing.window,
+ (xevent->xcrossing.subwindow ? xevent->xcrossing.
+ subwindow : xevent->xcrossing.window),
+ xevent->xcrossing.root,
+ xevent->xcrossing.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xcrossing.x, xevent->xcrossing.y,
+ xevent->xcrossing.x_root, xevent->xcrossing.y_root);
+ }
+ {
+ Ecore_X_Event_Mouse_Out *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
+ if (!e)
+ return;
+
+ e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->root.x = xevent->xcrossing.x_root;
+ e->root.y = xevent->xcrossing.y_root;
+ if (xevent->xcrossing.subwindow)
+ e->win = xevent->xcrossing.subwindow;
+ else
+ e->win = xevent->xcrossing.window;
+
+ e->same_screen = xevent->xcrossing.same_screen;
+ e->root_win = xevent->xcrossing.root;
+ e->event_win = xevent->xcrossing.window;
+
+ if (xevent->xcrossing.mode == NotifyNormal)
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xcrossing.mode == NotifyGrab)
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xcrossing.mode == NotifyUngrab)
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+
+ if (xevent->xcrossing.detail == NotifyAncestor)
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xcrossing.detail == NotifyVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xcrossing.detail == NotifyInferior)
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xcrossing.detail == NotifyNonlinear)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+
+ e->time = xevent->xcrossing.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_focus_in(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Focus_In *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
+ if (!e)
+ return;
+
+ e->win = xevent->xfocus.window;
+
+ if (xevent->xfocus.mode == NotifyNormal)
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xfocus.mode == NotifyWhileGrabbed)
+ e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
+ else if (xevent->xfocus.mode == NotifyGrab)
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xfocus.mode == NotifyUngrab)
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+
+ if (xevent->xfocus.detail == NotifyAncestor)
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xfocus.detail == NotifyVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyInferior)
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xfocus.detail == NotifyNonlinear)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyPointer)
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER;
+ else if (xevent->xfocus.detail == NotifyPointerRoot)
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
+ else if (xevent->xfocus.detail == NotifyDetailNone)
+ e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
+
+ e->time = _ecore_x_event_last_time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_focus_out(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Focus_Out *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
+ if (!e)
+ return;
+
+ e->win = xevent->xfocus.window;
+
+ if (xevent->xfocus.mode == NotifyNormal)
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xfocus.mode == NotifyWhileGrabbed)
+ e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
+ else if (xevent->xfocus.mode == NotifyGrab)
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xfocus.mode == NotifyUngrab)
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+
+ if (xevent->xfocus.detail == NotifyAncestor)
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xfocus.detail == NotifyVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyInferior)
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xfocus.detail == NotifyNonlinear)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyPointer)
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER;
+ else if (xevent->xfocus.detail == NotifyPointerRoot)
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
+ else if (xevent->xfocus.detail == NotifyDetailNone)
+ e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
+
+ e->time = _ecore_x_event_last_time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_keymap_notify(XEvent *xevent EINA_UNUSED)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ /* FIXME: handle this event type */
+}
+
+void
+_ecore_x_event_handle_expose(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Damage *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
+ if (!e)
+ return;
+
+ e->win = xevent->xexpose.window;
+ e->time = _ecore_x_event_last_time;
+ e->x = xevent->xexpose.x;
+ e->y = xevent->xexpose.y;
+ e->w = xevent->xexpose.width;
+ e->h = xevent->xexpose.height;
+ e->count = xevent->xexpose.count;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_graphics_expose(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Damage *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
+ if (!e)
+ return;
+
+ e->win = xevent->xgraphicsexpose.drawable;
+ e->time = _ecore_x_event_last_time;
+ e->x = xevent->xgraphicsexpose.x;
+ e->y = xevent->xgraphicsexpose.y;
+ e->w = xevent->xgraphicsexpose.width;
+ e->h = xevent->xgraphicsexpose.height;
+ e->count = xevent->xgraphicsexpose.count;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_visibility_notify(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+// if (xevent->xvisibility.state != VisibilityPartiallyObscured)
+ {
+ Ecore_X_Event_Window_Visibility_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
+ if (!e)
+ return;
+
+ e->win = xevent->xvisibility.window;
+ e->time = _ecore_x_event_last_time;
+ if (xevent->xvisibility.state == VisibilityFullyObscured)
+ e->fully_obscured = 1;
+ else
+ e->fully_obscured = 0;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_create_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Create *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
+ if (!e)
+ return;
+
+ e->win = xevent->xcreatewindow.window;
+ e->parent = xevent->xcreatewindow.parent;
+ if (xevent->xcreatewindow.override_redirect)
+ e->override = 1;
+ else
+ e->override = 0;
+
+ e->x = xevent->xcreatewindow.x;
+ e->y = xevent->xcreatewindow.y;
+ e->w = xevent->xcreatewindow.width;
+ e->h = xevent->xcreatewindow.height;
+ e->border = xevent->xcreatewindow.border_width;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_destroy_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Destroy *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
+ if (!e)
+ return;
+
+ e->win = xevent->xdestroywindow.window;
+ e->event_win = xevent->xdestroywindow.event;
+ e->time = _ecore_x_event_last_time;
+ if (e->win == _ecore_x_event_last_win)
+ _ecore_x_event_last_win = 0;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_unmap_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Hide *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
+ if (!e)
+ return;
+
+ e->win = xevent->xunmap.window;
+ e->event_win = xevent->xunmap.event;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_map_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Show *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
+ if (!e)
+ return;
+
+ e->win = xevent->xmap.window;
+ e->event_win = xevent->xmap.event;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_map_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Show_Request *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
+ if (!e)
+ return;
+
+ e->win = xevent->xmaprequest.window;
+ e->time = _ecore_x_event_last_time;
+ e->parent = xevent->xmaprequest.parent;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_reparent_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Reparent *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
+ if (!e)
+ return;
+
+ e->win = xevent->xreparent.window;
+ e->event_win = xevent->xreparent.event;
+ e->parent = xevent->xreparent.parent;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_configure_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Configure *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
+ if (!e)
+ return;
+
+ e->win = xevent->xconfigure.window;
+ e->event_win = xevent->xconfigure.event;
+ e->abovewin = xevent->xconfigure.above;
+ e->x = xevent->xconfigure.x;
+ e->y = xevent->xconfigure.y;
+ e->w = xevent->xconfigure.width;
+ e->h = xevent->xconfigure.height;
+ e->border = xevent->xconfigure.border_width;
+ e->override = xevent->xconfigure.override_redirect;
+ e->from_wm = xevent->xconfigure.send_event;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_configure_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Configure_Request *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
+ if (!e)
+ return;
+
+ e->win = xevent->xconfigurerequest.window;
+ e->parent_win = xevent->xconfigurerequest.parent;
+ e->abovewin = xevent->xconfigurerequest.above;
+ e->x = xevent->xconfigurerequest.x;
+ e->y = xevent->xconfigurerequest.y;
+ e->w = xevent->xconfigurerequest.width;
+ e->h = xevent->xconfigurerequest.height;
+ e->border = xevent->xconfigurerequest.border_width;
+ e->value_mask = xevent->xconfigurerequest.value_mask;
+ e->time = _ecore_x_event_last_time;
+
+ if (xevent->xconfigurerequest.detail == Above)
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ else if (xevent->xconfigurerequest.detail == Below)
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+ else if (xevent->xconfigurerequest.detail == TopIf)
+ e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
+ else if (xevent->xconfigurerequest.detail == BottomIf)
+ e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
+ else if (xevent->xconfigurerequest.detail == Opposite)
+ e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_gravity_notify(XEvent *xevent EINA_UNUSED)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ /* FIXME: handle this event type */
+}
+
+void
+_ecore_x_event_handle_resize_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Resize_Request *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
+ if (!e)
+ return;
+
+ e->win = xevent->xresizerequest.window;
+ e->w = xevent->xresizerequest.width;
+ e->h = xevent->xresizerequest.height;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_circulate_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Stack *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
+ if (!e)
+ return;
+
+ e->win = xevent->xcirculate.window;
+ e->event_win = xevent->xcirculate.event;
+ if (xevent->xcirculate.place == PlaceOnTop)
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ else
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_circulate_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Stack_Request *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
+ if (!e)
+ return;
+
+ e->win = xevent->xcirculaterequest.window;
+ e->parent = xevent->xcirculaterequest.parent;
+ if (xevent->xcirculaterequest.place == PlaceOnTop)
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ else
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_property_notify(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ {
+ Ecore_X_Event_Window_Property *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Property));
+ if (!e)
+ return;
+
+ e->win = xevent->xproperty.window;
+ e->atom = xevent->xproperty.atom;
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_selection_clear(XEvent *xevent)
+{
+// Ecore_X_Selection_Intern *d;
+ Ecore_X_Event_Selection_Clear *e;
+ Ecore_X_Atom sel;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_last_event_mouse_move = 0;
+/* errr..... why? paranoia.
+ d = _ecore_x_selection_get(xevent->xselectionclear.selection);
+ if (d && (xevent->xselectionclear.time > d->time))
+ {
+ _ecore_x_selection_set(None, NULL, 0,
+ xevent->xselectionclear.selection);
+ }
+ */
+/* Generate event for app cleanup */
+ e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
+ e->win = xevent->xselectionclear.window;
+ e->time = xevent->xselectionclear.time;
+ e->atom = sel = xevent->xselectionclear.selection;
+ if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+
+ ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_selection_request(XEvent *xevent)
+{
+ Ecore_X_Event_Selection_Request *e;
+ Ecore_X_Selection_Intern *sd;
+ void *data = NULL;
+ int len;
+ int typesize;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_last_event_mouse_move = 0;
+ /*
+ * Generate a selection request event.
+ */
+ e = malloc(sizeof(Ecore_X_Event_Selection_Request));
+ e->owner = xevent->xselectionrequest.owner;
+ e->requestor = xevent->xselectionrequest.requestor;
+ e->time = xevent->xselectionrequest.time;
+ e->selection = xevent->xselectionrequest.selection;
+ e->target = xevent->xselectionrequest.target;
+ e->property = xevent->xselectionrequest.property;
+ ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL);
+
+ if ((sd = _ecore_x_selection_get(xevent->xselectionrequest.selection)) &&
+ (sd->win == xevent->xselectionrequest.owner))
+ {
+ Ecore_X_Selection_Intern *si;
+
+ si = _ecore_x_selection_get(xevent->xselectionrequest.selection);
+ if (si->data)
+ {
+ Ecore_X_Atom property = None;
+ Ecore_X_Atom type;
+
+ /* Set up defaults for strings first */
+ type = xevent->xselectionrequest.target;
+ typesize = 8;
+ len = sd->length;
+
+ if (!ecore_x_selection_convert(xevent->xselectionrequest.selection,
+ xevent->xselectionrequest.target,
+ &data, &len, &type, &typesize))
+ /* Refuse selection, conversion to requested target failed */
+ property = None;
+ else if (data)
+ {
+ /* FIXME: This does not properly handle large data transfers */
+ ecore_x_window_prop_property_set(
+ xevent->xselectionrequest.requestor,
+ xevent->xselectionrequest.
+ property,
+ type,
+ typesize,
+ data,
+ len);
+ property = xevent->xselectionrequest.property;
+ free(data);
+ }
+
+ ecore_x_selection_notify_send(xevent->xselectionrequest.requestor,
+ xevent->xselectionrequest.selection,
+ xevent->xselectionrequest.target,
+ property,
+ xevent->xselectionrequest.time);
+ }
+ }
+}
+
+void
+_ecore_x_event_handle_selection_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Selection_Notify *e;
+ unsigned char *data = NULL;
+ Ecore_X_Atom selection;
+ int num_ret, format;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_last_event_mouse_move = 0;
+ selection = xevent->xselection.selection;
+
+ if (xevent->xselection.target == ECORE_X_ATOM_SELECTION_TARGETS)
+ {
+ format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
+ xevent->xselection.property,
+ XA_ATOM, 32, &data, &num_ret);
+ if (!format)
+ {
+ /* fallback if targets handling is not working and try get the
+ * selection directly */
+ XConvertSelection(_ecore_x_disp, selection,
+ ECORE_X_ATOM_UTF8_STRING,
+ selection,
+ xevent->xselection.requestor,
+ CurrentTime);
+ return;
+ }
+ }
+ else
+ format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
+ xevent->xselection.property,
+ AnyPropertyType, 8, &data,
+ &num_ret);
+
+ e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
+ if (!e)
+ return;
+
+ e->win = xevent->xselection.requestor;
+ e->time = xevent->xselection.time;
+ e->atom = selection;
+ e->target = _ecore_x_selection_target_get(xevent->xselection.target);
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ e->selection = ECORE_X_SELECTION_XDND;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+
+ e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);
+
+ ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e,
+ _ecore_x_event_free_selection_notify, NULL);
+}
+
+void
+_ecore_x_event_handle_colormap_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Colormap *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Colormap));
+ if (!e)
+ return;
+
+ e->win = xevent->xcolormap.window;
+ e->cmap = xevent->xcolormap.colormap;
+ e->time = _ecore_x_event_last_time;
+ if (xevent->xcolormap.state == ColormapInstalled)
+ e->installed = EINA_TRUE;
+ else
+ e->installed = EINA_FALSE;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_client_message(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ /* 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 */
+ if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) &&
+ (xevent->xclient.format == 32) &&
+ (xevent->xclient.data.l[0] == (long)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;
+
+ e->win = xevent->xclient.window;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
+ (xevent->xclient.format == 32) &&
+/* Ignore move and resize with keyboard */
+ (xevent->xclient.data.l[2] < 9))
+ {
+ Ecore_X_Event_Window_Move_Resize_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
+ if (!e)
+ return;
+
+ e->win = xevent->xclient.window;
+ e->x = xevent->xclient.data.l[0];
+ e->y = xevent->xclient.data.l[1];
+ e->direction = xevent->xclient.data.l[2];
+ e->button = xevent->xclient.data.l[3];
+ e->source = xevent->xclient.data.l[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 (xevent->xclient.message_type == ECORE_X_ATOM_XDND_ENTER)
+ {
+ Ecore_X_Event_Xdnd_Enter *e;
+ Ecore_X_DND_Target *target;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
+ if (!e) return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ target = _ecore_x_dnd_target_get();
+ target->state = ECORE_X_DND_TARGET_ENTERED;
+ target->source = xevent->xclient.data.l[0];
+ target->win = xevent->xclient.window;
+ target->version = (int)(xevent->xclient.data.l[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);
+ free(e);
+ return;
+ }
+
+ if (xevent->xclient.data.l[1] & 0x1UL)
+ {
+ /* source supports more than 3 types, fetch property */
+ unsigned char *data;
+ Ecore_X_Atom *types;
+ int i, num_ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!(ecore_x_window_prop_property_get(target->source,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM,
+ 32, &data, &num_ret)))
+ {
+ WRN(
+ "DND: Could not fetch data type list from source window, aborting.");
+ free(e);
+ return;
+ }
+
+ types = (Ecore_X_Atom *)data;
+ e->types = calloc(num_ret, sizeof(char *));
+ if (e->types)
+ {
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ for (i = 0; i < num_ret; i++)
+ e->types[i] = XGetAtomName(_ecore_x_disp, types[i]);
+ }
+
+ e->num_types = num_ret;
+ }
+ else
+ {
+ int i = 0;
+
+ e->types = calloc(3, sizeof(char *));
+ if (e->types)
+ {
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ while ((i < 3) && (xevent->xclient.data.l[i + 2]))
+ {
+ e->types[i] = XGetAtomName(_ecore_x_disp,
+ xevent->xclient.data.l[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);
+ }
+ /* Message Type: XdndPosition target */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_POSITION)
+ {
+ Ecore_X_Event_Xdnd_Position *e;
+ Ecore_X_DND_Target *target;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ target = _ecore_x_dnd_target_get();
+ if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
+ (target->win != xevent->xclient.window))
+ return;
+
+ target->pos.x = xevent->xclient.data.l[2] >> 16;
+ target->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL;
+ target->action = xevent->xclient.data.l[4]; /* Version 2 */
+
+ target->time = (target->version >= 1) ?
+ (Time)xevent->xclient.data.l[3] : CurrentTime;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
+ if (!e) return;
+
+ e->win = target->win;
+ e->source = target->source;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ e->action = target->action;
+ ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
+ }
+ /* Message Type: XdndStatus source */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_STATUS)
+ {
+ Ecore_X_Event_Xdnd_Status *e;
+ Ecore_X_DND_Source *source;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ source = _ecore_x_dnd_source_get();
+ /* Make sure source/target match */
+ if ((source->win != xevent->xclient.window) ||
+ (source->dest != (Window)xevent->xclient.data.l[0]))
+ return;
+
+ source->await_status = 0;
+
+ source->will_accept = xevent->xclient.data.l[1] & 0x1UL;
+ source->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1;
+
+ source->rectangle.x = xevent->xclient.data.l[2] >> 16;
+ source->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL;
+ source->rectangle.width = xevent->xclient.data.l[3] >> 16;
+ source->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL;
+
+ source->accepted_action = xevent->xclient.data.l[4];
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
+ if (!e) return;
+
+ e->win = source->win;
+ e->target = source->dest;
+ e->will_accept = source->will_accept;
+ e->rectangle.x = source->rectangle.x;
+ e->rectangle.y = source->rectangle.y;
+ e->rectangle.width = source->rectangle.width;
+ e->rectangle.height = source->rectangle.height;
+ e->action = source->accepted_action;
+
+ 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 (xevent->xclient.message_type == ECORE_X_ATOM_XDND_LEAVE)
+ {
+ Ecore_X_Event_Xdnd_Leave *e;
+ Ecore_X_DND_Target *target;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ target = _ecore_x_dnd_target_get();
+ if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
+ (target->win != xevent->xclient.window))
+ return;
+
+ target->state = ECORE_X_DND_TARGET_IDLE;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
+ if (!e) return;
+
+ e->win = xevent->xclient.window;
+ e->source = (Window)xevent->xclient.data.l[0];
+ ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
+ }
+ /* Message Type: XdndDrop target */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_DROP)
+ {
+ Ecore_X_Event_Xdnd_Drop *e;
+ Ecore_X_DND_Target *target;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ target = _ecore_x_dnd_target_get();
+ /* Match source/target */
+ if ((target->source != (Window)xevent->xclient.data.l[0]) ||
+ (target->win != xevent->xclient.window))
+ return;
+
+ target->time = (target->version >= 1) ?
+ (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
+ if (!e) return;
+
+ e->win = target->win;
+ e->source = target->source;
+ e->action = target->action;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
+ }
+ /* Message Type: XdndFinished source */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_FINISHED)
+ {
+ Ecore_X_Event_Xdnd_Finished *e;
+ Ecore_X_DND_Source *source;
+ Eina_Bool completed = EINA_TRUE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ source = _ecore_x_dnd_source_get();
+ /* Match source/target */
+ if ((source->win != xevent->xclient.window) ||
+ (source->dest != (Window)xevent->xclient.data.l[0]))
+ return;
+
+ if ((source->version < 5) || (xevent->xclient.data.l[1] & 0x1UL))
+ {
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* Target successfully performed drop action */
+ ecore_x_selection_xdnd_clear();
+ source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ else if (source->version >= 5)
+ {
+ completed = EINA_FALSE;
+ source->state = ECORE_X_DND_SOURCE_CONVERTING;
+
+ /* 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;
+
+ e->win = source->win;
+ e->target = source->dest;
+ e->completed = completed;
+ if (source->version >= 5)
+ {
+ source->accepted_action = xevent->xclient.data.l[2];
+ e->action = source->accepted_action;
+ }
+ else
+ {
+ source->accepted_action = 0;
+ e->action = source->action;
+ }
+
+ ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
+ }
+ else if (xevent->xclient.message_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;
+
+ e->win = xevent->xclient.window;
+ if (xevent->xclient.data.l[0] == 0)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
+ else if (xevent->xclient.data.l[0] == 1)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
+ else if (xevent->xclient.data.l[0] == 2)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
+ else
+ {
+ free(e);
+ return;
+ }
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ e->state[0] = _ecore_x_netwm_state_get(xevent->xclient.data.l[1]);
+ if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+// char *name;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+// name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[1]);
+// if (name) ERR("Unknown state: %s", name);
+// XFree(name);
+ }
+ e->state[1] = _ecore_x_netwm_state_get(xevent->xclient.data.l[2]);
+ if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+// char *name;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+// name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[2]);
+// if (name) ERR("Unknown state: %s", name);
+// XFree(name);
+ }
+
+ e->source = xevent->xclient.data.l[3];
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_CHANGE_STATE)
+ && (xevent->xclient.format == 32)
+ && (xevent->xclient.data.l[0] == IconicState))
+ {
+ Ecore_X_Event_Window_State_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
+ if (!e)
+ return;
+
+ e->win = xevent->xclient.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 ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_DESKTOP)
+ && (xevent->xclient.format == 32))
+ {
+ Ecore_X_Event_Desktop_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
+ if (!e)
+ return;
+
+ e->win = xevent->xclient.window;
+ e->desk = xevent->xclient.data.l[0];
+ e->source = xevent->xclient.data.l[1];
+
+ ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_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;
+
+ e->win = xevent->xclient.window;
+
+ ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS)
+ && ((Ecore_X_Atom)xevent->xclient.data.l[0] ==
+ ECORE_X_ATOM_NET_WM_PING)
+ && (xevent->xclient.format == 32))
+ {
+ Ecore_X_Event_Ping *e;
+ Ecore_X_Window root = 0;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Ping));
+ if (!e)
+ return;
+
+ e->win = xevent->xclient.window;
+ e->time = xevent->xclient.data.l[1];
+ e->event_win = xevent->xclient.data.l[2];
+
+ /* send a reply anyway - we are alive... eventloop at least */
+ ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
+ if (ScreenCount(_ecore_x_disp) > 1)
+ {
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ root = ecore_x_window_root_get(e->win);
+ }
+ else
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ if (xevent->xclient.window != root)
+ {
+ xevent->xclient.window = root;
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ xevent);
+ }
+ }
+ else if ((xevent->xclient.message_type ==
+ ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
+ (xevent->xclient.format == 8))
+ _ecore_x_netwm_startup_info_begin(xevent->xclient.window,
+ xevent->xclient.data.b);
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
+ (xevent->xclient.format == 8))
+ _ecore_x_netwm_startup_info(xevent->xclient.window,
+ xevent->xclient.data.b);
+ else if ((xevent->xclient.message_type == 27777)
+ && (xevent->xclient.data.l[0] == 0x7162534)
+ && (xevent->xclient.format == 32)
+ && (xevent->xclient.window == _ecore_x_private_win))
+ {
+ /* a grab sync marker */
+ if (xevent->xclient.data.l[1] == 0x10000001)
+ _ecore_x_window_grab_remove(xevent->xclient.data.l[2]);
+ else if (xevent->xclient.data.l[1] == 0x10000002)
+ _ecore_x_key_grab_remove(xevent->xclient.data.l[2]);
+ }
+ else
+ {
+ Ecore_X_Event_Client_Message *e;
+ int i;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
+ if (!e)
+ return;
+
+ e->win = xevent->xclient.window;
+ e->message_type = xevent->xclient.message_type;
+ e->format = xevent->xclient.format;
+ for (i = 0; i < 5; i++)
+ e->data.l[i] = xevent->xclient.data.l[i];
+
+ ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_mapping_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Mapping_Change *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ XRefreshKeyboardMapping((XMappingEvent *)xevent);
+ _ecore_x_modifiers_get();
+ e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change));
+ if (!e) return;
+ switch (xevent->xmapping.request)
+ {
+ case MappingModifier:
+ e->type = ECORE_X_MAPPING_MODIFIER;
+ break;
+
+ case MappingKeyboard:
+ e->type = ECORE_X_MAPPING_KEYBOARD;
+ break;
+
+ case MappingPointer:
+ default:
+ e->type = ECORE_X_MAPPING_MOUSE;
+ break;
+ }
+ e->keycode = xevent->xmapping.first_keycode;
+ e->num = xevent->xmapping.count;
+ ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_shape_change(XEvent *xevent)
+{
+ XShapeEvent *shape_event;
+ Ecore_X_Event_Window_Shape *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ shape_event = (XShapeEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
+ if (!e)
+ return;
+
+ e->win = shape_event->window;
+ e->time = shape_event->time;
+ switch (shape_event->kind)
+ {
+ case ShapeBounding:
+ e->type = ECORE_X_SHAPE_BOUNDING;
+ break;
+
+ case ShapeClip:
+ e->type = ECORE_X_SHAPE_CLIP;
+ break;
+
+ case ShapeInput:
+ e->type = ECORE_X_SHAPE_INPUT;
+ break;
+
+ default:
+ break;
+ }
+ e->x = shape_event->x;
+ e->y = shape_event->y;
+ e->w = shape_event->width;
+ e->h = shape_event->height;
+ e->shaped = shape_event->shaped;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_screensaver_notify(XEvent *xevent)
+{
+#ifdef ECORE_XSS
+ XScreenSaverNotifyEvent *screensaver_event;
+ Ecore_X_Event_Screensaver_Notify *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ screensaver_event = (XScreenSaverNotifyEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify));
+ if (!e)
+ return;
+
+ e->win = screensaver_event->window;
+ if ((screensaver_event->state == ScreenSaverOn) ||
+ (screensaver_event->state == ScreenSaverCycle))
+ e->on = EINA_TRUE;
+ else
+ e->on = EINA_FALSE;
+
+ e->time = screensaver_event->time;
+ ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
+#else /* ifdef ECORE_XSS */
+ xevent = NULL;
+#endif /* ifdef ECORE_XSS */
+}
+
+void
+_ecore_x_event_handle_sync_counter(XEvent *xevent)
+{
+ XSyncCounterNotifyEvent *sync_counter_event;
+ Ecore_X_Event_Sync_Counter *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ sync_counter_event = (XSyncCounterNotifyEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
+ if (!e)
+ return;
+
+ e->time = sync_counter_event->time;
+ ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_sync_alarm(XEvent *xevent)
+{
+ XSyncAlarmNotifyEvent *sync_alarm_event;
+ Ecore_X_Event_Sync_Alarm *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ sync_alarm_event = (XSyncAlarmNotifyEvent *)xevent;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
+ if (!e)
+ return;
+
+ e->time = sync_alarm_event->time;
+ e->alarm = sync_alarm_event->alarm;
+ ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
+}
+
+#ifdef ECORE_XRANDR
+void
+_ecore_x_event_handle_randr_change(XEvent *xevent)
+{
+ XRRScreenChangeNotifyEvent *randr_event;
+ Ecore_X_Event_Screen_Change *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ randr_event = (XRRScreenChangeNotifyEvent *)xevent;
+ if (!XRRUpdateConfiguration(xevent))
+ ERR("Can't update RR config!");
+
+ e = calloc(1, sizeof(Ecore_X_Event_Screen_Change));
+ if (!e)
+ return;
+
+ e->win = randr_event->window;
+ e->root = randr_event->root;
+ e->size.width = randr_event->width;
+ e->size.height = randr_event->height;
+ e->time = randr_event->timestamp;
+ e->config_time = randr_event->config_timestamp;
+ e->size.width_mm = randr_event->mwidth;
+ e->size.height_mm = randr_event->mheight;
+ e->orientation = randr_event->rotation;
+ e->subpixel_order = randr_event->subpixel_order;
+ ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
+}
+
+static void
+_ecore_x_event_handle_randr_notify_crtc_change(const XRRNotifyEvent *xevent)
+{
+ const XRRCrtcChangeNotifyEvent *randr_event;
+ Ecore_X_Event_Randr_Crtc_Change *e;
+
+ randr_event = (const XRRCrtcChangeNotifyEvent *)xevent;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change));
+ if (!e)
+ return;
+
+ e->win = randr_event->window;
+ e->crtc = randr_event->crtc;
+ e->mode = randr_event->mode;
+ e->orientation = randr_event->rotation;
+ e->geo.x = randr_event->x;
+ e->geo.y = randr_event->y;
+ e->geo.w = randr_event->width;
+ e->geo.h = randr_event->height;
+ ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL);
+}
+
+static void
+_ecore_x_event_handle_randr_notify_output_change(const XRRNotifyEvent *xevent)
+{
+ const XRROutputChangeNotifyEvent *randr_event;
+ Ecore_X_Event_Randr_Output_Change *e;
+
+ randr_event = (const XRROutputChangeNotifyEvent *)xevent;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Change));
+ if (!e)
+ return;
+
+ e->win = randr_event->window;
+ e->output = randr_event->output;
+ e->crtc = randr_event->crtc;
+ e->mode = randr_event->mode;
+ e->orientation = randr_event->rotation;
+ e->connection = randr_event->connection;
+ e->subpixel_order = randr_event->subpixel_order;
+ ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL);
+}
+
+static void
+_ecore_x_event_handle_randr_notify_output_property(const XRRNotifyEvent *xevent)
+{
+ const XRROutputPropertyNotifyEvent *randr_event;
+ Ecore_X_Event_Randr_Output_Property_Notify *e;
+
+ randr_event = (const XRROutputPropertyNotifyEvent *)xevent;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify));
+ if (!e)
+ return;
+
+ e->win = randr_event->window;
+ e->output = randr_event->output;
+ e->property = randr_event->property;
+ e->time = randr_event->timestamp;
+ if (randr_event->state == PropertyNewValue)
+ 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);
+}
+
+void
+_ecore_x_event_handle_randr_notify(XEvent *xevent)
+{
+ const XRRNotifyEvent *randr_event;
+
+ _ecore_x_last_event_mouse_move = 0;
+ randr_event = (const XRRNotifyEvent *)xevent;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch (randr_event->subtype)
+ {
+ case RRNotify_CrtcChange:
+ _ecore_x_event_handle_randr_notify_crtc_change(randr_event);
+ break;
+
+ case RRNotify_OutputChange:
+ _ecore_x_event_handle_randr_notify_output_change(randr_event);
+ break;
+
+ case RRNotify_OutputProperty:
+ _ecore_x_event_handle_randr_notify_output_property(randr_event);
+ break;
+
+ default:
+ ERR("Unknown XRandR RRNotify subtype: %d.",
+ randr_event->subtype);
+ break;
+ }
+}
+
+#endif /* ifdef ECORE_XRANDR */
+
+#ifdef ECORE_XFIXES
+void
+_ecore_x_event_handle_fixes_selection_notify(XEvent *event)
+{
+ XFixesSelectionNotifyEvent *notify_event =
+ (XFixesSelectionNotifyEvent *)event;
+ Ecore_X_Event_Fixes_Selection_Notify *e;
+ Ecore_X_Atom sel;
+
+ _ecore_x_last_event_mouse_move = 0;
+ /* Nothing here yet */
+
+ e = calloc(1, sizeof(*e));
+ if (!e)
+ return;
+
+ e->win = notify_event->window;
+ e->owner = notify_event->owner;
+ e->time = notify_event->timestamp;
+ e->selection_time = notify_event->selection_timestamp;
+ e->atom = sel = notify_event->selection;
+ if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+ e->reason = notify_event->subtype;
+
+ ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
+}
+
+#endif /* ifdef ECORE_XFIXES */
+
+#ifdef ECORE_XDAMAGE
+void
+_ecore_x_event_handle_damage_notify(XEvent *event)
+{
+ XDamageNotifyEvent *damage_event;
+ Ecore_X_Event_Damage *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ damage_event = (XDamageNotifyEvent *)event;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Damage));
+ if (!e)
+ return;
+
+ e->level = damage_event->level;
+ e->drawable = damage_event->drawable;
+ e->damage = damage_event->damage;
+ e->more = damage_event->more;
+ e->time = damage_event->timestamp;
+ e->area.x = damage_event->area.x;
+ e->area.y = damage_event->area.y;
+ e->area.width = damage_event->area.width;
+ e->area.height = damage_event->area.height;
+ e->geometry.x = damage_event->geometry.x;
+ e->geometry.y = damage_event->geometry.y;
+ e->geometry.width = damage_event->geometry.width;
+ e->geometry.height = damage_event->geometry.height;
+
+ ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
+}
+
+#endif /* ifdef ECORE_XDAMAGE */
+
+static void
+_ecore_x_event_free_generic_event(void *data,
+ void *ev)
+{
+#ifdef ECORE_XI2
+ Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic *)ev;
+
+ if (data)
+ {
+ if (e->data)
+ XFreeEventData(_ecore_x_disp, (XGenericEventCookie *)data);
+ free(data);
+ }
+ free(e);
+#else
+ return;
+ data = NULL; ev = NULL;
+#endif /* ifdef ECORE_XI2 */
+}
+
+void
+_ecore_x_event_handle_generic_event(XEvent *event)
+{
+#ifdef ECORE_XI2
+ XGenericEvent *generic_event;
+ Ecore_X_Event_Generic *e;
+ XGenericEventCookie *data;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ generic_event = (XGenericEvent *)event;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Generic));
+ if (!e)
+ return;
+
+ if (XGetEventData(_ecore_x_disp, &(event->xcookie)))
+ {
+ e->cookie = event->xcookie.cookie;
+ e->data = event->xcookie.data;
+ }
+ else
+ {
+ e->cookie = 0;
+ e->data = NULL;
+ }
+
+ e->extension = generic_event->extension;
+ e->evtype = generic_event->evtype;
+
+ if (e->extension == _ecore_x_xi2_opcode)
+ _ecore_x_input_handler(event);
+
+ data = malloc(sizeof(XGenericEventCookie));
+ if (data) memcpy(data, &(event->xcookie), sizeof(XGenericEventCookie));
+ ecore_event_add(ECORE_X_EVENT_GENERIC,
+ e,
+ _ecore_x_event_free_generic_event,
+ data);
+#else
+ return;
+ event = NULL;
+#endif /* ifdef ECORE_XI2 */
+}
+
+#ifdef ECORE_XGESTURE
+void
+_ecore_x_event_handle_gesture_notify_flick(XEvent *xevent)
+{
+ XGestureNotifyFlickEvent *xfe;
+ Ecore_X_Event_Gesture_Notify_Flick *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xfe = (XGestureNotifyFlickEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Flick));
+ if (!e)
+ return;
+
+ e->win = xfe->window;
+ e->time = xfe->time;
+ e->subtype = xfe->kind;
+ e->num_fingers = xfe->num_finger;
+ e->distance = xfe->distance;
+ e->duration = xfe->duration;
+ e->direction = xfe->direction;
+ e->angle = XFixedToDouble(xfe->angle);
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_FLICK, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_gesture_notify_pan(XEvent *xevent)
+{
+ XGestureNotifyPanEvent *xpe;
+ Ecore_X_Event_Gesture_Notify_Pan *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xpe = (XGestureNotifyPanEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Pan));
+ if (!e)
+ return;
+
+ e->win = xpe->window;
+ e->time = xpe->time;
+ e->subtype = xpe->kind;
+ e->num_fingers = xpe->num_finger;
+ e->dx = xpe->dx;
+ e->dy = xpe->dy;
+ e->distance = xpe->distance;
+ e->duration = xpe->duration;
+ e->direction = xpe->direction;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PAN, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_gesture_notify_pinchrotation(XEvent *xevent)
+{
+ XGestureNotifyPinchRotationEvent *xpre;
+ Ecore_X_Event_Gesture_Notify_PinchRotation *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xpre = (XGestureNotifyPinchRotationEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_PinchRotation));
+ if (!e)
+ return;
+
+ e->win = xpre->window;
+ e->time = xpre->time;
+ e->subtype = xpre->kind;
+ e->num_fingers = xpre->num_finger;
+ e->distance = xpre->distance;
+ e->cx = xpre->cx;
+ e->cy = xpre->cy;
+ e->zoom = XFixedToDouble(xpre->zoom);
+ e->angle = XFixedToDouble(xpre->angle);
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_gesture_notify_tap(XEvent *xevent)
+{
+ XGestureNotifyTapEvent *xte;
+ Ecore_X_Event_Gesture_Notify_Tap *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xte = (XGestureNotifyTapEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Tap));
+ if (!e)
+ return;
+
+ e->win = xte->window;
+ e->time = xte->time;
+ e->subtype = xte->kind;
+ e->num_fingers = xte->num_finger;
+ e->cx = xte->cx;
+ e->cy = xte->cy;
+ e->tap_repeat = xte->tap_repeat;
+ e->interval = xte->interval;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAP, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_gesture_notify_tapnhold(XEvent *xevent)
+{
+ XGestureNotifyTapNHoldEvent *xthe;
+ Ecore_X_Event_Gesture_Notify_TapNHold *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xthe = (XGestureNotifyTapNHoldEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_TapNHold));
+ if (!e)
+ return;
+
+ e->win = xthe->window;
+ e->time = xthe->time;
+ e->subtype = xthe->kind;
+ e->num_fingers = xthe->num_finger;
+ e->cx = xthe->cx;
+ e->cy = xthe->cy;
+ e->interval = xthe->interval;
+ e->hold_time = xthe->holdtime;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_gesture_notify_hold(XEvent *xevent)
+{
+ XGestureNotifyHoldEvent *xhe;
+ Ecore_X_Event_Gesture_Notify_Hold *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xhe = (XGestureNotifyHoldEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Hold));
+ if (!e)
+ return;
+
+ e->win = xhe->window;
+ e->time = xhe->time;
+ e->subtype = xhe->kind;
+ e->num_fingers = xhe->num_finger;
+ e->cx = xhe->cx;
+ e->cy = xhe->cy;
+ e->hold_time = xhe->holdtime;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_gesture_notify_group(XEvent *xevent)
+{
+ XGestureNotifyGroupEvent *xge;
+ Ecore_X_Event_Gesture_Notify_Group *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xge = (XGestureNotifyGroupEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Group));
+ if (!e)
+ return;
+
+ e->win = xge->window;
+ e->time = xge->time;
+ e->subtype = xge->kind;
+ e->num_groups = xge->num_group;
+ e->group_id = xge->groupid;
+
+ ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_GROUP, e, NULL, NULL);
+}
+
+#endif /* ifdef ECORE_XGESTURE */
+#ifdef ECORE_XKB
+void
+_ecore_x_event_handle_xkb(XEvent *xevent)
+{
+ XkbEvent *xkbev;
+ Ecore_X_Event_Xkb *e;
+
+ xkbev = (XkbEvent *) xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Xkb));
+ if (!e)
+ return;
+ e->group = xkbev->state.group;
+ if (xkbev->any.xkb_type == XkbStateNotify)
+ ecore_event_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, e, NULL, NULL);
+ else if ((xkbev->any.xkb_type == XkbNewKeyboardNotify) ||
+ (xkbev->any.xkb_type == XkbMapNotify))
+ {
+ if (xkbev->any.xkb_type == XkbMapNotify)
+ {
+ XkbMapNotifyEvent *xkbmapping;
+
+ xkbmapping = (XkbMapNotifyEvent *)xkbev;
+ XkbRefreshKeyboardMapping(xkbmapping);
+ }
+ ecore_event_add(ECORE_X_EVENT_XKB_NEWKBD_NOTIFY, e, NULL, NULL);
+ }
+}
+#endif /* ifdef ECORE_XKB */
diff --git a/src/lib/ecore_x/xlib/ecore_x_fixes.c b/src/lib/ecore_x/xlib/ecore_x_fixes.c
new file mode 100644
index 0000000000..da0a6c3ac9
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_fixes.c
@@ -0,0 +1,365 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+static int _fixes_available;
+#ifdef ECORE_XFIXES
+static int _fixes_major, _fixes_minor;
+#endif /* ifdef ECORE_XFIXES */
+
+void
+_ecore_x_fixes_init(void)
+{
+#ifdef ECORE_XFIXES
+ _fixes_major = 3;
+ _fixes_minor = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XFixesQueryVersion(_ecore_x_disp, &_fixes_major, &_fixes_minor))
+ {
+ _fixes_available = 1;
+
+ ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = ecore_event_type_new();
+ }
+ else
+ _fixes_available = 0;
+
+#else /* ifdef ECORE_XFIXES */
+ _fixes_available = 0;
+#endif /* ifdef ECORE_XFIXES */
+}
+
+#ifdef ECORE_XFIXES
+/* I don't know what to call this function. */
+static XRectangle *
+_ecore_x_rectangle_ecore_to_x(Ecore_X_Rectangle *rects,
+ int num)
+{
+ XRectangle *xrect;
+ int i;
+
+ if (num == 0)
+ return NULL;
+
+ xrect = malloc(sizeof(XRectangle) * 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_x_rectangle_x_to_ecore(XRectangle *xrect,
+ int num)
+{
+ Ecore_X_Rectangle *rects;
+ int i;
+
+ if (num == 0)
+ return NULL;
+
+ rects = malloc(sizeof(Ecore_X_Rectangle) * num);
+ if (!rects)
+ return NULL;
+
+ for (i = 0; i < num; i++)
+ {
+ rects[i].x = xrect[i].x;
+ rects[i].y = xrect[i].y;
+ rects[i].width = xrect[i].width;
+ rects[i].height = xrect[i].height;
+ }
+ return rects;
+}
+
+#endif /* ifdef ECORE_XFIXES */
+
+EAPI Eina_Bool
+ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection)
+{
+#ifdef ECORE_XFIXES
+ if (_fixes_available)
+ {
+ XFixesSelectSelectionInput (_ecore_x_disp,
+ DefaultRootWindow(_ecore_x_disp),
+ selection,
+ XFixesSetSelectionOwnerNotifyMask |
+ XFixesSelectionWindowDestroyNotifyMask |
+ XFixesSelectionClientCloseNotifyMask);
+ return EINA_TRUE;
+ }
+#endif
+ return EINA_FALSE;
+}
+
+EAPI Ecore_X_Region
+ecore_x_region_new(Ecore_X_Rectangle *rects,
+ int num)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+ XRectangle *xrect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xrect = _ecore_x_rectangle_ecore_to_x(rects, num);
+ region = XFixesCreateRegion(_ecore_x_disp, xrect, num);
+ free(xrect);
+ return region;
+#else /* ifdef ECORE_XFIXES */
+ return 0;
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI Ecore_X_Region
+ecore_x_region_new_from_bitmap(Ecore_X_Pixmap bitmap)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ region = XFixesCreateRegionFromBitmap(_ecore_x_disp, bitmap);
+ return region;
+#else /* ifdef ECORE_XFIXES */
+ return 0;
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI Ecore_X_Region
+ecore_x_region_new_from_window(Ecore_X_Window win,
+ Ecore_X_Region_Type type)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ region = XFixesCreateRegionFromWindow(_ecore_x_disp, win, type);
+ return region;
+#else /* ifdef ECORE_XFIXES */
+ return 0;
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI Ecore_X_Region
+ecore_x_region_new_from_gc(Ecore_X_GC gc)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ region = XFixesCreateRegionFromGC(_ecore_x_disp, gc);
+ return region;
+#else /* ifdef ECORE_XFIXES */
+ return 0;
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI Ecore_X_Region
+ecore_x_region_new_from_picture(Ecore_X_Picture picture)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ region = XFixesCreateRegionFromPicture(_ecore_x_disp, picture);
+ return region;
+#else /* ifdef ECORE_XFIXES */
+ return 0;
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_free(Ecore_X_Region region)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesDestroyRegion(_ecore_x_disp, region);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_set(Ecore_X_Region region,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+#ifdef ECORE_XFIXES
+ XRectangle *xrect = _ecore_x_rectangle_ecore_to_x(rects, num);
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSetRegion(_ecore_x_disp, region, xrect, num);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_copy(Ecore_X_Region dest,
+ Ecore_X_Region source)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesCopyRegion(_ecore_x_disp, dest, source);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_combine(Ecore_X_Region dest,
+ Ecore_X_Region source1,
+ Ecore_X_Region source2)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesUnionRegion(_ecore_x_disp, dest, source1, source2);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_intersect(Ecore_X_Region dest,
+ Ecore_X_Region source1,
+ Ecore_X_Region source2)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesIntersectRegion(_ecore_x_disp, dest, source1, source2);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_subtract(Ecore_X_Region dest,
+ Ecore_X_Region source1,
+ Ecore_X_Region source2)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSubtractRegion(_ecore_x_disp, dest, source1, source2);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_invert(Ecore_X_Region dest,
+ Ecore_X_Rectangle *bounds,
+ Ecore_X_Region source)
+{
+#ifdef ECORE_XFIXES
+ XRectangle *xbound;
+ int num = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ while (bounds + num)
+ num++;
+ xbound = _ecore_x_rectangle_ecore_to_x(bounds, num);
+
+ XFixesInvertRegion(_ecore_x_disp, dest, xbound, source);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_translate(Ecore_X_Region region,
+ int dx,
+ int dy)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesTranslateRegion(_ecore_x_disp, region, dx, dy);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_extents(Ecore_X_Region dest,
+ Ecore_X_Region source)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesRegionExtents(_ecore_x_disp, dest, source);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI Ecore_X_Rectangle *
+ecore_x_region_fetch(Ecore_X_Region region,
+ int *num,
+ Ecore_X_Rectangle *bounds){
+#ifdef ECORE_XFIXES
+ Ecore_X_Rectangle *rects;
+ XRectangle *xrect, xbound;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xrect = XFixesFetchRegionAndBounds(_ecore_x_disp, region, num, &xbound);
+ rects = _ecore_x_rectangle_x_to_ecore(xrect, *num);
+ (*bounds).x = xbound.x;
+ (*bounds).y = xbound.y;
+ (*bounds).width = xbound.width;
+ (*bounds).height = xbound.height;
+ return rects;
+#else /* ifdef ECORE_XFIXES */
+ return NULL;
+#endif /* ifdef ECORE_XFIXES */
+}
+
+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)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesExpandRegion(_ecore_x_disp, dest, source, left, right, top, bottom);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_gc_clip_set(Ecore_X_Region region,
+ Ecore_X_GC gc,
+ int x_origin,
+ int y_origin)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSetGCClipRegion(_ecore_x_disp, gc, x_origin, y_origin, region);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_window_shape_set(Ecore_X_Region region,
+ Ecore_X_Window win,
+ Ecore_X_Shape_Type type,
+ int x_offset,
+ int y_offset)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSetWindowShapeRegion(_ecore_x_disp,
+ win,
+ type,
+ x_offset,
+ y_offset,
+ region);
+#endif /* ifdef ECORE_XFIXES */
+}
+
+EAPI void
+ecore_x_region_picture_clip_set(Ecore_X_Region region,
+ Ecore_X_Picture picture,
+ int x_origin,
+ int y_origin)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSetPictureClipRegion(_ecore_x_disp,
+ picture,
+ x_origin,
+ y_origin,
+ region);
+#endif /* ifdef ECORE_XFIXES */
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_gc.c b/src/lib/ecore_x/xlib/ecore_x_gc.c
new file mode 100644
index 0000000000..539636648f
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_gc.c
@@ -0,0 +1,171 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+/**
+ * Creates a new default graphics context associated with the given
+ * drawable.
+ * @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.
+ */
+EAPI Ecore_X_GC
+ecore_x_gc_new(Ecore_X_Drawable draw,
+ Ecore_X_GC_Value_Mask value_mask,
+ const unsigned int *value_list)
+{
+ XGCValues gcv;
+ int mask;
+ int idx;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!draw)
+ draw = DefaultRootWindow(_ecore_x_disp);
+
+ memset(&gcv, 0, sizeof (gcv));
+
+ for (i = 0, idx = 0, mask = 1; i <= 22; i++, mask <<= 1)
+ {
+ switch (mask & value_mask)
+ {
+ case ECORE_X_GC_VALUE_MASK_FUNCTION:
+ gcv.function = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_PLANE_MASK:
+ gcv.plane_mask = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_FOREGROUND:
+ gcv.foreground = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_BACKGROUND:
+ gcv.background = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_LINE_WIDTH:
+ gcv.line_width = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_LINE_STYLE:
+ gcv.line_style = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_CAP_STYLE:
+ gcv.cap_style = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_JOIN_STYLE:
+ gcv.join_style = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_FILL_STYLE:
+ gcv.fill_style = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_FILL_RULE:
+ gcv.fill_rule = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_TILE:
+ gcv.tile = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_STIPPLE:
+ gcv.stipple = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_X:
+ gcv.ts_x_origin = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_Y:
+ gcv.ts_y_origin = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_FONT:
+ gcv.font = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_SUBWINDOW_MODE:
+ gcv.subwindow_mode = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_GRAPHICS_EXPOSURES:
+ gcv.graphics_exposures = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_X:
+ gcv.clip_x_origin = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_Y:
+ gcv.clip_y_origin = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_CLIP_MASK:
+ gcv.clip_mask = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_DASH_OFFSET:
+ gcv.dash_offset = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_DASH_LIST:
+ gcv.dashes = value_list[idx];
+ idx++;
+ break;
+
+ case ECORE_X_GC_VALUE_MASK_ARC_MODE:
+ gcv.arc_mode = value_list[idx];
+ idx++;
+ break;
+ }
+ }
+
+ return XCreateGC(_ecore_x_disp, draw, value_mask, &gcv);
+}
+
+/**
+ * Deletes and frees the given graphics context.
+ * @param gc The given graphics context.
+ */
+EAPI void
+ecore_x_gc_free(Ecore_X_GC gc)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFreeGC(_ecore_x_disp, gc);
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_gesture.c b/src/lib/ecore_x/xlib/ecore_x_gesture.c
new file mode 100644
index 0000000000..dbde8b0db2
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_gesture.c
@@ -0,0 +1,137 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "ecore_x_private.h"
+
+static Eina_Bool _gesture_available = EINA_FALSE;
+
+#ifdef ECORE_XGESTURE
+static int _gesture_major, _gesture_minor, _gesture_patch;
+int _gesture_version;
+#endif /* ifdef ECORE_XGESTURE */
+
+void
+_ecore_x_gesture_init(void)
+{
+#ifdef ECORE_XGESTURE
+ _gesture_major = 0;
+ _gesture_minor = 0;
+ _gesture_patch = 0;
+ _gesture_version = 0;
+
+ if (XGestureQueryVersion(_ecore_x_disp, &_gesture_major, &_gesture_minor, &_gesture_patch))
+ {
+ _gesture_version = (_gesture_major << 16) | _gesture_minor;
+ _gesture_available = EINA_TRUE;
+ }
+ else
+ _gesture_available = EINA_FALSE;
+#else /* ifdef ECORE_XGESTURE */
+ _gesture_available = EINA_FALSE;
+#endif /* ifdef ECORE_XGESTURE */
+}
+
+/*
+ * @brief Query whether gesture is available or not.
+ *
+ * @return @c EINA_TRUE, if extension is available, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_gesture_supported(void)
+{
+ return _gesture_available;
+}
+
+EAPI Eina_Bool
+ecore_x_gesture_events_select(Ecore_X_Window win,
+ Ecore_X_Gesture_Event_Mask mask)
+{
+#ifdef ECORE_XGESTURE
+ if (!_gesture_available)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGestureSelectEvents(_ecore_x_disp, win, mask);
+
+ return EINA_TRUE;
+#else /* ifdef ECORE_XGESTURE */
+ (void) win;
+ (void) mask;
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XGESTURE */
+}
+
+EAPI Ecore_X_Gesture_Event_Mask
+ecore_x_gesture_events_selected_get(Ecore_X_Window win)
+{
+#ifdef ECORE_XGESTURE
+ Ecore_X_Gesture_Event_Mask mask;
+
+ if (!_gesture_available)
+ return ECORE_X_GESTURE_EVENT_MASK_NONE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (GestureSuccess != XGestureGetSelectedEvents(_ecore_x_disp, win, &mask))
+ {
+ mask = ECORE_X_GESTURE_EVENT_MASK_NONE;
+ return mask;
+ }
+
+ return mask;
+#else /* ifdef ECORE_XGESTURE */
+ (void) win;
+ return ECORE_X_GESTURE_EVENT_MASK_NONE;
+#endif /* ifdef ECORE_XGESTURE */
+}
+
+EAPI Eina_Bool
+ecore_x_gesture_event_grab(Ecore_X_Window win,
+ Ecore_X_Gesture_Event_Type type,
+ int num_fingers)
+{
+#ifdef ECORE_XGESTURE
+ if (!_gesture_available)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (GestureGrabSuccess != XGestureGrabEvent(_ecore_x_disp, win, type, num_fingers, CurrentTime))
+ {
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+#else /* ifdef ECORE_XGESTURE */
+ (void) win;
+ (void) type;
+ (void) num_fingers;
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XGESTURE */
+}
+
+EAPI Eina_Bool
+ecore_x_gesture_event_ungrab(Ecore_X_Window win,
+ Ecore_X_Gesture_Event_Type type,
+ int num_fingers)
+{
+#ifdef ECORE_XGESTURE
+ Ecore_X_Gesture_Event_Mask mask;
+
+ if (!_gesture_available)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (GestureUngrabSuccess != XGestureUngrabEvent(_ecore_x_disp, win, type, num_fingers, CurrentTime))
+ {
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+#else /* ifdef ECORE_XGESTURE */
+ (void) win;
+ (void) type;
+ (void) num_fingers;
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XGESTURE */
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_icccm.c b/src/lib/ecore_x/xlib/ecore_x_icccm.c
new file mode 100644
index 0000000000..8d6ea1f50e
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_icccm.c
@@ -0,0 +1,1214 @@
+/*
+ * Various ICCCM related functions.
+ *
+ * This is ALL the code involving anything ICCCM related. for both WM and
+ * client.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+EAPI void
+ecore_x_icccm_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+}
+
+EAPI void
+ecore_x_icccm_state_set(Ecore_X_Window win,
+ Ecore_X_Window_State_Hint state)
+{
+ unsigned long c[2];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ c[0] = WithdrawnState;
+ else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ c[0] = NormalState;
+ else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ c[0] = IconicState;
+
+ c[1] = None;
+ XChangeProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE,
+ ECORE_X_ATOM_WM_STATE, 32, PropModeReplace,
+ (unsigned char *)c, 2);
+}
+
+EAPI Ecore_X_Window_State_Hint
+ecore_x_icccm_state_get(Ecore_X_Window win)
+{
+ unsigned char *prop_ret = NULL;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ Ecore_X_Window_State_Hint hint;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ hint = ECORE_X_WINDOW_STATE_HINT_NONE;
+ XGetWindowProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE,
+ 0, 0x7fffffff, False, ECORE_X_ATOM_WM_STATE,
+ &type_ret, &format_ret, &num_ret, &bytes_after,
+ &prop_ret);
+ if ((prop_ret) && (num_ret == 2))
+ {
+ if (prop_ret[0] == WithdrawnState)
+ hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else if (prop_ret[0] == NormalState)
+ hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ else if (prop_ret[0] == IconicState)
+ hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return hint;
+}
+
+EAPI void
+ecore_x_icccm_delete_window_send(Ecore_X_Window win,
+ Ecore_X_Time t)
+{
+ 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_take_focus_send(Ecore_X_Window win,
+ Ecore_X_Time t)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ 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,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_SAVE_YOURSELF,
+ t, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_icccm_move_resize_send(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ XEvent ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ev.type = ConfigureNotify;
+ ev.xconfigure.display = _ecore_x_disp;
+ ev.xconfigure.event = win;
+ ev.xconfigure.window = win;
+ ev.xconfigure.x = x;
+ ev.xconfigure.y = y;
+ ev.xconfigure.width = w;
+ ev.xconfigure.height = h;
+ ev.xconfigure.border_width = 0;
+ ev.xconfigure.above = None;
+ ev.xconfigure.override_redirect = False;
+ XSendEvent(_ecore_x_disp, win, False, StructureNotifyMask, &ev);
+}
+
+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)
+{
+ XWMHints *hints;
+
+ hints = XAllocWMHints();
+ if (!hints)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ hints->flags = InputHint | StateHint;
+ hints->input = accepts_focus;
+ if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ hints->initial_state = WithdrawnState;
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ hints->initial_state = NormalState;
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ hints->initial_state = IconicState;
+
+ if (icon_pixmap != 0)
+ {
+ hints->icon_pixmap = icon_pixmap;
+ hints->flags |= IconPixmapHint;
+ }
+
+ if (icon_mask != 0)
+ {
+ hints->icon_mask = icon_mask;
+ hints->flags |= IconMaskHint;
+ }
+
+ if (icon_window != 0)
+ {
+ hints->icon_window = icon_window;
+ hints->flags |= IconWindowHint;
+ }
+
+ if (window_group != 0)
+ {
+ hints->window_group = window_group;
+ hints->flags |= WindowGroupHint;
+ }
+
+ if (is_urgent)
+ hints->flags |= XUrgencyHint;
+
+ XSetWMHints(_ecore_x_disp, win, hints);
+ XFree(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)
+{
+ XWMHints *hints;
+
+ 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;
+
+ hints = XGetWMHints(_ecore_x_disp, win);
+ if (hints)
+ {
+ if ((hints->flags & InputHint) && (accepts_focus))
+ {
+ if (hints->input)
+ *accepts_focus = EINA_TRUE;
+ else
+ *accepts_focus = EINA_FALSE;
+ }
+
+ if ((hints->flags & StateHint) && (initial_state))
+ {
+ if (hints->initial_state == WithdrawnState)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else if (hints->initial_state == NormalState)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ else if (hints->initial_state == IconicState)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ }
+
+ if ((hints->flags & IconPixmapHint) && (icon_pixmap))
+ *icon_pixmap = hints->icon_pixmap;
+
+ if ((hints->flags & IconMaskHint) && (icon_mask))
+ *icon_mask = hints->icon_mask;
+
+ if ((hints->flags & IconWindowHint) && (icon_window))
+ *icon_window = hints->icon_window;
+
+ if ((hints->flags & WindowGroupHint) && (window_group))
+ *window_group = hints->window_group;
+
+ if ((hints->flags & XUrgencyHint) && (is_urgent))
+ *is_urgent = EINA_TRUE;
+
+ XFree(hints);
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+EAPI void
+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)
+{
+ XSizeHints hint;
+ long mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask))
+ memset(&hint, 0, sizeof(XSizeHints));
+
+ hint.flags = 0;
+ if (request_pos)
+ hint.flags |= USPosition;
+
+ if (gravity != ECORE_X_GRAVITY_NW)
+ {
+ hint.flags |= PWinGravity;
+ hint.win_gravity = gravity;
+ }
+
+ if ((min_w > 0) || (min_h > 0))
+ {
+ hint.flags |= PMinSize;
+ hint.min_width = min_w;
+ hint.min_height = min_h;
+ }
+
+ if ((max_w > 0) || (max_h > 0))
+ {
+ hint.flags |= PMaxSize;
+ hint.max_width = max_w;
+ hint.max_height = max_h;
+ }
+
+ if ((base_w > 0) || (base_h > 0))
+ {
+ hint.flags |= PBaseSize;
+ hint.base_width = base_w;
+ hint.base_height = base_h;
+ }
+
+ if ((step_x > 1) || (step_y > 1))
+ {
+ hint.flags |= PResizeInc;
+ hint.width_inc = step_x;
+ hint.height_inc = step_y;
+ }
+
+ if ((min_aspect > 0.0) || (max_aspect > 0.0))
+ {
+ hint.flags |= PAspect;
+ hint.min_aspect.x = min_aspect * 10000;
+ hint.min_aspect.y = 10000;
+ hint.max_aspect.x = max_aspect * 10000;
+ hint.max_aspect.y = 10000;
+ }
+
+ XSetWMNormalHints(_ecore_x_disp, win, &hint);
+}
+
+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)
+{
+ XSizeHints hint;
+ long mask;
+
+ int minw = 0, minh = 0;
+ int maxw = 32767, maxh = 32767;
+ int basew = -1, baseh = -1;
+ int stepx = -1, stepy = -1;
+ double mina = 0.0, maxa = 0.0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask))
+ return EINA_FALSE;
+
+ if ((hint.flags & USPosition) || ((hint.flags & PPosition)))
+ {
+ if (request_pos)
+ *request_pos = EINA_TRUE;
+ }
+ else if (request_pos)
+ *request_pos = EINA_FALSE;
+
+ if (hint.flags & PWinGravity)
+ {
+ if (gravity)
+ *gravity = hint.win_gravity;
+ }
+ else if (gravity)
+ *gravity = ECORE_X_GRAVITY_NW;
+
+ if (hint.flags & PMinSize)
+ {
+ minw = hint.min_width;
+ minh = hint.min_height;
+ }
+
+ if (hint.flags & PMaxSize)
+ {
+ maxw = hint.max_width;
+ maxh = hint.max_height;
+ if (maxw < minw)
+ maxw = minw;
+
+ if (maxh < minh)
+ maxh = minh;
+ }
+
+ if (hint.flags & PBaseSize)
+ {
+ basew = hint.base_width;
+ baseh = hint.base_height;
+ if (basew > minw)
+ minw = basew;
+
+ if (baseh > minh)
+ minh = baseh;
+ }
+
+ if (hint.flags & PResizeInc)
+ {
+ stepx = hint.width_inc;
+ stepy = hint.height_inc;
+ if (stepx < 1)
+ stepx = 1;
+
+ if (stepy < 1)
+ stepy = 1;
+ }
+
+ if (hint.flags & PAspect)
+ {
+ if (hint.min_aspect.y > 0)
+ mina = ((double)hint.min_aspect.x) / ((double)hint.min_aspect.y);
+
+ if (hint.max_aspect.y > 0)
+ maxa = ((double)hint.max_aspect.x) / ((double)hint.max_aspect.y);
+ }
+
+ 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;
+}
+
+EAPI void
+ecore_x_icccm_title_set(Ecore_X_Window win,
+ const char *t)
+{
+ char *list[1];
+ XTextProperty xprop;
+ int ret;
+
+ if (!t)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xprop.value = NULL;
+#ifdef X_HAVE_UTF8_STRING
+ list[0] = strdup(t);
+ ret =
+ Xutf8TextListToTextProperty(_ecore_x_disp, list, 1, XUTF8StringStyle,
+ &xprop);
+#else /* ifdef X_HAVE_UTF8_STRING */
+ list[0] = strdup(t);
+ ret =
+ XmbTextListToTextProperty(_ecore_x_disp, list, 1, XStdICCTextStyle,
+ &xprop);
+#endif /* ifdef X_HAVE_UTF8_STRING */
+ if (ret >= Success)
+ {
+ XSetWMName(_ecore_x_disp, win, &xprop);
+ if (xprop.value)
+ XFree(xprop.value);
+ }
+ else if (XStringListToTextProperty(list, 1, &xprop) >= Success)
+ {
+ XSetWMName(_ecore_x_disp, win, &xprop);
+ if (xprop.value)
+ XFree(xprop.value);
+ }
+
+ free(list[0]);
+}
+
+EAPI char *
+ecore_x_icccm_title_get(Ecore_X_Window win)
+{
+ XTextProperty xprop;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xprop.value = NULL;
+ if (XGetWMName(_ecore_x_disp, win, &xprop) >= Success)
+ {
+ if (xprop.value)
+ {
+ char **list = NULL;
+ char *t = NULL;
+ int num = 0;
+ int ret;
+
+ if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING)
+ t = strdup((char *)xprop.value);
+ else
+ {
+ /* convert to utf8 */
+#ifdef X_HAVE_UTF8_STRING
+ ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#else /* ifdef X_HAVE_UTF8_STRING */
+ ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#endif /* ifdef X_HAVE_UTF8_STRING */
+
+ 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);
+
+ return t;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * 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_protocol_atoms_set(Ecore_X_Window win,
+ Ecore_X_Atom *protos,
+ int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num > 0)
+ XSetWMProtocols(_ecore_x_disp, win, (Atom *)(protos), num);
+ else
+ XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_PROTOCOLS);
+}
+
+/**
+ * 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_protocol_set(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol,
+ Eina_Bool on)
+{
+ Atom *protos = NULL;
+ Atom proto;
+ int protos_count = 0;
+ int already_set = 0;
+ int i;
+
+ /* Check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ proto = _ecore_x_atoms_wm_protocols[protocol];
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ {
+ protos = NULL;
+ protos_count = 0;
+ }
+
+ for (i = 0; i < protos_count; i++)
+ {
+ if (protos[i] == proto)
+ {
+ already_set = 1;
+ break;
+ }
+ }
+
+ if (on)
+ {
+ Atom *new_protos = NULL;
+
+ if (already_set)
+ goto leave;
+
+ new_protos = malloc((protos_count + 1) * sizeof(Atom));
+ if (!new_protos)
+ goto leave;
+
+ for (i = 0; i < protos_count; i++)
+ new_protos[i] = protos[i];
+ new_protos[protos_count] = proto;
+ XSetWMProtocols(_ecore_x_disp, win, new_protos, protos_count + 1);
+ free(new_protos);
+ }
+ else
+ {
+ if (!already_set)
+ goto leave;
+
+ for (i = 0; i < protos_count; i++)
+ {
+ if (protos[i] == proto)
+ {
+ int j;
+
+ for (j = i + 1; j < protos_count; j++)
+ protos[j - 1] = protos[j];
+ if (protos_count > 1)
+ XSetWMProtocols(_ecore_x_disp, win, protos,
+ protos_count - 1);
+ else
+ XDeleteProperty(_ecore_x_disp, win,
+ ECORE_X_ATOM_WM_PROTOCOLS);
+
+ goto leave;
+ }
+ }
+ }
+
+leave:
+ if (protos)
+ XFree(protos);
+}
+
+/**
+ * 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 Eina_Bool
+ecore_x_icccm_protocol_isset(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol)
+{
+ Atom proto, *protos = NULL;
+ int i, protos_count = 0;
+ Eina_Bool ret = EINA_FALSE;
+
+ /* check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ proto = _ecore_x_atoms_wm_protocols[protocol];
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ return EINA_FALSE;
+
+ for (i = 0; i < protos_count; i++)
+ if (protos[i] == proto)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+
+ if (protos)
+ XFree(protos);
+
+ return ret;
+}
+
+/**
+ * Set a window name & class.
+ * @param win The window
+ * @param n The name string
+ * @param c The class string
+ *
+ * Set a window name * class
+ */
+EAPI void
+ecore_x_icccm_name_class_set(Ecore_X_Window win,
+ const char *n,
+ const char *c)
+{
+ XClassHint *xch;
+
+ xch = XAllocClassHint();
+ if (!xch)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xch->res_name = (char *)n;
+ xch->res_class = (char *)c;
+ XSetClassHint(_ecore_x_disp, win, xch);
+ XFree(xch);
+}
+
+/**
+ * Get a window name & class.
+ * @param win The window
+ * @param n The name string
+ * @param c The class string
+ *
+ * Get a window name * class
+ */
+EAPI void
+ecore_x_icccm_name_class_get(Ecore_X_Window win,
+ char **n,
+ char **c)
+{
+ XClassHint xch;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (n)
+ *n = NULL;
+
+ if (c)
+ *c = NULL;
+
+ xch.res_name = NULL;
+ xch.res_class = NULL;
+ if (XGetClassHint(_ecore_x_disp, win, &xch))
+ {
+ if (n)
+ if (xch.res_name)
+ *n = strdup(xch.res_name);
+
+ if (c)
+ if (xch.res_class)
+ *c = strdup(xch.res_class);
+
+ XFree(xch.res_name);
+ XFree(xch.res_class);
+ }
+}
+
+/**
+ * Get a window client machine string.
+ * @param win The window
+ * @return The windows client machine string
+ *
+ * Return the client machine of a window. String must be free'd when done with.
+ */
+EAPI char *
+ecore_x_icccm_client_machine_get(Ecore_X_Window win)
+{
+ char *name;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ name = ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_CLIENT_MACHINE);
+ return name;
+}
+
+/**
+ * Sets the WM_COMMAND property for @a win.
+ *
+ * @param win The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ */
+EAPI void
+ecore_x_icccm_command_set(Ecore_X_Window win,
+ int argc,
+ char **argv)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetCommand(_ecore_x_disp, win, argv, argc);
+}
+
+/**
+ * Get the WM_COMMAND property for @a win.
+ *
+ * Return the command of a window. String must be free'd when done with.
+ *
+ * @param win The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ */
+EAPI void
+ecore_x_icccm_command_get(Ecore_X_Window win,
+ int *argc,
+ char ***argv)
+{
+ int i, c;
+ char **v;
+
+ if (argc)
+ *argc = 0;
+
+ if (argv)
+ *argv = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetCommand(_ecore_x_disp, win, &v, &c))
+ return;
+
+ if (c < 1)
+ {
+ if (v)
+ XFreeStringList(v);
+
+ return;
+ }
+
+ if (argc)
+ *argc = c;
+
+ if (argv)
+ {
+ (*argv) = malloc(c * sizeof(char *));
+ if (!*argv)
+ {
+ XFreeStringList(v);
+ if (argc)
+ *argc = 0;
+
+ return;
+ }
+
+ for (i = 0; i < c; i++)
+ {
+ if (v[i])
+ (*argv)[i] = strdup(v[i]);
+ else
+ (*argv)[i] = strdup("");
+ }
+ }
+
+ XFreeStringList(v);
+}
+
+/**
+ * Set a window icon name.
+ * @param win The window
+ * @param t The icon name string
+ *
+ * Set a window icon name
+ */
+EAPI void
+ecore_x_icccm_icon_name_set(Ecore_X_Window win,
+ const char *t)
+{
+ char *list[1];
+ XTextProperty xprop;
+ int ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xprop.value = NULL;
+#ifdef X_HAVE_UTF8_STRING
+ list[0] = strdup(t);
+ ret = Xutf8TextListToTextProperty(_ecore_x_disp, list, 1,
+ XUTF8StringStyle, &xprop);
+#else /* ifdef X_HAVE_UTF8_STRING */
+ list[0] = strdup(t);
+ ret = XmbTextListToTextProperty(_ecore_x_disp, list, 1,
+ XStdICCTextStyle, &xprop);
+#endif /* ifdef X_HAVE_UTF8_STRING */
+ if (ret >= Success)
+ {
+ XSetWMIconName(_ecore_x_disp, win, &xprop);
+ if (xprop.value)
+ XFree(xprop.value);
+ }
+ else if (XStringListToTextProperty(list, 1, &xprop) >= Success)
+ {
+ XSetWMIconName(_ecore_x_disp, win, &xprop);
+ if (xprop.value)
+ XFree(xprop.value);
+ }
+
+ free(list[0]);
+}
+
+/**
+ * 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)
+{
+ XTextProperty xprop;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xprop.value = NULL;
+ if (XGetWMIconName(_ecore_x_disp, win, &xprop) >= Success)
+ {
+ if (xprop.value)
+ {
+ char **list = NULL;
+ char *t = NULL;
+ int num = 0;
+ int ret;
+
+ if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING)
+ t = strdup((char *)xprop.value);
+ else
+ {
+ /* convert to utf8 */
+#ifdef X_HAVE_UTF8_STRING
+ ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#else /* ifdef X_HAVE_UTF8_STRING */
+ ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#endif /* ifdef X_HAVE_UTF8_STRING */
+
+ 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);
+
+ return t;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * 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 void
+ecore_x_icccm_colormap_window_set(Ecore_X_Window win,
+ Ecore_X_Window subwin)
+{
+ int num = 0, i;
+ unsigned char *old_data = NULL;
+ unsigned char *data = NULL;
+ Window *oldset = NULL;
+ Window *newset = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, &old_data, &num))
+ {
+ newset = calloc(1, sizeof(Window));
+ if (!newset)
+ return;
+
+ newset[0] = subwin;
+ num = 1;
+ data = (unsigned char *)newset;
+ }
+ else
+ {
+ newset = calloc(num + 1, sizeof(Window));
+ oldset = (Window *)old_data;
+ if (!newset)
+ return;
+
+ for (i = 0; i < num; ++i)
+ {
+ if (oldset[i] == subwin)
+ {
+ if (old_data)
+ XFree(old_data);
+
+ old_data = NULL;
+ free(newset);
+ return;
+ }
+
+ newset[i] = oldset[i];
+ }
+
+ newset[num++] = subwin;
+ if (old_data)
+ XFree(old_data);
+
+ data = (unsigned char *)newset;
+ }
+
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, data, num);
+ free(newset);
+}
+
+/**
+ * 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_colormap_window_unset(Ecore_X_Window win,
+ Ecore_X_Window subwin)
+{
+ int num = 0, i, j, k = 0;
+ unsigned char *old_data = NULL;
+ unsigned char *data = NULL;
+ Window *oldset = NULL;
+ Window *newset = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, &old_data, &num))
+ return;
+
+ oldset = (Window *)old_data;
+ for (i = 0; i < num; i++)
+ {
+ if (oldset[i] == subwin)
+ {
+ if (num == 1)
+ {
+ XDeleteProperty(_ecore_x_disp,
+ win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
+ if (old_data)
+ XFree(old_data);
+
+ old_data = NULL;
+ return;
+ }
+ else
+ {
+ newset = calloc(num - 1, sizeof(Window));
+ data = (unsigned char *)newset;
+ for (j = 0; j < num; ++j)
+ if (oldset[j] != subwin)
+ newset[k++] = oldset[j];
+
+ ecore_x_window_prop_property_set(
+ win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW,
+ 32,
+ data,
+ k);
+ if (old_data)
+ XFree(old_data);
+
+ old_data = NULL;
+ free(newset);
+ return;
+ }
+ }
+ }
+
+ if (old_data)
+ XFree(old_data);
+}
+
+/**
+ * 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_transient_for_set(Ecore_X_Window win,
+ Ecore_X_Window forwin)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetTransientForHint(_ecore_x_disp, win, forwin);
+}
+
+/**
+ * Remove the transient_for setting from a window.
+ * @param win The window
+ */
+EAPI void
+ecore_x_icccm_transient_for_unset(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_TRANSIENT_FOR);
+}
+
+/**
+ * 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 Ecore_X_Window
+ecore_x_icccm_transient_for_get(Ecore_X_Window win)
+{
+ Window forwin;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGetTransientForHint(_ecore_x_disp, win, &forwin))
+ return (Ecore_X_Window)forwin;
+ else
+ return 0;
+}
+
+/**
+ * Set the window role hint.
+ * @param win The window
+ * @param role The role string
+ */
+EAPI void
+ecore_x_icccm_window_role_set(Ecore_X_Window win,
+ const char *role)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE,
+ (char *)role);
+}
+
+/**
+ * Get the window role.
+ * @param win The window
+ * @return The window's role string.
+ */
+EAPI char *
+ecore_x_icccm_window_role_get(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE);
+}
+
+/**
+ * Set the window's client leader.
+ * @param win The window
+ * @param l 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.
+ */
+EAPI void
+ecore_x_icccm_client_leader_set(Ecore_X_Window win,
+ Ecore_X_Window l)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
+ &l, 1);
+}
+
+/**
+ * Get the window's client leader.
+ * @param win The window
+ * @return The window's client leader window, or 0 if unset */
+EAPI Ecore_X_Window
+ecore_x_icccm_client_leader_get(Ecore_X_Window win)
+{
+ Ecore_X_Window l;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
+ &l, 1) > 0)
+ return l;
+
+ return 0;
+}
+
+EAPI void
+ecore_x_icccm_iconic_request_send(Ecore_X_Window win,
+ Ecore_X_Window root)
+{
+ XEvent xev;
+
+ if (!win)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root)
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_CHANGE_STATE;
+ xev.xclient.data.l[0] = IconicState;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+}
+
+/* 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 */
diff --git a/src/lib/ecore_x/xlib/ecore_x_image.c b/src/lib/ecore_x/xlib/ecore_x_image.c
new file mode 100644
index 0000000000..def81104a2
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_image.c
@@ -0,0 +1,626 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif !defined alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# elif !defined HAVE_ALLOCA
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+#include <X11/extensions/XShm.h>
+#include <X11/Xutil.h>
+
+static int _ecore_x_image_shm_can = -1;
+static int _ecore_x_image_err = 0;
+
+static int
+_ecore_x_image_error_handler(Display *d EINA_UNUSED,
+ XErrorEvent *ev EINA_UNUSED)
+{
+ _ecore_x_image_err = 1;
+ return 0;
+}
+
+static void
+_ecore_x_image_shm_check(void)
+{
+ XErrorHandler ph;
+ XShmSegmentInfo shminfo;
+ XImage *xim;
+
+ if (_ecore_x_image_shm_can != -1)
+ return;
+
+ XSync(_ecore_x_disp, False);
+ _ecore_x_image_err = 0;
+
+ xim = XShmCreateImage(_ecore_x_disp,
+ DefaultVisual(_ecore_x_disp,
+ DefaultScreen(_ecore_x_disp)),
+ DefaultDepth(_ecore_x_disp,
+ DefaultScreen(_ecore_x_disp)),
+ ZPixmap, NULL,
+ &shminfo, 1, 1);
+ if (!xim)
+ {
+ _ecore_x_image_shm_can = 0;
+ return;
+ }
+
+ shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
+ IPC_CREAT | 0666);
+ if (shminfo.shmid == -1)
+ {
+ XDestroyImage(xim);
+ _ecore_x_image_shm_can = 0;
+ return;
+ }
+
+ shminfo.readOnly = False;
+ shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
+ xim->data = shminfo.shmaddr;
+
+ if (xim->data == (char *)-1)
+ {
+ XDestroyImage(xim);
+ _ecore_x_image_shm_can = 0;
+ return;
+ }
+
+ ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
+ XShmAttach(_ecore_x_disp, &shminfo);
+ XShmGetImage(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp),
+ xim, 0, 0, 0xffffffff);
+ XSync(_ecore_x_disp, False);
+ XSetErrorHandler((XErrorHandler)ph);
+ if (_ecore_x_image_err)
+ {
+ XShmDetach(_ecore_x_disp, &shminfo);
+ XDestroyImage(xim);
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+ _ecore_x_image_shm_can = 0;
+ return;
+ }
+
+ XShmDetach(_ecore_x_disp, &shminfo);
+ XDestroyImage(xim);
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+
+ _ecore_x_image_shm_can = 1;
+}
+
+struct _Ecore_X_Image
+{
+ XShmSegmentInfo shminfo;
+ Ecore_X_Visual vis;
+ XImage *xim;
+ int depth;
+ int w, h;
+ int bpl, bpp, rows;
+ unsigned char *data;
+ Eina_Bool shm : 1;
+};
+
+EAPI Ecore_X_Image *
+ecore_x_image_new(int w,
+ int h,
+ Ecore_X_Visual vis,
+ int depth)
+{
+ Ecore_X_Image *im;
+
+ im = calloc(1, sizeof(Ecore_X_Image));
+ if (!im)
+ return NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ im->w = w;
+ im->h = h;
+ im->vis = vis;
+ im->depth = depth;
+ _ecore_x_image_shm_check();
+ im->shm = _ecore_x_image_shm_can;
+ return im;
+}
+
+EAPI void
+ecore_x_image_free(Ecore_X_Image *im)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (im->shm)
+ {
+ if (im->xim)
+ {
+ XShmDetach(_ecore_x_disp, &(im->shminfo));
+ XDestroyImage(im->xim);
+ shmdt(im->shminfo.shmaddr);
+ shmctl(im->shminfo.shmid, IPC_RMID, 0);
+ }
+ }
+ else if (im->xim)
+ {
+ free(im->xim->data);
+ im->xim->data = NULL;
+ XDestroyImage(im->xim);
+ }
+
+ free(im);
+}
+
+static void
+_ecore_x_image_shm_create(Ecore_X_Image *im)
+{
+ im->xim = XShmCreateImage(_ecore_x_disp, im->vis, im->depth,
+ ZPixmap, NULL, &(im->shminfo),
+ im->w, im->h);
+ if (!im->xim)
+ return;
+
+ im->shminfo.shmid = shmget(IPC_PRIVATE,
+ im->xim->bytes_per_line * im->xim->height,
+ IPC_CREAT | 0666);
+ if (im->shminfo.shmid == -1)
+ {
+ XDestroyImage(im->xim);
+ return;
+ }
+
+ im->shminfo.readOnly = False;
+ im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0);
+ im->xim->data = im->shminfo.shmaddr;
+ if ((im->xim->data == (char *)-1) ||
+ (!im->xim->data))
+ {
+ shmdt(im->shminfo.shmaddr);
+ shmctl(im->shminfo.shmid, IPC_RMID, 0);
+ XDestroyImage(im->xim);
+ return;
+ }
+
+ XShmAttach(_ecore_x_disp, &im->shminfo);
+
+ im->data = (unsigned char *)im->xim->data;
+
+ im->bpl = im->xim->bytes_per_line;
+ im->rows = im->xim->height;
+ if (im->xim->bits_per_pixel <= 8)
+ im->bpp = 1;
+ else if (im->xim->bits_per_pixel <= 16)
+ im->bpp = 2;
+ else
+ im->bpp = 4;
+}
+
+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;
+ XErrorHandler ph;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (im->shm)
+ {
+ if (!im->xim)
+ _ecore_x_image_shm_create(im);
+
+ if (!im->xim)
+ return 0;
+
+ _ecore_x_image_err = 0;
+ // optimised path
+ ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
+ if ((sx == 0) && (w == im->w))
+ {
+ im->xim->data = (char *)
+ im->data + (im->xim->bytes_per_line * sy) + (sx * im->bpp);
+ im->xim->width = w;
+ im->xim->height = h;
+ XGrabServer(_ecore_x_disp);
+ if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff))
+ ret = EINA_FALSE;
+ XUngrabServer(_ecore_x_disp);
+ ecore_x_sync();
+ }
+ // unavoidable thanks to mit-shm get api - tmp shm buf + copy into it
+ else
+ {
+ Ecore_X_Image *tim;
+ unsigned char *spixels, *sp, *pixels, *p;
+ int bpp, bpl, rows, sbpp, sbpl, srows;
+ int r;
+
+ 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)
+ {
+ spixels = ecore_x_image_data_get(tim,
+ &sbpl,
+ &srows,
+ &sbpp);
+ pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp);
+ if ((pixels) && (spixels))
+ {
+ 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);
+ }
+ }
+
+ XSetErrorHandler((XErrorHandler)ph);
+ if (_ecore_x_image_err)
+ ret = EINA_FALSE;
+ }
+ else
+ {
+ printf("currently unimplemented ecore_x_image_get without shm\n");
+ ret = EINA_FALSE;
+ }
+
+ return ret;
+}
+
+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)
+ {
+ XGCValues gcv;
+ memset(&gcv, 0, sizeof(gcv));
+ gcv.subwindow_mode = IncludeInferiors;
+ tgc = XCreateGC(_ecore_x_disp, draw, GCSubwindowMode, &gcv);
+ gc = tgc;
+ }
+ if (!im->xim) _ecore_x_image_shm_create(im);
+ if (im->xim)
+ XShmPutImage(_ecore_x_disp, draw, gc, im->xim, sx, sy, x, y, w, h, False);
+ if (tgc) ecore_x_gc_free(tgc);
+}
+
+EAPI void *
+ecore_x_image_data_get(Ecore_X_Image *im,
+ int *bpl,
+ int *rows,
+ int *bpp)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!im->xim) _ecore_x_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 Eina_Bool
+ecore_x_image_is_argb32_get(Ecore_X_Image *im)
+{
+ Visual *vis = im->vis;
+ if (!im->xim) _ecore_x_image_shm_create(im);
+ if (((vis->class == TrueColor) ||
+ (vis->class == DirectColor)) &&
+ (im->depth >= 24) &&
+ (vis->red_mask == 0xff0000) &&
+ (vis->green_mask == 0x00ff00) &&
+ (vis->blue_mask == 0x0000ff))
+ {
+#ifdef WORDS_BIGENDIAN
+ if (im->xim->bitmap_bit_order == MSBFirst) return EINA_TRUE;
+#else
+ if (im->xim->bitmap_bit_order == LSBFirst) 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)
+{
+ Visual *vis = v;
+ XColor *cols = NULL;
+ int n = 0, nret = 0, i, row;
+ unsigned int pal[256], r, g, b;
+ enum
+ {
+ rgbnone = 0,
+ rgb565,
+ bgr565,
+ rgbx555,
+ argbx888,
+ abgrx888,
+ rgba888x,
+ bgra888x,
+ argbx666
+ };
+ int mode = 0;
+
+ sbpp *= 8;
+
+ n = vis->map_entries;
+ if ((n <= 256) &&
+ ((vis->class == PseudoColor) ||
+ (vis->class == StaticColor) ||
+ (vis->class == GrayScale) ||
+ (vis->class == StaticGray)))
+ {
+ if (!c)
+ c = DefaultColormap(_ecore_x_disp,
+ DefaultScreen(_ecore_x_disp));
+ cols = alloca(n * sizeof(XColor));
+ for (i = 0; i < n; i++)
+ {
+ cols[i].pixel = i;
+ cols[i].flags = DoRed | DoGreen | DoBlue;
+ cols[i].red = 0;
+ cols[i].green = 0;
+ cols[i].blue = 0;
+ }
+ XQueryColors(_ecore_x_disp, c, cols, n);
+ for (i = 0; i < n; i++)
+ {
+ pal[i] = 0xff000000 |
+ ((cols[i].red >> 8) << 16) |
+ ((cols[i].green >> 8) << 8) |
+ ((cols[i].blue >> 8));
+ }
+ nret = n;
+ }
+ else if ((vis->class == TrueColor) ||
+ (vis->class == DirectColor))
+ {
+ 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;
+ unsigned int *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;
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_mwm.c b/src/lib/ecore_x/xlib/ecore_x_mwm.c
new file mode 100644
index 0000000000..7812cc23ae
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_mwm.c
@@ -0,0 +1,106 @@
+/*
+ * Various MWM related functions.
+ *
+ * This is ALL the code involving anything MWM related. for both WM and
+ * client.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+#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)
+
+typedef struct _mwmhints
+{
+ CARD32 flags;
+ CARD32 functions;
+ CARD32 decorations;
+ INT32 inputmode;
+ CARD32 status;
+}
+MWMHints;
+
+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)
+{
+ unsigned char *p = NULL;
+ MWMHints *mwmhints = NULL;
+ int num;
+ Eina_Bool ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = EINA_FALSE;
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ 32, &p, &num))
+ return EINA_FALSE;
+
+ mwmhints = (MWMHints *)p;
+ if (mwmhints)
+ {
+ if (num >= 4)
+ {
+ if (dhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_DECORATIONS)
+ *dhint = mwmhints->decorations;
+ else
+ *dhint = ECORE_X_MWM_HINT_DECOR_ALL;
+ }
+
+ if (fhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_FUNCTIONS)
+ *fhint = mwmhints->functions;
+ else
+ *fhint = ECORE_X_MWM_HINT_FUNC_ALL;
+ }
+
+ if (ihint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_INPUT_MODE)
+ *ihint = mwmhints->inputmode;
+ else
+ *ihint = ECORE_X_MWM_HINT_INPUT_MODELESS;
+ }
+
+ ret = EINA_TRUE;
+ }
+
+ free(mwmhints);
+ }
+
+ return ret;
+}
+
+EAPI void
+ecore_x_mwm_borderless_set(Ecore_X_Window win,
+ Eina_Bool borderless)
+{
+ unsigned int data[5] = {0, 0, 0, 0, 0};
+
+ data[0] = 2; /* just set the decorations hint! */
+ data[2] = !borderless;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ 32, (void *)data, 5);
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_netwm.c b/src/lib/ecore_x/xlib/ecore_x_netwm.c
new file mode 100644
index 0000000000..3f08af8b9c
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_netwm.c
@@ -0,0 +1,2083 @@
+/*
+ * _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info;
+
+struct _Ecore_X_Startup_Info
+{
+ Ecore_X_Window win;
+
+ int init;
+
+ int buffer_size;
+ char *buffer;
+
+ int length;
+
+ /* 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;
+};
+
+static void _ecore_x_window_prop_string_utf8_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ const char *str);
+static char *_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win,
+ 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);
+
+/*
+ * Convenience macros
+ */
+#define _ATOM_SET_UTF8_STRING_LIST(win, atom, string, cnt) \
+ XChangeProperty(_ecore_x_disp, \
+ win, \
+ atom, \
+ ECORE_X_ATOM_UTF8_STRING, \
+ 8, \
+ PropModeReplace, \
+ (unsigned char *)string, \
+ cnt)
+
+/*
+ * Local variables
+ */
+
+static Eina_Hash *startup_info = NULL;
+
+EAPI void
+ecore_x_netwm_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ startup_info = eina_hash_string_superfast_new(
+ _ecore_x_netwm_startup_info_free);
+}
+
+EAPI void
+ecore_x_netwm_shutdown(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (startup_info)
+ eina_hash_free(startup_info);
+
+ startup_info = NULL;
+}
+
+/*
+ * WM identification
+ */
+EAPI void
+ecore_x_netwm_wm_identify(Ecore_X_Window root,
+ Ecore_X_Window check,
+ const char *wm_name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ 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_window_prop_window_set(root,
+ ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK,
+ &check,
+ 1);
+}
+
+/*
+ * Set supported atoms
+ */
+EAPI void
+ecore_x_netwm_supported_set(Ecore_X_Window root,
+ Ecore_X_Atom *supported,
+ int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_atom_set(root,
+ ECORE_X_ATOM_NET_SUPPORTED,
+ supported,
+ num);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_supported_get(Ecore_X_Window root,
+ Ecore_X_Atom **supported,
+ int *num)
+{
+ int num_ret;
+
+ if (num)
+ *num = 0;
+
+ if (supported)
+ *supported = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ 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;
+
+ return EINA_TRUE;
+}
+
+/*
+ * Desktop configuration and status
+ */
+EAPI void
+ecore_x_netwm_desk_count_set(Ecore_X_Window root,
+ unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
+ &n_desks, 1);
+}
+
+EAPI void
+ecore_x_netwm_desk_roots_set(Ecore_X_Window root,
+ Ecore_X_Window *vroots,
+ unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(root,
+ ECORE_X_ATOM_NET_VIRTUAL_ROOTS,
+ vroots,
+ n_desks);
+}
+
+EAPI void
+ecore_x_netwm_desk_names_set(Ecore_X_Window root,
+ const char **names,
+ unsigned int n_desks)
+{
+ char ss[32], *buf, *t;
+ const char *s;
+ unsigned int i;
+ int l, len;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ buf = NULL;
+ len = 0;
+
+ 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;
+ }
+
+ l = strlen(s) + 1;
+ t = realloc(buf, len + l);
+ if (t)
+ {
+ buf = t;
+ memcpy(buf + len, s, l);
+ }
+ len += l;
+ }
+
+ _ATOM_SET_UTF8_STRING_LIST(root, ECORE_X_ATOM_NET_DESKTOP_NAMES, buf, len);
+
+ free(buf);
+}
+
+EAPI void
+ecore_x_netwm_desk_size_set(Ecore_X_Window root,
+ unsigned int width,
+ unsigned int height)
+{
+ unsigned int size[2];
+
+ 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
+ origins, 2 * n_desks);
+}
+
+EAPI void
+ecore_x_netwm_desk_layout_set(Ecore_X_Window root,
+ int orientation,
+ int columns,
+ int rows,
+ int starting_corner)
+{
+ unsigned int 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);
+}
+
+EAPI void
+ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
+ unsigned int *areas,
+ unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_WORKAREA, areas,
+ 4 * n_desks);
+}
+
+EAPI unsigned int *
+ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, unsigned int *n_desks)
+{
+ int ret;
+ unsigned int *areas = NULL;
+
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+
+ ret = ecore_x_window_prop_card32_list_get(root, ECORE_X_ATOM_NET_WORKAREA,
+ &areas);
+ if (!areas)
+ {
+ if (n_desks) *n_desks = 0;
+ return 0;
+ }
+ if (n_desks) *n_desks = ret / 4;
+ return areas;
+}
+
+EAPI void
+ecore_x_netwm_desk_current_set(Ecore_X_Window root,
+ unsigned int desk)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_CURRENT_DESKTOP, &desk,
+ 1);
+}
+
+EAPI void
+ecore_x_netwm_showing_desktop_set(Ecore_X_Window root,
+ Eina_Bool on)
+{
+ unsigned int val;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ val = (on) ? 1 : 0;
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, &val,
+ 1);
+}
+
+/*
+ * Client status
+ */
+
+/* Mapping order */
+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__);
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST,
+ p_clients, n_clients);
+}
+
+/* Stacking order */
+EAPI void
+ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root,
+ Ecore_X_Window *p_clients,
+ unsigned int n_clients)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST_STACKING,
+ p_clients, n_clients);
+}
+
+EAPI void
+ecore_x_netwm_client_active_set(Ecore_X_Window root,
+ Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_ACTIVE_WINDOW,
+ &win, 1);
+}
+
+EAPI void
+ecore_x_netwm_client_active_request(Ecore_X_Window root,
+ Ecore_X_Window win,
+ int type,
+ Ecore_X_Window current_win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root)
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_NET_ACTIVE_WINDOW;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = type;
+ xev.xclient.data.l[1] = CurrentTime;
+ xev.xclient.data.l[2] = current_win;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+}
+
+EAPI void
+ecore_x_netwm_name_set(Ecore_X_Window win,
+ const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_NAME, name);
+}
+
+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_utf8_get(win,
+ ECORE_X_ATOM_NET_WM_NAME);
+
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_startup_id_set(Ecore_X_Window win,
+ const char *id)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id);
+}
+
+EAPI int
+ecore_x_netwm_startup_id_get(Ecore_X_Window win,
+ char **id)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (id)
+ *id = _ecore_x_window_prop_string_utf8_get(win,
+ ECORE_X_ATOM_NET_STARTUP_ID);
+
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_visible_name_set(Ecore_X_Window win,
+ const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
+ name);
+}
+
+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_utf8_get(
+ win,
+ ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
+
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_icon_name_set(Ecore_X_Window win,
+ const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME,
+ name);
+}
+
+EAPI int
+ecore_x_netwm_icon_name_get(Ecore_X_Window win,
+ char **name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(
+ win,
+ ECORE_X_ATOM_NET_WM_ICON_NAME);
+
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win,
+ const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win,
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
+ name);
+}
+
+EAPI int
+ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win,
+ char **name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(
+ win,
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
+
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_desktop_set(Ecore_X_Window win,
+ unsigned int desk)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_desktop_get(Ecore_X_Window win,
+ unsigned int *desk)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP,
+ &tmp, 1);
+
+ if (desk)
+ *desk = tmp;
+
+ return ret == 1 ? EINA_TRUE : EINA_FALSE;
+}
+
+/*
+ * _NET_WM_STRUT is deprecated
+ */
+EAPI void
+ecore_x_netwm_strut_set(Ecore_X_Window win,
+ int left,
+ int right,
+ int top,
+ int bottom)
+{
+ unsigned int strut[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ strut[0] = left;
+ strut[1] = right;
+ strut[2] = top;
+ strut[3] = bottom;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
+}
+
+/*
+ * _NET_WM_STRUT is deprecated
+ */
+EAPI Eina_Bool
+ecore_x_netwm_strut_get(Ecore_X_Window win,
+ int *left,
+ int *right,
+ int *top,
+ int *bottom)
+{
+ int ret = 0;
+ unsigned int strut[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_NET_WM_STRUT,
+ strut,
+ 4);
+ if (ret != 4)
+ return EINA_FALSE;
+
+ if (left)
+ *left = strut[0];
+
+ if (right)
+ *right = strut[1];
+
+ if (top)
+ *top = strut[2];
+
+ if (bottom)
+ *bottom = strut[3];
+
+ return EINA_TRUE;
+}
+
+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];
+
+ 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(win,
+ ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
+ strut,
+ 12);
+}
+
+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)
+{
+ int ret = 0;
+ unsigned int strut[12];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
+ strut,
+ 12);
+ if (ret != 12)
+ return EINA_FALSE;
+
+ 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];
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_icons_set(Ecore_X_Window win,
+ Ecore_X_Icon *icon,
+ int num)
+{
+ unsigned int *data, *p, *p2;
+ unsigned int i, size, x, y;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ size = 0;
+ for (i = 0; i < (unsigned int)num; i++)
+ {
+ size += 2 + (icon[i].width * icon[i].height);
+ }
+ data = malloc(size * sizeof(unsigned int));
+ if (!data) return;
+ p = data;
+ for (i = 0; i < (unsigned int)num; i++)
+ {
+ p[0] = icon[i].width;
+ p[1] = icon[i].height;
+ p += 2;
+ p2 = icon[i].data;
+ for (y = 0; y < icon[i].height; y++)
+ {
+ for (x = 0; x < icon[i].width; x++)
+ {
+ unsigned int r, g, b, a;
+
+ a = (*p2 >> 24) & 0xff;
+ r = (*p2 >> 16) & 0xff;
+ g = (*p2 >> 8 ) & 0xff;
+ b = (*p2 ) & 0xff;
+ if ((a > 0) && (a < 255))
+ {
+ // unpremul
+ r = (r * 255) / a;
+ g = (g * 255) / a;
+ b = (b * 255) / a;
+ }
+ *p = (a << 24) | (r << 16) | (g << 8) | b;
+ p++;
+ p2++;
+ }
+ }
+ }
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON,
+ data, size);
+ free(data);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_icons_get(Ecore_X_Window win,
+ Ecore_X_Icon **icon,
+ int *num)
+{
+ unsigned int *data, *p;
+ unsigned int *src;
+ unsigned int len, icons, i;
+ int num_ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num)
+ *num = 0;
+
+ if (icon)
+ *icon = NULL;
+
+ num_ret = ecore_x_window_prop_card32_list_get(win, ECORE_X_ATOM_NET_WM_ICON,
+ &data);
+ if (num_ret <= 0)
+ return EINA_FALSE;
+
+ if (!data)
+ return EINA_FALSE;
+
+ if (num_ret < 2)
+ {
+ free(data);
+ return EINA_FALSE;
+ }
+
+ /* 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 EINA_FALSE;
+ }
+
+ icons++;
+
+ if ((p - data) == num_ret)
+ p = NULL;
+ }
+ if (num)
+ *num = icons;
+
+ /* If the user doesn't want the icons, return */
+ if (!icon)
+ {
+ free(data);
+ return EINA_TRUE;
+ }
+
+ /* Allocate memory */
+ *icon = malloc(icons * sizeof(Ecore_X_Icon));
+ if (!(*icon))
+ {
+ free(data);
+ return EINA_FALSE;
+ }
+
+ /* Fetch the icons */
+ p = data;
+ for (i = 0; i < icons; i++)
+ {
+ unsigned int *ps, *pd, *pe;
+
+ 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;
+ }
+
+ pd = ((*icon)[i]).data;
+ ps = src;
+ pe = ps + len;
+ for (; ps < pe; ps++)
+ {
+ unsigned int 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++;
+ }
+ p += (len + 2);
+ }
+
+ free(data);
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_icon_geometry_set(Ecore_X_Window win,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ unsigned int geometry[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ geometry[0] = x;
+ geometry[1] = y;
+ geometry[2] = width;
+ geometry[3] = height;
+ ecore_x_window_prop_card32_set(win,
+ ECORE_X_ATOM_NET_WM_ICON_GEOMETRY,
+ geometry,
+ 4);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_icon_geometry_get(Ecore_X_Window win,
+ int *x,
+ int *y,
+ int *width,
+ int *height)
+{
+ int ret;
+ unsigned int geometry[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_NET_WM_ICON_GEOMETRY,
+ geometry,
+ 4);
+ if (ret != 4)
+ return EINA_FALSE;
+
+ if (x)
+ *x = geometry[0];
+
+ if (y)
+ *y = geometry[1];
+
+ if (width)
+ *width = geometry[2];
+
+ if (height)
+ *height = geometry[3];
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_pid_set(Ecore_X_Window win,
+ int pid)
+{
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ tmp = pid;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_PID,
+ &tmp, 1);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_pid_get(Ecore_X_Window win,
+ int *pid)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID,
+ &tmp, 1);
+ if (pid)
+ *pid = tmp;
+
+ return ret == 1 ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI void
+ecore_x_netwm_handled_icons_set(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_handled_icons_get(Ecore_X_Window win)
+{
+ int ret = 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0);
+ return ret == 0 ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI void
+ecore_x_netwm_user_time_set(Ecore_X_Window win,
+ unsigned int tim)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME,
+ &tim, 1);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_user_time_get(Ecore_X_Window win,
+ unsigned int *tim)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME,
+ &tmp, 1);
+ if (tim)
+ *tim = tmp;
+
+ return ret == 1 ? EINA_TRUE : EINA_FALSE;
+}
+
+Ecore_X_Window_State
+_ecore_x_netwm_state_get(Ecore_X_Atom a)
+{
+ 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;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_state_atom_get(Ecore_X_Window_State s)
+{
+ switch (s)
+ {
+ 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;
+ }
+}
+
+EAPI void
+ecore_x_netwm_window_state_set(Ecore_X_Window win,
+ Ecore_X_Window_State *state,
+ unsigned int num)
+{
+ Ecore_X_Atom *set;
+ unsigned int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!num)
+ {
+ 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]);
+
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_STATE, set, num);
+
+ free(set);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_window_state_get(Ecore_X_Window win,
+ Ecore_X_Window_State **state,
+ unsigned int *num)
+{
+ int num_ret, i;
+ Ecore_X_Atom *atoms;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num)
+ *num = 0;
+
+ if (state)
+ *state = NULL;
+
+ num_ret = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_STATE,
+ &atoms);
+ if (num_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]);
+
+ if (num)
+ *num = num_ret;
+ }
+
+ free(atoms);
+ return EINA_TRUE;
+}
+
+static Ecore_X_Window_Type
+_ecore_x_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 if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
+ return ECORE_X_WINDOW_TYPE_DROPDOWN_MENU;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU)
+ return ECORE_X_WINDOW_TYPE_POPUP_MENU;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP)
+ return ECORE_X_WINDOW_TYPE_TOOLTIP;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION)
+ return ECORE_X_WINDOW_TYPE_NOTIFICATION;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO)
+ return ECORE_X_WINDOW_TYPE_COMBO;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND)
+ return ECORE_X_WINDOW_TYPE_DND;
+ else
+ return ECORE_X_WINDOW_TYPE_UNKNOWN;
+}
+
+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;
+
+ 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;
+ }
+}
+
+/*
+ * 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
+ */
+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_x_netwm_window_type_atom_get(type);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atom, 1);
+}
+
+/* FIXME: Maybe return 0 on some conditions? */
+EAPI Eina_Bool
+ecore_x_netwm_window_type_get(Ecore_X_Window win,
+ Ecore_X_Window_Type *type)
+{
+ int num;
+ Ecore_X_Atom *atoms = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (type)
+ *type = ECORE_X_WINDOW_TYPE_NORMAL;
+
+ num = ecore_x_window_prop_atom_list_get(win,
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atoms);
+ if ((type) && (num >= 1) && (atoms))
+ *type = _ecore_x_netwm_window_type_type_get(atoms[0]);
+
+ free(atoms);
+ if (num >= 1)
+ return EINA_TRUE;
+
+ return EINA_FALSE;
+}
+
+EAPI int
+ecore_x_netwm_window_types_get(Ecore_X_Window win,
+ Ecore_X_Window_Type **types)
+{
+ int num, i;
+ 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;
+ }
+
+ atoms2 = malloc(num * sizeof(Ecore_X_Window_Type));
+ if (!atoms2)
+ return 0;
+
+ for (i = 0; i < num; i++)
+ atoms2[i] = _ecore_x_netwm_window_type_type_get(atoms[i]);
+ free(atoms);
+ if (types)
+ *types = atoms2;
+ else
+ free(atoms2);
+
+ return num;
+}
+
+static Ecore_X_Atom
+_ecore_x_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;
+ }
+}
+
+/* FIXME: Get complete list */
+EAPI Eina_Bool
+ecore_x_netwm_allowed_action_isset(Ecore_X_Window win,
+ Ecore_X_Action action)
+{
+ int num, i;
+ Ecore_X_Atom *atoms, atom;
+ Eina_Bool ret = EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ num = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atoms);
+ if (num <= 0)
+ return ret;
+
+ atom = _ecore_x_netwm_action_atom_get(action);
+
+ for (i = 0; i < num; ++i)
+ {
+ if (atom == atoms[i])
+ {
+ ret = 1;
+ break;
+ }
+ }
+
+ free(atoms);
+ return ret;
+}
+
+/* FIXME: Set complete list */
+EAPI void
+ecore_x_netwm_allowed_action_set(Ecore_X_Window win,
+ Ecore_X_Action *action,
+ unsigned int num)
+{
+ Ecore_X_Atom *set;
+ unsigned int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!num)
+ {
+ ecore_x_window_prop_property_del(win,
+ ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
+ return;
+ }
+
+ set = malloc(num * sizeof(Ecore_X_Atom));
+ if (!set)
+ return;
+
+ for (i = 0; i < num; i++)
+ set[i] = _ecore_x_netwm_action_atom_get(action[i]);
+
+ ecore_x_window_prop_atom_set(win,
+ ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
+ set,
+ num);
+
+ free(set);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_allowed_action_get(Ecore_X_Window win,
+ Ecore_X_Action **action,
+ unsigned int *num)
+{
+ int num_ret, i;
+ Ecore_X_Atom *atoms;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ 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)
+ for (i = 0; i < num_ret; ++i)
+ (*action)[i] = _ecore_x_netwm_action_atom_get(atoms[i]);
+
+ if (num)
+ *num = num_ret;
+ }
+
+ free(atoms);
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_x_netwm_opacity_set(Ecore_X_Window win,
+ unsigned int opacity)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &opacity, 1);
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_opacity_get(Ecore_X_Window win,
+ unsigned int *opacity)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &tmp, 1);
+ if (opacity)
+ *opacity = tmp;
+
+ return ret == 1 ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI void
+ecore_x_netwm_frame_size_set(Ecore_X_Window win,
+ int fl,
+ int fr,
+ int ft,
+ int fb)
+{
+ unsigned int frames[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ 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);
+}
+
+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];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_NET_FRAME_EXTENTS,
+ frames,
+ 4);
+ if (ret != 4)
+ return EINA_FALSE;
+
+ if (fl)
+ *fl = frames[0];
+
+ if (fr)
+ *fr = frames[1];
+
+ if (ft)
+ *ft = frames[2];
+
+ if (fb)
+ *fb = frames[3];
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_netwm_sync_counter_get(Ecore_X_Window win,
+ Ecore_X_Sync_Counter *counter)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(
+ win,
+ ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
+ &tmp,
+ 1);
+
+ if (counter)
+ *counter = tmp;
+
+ return ret == 1 ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI void
+ecore_x_netwm_ping_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ if (!win)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_PING;
+ xev.xclient.data.l[1] = _ecore_x_event_last_time;
+ xev.xclient.data.l[2] = win;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+EAPI void
+ecore_x_netwm_sync_request_send(Ecore_X_Window win,
+ unsigned int serial)
+{
+ XSyncValue value;
+ XEvent xev;
+
+ if (!win)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntToValue(&value, (int)serial);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+ xev.xclient.data.l[1] = _ecore_x_event_last_time;
+ xev.xclient.data.l[2] = XSyncValueLow32(value);
+ xev.xclient.data.l[3] = XSyncValueHigh32(value);
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+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)
+{
+ XEvent xev;
+
+ if (!win)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root)
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = ECORE_X_ATOM_NET_WM_STATE;
+ xev.xclient.data.l[0] = !!set;
+ xev.xclient.data.l[1] = _ecore_x_netwm_state_atom_get(s1);
+ xev.xclient.data.l[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 */
+ xev.xclient.data.l[3] = 1;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+}
+
+EAPI void
+ecore_x_netwm_desktop_request_send(Ecore_X_Window win,
+ Ecore_X_Window root,
+ unsigned int desktop)
+{
+ XEvent xev;
+
+ if (!win)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root)
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = ECORE_X_ATOM_NET_WM_DESKTOP;
+ xev.xclient.data.l[0] = desktop;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+}
+
+EAPI void
+ecore_x_netwm_moveresize_request_send(Ecore_X_Window win,
+ int x,
+ int y,
+ Ecore_X_Netwm_Direction direction,
+ unsigned int button)
+{
+ XEvent xev;
+
+ if (!win)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.window = win;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.message_type = ECORE_X_ATOM_NET_WM_MOVERESIZE;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = x;
+ xev.xclient.data.l[1] = y;
+ xev.xclient.data.l[2] = direction;
+ xev.xclient.data.l[3] = button;
+ xev.xclient.data.l[4] = 1;
+
+ XSendEvent(_ecore_x_disp, win, False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+}
+
+int
+_ecore_x_netwm_startup_info_begin(Ecore_X_Window win EINA_UNUSED,
+ char *data EINA_UNUSED)
+{
+#if 0
+ Ecore_X_Startup_Info *info;
+ unsigned char *exists = 0;
+
+ if (!startup_info)
+ return 0;
+
+ info = eina_hash_find(startup_info, (void *)win);
+ if (info)
+ {
+ exists = 1;
+ WRN("Already got info for win: 0x%x", win);
+ _ecore_x_netwm_startup_info_free(info);
+ }
+
+ info = calloc(1, sizeof(Ecore_X_Startup_Info));
+ if (!info)
+ return 0;
+
+ 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;
+ }
+
+ 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);
+
+ if (strlen(info->buffer) != 20)
+ /* We have a '\0' in there, the message is done */
+ _ecore_x_netwm_startup_info_process(info);
+
+#endif /* if 0 */
+ return 1;
+}
+
+int
+_ecore_x_netwm_startup_info(Ecore_X_Window win EINA_UNUSED,
+ char *data EINA_UNUSED)
+{
+#if 0
+ Ecore_X_Startup_Info *info;
+ char *p;
+
+ if (!startup_info)
+ return 0;
+
+ info = eina_hash_find(startup_info, (void *)win);
+ if (!info)
+ return 0;
+
+ 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;
+ }
+ }
+
+ 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);
+
+#endif /* if 0 */
+ return 1;
+}
+
+/*
+ * Set UTF-8 string property
+ */
+static void
+_ecore_x_window_prop_string_utf8_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ const char *str)
+{
+ XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8,
+ PropModeReplace, (unsigned char *)str, strlen(str));
+}
+
+/*
+ * Get UTF-8 string property
+ */
+static char *
+_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win,
+ Ecore_X_Atom atom)
+{
+ char *str;
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+
+ str = NULL;
+ prop_ret = NULL;
+ XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ ECORE_X_ATOM_UTF8_STRING, &type_ret,
+ &format_ret, &num_ret, &bytes_after, &prop_ret);
+ if (prop_ret && num_ret > 0 && format_ret == 8)
+ {
+ str = malloc(num_ret + 1);
+ if (str)
+ {
+ memcpy(str, prop_ret, num_ret);
+ str[num_ret] = '\0';
+ }
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return str;
+}
+
+#if 0 /* Unused */
+/*
+ * Process startup info
+ */
+static int
+_ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info)
+{
+ Ecore_X_Event_Startup_Sequence *e;
+ int event;
+ char *p;
+
+ p = strchr(info->buffer, ':');
+ if (!p)
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+
+ *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;
+
+ 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
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+
+ p++;
+
+ 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;
+ }
+
+ 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;
+ }
+
+ e->win = info->win;
+ ecore_event_add(event, e, NULL, NULL);
+ }
+
+ 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;
+ }
+
+ return 1;
+}
+
+/*
+ * Parse startup info
+ */
+static int
+_ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info,
+ char *data)
+{
+ 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;
+
+ data = p;
+ *pp = 0;
+
+ /* 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);
+
+ info->name = strdup(value);
+ }
+ else if (!strcmp(key, "SCREEN"))
+ info->screen = atoi(value);
+ 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);
+
+ 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);
+
+ info->description = strdup(value);
+ }
+ else if (!strcmp(key, "WMCLASS"))
+ {
+ if (info->wmclass)
+ free(info->wmclass);
+
+ info->wmclass = strdup(value);
+ }
+ else if (!strcmp(key, "SILENT"))
+ info->silent = atoi(value);
+ else
+ ERR("Ecore X Sequence, Unknown: %s=%s", key, value);
+ }
+ if (!info->id)
+ return 0;
+
+ return 1;
+}
+
+#endif /* if 0 */
+
+/*
+ * Free startup info struct
+ */
+static void
+_ecore_x_netwm_startup_info_free(void *data)
+{
+ Ecore_X_Startup_Info *info;
+
+ info = data;
+ if (!info)
+ 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);
+}
+
+/*
+ * Is screen composited?
+ */
+EAPI Eina_Bool
+ecore_x_screen_is_composited(int screen)
+{
+ Ecore_X_Window win;
+ static Ecore_X_Atom atom = None;
+ char buf[32];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
+ if (atom == None)
+ atom = XInternAtom(_ecore_x_disp, buf, False);
+
+ if (atom == None)
+ return EINA_FALSE;
+
+ win = XGetSelectionOwner(_ecore_x_disp, atom);
+
+ return (win != None) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI void
+ecore_x_screen_is_composited_set(int screen,
+ Ecore_X_Window win)
+{
+ static Ecore_X_Atom atom = None;
+ char buf[32];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
+ if (atom == None)
+ atom = XInternAtom(_ecore_x_disp, buf, False);
+
+ if (atom == None)
+ return;
+
+ XSetSelectionOwner(_ecore_x_disp, atom, win, _ecore_x_event_last_time);
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_pixmap.c b/src/lib/ecore_x/xlib/ecore_x_pixmap.c
new file mode 100644
index 0000000000..7b13615675
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_pixmap.c
@@ -0,0 +1,121 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+/**
+ * @defgroup Ecore_X_Pixmap_Group X Pixmap Functions
+ *
+ * Functions that operate on pixmaps.
+ */
+
+/**
+ * Creates a new pixmap.
+ * @param win Window used to determine which screen of the display the
+ * pixmap should be created on. If 0, the default root window
+ * is used.
+ * @param w Width of the new pixmap.
+ * @param h Height of the new pixmap.
+ * @param dep Depth of the pixmap. If 0, the default depth of the default
+ * screen is used.
+ * @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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0)
+ win = DefaultRootWindow(_ecore_x_disp);
+
+ if (dep == 0)
+ dep = DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp));
+
+ return XCreatePixmap(_ecore_x_disp, win, w, h, dep);
+}
+
+/**
+ * Deletes the reference to the given pixmap.
+ *
+ * If no other clients have a reference to the given pixmap, the server
+ * will destroy it.
+ *
+ * @param pmap The given pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI void
+ecore_x_pixmap_free(Ecore_X_Pixmap pmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFreePixmap(_ecore_x_disp, pmap);
+}
+
+/**
+ * Pastes a rectangular area of the given pixmap onto the given drawable.
+ * @param pmap The given pixmap.
+ * @param dest The given drawable.
+ * @param gc The graphics context which governs which operation will
+ * be used to paste the area onto the drawable.
+ * @param sx The X position of the area on the pixmap.
+ * @param sy The Y position of the area on the pixmap.
+ * @param w The width of the area.
+ * @param h The height of the area.
+ * @param dx The X position at which to paste the area on @p dest.
+ * @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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XCopyArea(_ecore_x_disp, pmap, dest, gc, sx, sy, w, h, dx, dy);
+}
+
+/**
+ * Retrieves the size of the given pixmap.
+ * @param pmap The given pixmap.
+ * @param x Pointer to an integer in which to store the X position.
+ * @param y Pointer to an integer in which to store the Y position.
+ * @param w Pointer to an integer in which to store the width.
+ * @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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (pmap)
+ ecore_x_drawable_geometry_get(pmap, x, y, w, h);
+}
+
+/**
+ * Retrieves the depth of the given pixmap.
+ * @param pmap The given pixmap.
+ * @return The depth of the pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI int
+ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_drawable_depth_get(pmap);
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_private.h b/src/lib/ecore_x/xlib/ecore_x_private.h
new file mode 100644
index 0000000000..f962ffb4b2
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_private.h
@@ -0,0 +1,379 @@
+#ifndef _ECORE_X_PRIVATE_H
+#define _ECORE_X_PRIVATE_H
+
+#include <sys/param.h>
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif /* ifndef MAXHOSTNAMELEN */
+
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xresource.h>
+#include <X11/keysymdef.h>
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/shape.h>
+#include <X11/extensions/sync.h>
+#include <X11/extensions/dpms.h>
+#ifdef ECORE_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+#endif /* ifdef ECORE_XCURSOR */
+#ifdef ECORE_XPRINT
+#include <X11/extensions/Print.h>
+#endif /* ifdef ECORE_XPRINT */
+#ifdef ECORE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif /* ifdef ECORE_XINERAMA */
+#ifdef ECORE_XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif /* ifdef ECORE_XRANDR */
+#ifdef ECORE_XSS
+#include <X11/extensions/scrnsaver.h>
+#endif /* ifdef ECORE_XSS */
+#ifdef ECORE_XRENDER
+#include <X11/extensions/Xrender.h>
+#endif /* ifdef ECORE_XRENDER */
+#ifdef ECORE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif /* ifdef ECORE_XFIXES */
+#ifdef ECORE_XCOMPOSITE
+#include <X11/extensions/Xcomposite.h>
+#endif /* ifdef ECORE_XCOMPOSITE */
+#ifdef ECORE_XDAMAGE
+#include <X11/extensions/Xdamage.h>
+#endif /* ifdef ECORE_XDAMAGE */
+#ifdef ECORE_XGESTURE
+#include <X11/extensions/gesture.h>
+#include <X11/extensions/gestureproto.h>
+#endif /* ifdef ECORE_XGESTURE */
+#ifdef ECORE_XDPMS
+#include <X11/extensions/dpms.h>
+#endif /* ifdef ECORE_XDPMS */
+#ifdef ECORE_XKB
+#include <X11/XKBlib.h>
+#endif /* ifdef ECORE_XKB */
+#ifdef ECORE_XI2
+#include <X11/extensions/XInput2.h>
+#endif /* ifdef ECORE_XI2 */
+
+#ifndef XK_MISCELLANY
+# define XK_MISCELLANY 1
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_X.h"
+#include "Ecore_Input.h"
+
+extern int _ecore_xlib_log_dom;
+#ifdef ECORE_XLIB_DEFAULT_LOG_COLOR
+# undef ECORE_XLIB_DEFAULT_LOG_COLOR
+#endif /* ifdef ECORE_XLIB_DEFAULT_LOG_COLOR */
+#define ECORE_XLIB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif /* ifdef ERR */
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_xlib_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif /* ifdef DBG */
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_xlib_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif /* ifdef INF */
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_xlib_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif /* ifdef WRN */
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_xlib_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif /* ifdef CRIT */
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_xlib_log_dom, __VA_ARGS__)
+
+typedef struct _Ecore_X_Selection_Intern Ecore_X_Selection_Intern;
+
+struct _Ecore_X_Selection_Intern
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom selection;
+ unsigned char *data;
+ int length;
+ Time time;
+};
+
+typedef struct _Ecore_X_Selection_Converter Ecore_X_Selection_Converter;
+
+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 *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;
+};
+
+typedef struct _Ecore_X_DND_Source
+{
+ 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;
+
+ Time time;
+
+ Ecore_X_Atom action, accepted_action;
+
+ int will_accept;
+ int suppress;
+
+ int await_status;
+} Ecore_X_DND_Source;
+
+typedef struct _Ecore_X_DND_Target
+{
+ int version;
+ Ecore_X_Window win, source;
+
+ enum {
+ ECORE_X_DND_TARGET_IDLE,
+ ECORE_X_DND_TARGET_ENTERED
+ } state;
+
+ struct
+ {
+ int x, y;
+ } pos;
+
+ Time time;
+
+ Ecore_X_Atom action, accepted_action;
+
+ int will_accept;
+} Ecore_X_DND_Target;
+
+extern Display *_ecore_x_disp;
+extern double _ecore_x_double_click_time;
+extern Time _ecore_x_event_last_time;
+extern Window _ecore_x_event_last_win;
+extern int _ecore_x_event_last_root_x;
+extern int _ecore_x_event_last_root_y;
+extern Eina_Bool _ecore_x_xcursor;
+
+extern Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
+
+extern int _ecore_window_grabs_num;
+extern 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_x_private_win;
+
+void _ecore_x_error_handler_init(void);
+void _ecore_x_event_handle_any_event(XEvent *xevent);
+void _ecore_x_event_handle_key_press(XEvent *xevent);
+void _ecore_x_event_handle_key_release(XEvent *xevent);
+void _ecore_x_event_handle_button_press(XEvent *xevent);
+void _ecore_x_event_handle_button_release(XEvent *xevent);
+void _ecore_x_event_handle_motion_notify(XEvent *xevent);
+void _ecore_x_event_handle_enter_notify(XEvent *xevent);
+void _ecore_x_event_handle_leave_notify(XEvent *xevent);
+void _ecore_x_event_handle_focus_in(XEvent *xevent);
+void _ecore_x_event_handle_focus_out(XEvent *xevent);
+void _ecore_x_event_handle_keymap_notify(XEvent *xevent);
+void _ecore_x_event_handle_expose(XEvent *xevent);
+void _ecore_x_event_handle_graphics_expose(XEvent *xevent);
+void _ecore_x_event_handle_visibility_notify(XEvent *xevent);
+void _ecore_x_event_handle_create_notify(XEvent *xevent);
+void _ecore_x_event_handle_destroy_notify(XEvent *xevent);
+void _ecore_x_event_handle_unmap_notify(XEvent *xevent);
+void _ecore_x_event_handle_map_notify(XEvent *xevent);
+void _ecore_x_event_handle_map_request(XEvent *xevent);
+void _ecore_x_event_handle_reparent_notify(XEvent *xevent);
+void _ecore_x_event_handle_configure_notify(XEvent *xevent);
+void _ecore_x_event_handle_configure_request(XEvent *xevent);
+void _ecore_x_event_handle_gravity_notify(XEvent *xevent);
+void _ecore_x_event_handle_resize_request(XEvent *xevent);
+void _ecore_x_event_handle_circulate_notify(XEvent *xevent);
+void _ecore_x_event_handle_circulate_request(XEvent *xevent);
+void _ecore_x_event_handle_property_notify(XEvent *xevent);
+void _ecore_x_event_handle_selection_clear(XEvent *xevent);
+void _ecore_x_event_handle_selection_request(XEvent *xevent);
+void _ecore_x_event_handle_selection_notify(XEvent *xevent);
+void _ecore_x_event_handle_colormap_notify(XEvent *xevent);
+void _ecore_x_event_handle_client_message(XEvent *xevent);
+void _ecore_x_event_handle_mapping_notify(XEvent *xevent);
+void _ecore_x_event_handle_shape_change(XEvent *xevent);
+void _ecore_x_event_handle_screensaver_notify(XEvent *xevent);
+#ifdef ECORE_XGESTURE
+void _ecore_x_event_handle_gesture_notify_flick(XEvent *xevent);
+void _ecore_x_event_handle_gesture_notify_pan(XEvent *xevent);
+void _ecore_x_event_handle_gesture_notify_pinchrotation(XEvent *xevent);
+void _ecore_x_event_handle_gesture_notify_tap(XEvent *xevent);
+void _ecore_x_event_handle_gesture_notify_tapnhold(XEvent *xevent);
+void _ecore_x_event_handle_gesture_notify_hold(XEvent *xevent);
+void _ecore_x_event_handle_gesture_notify_group(XEvent *xevent);
+#endif /* ifdef ECORE_XGESTURE */
+void _ecore_x_event_handle_sync_counter(XEvent *xevent);
+void _ecore_x_event_handle_sync_alarm(XEvent *xevent);
+#ifdef ECORE_XRANDR
+void _ecore_x_event_handle_randr_change(XEvent *xevent);
+void _ecore_x_event_handle_randr_notify(XEvent *xevent);
+#endif /* ifdef ECORE_XRANDR */
+#ifdef ECORE_XFIXES
+void _ecore_x_event_handle_fixes_selection_notify(XEvent *xevent);
+#endif /* ifdef ECORE_XFIXES */
+#ifdef ECORE_XDAMAGE
+void _ecore_x_event_handle_damage_notify(XEvent *xevent);
+#endif /* ifdef ECORE_XDAMAGE */
+#ifdef ECORE_XKB
+void _ecore_x_event_handle_xkb(XEvent *xevent);
+#endif /* ifdef ECORE_XKB */
+void _ecore_x_event_handle_generic_event(XEvent *xevent);
+
+void _ecore_x_selection_data_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);
+Eina_Bool _ecore_x_selection_set(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,
+ Ecore_X_Atom *targettype,
+ int *targetsize);
+void *_ecore_x_selection_parse(const char *target,
+ void *data,
+ int size,
+ int format);
+
+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);
+
+/* from dnd */
+void _ecore_x_dnd_init(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);
+void _ecore_x_dnd_shutdown(void);
+
+/* from 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);
+
+/* Fixes * Damage * Composite * DPMS */
+void _ecore_x_fixes_init(void);
+void _ecore_x_damage_init(void);
+void _ecore_x_composite_init(void);
+void _ecore_x_dpms_init(void);
+void _ecore_x_randr_init(void);
+void _ecore_x_gesture_init(void);
+
+void _ecore_x_atoms_init(void);
+
+extern int _ecore_x_xi2_opcode;
+
+void _ecore_x_events_init(void);
+void _ecore_x_events_shutdown(void);
+
+void _ecore_x_input_init(void);
+void _ecore_x_input_shutdown(void);
+void _ecore_x_input_handler(XEvent *xevent);
+/* from sync */
+
+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,
+ int dev,
+ double radx,
+ double rady,
+ double pressure,
+ double angle,
+ double mx,
+ double my,
+ double mrx,
+ double mry);
+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,
+ int dev,
+ double radx,
+ double rady,
+ double pressure,
+ double angle,
+ double mx,
+ double my,
+ double mrx,
+ double mry);
+
+void _ecore_x_modifiers_get(void);
+KeySym _ecore_x_XKeycodeToKeysym(Display *display, KeyCode keycode, int index);
+
+//#define LOGFNS 1
+
+#ifdef LOGFNS
+#include <stdio.h>
+#define LOGFN(fl, ln, fn) printf("-ECORE-X: %25s: %5i - %s\n", fl, ln, fn);
+#else /* ifdef LOGFNS */
+#define LOGFN(fl, ln, fn)
+#endif /* ifdef LOGFNS */
+
+#endif /* ifndef _ECORE_X_PRIVATE_H */
diff --git a/src/lib/ecore_x/xlib/ecore_x_randr.c b/src/lib/ecore_x/xlib/ecore_x_randr.c
new file mode 100644
index 0000000000..58a28305ac
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_randr.c
@@ -0,0 +1,103 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "ecore_x_private.h"
+#include "ecore_x_randr.h"
+
+static Eina_Bool _randr_available = EINA_FALSE;
+#ifdef ECORE_XRANDR
+static int _randr_major, _randr_minor;
+int _randr_version;
+#define RANDR_1_1 ((1 << 16) | 1)
+#define RANDR_1_2 ((1 << 16) | 2)
+#define RANDR_1_3 ((1 << 16) | 3)
+
+#define RANDR_VALIDATE_ROOT(screen, \
+ root) ((screen = \
+ XRRRootToScreen(_ecore_x_disp, \
+ root)) != -1)
+
+#define Ecore_X_Randr_Unset -1
+
+XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * dpy,
+ Window window);
+
+#endif /* ifdef ECORE_XRANDR */
+
+void
+_ecore_x_randr_init(void)
+{
+#ifdef ECORE_XRANDR
+ _randr_major = 1;
+ _randr_minor = 3;
+ _randr_version = 0;
+
+ _ecore_x_randr_get_screen_resources = NULL;
+ if (XRRQueryVersion(_ecore_x_disp, &_randr_major, &_randr_minor))
+ {
+ _randr_version = (_randr_major << 16) | _randr_minor;
+ if (_randr_version >= RANDR_1_3)
+ _ecore_x_randr_get_screen_resources = XRRGetScreenResourcesCurrent;
+ else if (_randr_version == RANDR_1_2)
+ _ecore_x_randr_get_screen_resources = XRRGetScreenResources;
+
+ _randr_available = EINA_TRUE;
+ }
+ else
+ _randr_available = EINA_FALSE;
+
+#else
+ _randr_available = EINA_FALSE;
+#endif
+}
+
+/*
+ * @brief Query whether randr is available or not.
+ *
+ * @return @c EINA_TRUE, if extension is available, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_randr_query(void)
+{
+ return _randr_available;
+}
+
+/*
+ * @return version of the RandR extension supported by the server or, in case
+ * RandR extension is not available, Ecore_X_Randr_Unset (=-1).
+ * bit version information: 31 MAJOR 16 | 15 MINOR 0
+ */
+EAPI int
+ecore_x_randr_version_get(void)
+{
+#ifdef ECORE_XRANDR
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (_randr_available)
+ {
+ return _randr_version;
+ }
+ else
+ {
+ return Ecore_X_Randr_Unset;
+ }
+#else
+ return -1;
+#endif
+}
+
+Eina_Bool
+_ecore_x_randr_root_validate(Ecore_X_Window root)
+{
+#ifdef ECORE_XRANDR
+ Ecore_X_Randr_Screen scr = -1;
+ if (root && RANDR_VALIDATE_ROOT(scr, root))
+ return EINA_TRUE;
+ else
+ return EINA_FALSE;
+
+#else
+ return EINA_FALSE;
+#endif
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_randr.h b/src/lib/ecore_x/xlib/ecore_x_randr.h
new file mode 100644
index 0000000000..eca3c0c32c
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_randr.h
@@ -0,0 +1,7 @@
+#ifndef ECORE_X_INLINE_X
+#define ECORE_X_INLINE_X
+Eina_Bool _ecore_x_randr_root_validate(Ecore_X_Window root);
+Eina_Bool _ecore_x_randr_output_validate(Ecore_X_Window root,
+ Ecore_X_Randr_Output
+ output);
+#endif
diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_11.c b/src/lib/ecore_x/xlib/ecore_x_randr_11.c
new file mode 100644
index 0000000000..7d2b3b34b5
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_randr_11.c
@@ -0,0 +1,334 @@
+/*
+ * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "ecore_x_private.h"
+#include "ecore_x_randr.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#define Ecore_X_Randr_None 0
+#ifdef ECORE_XRANDR
+
+#define RANDR_1_1 ((1 << 16) | 1)
+
+#define RANDR_VALIDATE_ROOT(screen, \
+ root) ((screen = \
+ XRRRootToScreen(_ecore_x_disp, \
+ root)) != -1)
+#define RANDR_CHECK_1_1_RET(ret) if (_randr_version < RANDR_1_1) \
+ return ret
+
+extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display *
+ dpy,
+ Window
+ window);
+extern int _randr_version;
+#endif /* ifdef ECORE_XRANDR */
+
+/*
+ * @param root window which's primary output will be queried
+ */
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root)
+{
+#ifdef ECORE_XRANDR
+ Rotation rot = Ecore_X_Randr_None, crot;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rot =
+ XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+ root), &crot);
+ return rot;
+#else /* ifdef ECORE_XRANDR */
+ return Ecore_X_Randr_None;
+#endif /* ifdef ECORE_XRANDR */
+}
+
+/*
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ Rotation crot = Ecore_X_Randr_None;
+ XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+ root), &crot);
+ return crot;
+#else /* ifdef ECORE_XRANDR */
+ return Ecore_X_Randr_None;
+#endif /* ifdef ECORE_XRANDR */
+}
+
+/*
+ * @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 @c 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)
+{
+#ifdef ECORE_XRANDR
+ XRRScreenConfiguration *xrr_screen_cfg = NULL;
+ int sizeid;
+ Rotation crot;
+ Eina_Bool ret = EINA_FALSE;
+ if (!(xrr_screen_cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
+ return EINA_FALSE;
+
+ sizeid = XRRConfigCurrentConfiguration(xrr_screen_cfg, &crot);
+ if (!XRRSetScreenConfig(_ecore_x_disp, xrr_screen_cfg, root, sizeid,
+ orientation, CurrentTime))
+ ret = EINA_TRUE;
+
+ if (xrr_screen_cfg)
+ XRRFreeScreenConfigInfo(xrr_screen_cfg);
+
+ return ret;
+#else /* ifdef ECORE_XRANDR */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XRANDR */
+}
+
+/*
+ * @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_XRANDR
+ Ecore_X_Randr_Screen_Size_MM *ret = NULL;
+ XRRScreenSize *sizes;
+ int i, n;
+
+ /* we don't have to free sizes, because they're hold in a cache inside X*/
+ sizes =
+ XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+ root), &n);
+ if ((!sizes) || (n <= 0)) return NULL;
+ ret = calloc(n, sizeof(Ecore_X_Randr_Screen_Size_MM));
+ if (!ret)
+ return NULL;
+
+ if (num)
+ *num = n;
+
+ for (i = 0; i < n; 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;
+ }
+ return ret;
+#else /* ifdef ECORE_XRANDR */
+ return NULL;
+#endif /* ifdef ECORE_XRANDR */
+}
+
+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)
+{
+#ifdef ECORE_XRANDR
+ XRRScreenSize *sizes;
+ XRRScreenConfiguration *sc = NULL;
+ int idx;
+ Rotation orientation;
+ int n;
+
+ if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root)))
+ {
+ ERR("Couldn't get screen information for %d", root);
+ return;
+ }
+
+ idx = XRRConfigCurrentConfiguration(sc, &orientation);
+
+ sizes =
+ XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+ root), &n);
+ if ((idx < n) && (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;
+ }
+
+ XRRFreeScreenConfigInfo(sc);
+#endif /* ifdef ECORE_XRANDR */
+}
+
+/*
+ * @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 @c EINA_TRUE on success, @c 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)
+{
+#ifdef ECORE_XRANDR
+ XRRScreenConfiguration *sc = NULL;
+ Eina_Bool ret = EINA_FALSE;
+ int nsizes = 0;
+
+ if (size_index >= 0 && _ecore_x_randr_root_validate(root))
+ {
+ XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+ root), &nsizes);
+
+ if (size_index < nsizes)
+ {
+ sc = XRRGetScreenInfo(_ecore_x_disp, root);
+ if (!XRRSetScreenConfig(_ecore_x_disp, sc,
+ root, size_index,
+ ECORE_X_RANDR_ORIENTATION_ROT_0, CurrentTime))
+ {
+ ret = EINA_TRUE;
+ }
+
+ if (sc)
+ XRRFreeScreenConfigInfo(sc);
+ }
+ }
+
+ return ret;
+#else /* ifdef ECORE_XRANDR */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XRANDR */
+}
+
+/*
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ Ecore_X_Randr_Refresh_Rate ret = 0.0;
+ XRRScreenConfiguration *sc = NULL;
+
+ if (!_ecore_x_randr_root_validate(root) ||
+ !(sc = XRRGetScreenInfo(_ecore_x_disp, root)))
+ return ret;
+
+ ret = XRRConfigCurrentRate(sc);
+ if (sc)
+ XRRFreeScreenConfigInfo(sc);
+
+ return ret;
+#else /* ifdef ECORE_XRANDR */
+ return 0.0;
+#endif /* ifdef ECORE_XRANDR */
+}
+
+/*
+ * @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_XRANDR
+ Ecore_X_Randr_Refresh_Rate *ret = NULL, *rates = NULL;
+ Ecore_X_Randr_Screen scr;
+ int n;
+
+ if (num
+ && RANDR_VALIDATE_ROOT(scr, root)
+ && (rates = XRRRates(_ecore_x_disp, scr, size_index, &n)))
+ {
+ if (rates && (ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * n)))
+ {
+ memcpy(ret, rates, (sizeof(Ecore_X_Randr_Refresh_Rate) * n));
+ *num = n;
+ }
+ }
+
+ return ret;
+#else /* ifdef ECORE_XRANDR */
+ return NULL;
+#endif /* ifdef ECORE_XRANDR */
+}
+
+//>= 1.1
+/*
+ * @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 @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ */
+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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_1_RET(EINA_FALSE);
+ Eina_Bool ret = EINA_FALSE;
+ XRRScreenConfiguration *sc = NULL;
+
+ if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root)))
+ return ret;
+
+ if (!XRRSetScreenConfigAndRate(_ecore_x_disp, sc,
+ root, size_index,
+ RR_Rotate_0, rate, CurrentTime))
+ ret = EINA_TRUE;
+
+ XRRFreeScreenConfigInfo(sc);
+ return ret;
+#else /* ifdef ECORE_XRANDR */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XRANDR */
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_12.c b/src/lib/ecore_x/xlib/ecore_x_randr_12.c
new file mode 100644
index 0000000000..9e937d7bf7
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_randr_12.c
@@ -0,0 +1,2438 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif !defined alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# elif !defined HAVE_ALLOCA
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+#endif
+
+#include "ecore_x_private.h"
+#include "ecore_x_randr.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#define Ecore_X_Randr_None (Ecore_X_Randr_Crtc)0
+#define Ecore_X_Randr_Unset (Ecore_X_Randr_Crtc) - 1
+
+#ifdef ECORE_XRANDR
+
+#define RANDR_1_2 ((1 << 16) | 2)
+
+#define RANDR_VALIDATE_ROOT(screen, root) \
+ ((screen = XRRRootToScreen(_ecore_x_disp, root)) != -1)
+
+#define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) \
+ return ret
+
+#define RANDR_PROPERTY_EDID "EDID"
+#define RANDR_PROPERTY_BACKLIGHT "Backlight"
+#define RANDR_PROPERTY_SIGNAL_FORMAT "SignalFormat"
+#define RANDR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties"
+#define RANDR_PROPERTY_CONNECTOR_TYPE "ConnectorType"
+#define RANDR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber"
+#define RANDR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList"
+#define RANDR_PROPERTY_CLONE_LIST "CloneList"
+
+extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display *
+ dpy,
+ Window
+ window);
+extern int _randr_version;
+#endif
+
+/**
+ * @brief Enable event selection. This enables basic interaction with
+ * output/crtc events and requires RandR >= 1.2.
+ *
+ * @param win Select this window's properties for RandR events.
+ * @param on Enable/disable selecting.
+ */
+EAPI void
+ecore_x_randr_events_select(Ecore_X_Window win,
+ Eina_Bool on)
+{
+#ifdef ECORE_XRANDR
+ int mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!on)
+ mask = 0;
+ else
+ {
+ mask = RRScreenChangeNotifyMask;
+ if (_randr_version >= RANDR_1_2)
+ mask |= (RRCrtcChangeNotifyMask |
+ RROutputChangeNotifyMask |
+ RROutputPropertyNotifyMask);
+ }
+
+ XRRSelectInput(_ecore_x_disp, win, mask);
+#endif
+}
+
+/**
+ * @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, @c EINA_TRUE will be returned, @c EINA_FALSE
+ * otherwise.
+ */
+static inline Eina_Bool
+_ecore_x_randr_crtc_validate(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ XRRScreenResources *res = NULL;
+ int i;
+ Eina_Bool ret = EINA_FALSE;
+
+ if ((crtc == Ecore_X_Randr_None) ||
+ (crtc == Ecore_X_Randr_Unset))
+ return ret;
+
+ if (_ecore_x_randr_root_validate(root) && crtc &&
+ (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+ {
+ for (i = 0; i < res->ncrtc; i++)
+ {
+ if (res->crtcs[i] == crtc)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+ }
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+Eina_Bool
+_ecore_x_randr_output_validate(Ecore_X_Window root,
+ Ecore_X_Randr_Output output)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ Eina_Bool ret = EINA_FALSE;
+ XRRScreenResources *res = NULL;
+ int i;
+
+ if (_ecore_x_randr_root_validate(root) && output &&
+ (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+ {
+ for (i = 0; i < res->noutput; i++)
+ {
+ if (res->outputs[i] == output)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+ }
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+static inline Eina_Bool
+_ecore_x_randr_mode_validate(Ecore_X_Window root,
+ Ecore_X_Randr_Mode mode)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ Eina_Bool ret = EINA_FALSE;
+ XRRScreenResources *res = NULL;
+ int i;
+
+ if (_ecore_x_randr_root_validate(root) && mode &&
+ (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+ {
+ for (i = 0; i < res->nmode; i++)
+ {
+ if (res->modes[i].id == mode)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+ }
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return EINA_FALSE;
+#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_XRANDR
+ RANDR_CHECK_1_2_RET();
+ Ecore_X_Randr_Screen scr;
+
+ if (!RANDR_VALIDATE_ROOT(scr, root))
+ return;
+
+ if (w)
+ *w = DisplayWidth(_ecore_x_disp, scr);
+
+ if (h)
+ *h = DisplayHeight(_ecore_x_disp, scr);
+
+ if (w_mm)
+ *w_mm = DisplayWidthMM(_ecore_x_disp, scr);
+
+ if (h_mm)
+ *h_mm = DisplayHeightMM(_ecore_x_disp, scr);
+
+#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 *wmin,
+ int *hmin,
+ int *wmax,
+ int *hmax)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET();
+ int twmin, thmin, twmax, thmax;
+ if (XRRGetScreenSizeRange (_ecore_x_disp, root, &twmin, &thmin, &twmax,
+ &thmax))
+ {
+ if (wmin)
+ *wmin = twmin;
+
+ if (hmin)
+ *hmin = thmin;
+
+ if (wmax)
+ *wmax = twmax;
+
+ if (hmax)
+ *hmax = thmax;
+ }
+
+#endif
+}
+
+/*
+ * @param root Window which's screen's size should be set. If invalid (e.g.
+ * @c 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 @c 0, current
+ * aspect is assumed.
+ * @param h_mm Height in mm the screen should be set to. If @c 0, current
+ * aspect is assumed.
+ * @return @c EINA_TRUE if request was successfully sent or screen is already
+ * in requested size, @c 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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ Ecore_X_Randr_Screen scr;
+ int w_c, h_c, w_mm_c, h_mm_c, twmin, thmin, twmax, thmax;
+
+ if (!RANDR_VALIDATE_ROOT(scr, root))
+ return EINA_FALSE;
+
+ ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, &w_mm_c, &h_mm_c);
+ if ((w == w_c) && (h == h_c) && (w_mm_c == w_mm) && (h_mm_c == h_mm))
+ return EINA_TRUE;
+
+ ecore_x_randr_screen_size_range_get(root, &twmin, &thmin, &twmax, &thmax);
+
+ if (((w != Ecore_X_Randr_None) &&
+ ((w < twmin) ||
+ (w > twmax))) ||
+ ((h != Ecore_X_Randr_None) && ((h < thmin) || (h > thmax))))
+ return EINA_FALSE;
+
+ if (w <= 0)
+ w = DisplayWidth(_ecore_x_disp, scr);
+
+ if (h <= 0)
+ h = DisplayHeight(_ecore_x_disp, scr);
+
+ if (w_mm <= 0)
+ w_mm =
+ (int)(((double)(DisplayWidthMM(_ecore_x_disp,
+ scr) /
+ (double)DisplayWidth(_ecore_x_disp,
+ scr))) * (double)w);
+
+ if (h_mm <= 0)
+ h_mm =
+ (int)(((double)(DisplayHeightMM(_ecore_x_disp,
+ scr) /
+ (double)DisplayHeight(_ecore_x_disp,
+ scr))) * (double)h);
+
+ XRRSetScreenSize (_ecore_x_disp, root, w, h, w_mm, h_mm);
+ return EINA_TRUE;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+/*
+ * @brief get detailed information for all modes related to a root window's screen
+ * @param root window which's screen's ressources are queried
+ * @param num number of modes returned
+ * @return modes' information
+ */
+EAPI Ecore_X_Randr_Mode_Info **
+ecore_x_randr_modes_info_get(Ecore_X_Window root,
+ int *num)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ Ecore_X_Randr_Mode_Info **ret = NULL;
+ int i;
+
+ if (_ecore_x_randr_root_validate(root) &&
+ (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+ {
+ if ((ret =
+ (Ecore_X_Randr_Mode_Info **)malloc(sizeof(
+ Ecore_X_Randr_Mode_Info *)
+ *
+ res->nmode)))
+ {
+ for (i = 0; i < res->nmode; i++)
+ {
+ if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
+ {
+ ret[i]->xid = res->modes[i].id;
+ ret[i]->width = res->modes[i].width;
+ ret[i]->height = res->modes[i].height;
+ ret[i]->dotClock = res->modes[i].dotClock;
+ ret[i]->hSyncStart = res->modes[i].hSyncStart;
+ ret[i]->hSyncEnd = res->modes[i].hSyncEnd;
+ ret[i]->hTotal = res->modes[i].hTotal;
+ ret[i]->hSkew = res->modes[i].hSkew;
+ ret[i]->vSyncStart = res->modes[i].vSyncStart;
+ ret[i]->vSyncEnd = res->modes[i].vSyncEnd;
+ ret[i]->vTotal = res->modes[i].vTotal;
+ if ((ret[i]->name = (malloc(res->modes[i].nameLength + 1))))
+ strncpy(ret[i]->name, res->modes[i].name,
+ (res->modes[i].nameLength + 1));
+ else
+ ret[i]->name = NULL;
+
+ ret[i]->nameLength = res->modes[i].nameLength;
+ ret[i]->modeFlags = res->modes[i].modeFlags;
+ }
+ else
+ {
+ while (i > 0)
+ free(ret[--i]);
+ free(ret);
+ ret = NULL;
+ break;
+ }
+ }
+ }
+
+ if (ret && num)
+ *num = res->nmode;
+
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
+/*
+ * @brief Add a mode to a display.
+ *
+ * @param root Window to which's screen's ressources are added.
+ * @param mode_info
+ * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode
+ * adding failed.
+ * @since 1.2.0
+ */
+EAPI Ecore_X_Randr_Mode
+ecore_x_randr_mode_info_add(Ecore_X_Window root,
+ Ecore_X_Randr_Mode_Info *mode_info)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+ Ecore_X_Randr_Mode mode = Ecore_X_Randr_None;
+
+ if (_ecore_x_randr_root_validate(root) && mode_info)
+ mode = XRRCreateMode(_ecore_x_disp, root, (XRRModeInfo*)mode_info);
+
+ return mode;
+#else
+ return Ecore_X_Randr_None;
+#endif
+}
+
+/*
+ * @brief Delete a mode from the display.
+ *
+ * @param mode_info
+ * @since 1.2.0
+ */
+EAPI void
+ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET();
+
+ XRRDestroyMode(_ecore_x_disp, mode);
+#else
+ return;
+#endif
+}
+
+/*
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ Ecore_X_Randr_Mode_Info *ret = NULL;
+ int i;
+
+ if (_ecore_x_randr_root_validate(root) &&
+ (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+ {
+ for (i = 0; i < res->nmode; i++)
+ {
+ if ((res->modes[i].id == mode) &&
+ (ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
+ {
+ ret->xid = res->modes[i].id;
+ ret->width = res->modes[i].width;
+ ret->height = res->modes[i].height;
+ ret->dotClock = res->modes[i].dotClock;
+ ret->hSyncStart = res->modes[i].hSyncStart;
+ ret->hSyncEnd = res->modes[i].hSyncEnd;
+ ret->hTotal = res->modes[i].hTotal;
+ ret->hSkew = res->modes[i].hSkew;
+ ret->vSyncStart = res->modes[i].vSyncStart;
+ ret->vSyncEnd = res->modes[i].vSyncEnd;
+ ret->vTotal = res->modes[i].vTotal;
+ ret->name = NULL;
+ ret->nameLength = 0;
+ if (res->modes[i].nameLength > 0)
+ {
+ ret->nameLength = res->modes[i].nameLength;
+ ret->name = malloc(res->modes[i].nameLength + 1);
+ if (ret->name)
+ memcpy(ret->name, res->modes[i].name,
+ res->modes[i].nameLength + 1);
+ }
+ ret->modeFlags = res->modes[i].modeFlags;
+ break;
+ }
+ }
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
+/*
+ * @brief Free detailed mode information. The pointer handed in will be set to
+ * @c 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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET();
+ if (!mode_info)
+ return;
+
+ if (mode_info->name)
+ free(mode_info->name);
+
+ free(mode_info);
+ mode_info = NULL;
+#endif
+}
+
+/*
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ Ecore_X_Randr_Crtc *ret = NULL;
+
+ if (root &&
+ (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+ {
+ if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc) * res->ncrtc)))
+ {
+ int i = 0;
+
+ if (num) *num = res->ncrtc;
+
+ for (i = 0; i < res->ncrtc; i++)
+ ret[i] = res->crtcs[i];
+ }
+
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
+/*
+ * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead.
+ * @brief get the CRTCs, which display a certain window
+ * @param window window the displaying crtcs shall be found for
+ * @param num the number of crtcs displaying the window
+ * @return Array of crtcs that display a certain window. @c NULL if no crtcs
+ * was found that displays the specified window.
+ */
+EAPI Ecore_X_Randr_Crtc *
+ecore_x_randr_current_crtc_get(Ecore_X_Window window,
+ int *num)
+{
+ return ecore_x_randr_window_crtcs_get(window, num);
+}
+
+/*
+ * @brief get the CRTCs, which display a certain window
+ * @param window window the displaying crtcs shall be found for
+ * @param num the number of crtcs displaying the window
+ * @return Array of crtcs that display a certain window. @c NULL if no crtcs
+ * was found that displays the specified window.
+ * @since 1.2.0
+ */
+EAPI Ecore_X_Randr_Crtc *
+ecore_x_randr_window_crtcs_get(Ecore_X_Window window,
+ int *num)
+{
+#ifdef ECORE_XRANDR
+ Ecore_X_Window root;
+ Eina_Rectangle w_geo, c_geo;
+ Ecore_X_Randr_Crtc *crtcs;
+ Ecore_X_Randr_Mode mode;
+ Ecore_X_Randr_Output *ret = NULL;
+ Window tw;
+ int ncrtcs, i, nret = 0, rx = 0, ry = 0;
+
+ if (_randr_version < RANDR_1_2) goto _ecore_x_randr_window_crtcs_get_fail;
+
+ 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) goto _ecore_x_randr_window_crtcs_get_fail;
+
+ /* now get window RELATIVE to root window - thats what matters. */
+ XTranslateCoordinates(_ecore_x_disp, window, root, 0, 0, &rx, &ry, &tw);
+ w_geo.x = rx;
+ w_geo.y = ry;
+
+ ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc));
+ if (!ret)
+ {
+ free(crtcs);
+ goto _ecore_x_randr_window_crtcs_get_fail;
+ }
+ for (i = 0, nret = 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))
+ {
+ ret[nret] = crtcs[i];
+ nret++;
+ }
+ }
+ free(crtcs);
+
+ if (num) *num = nret;
+ return ret;
+
+_ecore_x_randr_window_crtcs_get_fail:
+#endif
+ if (num) *num = 0;
+ return NULL;
+}
+
+EAPI Ecore_X_Randr_Output *
+ecore_x_randr_outputs_get(Ecore_X_Window root,
+ int *num)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ Ecore_X_Randr_Output *ret = NULL;
+
+ if (root &&
+ (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+ {
+ if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * res->noutput)))
+ {
+ int i = 0;
+
+ if (num) *num = res->noutput;
+
+ for (i = 0; i < res->noutput; i++)
+ ret[i] = res->outputs[i];
+ }
+
+ if (res)
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
+//Per Crtc
+/*
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ Ecore_X_Randr_Output *ret = NULL;
+ XRRCrtcInfo *crtc_info = NULL;
+
+ if (_ecore_x_randr_crtc_validate(root, crtc) &&
+ (res =
+ _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)) &&
+ (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+ {
+ if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->noutput)))
+ {
+ int i = 0;
+
+ if (num) *num = crtc_info->noutput;
+
+ for (i = 0; i < crtc_info->noutput; i++)
+ ret[i] = crtc_info->outputs[i];
+ }
+
+ if (crtc_info)
+ XRRFreeCrtcInfo(crtc_info);
+
+ if (res)
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
+/*
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ Ecore_X_Randr_Output *ret = NULL;
+ XRRCrtcInfo *crtc_info = NULL;
+
+ if (_ecore_x_randr_crtc_validate(root, crtc) &&
+ (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+ {
+ if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+ {
+ if ((ret =
+ malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->npossible)))
+ {
+ int i = 0;
+
+ if (num) *num = crtc_info->npossible;
+
+ for (i = 0; i < crtc_info->npossible; i++)
+ ret[i] = crtc_info->possible[i];
+ }
+
+ XRRFreeCrtcInfo(crtc_info);
+ }
+
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
+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_XRANDR
+ RANDR_CHECK_1_2_RET();
+ XRRScreenResources *res = NULL;
+ XRRCrtcInfo *crtc_info = NULL;
+
+ if (_ecore_x_randr_crtc_validate(root,
+ crtc) &&
+ (res =
+ _ecore_x_randr_get_screen_resources (_ecore_x_disp,
+ root)) &&
+ (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+ {
+ if (x)
+ *x = crtc_info->x;
+
+ if (y)
+ *y = crtc_info->y;
+
+ if (w)
+ *w = crtc_info->width;
+
+ if (h)
+ *h = crtc_info->height;
+
+ XRRFreeCrtcInfo(crtc_info);
+ XRRFreeScreenResources(res);
+ }
+
+#endif
+}
+
+/*
+ * @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 @c EINA_TRUE if position could 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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+ int w_c, h_c, w_new = 0, h_new = 0;
+ Eina_Rectangle crtc_geo;
+
+ ecore_x_randr_crtc_geometry_get(root,
+ crtc,
+ &crtc_geo.x,
+ &crtc_geo.y,
+ &crtc_geo.w,
+ &crtc_geo.h);
+ ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, NULL, NULL);
+ if (x < 0)
+ x = crtc_geo.x;
+
+ if (y < 0)
+ y = crtc_geo.y;
+
+ if ((x + crtc_geo.w) > w_c)
+ w_new = x + crtc_geo.w;
+
+ if ((y + crtc_geo.h) > h_c)
+ h_new = y + crtc_geo.h;
+
+ if ((w_new != 0) || (h_new != 0))
+ if (!ecore_x_randr_screen_current_size_set(root, w_new, h_new, 0, 0))
+ return EINA_FALSE;
+
+ return ecore_x_randr_crtc_settings_set(root,
+ crtc,
+ NULL,
+ Ecore_X_Randr_Unset,
+ x,
+ y,
+ Ecore_X_Randr_Unset,
+ Ecore_X_Randr_Unset);
+#else
+ return EINA_FALSE;
+#endif
+}
+
+/**
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset);
+ XRRScreenResources *res = NULL;
+ XRRCrtcInfo *crtc_info = NULL;
+ Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset;
+ if (_ecore_x_randr_root_validate(root) &&
+ _ecore_x_randr_crtc_validate(root,
+ crtc) &&
+ (res =
+ _ecore_x_randr_get_screen_resources(_ecore_x_disp,
+ root)) &&
+ (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+ {
+ ret = crtc_info->mode;
+ XRRFreeCrtcInfo(crtc_info);
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return Ecore_X_Randr_Unset;
+#endif
+}
+
+/**
+ * @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 @c NULL, CRTC will be disabled.
+ * @param noutputs Number of outputs in array to be used. Use
+ * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs.
+ * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be
+ * disabled. If set to @c -1 the call will fail.
+ * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE
+ * otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_randr_crtc_mode_set(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ Ecore_X_Randr_Output *outputs,
+ int noutputs,
+ Ecore_X_Randr_Mode mode)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if (mode == Ecore_X_Randr_Unset)
+ return EINA_FALSE;
+
+ return ecore_x_randr_crtc_settings_set(root,
+ crtc,
+ outputs,
+ noutputs,
+ Ecore_X_Randr_Unset,
+ Ecore_X_Randr_Unset,
+ mode,
+ Ecore_X_Randr_Unset);
+#else
+ return EINA_FALSE;
+#endif
+}
+
+EAPI void
+ecore_x_randr_crtc_size_get(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ int *w,
+ int *h)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET();
+ ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h);
+#endif
+}
+
+EAPI Ecore_X_Randr_Refresh_Rate
+ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ Ecore_X_Randr_Mode mode)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(0.0);
+ XRRScreenResources *res = NULL;
+ XRRCrtcInfo *crtc_info = NULL;
+ Ecore_X_Randr_Refresh_Rate ret = 0.0;
+ int i;
+
+ if (_ecore_x_randr_crtc_validate(root,
+ crtc) &&
+ (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+ {
+ for (i = 0; i < res->nmode; i++)
+ if (res->modes[i].id == mode)
+ {
+ if (res->modes[i].hTotal && res->modes[i].vTotal)
+ ret = ((double)res->modes[i].dotClock /
+ ((double)res->modes[i].hTotal *
+ (double)res->modes[i].vTotal));
+
+ break;
+ }
+ }
+
+ if (crtc_info)
+ XRRFreeCrtcInfo(crtc_info);
+
+ if (res)
+ XRRFreeScreenResources(res);
+
+ return ret;
+#else
+ return 0.0;
+#endif
+}
+
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_crtc_orientations_get(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
+ XRRCrtcInfo *crtc_info = NULL;
+ XRRScreenResources *res = NULL;
+ Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
+
+ if (_ecore_x_randr_crtc_validate(root,
+ crtc) &&
+ (res =
+ _ecore_x_randr_get_screen_resources (_ecore_x_disp,
+ root)) &&
+ (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+ {
+ ret = crtc_info->rotations;
+ }
+ if (crtc_info)
+ XRRFreeCrtcInfo(crtc_info);
+
+ if (res)
+ XRRFreeScreenResources(res);
+
+ return ret;
+#else
+ return Ecore_X_Randr_None;
+#endif
+}
+
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_crtc_orientation_get(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
+ XRRCrtcInfo *crtc_info = NULL;
+ XRRScreenResources *res = NULL;
+ Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
+
+ if (_ecore_x_randr_crtc_validate(root,
+ crtc) &&
+ (res =
+ _ecore_x_randr_get_screen_resources (_ecore_x_disp,
+ root)) &&
+ (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+ {
+ ret = crtc_info->rotation;
+ }
+ if (crtc_info)
+ XRRFreeCrtcInfo(crtc_info);
+
+ if (res)
+ XRRFreeScreenResources(res);
+
+ return ret;
+#else
+ return Ecore_X_Randr_None;
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_randr_crtc_orientation_set(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ Ecore_X_Randr_Orientation orientation)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+ Eina_Bool ret = EINA_FALSE;
+
+ if (orientation != Ecore_X_Randr_None)
+ {
+ ret = ecore_x_randr_crtc_settings_set(root,
+ crtc,
+ NULL,
+ Ecore_X_Randr_Unset,
+ Ecore_X_Randr_Unset,
+ Ecore_X_Randr_Unset,
+ Ecore_X_Randr_Unset,
+ orientation);
+ }
+
+ return ret;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+EAPI void
+ecore_x_randr_crtc_pos_get(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ int *x,
+ int *y)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET();
+
+ ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL);
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_randr_crtc_clone_set(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc original,
+ Ecore_X_Randr_Crtc clon)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ XRRScreenResources *res = NULL;
+ XRRCrtcInfo *clone_crtc_info = NULL;
+ Ecore_X_Randr_Mode original_mode = Ecore_X_Randr_None;
+ Ecore_X_Randr_Orientation original_orientation = Ecore_X_Randr_None;
+ Eina_Bool ret = EINA_FALSE;
+ int x, y;
+
+ if (_ecore_x_randr_root_validate(root) &&
+ _ecore_x_randr_crtc_validate(root,
+ original) &&
+ _ecore_x_randr_crtc_validate(root,
+ clon) &&
+ (res =
+ _ecore_x_randr_get_screen_resources (_ecore_x_disp,
+ root)) &&
+ (clone_crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, clon)))
+ {
+ ecore_x_randr_crtc_geometry_get(root, original, &x, &y, NULL, NULL);
+ original_mode = ecore_x_randr_crtc_mode_get(root, original);
+ original_orientation = ecore_x_randr_crtc_orientation_get(root,
+ original);
+ ret = ecore_x_randr_crtc_settings_set(root,
+ clon,
+ NULL,
+ Ecore_X_Randr_Unset,
+ x,
+ y,
+ original_mode,
+ original_orientation);
+ XRRFreeCrtcInfo(clone_crtc_info);
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+/**
+ * @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 @c EINA_TRUE if the configuration alteration was successful,
+ * @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+ecore_x_randr_crtc_settings_set(Ecore_X_Window root,
+ Ecore_X_Randr_Crtc crtc,
+ Ecore_X_Randr_Output *outputs,
+ int noutputs,
+ int x,
+ int y,
+ Ecore_X_Randr_Mode mode,
+ Ecore_X_Randr_Orientation orientation)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+ XRRScreenResources *res = NULL;
+ XRRCrtcInfo *crtc_info = NULL;
+ Eina_Bool ret = EINA_FALSE;
+
+ if (_ecore_x_randr_crtc_validate(root,
+ crtc) &&
+ (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+ {
+ if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+ {
+ if ((mode == Ecore_X_Randr_None) ||
+ (noutputs == Ecore_X_Randr_None))
+ {
+ outputs = NULL;
+ noutputs = 0;
+ }
+ else if (noutputs == (int)Ecore_X_Randr_Unset)
+ {
+ outputs = (Ecore_X_Randr_Output *)crtc_info->outputs;
+ noutputs = crtc_info->noutput;
+ }
+
+ if (mode == Ecore_X_Randr_Unset)
+ mode = crtc_info->mode;
+
+ if (x < 0)
+ x = crtc_info->x;
+
+ if (y < 0)
+ y = crtc_info->y;
+
+ if (orientation == Ecore_X_Randr_Unset)
+ orientation = crtc_info->rotation;
+
+ if (!XRRSetCrtcConfig(_ecore_x_disp, res, crtc, CurrentTime,
+ x, y, mode, orientation, (RROutput *)outputs,
+ noutputs))
+ ret = EINA_TRUE;
+
+ XRRFreeCrtcInfo(crtc_info);
+ }
+
+ XRRFreeScreenResources(res);
+ }
+
+ return ret;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+/**
+ * @brief Sets a CRTC relative to another one.
+ *
+ * @param root The root window which's default display will be set.
+ * @param crtc_r1 The CRTC to be positioned.
+ * @param crtc_r2 The CRTC the position should be relative to.
+ * @param policy The relation between the crtcs.
+ * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at
+ * CRTC2's borders.
+ * @return @c EINA_TRUE if crtc could be successfully positioned, @c 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 crtc_r1,
+ Ecore_X_Randr_Crtc crtc_r2,
+ Ecore_X_Randr_Output_Policy policy,
+ Ecore_X_Randr_Relative_Alignment alignment)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ Eina_Rectangle r1_geo, r2_geo;
+ int w_max, h_max, cw, ch, x_n = Ecore_X_Randr_Unset, y_n =
+ Ecore_X_Randr_Unset;
+ /*
+ int r1_noutputs, r2_noutputs, r1_nmodes, i, j, outputs_mode_found, mode_w, mode_h;
+ Ecore_X_Randr_Output *r1_outputs, *r2_outputs, *r2_r1_outputs;
+ Ecore_X_Randr_Mode *r1_modes, r2_mode, r1_mode;
+ Eina_Bool ret;
+ */
+
+ if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == Ecore_X_Randr_None)
+ || (ecore_x_randr_crtc_mode_get(root, crtc_r2) == Ecore_X_Randr_None))
+ return EINA_FALSE;
+
+ if (!_ecore_x_randr_crtc_validate(root, crtc_r1) ||
+ (!(crtc_r1 != crtc_r2) &&
+ !_ecore_x_randr_crtc_validate(root, crtc_r2)))
+ return EINA_FALSE;
+
+ ecore_x_randr_crtc_geometry_get(root,
+ crtc_r1,
+ &r1_geo.x,
+ &r1_geo.y,
+ &r1_geo.w,
+ &r1_geo.h);
+ ecore_x_randr_crtc_geometry_get(root,
+ crtc_r2,
+ &r2_geo.x,
+ &r2_geo.y,
+ &r2_geo.w,
+ &r2_geo.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:
+ //set r1 right of r2
+ x_n = r2_geo.x + r2_geo.w;
+
+ switch (alignment)
+ {
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
+ y_n = Ecore_X_Randr_Unset;
+ break;
+
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
+ y_n =
+ ((int)(((double)r2_geo.h /
+ 2.0) + (double)r2_geo.y - ((double)r1_geo.h / 2.0)));
+ break;
+
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
+ y_n = ((int)((double)ch / 2.0) - ((double)r1_geo.h / 2.0));
+ break;
+ }
+ break;
+
+ case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
+ //set r1 left of r2
+ x_n = r2_geo.x - r1_geo.w;
+
+ switch (alignment)
+ {
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
+ y_n = Ecore_X_Randr_Unset;
+ break;
+
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
+ y_n =
+ ((int)(((double)r2_geo.h /
+ 2.0) + r2_geo.y - ((double)r1_geo.h / 2.0)));
+ break;
+
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
+ y_n = ((int)(((double)ch / 2.0) - ((double)r1_geo.h / 2.0)));
+ break;
+ }
+ break;
+
+ case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
+ //set r1 below r2
+ y_n = r2_geo.y + r2_geo.h;
+
+ switch (alignment)
+ {
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
+ x_n = Ecore_X_Randr_Unset;
+ break;
+
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
+ x_n =
+ ((int)((((double)r2_geo.x +
+ (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
+ break;
+
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
+ x_n = ((int)((double)cw / 2.0));
+ break;
+ }
+ break;
+
+ case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
+ y_n = r2_geo.y - r1_geo.h;
+
+ //set r1 above r2
+ switch (alignment)
+ {
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
+ x_n = Ecore_X_Randr_Unset;
+ break;
+
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
+ x_n =
+ ((int)((((double)r2_geo.x +
+ (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
+ break;
+
+ case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
+ x_n = ((int)((double)cw / 2.0));
+ break;
+ }
+ break;
+
+ case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
+ return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y);
+
+ /* entire cloning (including modesetting)
+ //all outputs of crtc1 capable of crtc2's current mode?
+ r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
+ if (!(r1_outputs =
+ ecore_x_randr_crtc_outputs_get(root, crtc_r1,
+ &r1_noutputs)) ||
+ (r1_noutputs == 0))
+ return EINA_FALSE;
+
+ for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
+ {
+ if (!(r1_modes =
+ ecore_x_randr_output_modes_get(root, r1_outputs[i],
+ &r1_nmodes, NULL)))
+ {
+ free(r1_outputs);
+ return EINA_FALSE;
+ }
+
+ for (j = 0; j < r1_nmodes; j++)
+ {
+ ecore_x_randr_mode_size_get(root,
+ r1_modes[j],
+ &mode_w,
+ &mode_h);
+ if ((mode_w == r2_geo.w) && (mode_h == r2_geo.h))
+ {
+ r1_mode = r1_modes[j];
+ ++outputs_mode_found;
+ free(r1_modes);
+ r1_modes = NULL;
+ break;
+ }
+ }
+ if (r1_modes)
+ free(r1_modes);
+
+ if (outputs_mode_found <= i)
+ {
+ //an output doesn't support the set mode, cancel!
+ free(r1_outputs);
+ return EINA_FALSE;
+ }
+ }
+ free (r1_outputs);
+ //CRTC 1's outputs support a mode of same geometry as CRTC 2.
+ ret =
+ (ecore_x_randr_crtc_mode_set(root, crtc_r1, Ecore_X_Randr_None,
+ Ecore_X_Randr_None,
+ r1_mode) &&
+ ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y));
+ return ret;
+ */
+
+ /* entire cloning on same CRTC
+ //all outputs of crtc1 capable of crtc2's current mode?
+ r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
+ if (!(r1_outputs =
+ ecore_x_randr_crtc_outputs_get(root, crtc_r1,
+ &r1_noutputs)) ||
+ (r1_noutputs == 0))
+ return EINA_FALSE;
+
+ for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
+ {
+ if (!(r1_modes =
+ ecore_x_randr_output_modes_get(root, r1_outputs[i],
+ &r1_nmodes, NULL)))
+ {
+ free(r1_outputs);
+ return EINA_FALSE;
+ }
+
+ for (j = 0; j < r1_nmodes; j++)
+ {
+ if (r1_modes[j] == r2_mode)
+ {
+ ++outputs_mode_found;
+ free(r1_modes);
+ r1_modes = NULL;
+ break;
+ }
+ }
+ if (r1_modes)
+ free(r1_modes);
+
+ if (outputs_mode_found <= i)
+ {
+ //an output doesn't support the set mode, cancel!
+ free(r1_outputs);
+ return EINA_FALSE;
+ }
+ }
+ //check whether crtc r2 can use all outputs of r1.
+ if (!(r2_outputs =
+ ecore_x_randr_crtc_possible_outputs_get(root, crtc_r2,
+ &r2_noutputs)) ||
+ (r2_noutputs == 0))
+ {
+ free(r1_outputs);
+ return EINA_FALSE;
+ }
+
+ for (i = 0; i < r1_noutputs; i++)
+ {
+ for (j = 0; j < r2_noutputs; )
+ {
+ if (r1_outputs[i] == r2_outputs[j])
+ break;
+
+ j++;
+ }
+ if (j == r2_noutputs)
+ {
+ //didn't find the output!
+ free (r1_outputs);
+ free (r2_outputs);
+ return EINA_FALSE;
+ }
+ }
+
+ //apparently crtc2 supports all outputs of r1
+ //TODO: check with the compatible list of outputs (property in RR1.3)
+ r2_r1_outputs =
+ malloc(sizeof(Ecore_X_Randr_Output) * (r1_noutputs + r2_noutputs));
+ for (i = 0; i < r1_noutputs; i++)
+ {
+ r2_r1_outputs[i] = r1_outputs[i];
+ }
+ free(r1_outputs);
+ for (; i < r2_noutputs; i++)
+ {
+ r2_r1_outputs[i] = r2_outputs[i];
+ }
+ free(r2_outputs);
+ ret =
+ ecore_x_randr_crtc_mode_set(root, crtc_r2, r2_r1_outputs,
+ (r1_noutputs + r1_noutputs), r2_mode);
+ free (r2_r1_outputs);
+ return ret;
+ */
+ case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
+ break;
+ default:
+ return EINA_FALSE;
+ }
+ if ((x_n == r1_geo.x) && (y_n == r1_geo.x))
+ return EINA_TRUE;
+
+ //out of possible bounds?
+ if (((y_n + r1_geo.h) > h_max) || ((x_n + r1_geo.w) > w_max))
+ return EINA_FALSE;
+
+ return ecore_x_randr_crtc_pos_set(root, crtc_r1, x_n, y_n);
+#else
+ return EINA_FALSE;
+#endif
+}
+
+/*
+ * @brief Add given mode to given output.
+ *
+ * @param output The output the mode is added to.
+ * @param mode The mode added to the output.
+ * @return @c EINA_FALSE if output or mode equal Ecore_X_Randr_None, else
+ * @c EINA_TRUE.
+ * Additionally, if xcb backend is used, the success of the addition is
+ * reported back directly.
+ * @since 1.2.0
+ */
+EAPI Eina_Bool
+ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output,
+ Ecore_X_Randr_Mode mode)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+ if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
+ return EINA_FALSE;
+
+ XRRAddOutputMode(_ecore_x_disp, output, mode);
+ return EINA_TRUE;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+/*
+ * @brief delete given mode from given output
+ * @param output the output the mode is removed from
+ * @param mode the mode removed from the output
+ * @since 1.2.0
+ */
+EAPI void
+ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output,
+ Ecore_X_Randr_Mode mode)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET();
+
+ if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
+ return;
+
+ XRRDeleteOutputMode(_ecore_x_disp, output, mode);
+#else
+ return;
+#endif
+}
+
+EAPI Ecore_X_Randr_Mode *
+ecore_x_randr_output_modes_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *num,
+ int *npreferred)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ XRROutputInfo *output_info = NULL;
+ Ecore_X_Randr_Mode *modes = NULL;
+
+ if ((output != Ecore_X_Randr_None)
+ && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
+ && (output_info =
+ XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
+ {
+ if ((modes = malloc(sizeof(Ecore_X_Randr_Mode) * output_info->nmode)))
+ {
+ int i = 0;
+
+ if (num) *num = output_info->nmode;
+ if (npreferred) *npreferred = output_info->npreferred;
+
+ for (i = 0; i < output_info->nmode; i++)
+ modes[i] = output_info->modes[i];
+ }
+ }
+
+ if (output_info)
+ XRRFreeOutputInfo(output_info);
+
+ if (res)
+ XRRFreeScreenResources(res);
+
+ return modes;
+#else
+ return NULL;
+#endif
+}
+
+EAPI Ecore_X_Randr_Crtc *
+ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *num)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ XRROutputInfo *output_info = NULL;
+ Ecore_X_Randr_Crtc *crtcs = NULL;
+
+ if ((output != Ecore_X_Randr_None))
+ {
+ if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+ {
+ if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+ {
+ if ((crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc)))
+ {
+ memcpy(crtcs, output_info->crtcs, (sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc));
+ if (num) *num = output_info->ncrtc;
+ }
+ XRRFreeOutputInfo(output_info);
+ }
+ XRRFreeScreenResources(res);
+ }
+ }
+ return crtcs;
+#else
+ return Ecore_X_Randr_None;
+#endif
+}
+
+/**
+ * @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 Ecore_X_Randr_Output *
+ecore_x_randr_output_clones_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *num)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ XRROutputInfo *output_info = NULL;
+ Ecore_X_Randr_Output *outputs = NULL;
+
+ if ((output != Ecore_X_Randr_None))
+ {
+ if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+ {
+ if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+ {
+ if ((outputs = malloc(sizeof(Ecore_X_Randr_Output) * output_info->nclone)))
+ {
+ memcpy(outputs, output_info->clones, (sizeof(Ecore_X_Randr_Output) * output_info->nclone));
+ if (num) *num = output_info->nclone;
+ }
+ XRRFreeOutputInfo(output_info);
+ }
+ XRRFreeScreenResources(res);
+ }
+ }
+ return outputs;
+#else
+ return Ecore_X_Randr_None;
+#endif
+}
+
+EAPI Ecore_X_Randr_Crtc
+ecore_x_randr_output_crtc_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
+ XRRScreenResources *res = NULL;
+ XRROutputInfo *output_info = NULL;
+ Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None;
+
+ if ((output != Ecore_X_Randr_None))
+ {
+ if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+ {
+ if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+ {
+ ret = output_info->crtc;
+ XRRFreeOutputInfo(output_info);
+ }
+ XRRFreeScreenResources(res);
+ }
+ }
+
+ return ret;
+#else
+ return Ecore_X_Randr_None;
+#endif
+}
+
+/**
+ * @brief gets the given output's name as reported by X
+ * @param root the window which's screen will be queried
+ * @param output The output for which the name will be reported.
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ XRRScreenResources *res = NULL;
+ XRROutputInfo *output_info = NULL;
+ char *ret = NULL;
+
+ if ((output != Ecore_X_Randr_None)
+ && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
+ && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+ {
+ /*
+ * Actually the below command is correct, but due to a bug in libXrandr
+ * it doesn't work. Therefore we stick with strlen().
+ * Replace the line below with the following once this bug is
+ * fixed within libXrandr.
+ *
+ * *len = output_info->nameLen;
+ *
+ */
+ if ((ret = strdup(output_info->name)) && len)
+ *len = strlen(ret);
+
+ XRRFreeOutputInfo(output_info);
+ }
+
+ if (res)
+ XRRFreeScreenResources(res);
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * @brief gets the width and hight of a given mode
+ * @param mode the mode which's size is to be looked up
+ * @param w width of given mode in px
+ * @param h height of given mode in px
+ */
+EAPI void
+ecore_x_randr_mode_size_get(Ecore_X_Window root,
+ Ecore_X_Randr_Mode mode,
+ int *w,
+ int *h)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET();
+ XRRScreenResources *res = NULL;
+ int i;
+
+ if ((mode != Ecore_X_Randr_None)
+ && (w || h)
+ && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+ {
+ for (i = 0; i < res->nmode; i++)
+ {
+ if (res->modes[i].id == mode)
+ {
+ if (w)
+ *w = res->modes[i].width;
+
+ if (h)
+ *h = res->modes[i].height;
+
+ break;
+ }
+ }
+ }
+
+ if (res)
+ XRRFreeScreenResources(res);
+
+#endif
+}
+
+/**
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(NULL);
+ Atom name = XInternAtom (_ecore_x_disp, RANDR_PROPERTY_EDID, False);
+ unsigned char *prop_data, *ret = NULL;
+ int actual_format;
+ unsigned long nitems, bytes_after;
+ Atom actual_type;
+
+ if (!length || !_ecore_x_randr_output_validate(root, output))
+ return NULL;
+
+ if (XRRGetOutputProperty (_ecore_x_disp, output, name,
+ 0, 100, False, False,
+ AnyPropertyType,
+ &actual_type, &actual_format,
+ &nitems, &bytes_after, &prop_data) == Success)
+ {
+ if (actual_type == XA_INTEGER && actual_format == 8)
+ {
+ if ((ret = malloc(nitems * sizeof(unsigned char))))
+ {
+ if (length &&
+ (memcpy(ret, prop_data, (nitems * sizeof(unsigned char)))))
+ *length = nitems;
+
+ return ret;
+ }
+ }
+ }
+
+ return NULL;
+#else
+ return NULL;
+#endif
+}
+
+EAPI Ecore_X_Randr_Connection_Status
+ecore_x_randr_output_connection_status_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN);
+ XRRScreenResources *res = NULL;
+ XRROutputInfo *output_info = NULL;
+ Ecore_X_Randr_Connection_Status ret =
+ ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
+
+ if ((output != Ecore_X_Randr_None)
+ && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
+ && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+ {
+ ret = output_info->connection;
+ }
+
+ if (output_info)
+ XRRFreeOutputInfo(output_info);
+
+ if (res)
+ XRRFreeScreenResources(res);
+
+ return ret;
+#else
+ return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
+#endif
+}
+
+EAPI void
+ecore_x_randr_output_size_mm_get(Ecore_X_Window root,
+ Ecore_X_Randr_Output output,
+ int *w_mm,
+ int *h_mm)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET();
+ XRRScreenResources *res = NULL;
+ XRROutputInfo *output_info = NULL;
+
+ if ((output != Ecore_X_Randr_None)
+ && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+ {
+ if ((output_info =
+ XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
+ {
+ if (w_mm)
+ *w_mm = output_info->mm_width;
+
+ if (h_mm)
+ *h_mm = output_info->mm_height;
+
+ XRRFreeOutputInfo(output_info);
+ }
+
+ XRRFreeScreenResources(res);
+ }
+
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root,
+ const Ecore_X_Randr_Crtc *not_moved,
+ int nnot_moved,
+ int dx,
+ int dy)
+{
+#ifdef ECORE_XRANDR
+ Ecore_X_Randr_Crtc *crtcs_to_be_moved = NULL;
+ XRRScreenResources *res = NULL;
+ int i, j, k, n;
+ Eina_Bool ret;
+
+ if ((nnot_moved <= 0) || (!not_moved)
+ || !_ecore_x_randr_root_validate(root)
+ || !(res =
+ _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+ return EINA_FALSE;
+
+ n = (res->ncrtc - nnot_moved);
+ if ((crtcs_to_be_moved = malloc(sizeof(Ecore_X_Randr_Crtc) * n)))
+ {
+ for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++)
+ {
+ for (j = 0; j < nnot_moved; j++)
+ {
+ if (res->crtcs[i] == not_moved[j])
+ break;
+ }
+ if (j == nnot_moved)
+ //crtcs[i] is not in the 'not to move'-list
+ crtcs_to_be_moved[k++] = res->crtcs[i];
+ }
+ }
+
+ XRRFreeScreenResources(res);
+ ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy);
+ free(crtcs_to_be_moved);
+ return ret;
+#else
+ return EINA_FALSE;
+#endif
+}
+
+/*
+ * @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 @c 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 ncrtc,
+ int dx,
+ int dy)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+ XRRScreenResources *res = NULL;
+ XRRCrtcInfo **crtc_info = NULL;
+ Eina_Bool ret = EINA_TRUE;
+ int i, cw, ch, w_max, h_max, nw, nh;
+
+ crtc_info = alloca(sizeof(XRRCrtcInfo *) * ncrtc);
+ memset(crtc_info, 0, sizeof(XRRCrtcInfo *) * ncrtc);
+ if (_ecore_x_randr_root_validate(root)
+ && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+ {
+ 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);
+ nw = cw;
+ nh = ch;
+
+ for (i = 0;
+ (i < ncrtc) &&
+ (crtc_info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i]));
+ i++)
+ {
+ if (((crtc_info[i]->x + dx) < 0) ||
+ ((int)(crtc_info[i]->x + crtc_info[i]->width + dx) > w_max)
+ || ((crtc_info[i]->y + dy) < 0) ||
+ ((int)(crtc_info[i]->y + crtc_info[i]->height + dy) > h_max)
+ )
+ goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
+
+ nw = MAX((int)(crtc_info[i]->x + crtc_info[i]->width + dx), nw);
+ nh = MAX((int)(crtc_info[i]->y + crtc_info[i]->height + dy), nh);
+ }
+ //not out of bounds
+
+ //resize if necessary
+ if (!(((nw > cw) ||
+ (nh > ch)) ||
+ ecore_x_randr_screen_current_size_set(root, nw, nh,
+ Ecore_X_Randr_Unset,
+ Ecore_X_Randr_Unset)))
+ goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
+
+ //actually move all the crtcs, keep their rotation and mode.
+ for (i = 0; (i < ncrtc) && crtc_info[i]; i++)
+ {
+ if ((crtc_info[i]) &&
+ (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL,
+ Ecore_X_Randr_Unset,
+ (crtc_info[i]->x + dx),
+ (crtc_info[i]->y + dy),
+ crtc_info[i]->mode,
+ crtc_info[i]->rotation)))
+ {
+ ret = EINA_FALSE;
+ break;
+ }
+ }
+ if (i < ncrtc)
+ {
+ //something went wrong, let's try to move the already moved crtcs
+ //back.
+ while ((i--) >= 0)
+ {
+ if (crtc_info[i])
+ ecore_x_randr_crtc_settings_set(root,
+ crtcs[i],
+ NULL,
+ Ecore_X_Randr_Unset,
+ (crtc_info[i]->x - dx),
+ (crtc_info[i]->y - dy),
+ crtc_info[i]->mode,
+ crtc_info[i]->rotation);
+ }
+ }
+
+ for (i = 0; i < ncrtc; i++)
+ {
+ if (crtc_info[i]) XRRFreeCrtcInfo(crtc_info[i]);
+ }
+ }
+
+ XRRFreeScreenResources(res);
+
+ return ret;
+_ecore_x_randr_move_crtcs_fail_free_crtc_info:
+ while (i-- > 0)
+ XRRFreeCrtcInfo(crtc_info[i]);
+ XRRFreeScreenResources(res);
+ return EINA_FALSE;
+#else
+ return EINA_FALSE;
+#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_XRANDR
+ XRRCrtcInfo *crtc_info = NULL;
+ XRRScreenResources *res = NULL;
+ //the 100000 are just a random huge number.
+ int i, dx_min = 100000, dy_min = 100000, w_n = 0, h_n = 0, nenabled_crtcs = 0;
+
+ if (!_ecore_x_randr_root_validate(root) ||
+ !(res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+ return;
+
+ Ecore_X_Randr_Crtc enabled_crtcs[res->ncrtc];
+
+ for (i = 0; i < res->ncrtc; i++)
+ {
+ if (!(crtc_info =
+ XRRGetCrtcInfo(_ecore_x_disp, res,
+ res->crtcs[i])) ||
+ (crtc_info->mode == Ecore_X_Randr_None) ||
+ (crtc_info->mode == Ecore_X_Randr_Unset)
+ || ((crtc_info->noutput == 0)))
+ continue;
+
+ enabled_crtcs[nenabled_crtcs++] = res->crtcs[i];
+
+ if ((int)(crtc_info->x + crtc_info->width) > w_n)
+ w_n = (crtc_info->x + crtc_info->width);
+
+ if ((int)(crtc_info->y + crtc_info->height) > h_n)
+ h_n = (crtc_info->y + crtc_info->height);
+
+ if (crtc_info->x < dx_min)
+ dx_min = crtc_info->x;
+ if (crtc_info->y < dy_min)
+ dy_min = crtc_info->y;
+
+ XRRFreeCrtcInfo(crtc_info);
+ }
+ if ((dx_min > 0) || (dy_min > 0))
+ {
+ if (ecore_x_randr_move_crtcs(root, enabled_crtcs, nenabled_crtcs, -dx_min, -dy_min))
+ {
+ w_n -= dx_min;
+ h_n -= dy_min;
+ }
+ }
+ ecore_x_randr_screen_current_size_set(root,
+ w_n,
+ h_n,
+ Ecore_X_Randr_Unset,
+ Ecore_X_Randr_Unset);
+#endif
+}
+
+/**
+ * @brief Set up the backlight level to the given level.
+ *
+ * @param root The window's screen which will be set.
+ * @param level Of the backlight between @c 0 and @c 1.
+ */
+
+EAPI void
+ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root,
+ double level)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET();
+ Atom _backlight;
+ XRRScreenResources *resources = NULL;
+ Ecore_X_Randr_Output output;
+ int o;
+
+ if ((level < 0) || (level > 1))
+ {
+ ERR("Wrong value for the backlight level. It should be between 0 and 1.");
+ return;
+ }
+
+ /*
+ * To make sure that the _backlight atomic property still exists.
+ */
+ _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
+ if (_backlight == None)
+ {
+ WRN("Backlight setting is not supported on this server or driver");
+ return;
+ }
+
+ /* get the ressources */
+ resources = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root);
+ if (!resources) return;
+
+ for (o = 0; o < resources->noutput; o++)
+ {
+ output = resources->outputs[o];
+ if (ecore_x_randr_output_backlight_level_get(root, output) >= 0)
+ {
+ ecore_x_randr_output_backlight_level_set(root, output, level);
+ }
+ }
+ XRRFreeScreenResources(resources);
+#endif
+}
+
+/*
+ * @brief Check if a backlight is available.
+ * @return Whether a backlight is available.
+ */
+
+EAPI Eina_Bool
+ecore_x_randr_output_backlight_available(void)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_2_RET(-1);
+ Atom _backlight;
+
+ _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
+
+ return (_backlight == None) ? EINA_FALSE : EINA_TRUE;
+
+#endif
+ return EINA_FALSE;
+}
+
+/*
+ * @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_XRANDR
+ RANDR_CHECK_1_2_RET(-1);
+ Atom actual_type;
+ Atom _backlight;
+ XRRPropertyInfo *info = NULL;
+ double dvalue;
+ int actual_format;
+ long value, max, min;
+ unsigned long nitems;
+ unsigned long bytes_after;
+ unsigned char *prop = NULL;
+
+ /* set backlight variable if not already done */
+
+ _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
+ if (_backlight == None)
+ {
+ ERR("Backlight property is not suppported on this server or driver");
+ return -1;
+ }
+
+ if (!_ecore_x_randr_output_validate(root, output))
+ {
+ ERR("Invalid output");
+ return -1;
+ }
+
+ if (XRRGetOutputProperty(_ecore_x_disp, output, _backlight,
+ 0, 4, False, False, None,
+ &actual_type, &actual_format,
+ &nitems, &bytes_after, &prop) != Success)
+ {
+ WRN("Backlight not supported on this output");
+ return -1;
+ }
+
+ if ((actual_type != XA_INTEGER) || (nitems != 1) || (actual_format != 32)) return -1;
+
+ value = *((long *)prop);
+ free (prop);
+
+ /* I have the current value of the backlight */
+ /* Now retrieve the min and max intensities of the output */
+ info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight);
+ if (info)
+ {
+ dvalue = -1;
+ if ((info->range) && (info->num_values == 2))
+ {
+ /* finally convert the current value in the interval [0..1] */
+ min = info->values[0];
+ max = info->values[1];
+ dvalue = ((double)(value - min)) / ((double)(max - min));
+ }
+ free(info);
+ 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 @c 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_XRANDR
+ RANDR_CHECK_1_2_RET(EINA_FALSE);
+ Atom _backlight;
+ XRRPropertyInfo *info = NULL;
+ double min, max, tmp;
+ long new;
+
+ if ((level < 0) || (level > 1))
+ {
+ ERR("Backlight level should be between 0 and 1");
+ return EINA_FALSE;
+ }
+
+ if (!_ecore_x_randr_output_validate(root, output))
+ {
+ ERR("Wrong output value");
+ return EINA_FALSE;
+ }
+
+ _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
+ if (_backlight == None)
+ {
+ WRN("Backlight property is not suppported on this server or driver");
+ return EINA_FALSE;
+ }
+
+ info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight);
+ if (info)
+ {
+ if ((info->range) && (info->num_values == 2))
+ {
+ min = info->values[0];
+ max = info->values[1];
+ tmp = (level * (max - min)) + min;
+ new = tmp;
+ if (new > max) new = max;
+ if (new < min) new = min;
+ XRRChangeOutputProperty(_ecore_x_disp, output, _backlight, XA_INTEGER, 32,
+ PropModeReplace, (unsigned char *)&new, 1);
+ XFlush(_ecore_x_disp);
+ }
+ free(info);
+ return EINA_TRUE;
+ }
+#endif
+ return EINA_FALSE;
+}
+
+/*
+ * @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. @c 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_XRANDR
+ Ecore_X_Window root;
+ Ecore_X_Randr_Crtc *crtcs;
+ Ecore_X_Randr_Output *outputs, *ret = NULL, *tret;
+ int ncrtcs, noutputs, i, nret = 0;
+
+ if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail;
+
+ root = ecore_x_window_root_get(window);
+ if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs)))
+ goto _ecore_x_randr_current_output_get_fail;
+
+ for (i = 0, nret = 0; i < ncrtcs; i++)
+ {
+
+ outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i],
+ &noutputs);
+ if (!outputs)
+ goto _ecore_x_randr_current_output_get_fail_free;
+ tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output)));
+ if (!tret) goto _ecore_x_randr_current_output_get_fail_free;
+ ret = tret;
+ memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output)));
+ nret += noutputs;
+ free(outputs);
+ outputs = NULL;
+ }
+ free(crtcs);
+
+ if (num)
+ *num = nret;
+
+ return ret;
+
+_ecore_x_randr_current_output_get_fail_free:
+ free(outputs);
+ free(crtcs);
+ free(ret);
+_ecore_x_randr_current_output_get_fail:
+#endif
+ if (num) *num = 0;
+ return NULL;
+}
+
+/*
+ * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead.
+ * @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. @c NULL if no
+ * outputs was found that displays the specified window.
+ */
+
+EAPI Ecore_X_Randr_Output *
+ecore_x_randr_current_output_get(Ecore_X_Window window,
+ int *num)
+{
+ return ecore_x_randr_window_outputs_get(window, num);
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c b/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c
new file mode 100644
index 0000000000..5bda332a06
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2006-2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* Original Author: Adam Jackson <ajax@nwnk.net> */
+/* Heavily modified by: Leif Middelschulte <leif.middelschulte@gmail.com> */
+
+#include "Ecore_X.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+/* TODO:
+ * - see other TODO's within this file.
+ */
+
+#define ECORE_X_RANDR_EDID_VERSION_10 ((1 << 8) | 0)
+#define ECORE_X_RANDR_EDID_VERSION_11 ((1 << 8) | 1)
+#define ECORE_X_RANDR_EDID_VERSION_12 ((1 << 8) | 2)
+#define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3)
+#define ECORE_X_RANDR_EDID_VERSION_14 ((1 << 8) | 4)
+
+#define _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER 0x08
+#define _ECORE_X_RANDR_EDID_OFFSET_TYPE 0x14
+#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12
+#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13
+#define _ECORE_X_RANDR_EDID_OFFSET_DPMS 0x18
+#define _ECORE_X_RANDR_EDID_OFFSET_COLORSPACE 0x18
+#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36
+#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3
+#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5
+#define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED 15
+#define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO 14
+
+#define _ECORE_X_RANDR_EDID_MASK_DIGITAL 0x80
+#define _ECORE_X_RANDR_EDID_MASK_DIGITAL_INTERFACE 0x0f
+#define _ECORE_X_RANDR_EDID_MASK_DIGITAL_TMDS_DFP_10 0x01
+#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS 0x18
+#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444 0x10
+#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422 0x08
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED 0xe0
+#define _ECORE_X_RANDR_EDID_MASK_DPMS 0xE0
+#define _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY 0x80
+#define _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND 0x40
+#define _ECORE_X_RANDR_EDID_MASK_DPMS_OFF 0x20
+#define _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE 0x0f
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3 0x80
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9 0x40
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10 0x20
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4 0x10
+#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9 0x08
+
+#define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13
+
+typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio_Preferred {
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3 = 0x00,
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9 = 0x01,
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10 = 0x02,
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4 = 0x03,
+ ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9 = 0x04
+} Ecore_X_Randr_Edid_Aspect_Ratio_Preferred;
+
+/* Some convenience loops */
+#define _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, extension_block_iter) \
+ for (extension_block_iter = edid; extension_block_iter < (edid + edid_length); extension_block_iter += 128)
+
+#define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \
+ _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, cea_block_iter) \
+ if (cea_block_iter[0] == 0x02)
+
+/* The following macro is to be used with caution as it inherits another loop.
+ * Therefore using a 'break;' statement will lead to continuation in the
+ * inherent 'Extension block'-loop.
+ */
+#define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_DETAILED_BLOCK(edid, edid_length, cea_block_iter, detailed_block_iter) \
+ _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \
+ for (detailed_block_iter = cea_block_iter + cea_block_iter[2]; detailed_block_iter + 18 < cea_block_iter + 127; detailed_block_iter += 18) \
+ if (detailed_block_iter[0])
+
+#define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \
+ for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3 * 18)); block += 18)
+
+#define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \
+ _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \
+ if ((block[0] == 0) && (block[1] == 0))
+
+EAPI Eina_Bool
+ecore_x_randr_edid_has_valid_header(unsigned char *edid,
+ unsigned long edid_length)
+{
+ const unsigned char header[] =
+ { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
+ if (!edid) return EINA_FALSE;
+ if (edid_length < 8) return EINA_FALSE;
+ if (!memcmp(edid, header, 8)) return EINA_TRUE;
+ return EINA_FALSE;
+}
+
+EAPI int
+ecore_x_randr_edid_version_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) &&
+ (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
+ return (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) |
+ edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR];
+ return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+}
+
+EAPI int
+ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ if ((edid_length > 0x0b) &&
+ (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
+ return (int)(edid[0x0a] + (edid[0x0b] << 8));
+ return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+}
+
+EAPI int
+ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ if ((edid_length > 0x0f) &&
+ (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
+ return (int)(edid[0x0c] + (edid[0x0d] << 8) +
+ (edid[0x0e] << 16) + (edid[0x0f] << 24));
+ return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+}
+
+EAPI char *
+ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ if ((edid_length > (_ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER + 1)) &&
+ (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
+ {
+ unsigned char *x;
+ char *name;
+
+ x = (edid + _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER);
+ name = malloc(sizeof(char) * 4);
+ if (!name) return NULL;
+ name[0] = ((x[0] & 0x7c) >> 2) + '@';
+ name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xe0) >> 5) + '@';
+ name[2] = (x[1] & 0x1f) + '@';
+ name[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] = 0;
+ return name;
+ }
+ return NULL;
+}
+
+EAPI char *
+ecore_x_randr_edid_display_name_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ unsigned char *block = NULL;
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL;
+ _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+ {
+ if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfc)
+ {
+ char *name, *p;
+ const char *edid_name;
+
+ edid_name = (const char *)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT;
+ name = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
+ if (!name) return NULL;
+ strncpy(name, edid_name, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
+ name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0;
+ for (p = name; *p; p++)
+ {
+ if ((*p < ' ') || (*p > '~')) *p = 0;
+ }
+ return name;
+ }
+ }
+ return NULL;
+}
+
+EAPI Ecore_X_Randr_Edid_Aspect_Ratio
+ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ unsigned char *block = NULL;
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+ _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+ {
+ if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfd) &&
+ (block[10] == 0x04))
+ {
+ Ecore_X_Randr_Edid_Aspect_Ratio_Preferred preferred_ratio =
+ (Ecore_X_Randr_Edid_Aspect_Ratio_Preferred)
+ ((block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED] &
+ _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED) >> 5);
+ switch (preferred_ratio)
+ {
+ case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3:
+ return ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3;
+
+ case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9:
+ return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9;
+
+ case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10:
+ return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10;
+
+ case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4:
+ return ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4;
+
+ case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9:
+ return ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9;
+
+ default:
+ return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+ }
+ }
+ }
+ return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+}
+
+EAPI Ecore_X_Randr_Edid_Aspect_Ratio
+ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ Ecore_X_Randr_Edid_Aspect_Ratio ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+ unsigned char *block = NULL;
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+ _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+ {
+ if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfd) &&
+ (block[10] == 0x04))
+ {
+ if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3)
+ ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3;
+ if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9)
+ ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9;
+ if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10)
+ ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10;
+ if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4)
+ ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4;
+ if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9)
+ ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9;
+ }
+ }
+ return ret;
+}
+
+EAPI char *
+ecore_x_randr_edid_display_ascii_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ unsigned char *block = NULL;
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL;
+ _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+ {
+ if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfe)
+ {
+ char *ascii, *p;
+ const char *edid_ascii = (const char *)block +
+ _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT;
+ /*
+ * TODO: Two of these in a row, in the third and fourth slots,
+ * seems to be specified by SPWG: http://www.spwg.org/
+ */
+ ascii = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
+ if (!ascii) return NULL;
+ strncpy(ascii, edid_ascii, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
+ ascii[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0;
+ for (p = ascii; *p; p++)
+ {
+ if ((*p < ' ') || (*p > '~')) *p = 0;
+ }
+ return ascii;
+ }
+ }
+ return NULL;
+}
+
+EAPI char *
+ecore_x_randr_edid_display_serial_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ unsigned char *block = NULL;
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL;
+ _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
+ {
+ if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xff)
+ {
+ char *serial, *p;
+ const char *edid_serial = (const char *)block +
+ _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT;
+ /*
+ * TODO: Two of these in a row, in the third and fourth slots,
+ * seems to be specified by SPWG: http://www.spwg.org/
+ */
+ serial = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
+ if (!serial) return NULL;
+ strncpy(serial, edid_serial, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
+ serial[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0;
+ for (p = serial; *p; p++)
+ {
+ if ((*p < ' ') || (*p > '~')) *p = 0;
+ }
+ return serial;
+ }
+ }
+ return NULL;
+}
+
+EAPI Eina_Bool
+ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid,
+ unsigned long edid_length)
+{
+ unsigned char *cea_block_iter = NULL;
+ char sum = 0;
+ int i;
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+ if (edid_length < 128) return EINA_FALSE;
+
+ /* Check the EDID block itself */
+ for (i = 0; i < 128; i++)
+ sum += edid[i];
+ if (sum) return EINA_FALSE;
+
+ /* Check the cea extension blocks */
+ _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter)
+ {
+ for (i = 0, sum = 0; i < 128; i++)
+ sum += cea_block_iter[i];
+ }
+ if (sum) return EINA_FALSE;
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_x_randr_edid_dpms_available_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+ return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] &
+ _ECORE_X_RANDR_EDID_MASK_DPMS);
+}
+
+EAPI Eina_Bool
+ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+ if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS)
+ return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] &
+ _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY);
+ return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+ if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS)
+ return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] &
+ _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND);
+ return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+ if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS)
+ return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] &
+ _ECORE_X_RANDR_EDID_MASK_DPMS_OFF);
+ return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_randr_edid_display_type_digital_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE;
+ return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] &
+ _ECORE_X_RANDR_EDID_MASK_DIGITAL);
+}
+
+EAPI Ecore_X_Randr_Edid_Display_Colorscheme
+ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ Ecore_X_Randr_Edid_Display_Colorscheme colorscheme = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return colorscheme;
+ if (ecore_x_randr_edid_display_type_digital_get(edid, edid_length))
+ {
+ colorscheme = ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4;
+ if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] &
+ _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444)
+ colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4;
+ if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] &
+ _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422)
+ colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2;
+ }
+ else
+ colorscheme = edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS;
+ return colorscheme;
+}
+
+EAPI Ecore_X_Randr_Edid_Display_Interface_Type
+ecore_x_randr_edid_display_interface_type_get(unsigned char *edid,
+ unsigned long edid_length)
+{
+ Ecore_X_Randr_Edid_Display_Interface_Type type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+ int version = ecore_x_randr_edid_version_get(edid, edid_length);
+
+ if (version < ECORE_X_RANDR_EDID_VERSION_13) return type;
+ type = edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] &
+ _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE;
+ if (type > ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT)
+ type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
+ return type;
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_13.c b/src/lib/ecore_x/xlib/ecore_x_randr_13.c
new file mode 100644
index 0000000000..5d1c8e96db
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_randr_13.c
@@ -0,0 +1,68 @@
+/*
+ * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_x_private.h"
+#include "ecore_x_randr.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#define Ecore_X_Randr_None 0
+#define Ecore_X_Randr_Unset -1
+
+#ifdef ECORE_XRANDR
+
+#define RANDR_1_3 ((1 << 16) | 3)
+#define RANDR_CHECK_1_3_RET(ret) if (_randr_version < RANDR_1_3) \
+ return ret
+
+extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display *
+ dpy,
+ Window
+ window);
+extern int _randr_version;
+#endif
+
+/*
+ * @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)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_3_RET(Ecore_X_Randr_None);
+ if (!_ecore_x_randr_root_validate(root))
+ return Ecore_X_Randr_None;
+
+ return XRRGetOutputPrimary(_ecore_x_disp, root);
+#else
+ return Ecore_X_Randr_None;
+#endif
+}
+
+/*
+ * @param root window which's screen should be queried
+ * @param output that should be set as given root window's screen primary output
+ */
+EAPI void
+ecore_x_randr_primary_output_set(Ecore_X_Window root,
+ Ecore_X_Randr_Output output)
+{
+#ifdef ECORE_XRANDR
+ RANDR_CHECK_1_3_RET();
+
+ if (_ecore_x_randr_output_validate(root, output))
+ {
+ XRRSetOutputPrimary(_ecore_x_disp, root, output);
+ }
+
+#endif
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_region.c b/src/lib/ecore_x/xlib/ecore_x_region.c
new file mode 100644
index 0000000000..81d7eea49c
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_region.c
@@ -0,0 +1,158 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "ecore_x_private.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 *
+ecore_x_xregion_new()
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return (Ecore_X_XRegion *)XCreateRegion();
+}
+
+EAPI void
+ecore_x_xregion_free(Ecore_X_XRegion *region)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!region)
+ return;
+
+ XDestroyRegion((Region)region);
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_set(Ecore_X_XRegion *region,
+ Ecore_X_GC gc)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XSetRegion(_ecore_x_disp, gc, (Region)region) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI void
+ecore_x_xregion_translate(Ecore_X_XRegion *region,
+ int x,
+ int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!region)
+ return;
+
+ /* return value not used */
+ XOffsetRegion((Region)region, x, y);
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_intersect(Ecore_X_XRegion *dst,
+ Ecore_X_XRegion *r1,
+ Ecore_X_XRegion *r2)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XIntersectRegion((Region)r1, (Region)r2, (Region)dst) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_union(Ecore_X_XRegion *dst,
+ Ecore_X_XRegion *r1,
+ Ecore_X_XRegion *r2)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XUnionRegion((Region)r1, (Region)r2, (Region)dst) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_union_rect(Ecore_X_XRegion *dst,
+ Ecore_X_XRegion *src,
+ Ecore_X_Rectangle *rect)
+{
+ XRectangle xr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xr.x = rect->x;
+ xr.y = rect->y;
+ xr.width = rect->width;
+ xr.height = rect->height;
+
+ return XUnionRectWithRegion(&xr, (Region)src, (Region)dst) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_subtract(Ecore_X_XRegion *dst,
+ Ecore_X_XRegion *rm,
+ Ecore_X_XRegion *rs)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XSubtractRegion((Region)rm, (Region)rs, (Region)dst) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_is_empty(Ecore_X_XRegion *region)
+{
+ if (!region)
+ return EINA_TRUE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XEmptyRegion((Region)region) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_is_equal(Ecore_X_XRegion *r1,
+ Ecore_X_XRegion *r2)
+{
+ if (!r1 || !r2)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XEqualRegion((Region)r1, (Region)r1) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_point_contain(Ecore_X_XRegion *region,
+ int x,
+ int y)
+{
+ if (!region)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XPointInRegion((Region)region, x, y) ? EINA_TRUE : EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_xregion_rect_contain(Ecore_X_XRegion *region,
+ Ecore_X_Rectangle *rect)
+{
+ if (!region || !rect)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XRectInRegion((Region)region,
+ rect->x,
+ rect->y,
+ rect->width,
+ rect->height) ? EINA_TRUE : EINA_FALSE;
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_screensaver.c b/src/lib/ecore_x/xlib/ecore_x_screensaver.c
new file mode 100644
index 0000000000..3688a44c56
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_screensaver.c
@@ -0,0 +1,204 @@
+/*
+ * Screensaver code
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+static int _screensaver_available = -1;
+
+EAPI Eina_Bool
+ecore_x_screensaver_event_available_get(void)
+{
+ if (_screensaver_available >= 0)
+ return _screensaver_available;
+
+#ifdef ECORE_XSS
+ int _screensaver_major, _screensaver_minor;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _screensaver_major = 1;
+ _screensaver_minor = 0;
+
+ if (XScreenSaverQueryVersion(_ecore_x_disp, &_screensaver_major,
+ &_screensaver_minor))
+ _screensaver_available = 1;
+ else
+ _screensaver_available = 0;
+
+#else /* ifdef ECORE_XSS */
+ _screensaver_available = 0;
+#endif /* ifdef ECORE_XSS */
+ return _screensaver_available;
+}
+
+EAPI int
+ecore_x_screensaver_idle_time_get(void)
+{
+#ifdef ECORE_XSS
+ XScreenSaverInfo *xss;
+ int idle;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xss = XScreenSaverAllocInfo();
+ XScreenSaverQueryInfo(_ecore_x_disp,
+ RootWindow(_ecore_x_disp, DefaultScreen(
+ _ecore_x_disp)), xss);
+ idle = xss->idle / 1000;
+ XFree(xss);
+
+ return idle;
+#else
+ return 0;
+#endif /* ifdef ECORE_XSS */
+}
+
+EAPI void
+ecore_x_screensaver_set(int timeout,
+ int interval,
+ int prefer_blanking,
+ int allow_exposures)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetScreenSaver(_ecore_x_disp,
+ timeout,
+ interval,
+ prefer_blanking,
+ allow_exposures);
+}
+
+EAPI void
+ecore_x_screensaver_timeout_set(int timeout)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ XSetScreenSaver(_ecore_x_disp, timeout, pint, pblank, pexpo);
+}
+
+EAPI int
+ecore_x_screensaver_timeout_get(void)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ return pto;
+}
+
+EAPI void
+ecore_x_screensaver_blank_set(int blank)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ XSetScreenSaver(_ecore_x_disp, pto, pint, blank, pexpo);
+}
+
+EAPI int
+ecore_x_screensaver_blank_get(void)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ return pblank;
+}
+
+EAPI void
+ecore_x_screensaver_expose_set(int expose)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ XSetScreenSaver(_ecore_x_disp, pto, pint, pblank, expose);
+}
+
+EAPI int
+ecore_x_screensaver_expose_get(void)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ return pexpo;
+}
+
+EAPI void
+ecore_x_screensaver_interval_set(int interval)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ XSetScreenSaver(_ecore_x_disp, pto, interval, pblank, pexpo);
+}
+
+EAPI int
+ecore_x_screensaver_interval_get(void)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ return pint;
+}
+
+EAPI void
+ecore_x_screensaver_event_listen_set(Eina_Bool on)
+{
+#ifdef ECORE_XSS
+ Ecore_X_Window root;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ root = DefaultRootWindow(_ecore_x_disp);
+ if (on)
+ XScreenSaverSelectInput(_ecore_x_disp, root,
+ ScreenSaverNotifyMask | ScreenSaverCycle);
+ else
+ XScreenSaverSelectInput(_ecore_x_disp, root, 0);
+#else
+ return;
+ on = EINA_FALSE;
+#endif /* ifdef ECORE_XSS */
+}
+
+
+EAPI Eina_Bool
+ecore_x_screensaver_custom_blanking_enable(void)
+{
+#ifdef ECORE_XSS
+ XSetWindowAttributes attr;
+
+ XScreenSaverSetAttributes(_ecore_x_disp,
+ DefaultRootWindow(_ecore_x_disp),
+ -9999, -9999, 1, 1, 0,
+ CopyFromParent, InputOnly, CopyFromParent,
+ 0, &attr);
+ return EINA_TRUE;
+#else
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XSS */
+}
+
+EAPI Eina_Bool
+ecore_x_screensaver_custom_blanking_disable(void)
+{
+#ifdef ECORE_XSS
+ XScreenSaverUnsetAttributes(_ecore_x_disp,
+ DefaultRootWindow(_ecore_x_disp));
+ return EINA_TRUE;
+#else
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XSS */
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_selection.c b/src/lib/ecore_x/xlib/ecore_x_selection.c
new file mode 100644
index 0000000000..3e1d2d34a2
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_selection.c
@@ -0,0 +1,1021 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif !defined alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# elif !defined HAVE_ALLOCA
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.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 int _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 int _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 int _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 int _ecore_x_selection_data_targets_free(void *data);
+
+#define ECORE_X_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x))
+
+void
+_ecore_x_selection_data_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);
+}
+
+void
+_ecore_x_selection_shutdown(void)
+{
+ Ecore_X_Selection_Converter *cnv;
+ Ecore_X_Selection_Parser *prs;
+
+ /* free the selection converters */
+ cnv = converters;
+ while (cnv)
+ {
+ Ecore_X_Selection_Converter *tmp;
+
+ tmp = cnv->next;
+ free(cnv);
+ cnv = tmp;
+ }
+ converters = NULL;
+
+ /* free the selection parsers */
+ prs = parsers;
+ while (prs)
+ {
+ Ecore_X_Selection_Parser *tmp;
+
+ tmp = prs;
+ prs = prs->next;
+ free(tmp->target);
+ free(tmp);
+ }
+ parsers = NULL;
+}
+
+Ecore_X_Selection_Intern *
+_ecore_x_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;
+}
+
+Eina_Bool
+_ecore_x_selection_set(Window w,
+ const void *data,
+ int size,
+ Ecore_X_Atom selection)
+{
+ int in;
+ unsigned char *buf = NULL;
+
+ XSetSelectionOwner(_ecore_x_disp, selection, w, _ecore_x_event_last_time);
+ if (XGetSelectionOwner(_ecore_x_disp, selection) != w)
+ return EINA_FALSE;
+
+ 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;
+
+ if (data)
+ {
+ selections[in].win = w;
+ selections[in].selection = selection;
+ selections[in].length = size;
+ selections[in].time = _ecore_x_event_last_time;
+
+ buf = malloc(size);
+ if (!buf) return EINA_FALSE;
+ memcpy(buf, data, size);
+ selections[in].data = buf;
+ }
+ else if (selections[in].data)
+ {
+ free(selections[in].data);
+ memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data));
+ }
+
+ return EINA_TRUE;
+}
+
+/**
+ * Claim ownership of the PRIMARY selection and set its data.
+ * @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 w,
+ const void *data,
+ int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(w, 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.
+ *
+ */
+EAPI Eina_Bool
+ecore_x_selection_primary_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_PRIMARY);
+}
+
+/**
+ * Claim ownership of the SECONDARY selection and set its data.
+ * @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 w,
+ const void *data,
+ int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(w,
+ 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.
+ *
+ */
+EAPI Eina_Bool
+ecore_x_selection_secondary_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(None,
+ NULL,
+ 0,
+ ECORE_X_ATOM_SELECTION_SECONDARY);
+}
+
+/**
+ * Claim ownership of the XDND selection and set its data.
+ * @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 w,
+ const void *data,
+ int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(w, 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.
+ *
+ */
+EAPI Eina_Bool
+ecore_x_selection_xdnd_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_XDND);
+}
+
+/**
+ * Claim ownership of the CLIPBOARD selection and set its data.
+ * @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.
+ */
+EAPI Eina_Bool
+ecore_x_selection_clipboard_set(Ecore_X_Window w,
+ const void *data,
+ int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(w,
+ 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.
+ *
+ */
+EAPI Eina_Bool
+ecore_x_selection_clipboard_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(None,
+ NULL,
+ 0,
+ ECORE_X_ATOM_SELECTION_CLIPBOARD);
+}
+
+Ecore_X_Atom
+_ecore_x_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_x_selection_target_get(Ecore_X_Atom target)
+{
+ /* FIXME: Should not return mem allocated with strdup or X mixed,
+ * one should use free to free, the other XFree */
+ 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 XGetAtomName(_ecore_x_disp, target);
+}
+
+static void
+_ecore_x_selection_request(Ecore_X_Window w,
+ Ecore_X_Atom selection,
+ const char *target_str)
+{
+ Ecore_X_Atom target, prop;
+
+ target = _ecore_x_selection_target_atom_get(target_str);
+
+ 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;
+
+ XConvertSelection(_ecore_x_disp, selection, target, prop,
+ w, CurrentTime);
+}
+
+EAPI void
+ecore_x_selection_primary_request(Ecore_X_Window w,
+ const char *target)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_PRIMARY, target);
+}
+
+EAPI void
+ecore_x_selection_secondary_request(Ecore_X_Window w,
+ const char *target)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_SECONDARY, target);
+}
+
+EAPI void
+ecore_x_selection_xdnd_request(Ecore_X_Window w,
+ const char *target)
+{
+ 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);
+ XConvertSelection(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, atom,
+ ECORE_X_ATOM_SELECTION_PROP_XDND, w,
+ _target->time);
+}
+
+EAPI void
+ecore_x_selection_clipboard_request(Ecore_X_Window w,
+ const char *target)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_CLIPBOARD, target);
+}
+
+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))
+{
+ Ecore_X_Selection_Converter *cnv;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ 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));
+ if (!cnv->next) return;
+ cnv = cnv->next;
+ }
+ else
+ {
+ converters = calloc(1, sizeof(Ecore_X_Selection_Converter));
+ if (!converters) return;
+ cnv = converters;
+ }
+
+ cnv->target = target;
+ cnv->convert = func;
+}
+
+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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ x_target = _ecore_x_selection_target_atom_get(target);
+
+ ecore_x_selection_converter_atom_add(x_target, func);
+}
+
+EAPI void
+ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
+{
+ Ecore_X_Selection_Converter *cnv, *prev_cnv;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ prev_cnv = NULL;
+ cnv = converters;
+
+ while (cnv)
+ {
+ if (cnv->target == target)
+ {
+ if (prev_cnv)
+ prev_cnv->next = cnv->next;
+ else
+ {
+ converters = cnv->next; /* This was the first converter */
+ }
+
+ free(cnv);
+
+ return;
+ }
+
+ prev_cnv = cnv;
+ cnv = cnv->next;
+ }
+}
+
+EAPI void
+ecore_x_selection_converter_del(char *target)
+{
+ Ecore_X_Atom x_target;
+
+ if (!target)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ x_target = _ecore_x_selection_target_atom_get(target);
+ ecore_x_selection_converter_atom_del(x_target);
+}
+
+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 tim)
+{
+ XEvent xev;
+ XSelectionEvent xnotify;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xnotify.type = SelectionNotify;
+ xnotify.display = _ecore_x_disp;
+ xnotify.requestor = requestor;
+ xnotify.selection = selection;
+ xnotify.target = target;
+ xnotify.property = property;
+ xnotify.time = tim;
+ xnotify.send_event = True;
+ xnotify.serial = 0;
+
+ xev.xselection = xnotify;
+ return (XSendEvent(_ecore_x_disp, requestor, False, 0, &xev) > 0) ? EINA_TRUE : EINA_FALSE;
+}
+
+/* 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)
+{
+ Ecore_X_Selection_Intern *sel;
+ Ecore_X_Selection_Converter *cnv;
+ void *data;
+ char *tgt_str;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ sel = _ecore_x_selection_get(selection);
+ tgt_str = _ecore_x_selection_target_get(target);
+
+ 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 EINA_FALSE;
+ }
+ }
+
+ /* ICCCM says "If the selection cannot be converted into a form based on the target (and parameters, if any), the owner should refuse the SelectionRequest as previously described." */
+ 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;
+ */
+}
+
+/* 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 */
+EAPI Eina_Bool
+ecore_x_selection_converter_text(char *target,
+ void *data,
+ int size,
+ void **data_ret,
+ int *size_ret,
+ Ecore_X_Atom *targprop EINA_UNUSED,
+ int *s EINA_UNUSED)
+{
+ XTextProperty text_prop;
+ char *mystr;
+ XICCEncodingStyle style;
+
+ if (!data || !size)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ 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 /* ifdef X_HAVE_UTF8_STRING */
+ else
+ return EINA_FALSE;
+
+ mystr = alloca(size + 1);
+ memcpy(mystr, data, size);
+ mystr[size] = '\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);
+ if (!*data_ret)
+ {
+ return EINA_FALSE;
+ }
+ memcpy(*data_ret, text_prop.value, bufsize);
+ *size_ret = bufsize;
+ XFree(text_prop.value);
+ return EINA_TRUE;
+ }
+
+#else /* ifdef X_HAVE_UTF8_STRING */
+ if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style,
+ &text_prop) == Success)
+ {
+ int bufsize = strlen(text_prop.value) + 1;
+ *data_ret = malloc(bufsize);
+ if (!*data_ret) return EINA_FALSE;
+ memcpy(*data_ret, text_prop.value, bufsize);
+ *size_ret = bufsize;
+ XFree(text_prop.value);
+ return EINA_TRUE;
+ }
+
+#endif /* ifdef X_HAVE_UTF8_STRING */
+ else
+ {
+ return EINA_TRUE;
+ }
+}
+
+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 (!target)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ prs = parsers;
+ if (parsers)
+ {
+ while (prs->next)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ prs->parse = func;
+ return;
+ }
+
+ prs = prs->next;
+ }
+
+ prs->next = calloc(1, sizeof(Ecore_X_Selection_Parser));
+ if (!prs->next) return;
+ prs = prs->next;
+ }
+ else
+ {
+ parsers = calloc(1, sizeof(Ecore_X_Selection_Parser));
+ if (!parsers) return;
+ prs = parsers;
+ }
+
+ prs->target = strdup(target);
+ prs->parse = func;
+}
+
+EAPI void
+ecore_x_selection_parser_del(const char *target)
+{
+ Ecore_X_Selection_Parser *prs, *prev_prs;
+
+ if (!target)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ 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 */
+ }
+
+ free(prs->target);
+ free(prs);
+
+ return;
+ }
+
+ prev_prs = prs;
+ prs = prs->next;
+ }
+}
+
+/**
+ * Change the owner and last-change time for the specified selection.
+ * @param win The owner of the specified atom.
+ * @param atom The selection atom
+ * @param tim Specifies the time
+ * @since 1.1.0
+ */
+EAPI void
+ecore_x_selection_owner_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Time tim)
+{
+ XSetSelectionOwner(_ecore_x_disp, atom, win, tim);
+}
+
+/**
+ * Return the window that currently owns the specified selection.
+ *
+ * @param atom The specified selection atom.
+ *
+ * @return The window that currently owns the specified selection.
+ * @since 1.1.0
+ */
+EAPI Ecore_X_Window
+ecore_x_selection_owner_get(Ecore_X_Atom atom)
+{
+ return XGetSelectionOwner(_ecore_x_disp, atom);
+}
+
+/* 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;
+
+ for (prs = parsers; prs; prs = prs->next)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ sel = prs->parse(target, data, size, format);
+ if (sel) return sel;
+ }
+ }
+
+ /* Default, just return the data */
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data));
+ if (!sel) return NULL;
+ sel->free = _ecore_x_selection_data_default_free;
+ sel->length = size;
+ sel->format = format;
+ sel->data = data;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_default_free(void *data)
+{
+ Ecore_X_Selection_Data *sel;
+
+ sel = data;
+ free(sel->data);
+ free(sel);
+ return 1;
+}
+
+static void *
+_ecore_x_selection_parser_files(const char *target,
+ void *_data,
+ int size,
+ int format EINA_UNUSED)
+{
+ Ecore_X_Selection_Data_Files *sel;
+ char *t, *data = _data;
+ int i, is;
+ char *tmp;
+ char **t2;
+
+ if (strcmp(target, "text/uri-list") &&
+ strcmp(target, "_NETSCAPE_URL"))
+ return NULL;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files));
+ if (!sel) return NULL;
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free;
+
+ if (data && data[size - 1])
+ {
+ /* Isn't nul terminated */
+ size++;
+ t = realloc(data, size);
+ if (!t)
+ {
+ free(sel);
+ return NULL;
+ }
+ data = t;
+ data[size - 1] = 0;
+ }
+
+ tmp = malloc(size);
+ if (!tmp)
+ {
+ free(sel);
+ return NULL;
+ }
+ i = 0;
+ is = 0;
+ while ((is < size) && (data[is]))
+ {
+ if ((i == 0) && (data[is] == '#'))
+ for (; ((data[is]) && (data[is] != '\n')); is++) ;
+ else
+ {
+ if ((data[is] != '\r') &&
+ (data[is] != '\n'))
+ tmp[i++] = data[is++];
+ else
+ {
+ while ((data[is] == '\r') || (data[is] == '\n'))
+ is++;
+ tmp[i] = 0;
+ sel->num_files++;
+ t2 = realloc(sel->files, sel->num_files * sizeof(char *));
+ if (t2)
+ {
+ sel->files = t2;
+ sel->files[sel->num_files - 1] = strdup(tmp);
+ }
+ tmp[0] = 0;
+ i = 0;
+ }
+ }
+ }
+ if (i > 0)
+ {
+ tmp[i] = 0;
+ sel->num_files++;
+ t2 = realloc(sel->files, sel->num_files * sizeof(char *));
+ if (t2)
+ {
+ sel->files = t2;
+ sel->files[sel->num_files - 1] = strdup(tmp);
+ }
+ }
+
+ free(tmp);
+ free(data);
+
+ ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES;
+ ECORE_X_SELECTION_DATA(sel)->length = sel->num_files;
+
+ return ECORE_X_SELECTION_DATA(sel);
+}
+
+static int
+_ecore_x_selection_data_files_free(void *data)
+{
+ Ecore_X_Selection_Data_Files *sel;
+ int i;
+
+ sel = data;
+ if (sel->files)
+ {
+ for (i = 0; i < sel->num_files; i++)
+ free(sel->files[i]);
+ free(sel->files);
+ }
+
+ free(sel);
+ return 0;
+}
+
+static void *
+_ecore_x_selection_parser_text(const char *target EINA_UNUSED,
+ void *_data,
+ int size,
+ int format EINA_UNUSED)
+{
+ Ecore_X_Selection_Data_Text *sel;
+ unsigned char *data = _data;
+ void *t;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text));
+ if (!sel) return NULL;
+ if (data && data[size - 1])
+ {
+ /* Isn't nul terminated */
+ size++;
+ t = realloc(data, size);
+ if (!t)
+ {
+ free(sel);
+ return NULL;
+ }
+ data = t;
+ 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)->data = data;
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_text_free;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_text_free(void *data)
+{
+ Ecore_X_Selection_Data_Text *sel;
+
+ sel = data;
+ free(sel->text);
+ free(sel);
+ return 1;
+}
+
+static void *
+_ecore_x_selection_parser_targets(const char *target EINA_UNUSED,
+ void *data,
+ int size,
+ int format EINA_UNUSED)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+ unsigned long *targets;
+ int i;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets));
+ if (!sel) return NULL;
+ targets = (unsigned long *)data;
+
+ sel->num_targets = size - 2;
+ sel->targets = malloc((size - 2) * sizeof(char *));
+ if (!sel->targets)
+ {
+ free(sel);
+ return NULL;
+ }
+ for (i = 2; i < size; i++)
+ sel->targets[i - 2] = XGetAtomName(_ecore_x_disp, targets[i]);
+
+ 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;
+ ECORE_X_SELECTION_DATA(sel)->data = data;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_targets_free(void *data)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+ int i;
+
+ sel = data;
+
+ if (sel->targets)
+ {
+ for (i = 0; i < sel->num_targets; i++)
+ XFree(sel->targets[i]);
+ free(sel->targets);
+ }
+
+ free(ECORE_X_SELECTION_DATA(sel)->data);
+ free(sel);
+ return 1;
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_sync.c b/src/lib/ecore_x/xlib/ecore_x_sync.c
new file mode 100644
index 0000000000..0c7f546f1a
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_sync.c
@@ -0,0 +1,159 @@
+/*
+ * XSync code
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+EAPI Ecore_X_Sync_Alarm
+ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter)
+{
+ Ecore_X_Sync_Alarm alarm;
+ XSyncAlarmAttributes values;
+ XSyncValue init;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntToValue(&init, 0);
+ XSyncSetCounter(_ecore_x_disp, counter, init);
+
+ values.trigger.counter = counter;
+ values.trigger.value_type = XSyncAbsolute;
+ XSyncIntToValue(&values.trigger.wait_value, 1);
+ values.trigger.test_type = XSyncPositiveComparison;
+
+ XSyncIntToValue(&values.delta, 1);
+
+ values.events = True;
+
+ alarm = XSyncCreateAlarm(_ecore_x_disp,
+ XSyncCACounter |
+ XSyncCAValueType |
+ XSyncCAValue |
+ XSyncCATestType |
+ XSyncCADelta |
+ XSyncCAEvents,
+ &values);
+
+ ecore_x_sync();
+ return alarm;
+}
+
+EAPI Eina_Bool
+ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XSyncDestroyAlarm(_ecore_x_disp, alarm);
+}
+
+EAPI Eina_Bool
+ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter,
+ unsigned int *val)
+{
+ XSyncValue value;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XSyncQueryCounter(_ecore_x_disp, counter, &value))
+ {
+ *val = (unsigned int)XSyncValueLow32(value);
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+EAPI Ecore_X_Sync_Counter
+ecore_x_sync_counter_new(int val)
+{
+ XSyncCounter counter;
+ XSyncValue v;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntToValue(&v, val);
+ counter = XSyncCreateCounter(_ecore_x_disp, v);
+ return counter;
+}
+
+EAPI void
+ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncDestroyCounter(_ecore_x_disp, counter);
+}
+
+EAPI void
+ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter,
+ int by)
+{
+ XSyncValue v;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntToValue(&v, by);
+ XSyncChangeCounter(_ecore_x_disp, counter, v);
+}
+
+EAPI void
+ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter,
+ int val)
+{
+ XSyncWaitCondition cond;
+ XSyncValue v, v2;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncQueryCounter(_ecore_x_disp, counter, &v);
+ XSyncIntToValue(&v, val);
+ XSyncIntToValue(&v2, val + 1);
+ cond.trigger.counter = counter;
+ cond.trigger.value_type = XSyncAbsolute;
+ cond.trigger.wait_value = v;
+ cond.trigger.test_type = XSyncPositiveComparison;
+ cond.event_threshold = v2;
+ XSyncAwait(_ecore_x_disp, &cond, 1);
+// XSync(_ecore_x_disp, False); // dont need this
+}
+
+EAPI void
+ecore_x_sync_counter_set(Ecore_X_Sync_Counter counter,
+ int val)
+{
+ XSyncValue v;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntToValue(&v, val);
+ XSyncSetCounter(_ecore_x_disp, counter, v);
+}
+
+EAPI void
+ecore_x_sync_counter_2_set(Ecore_X_Sync_Counter counter,
+ int val_hi,
+ unsigned int val_lo)
+{
+ XSyncValue v;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntsToValue(&v, val_lo, val_hi);
+ XSyncSetCounter(_ecore_x_disp, counter, v);
+}
+
+EAPI Eina_Bool
+ecore_x_sync_counter_2_query(Ecore_X_Sync_Counter counter,
+ int *val_hi,
+ unsigned int *val_lo)
+{
+ XSyncValue value;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XSyncQueryCounter(_ecore_x_disp, counter, &value))
+ {
+ *val_lo = (unsigned int)XSyncValueLow32(value);
+ *val_hi = (int)XSyncValueHigh32(value);
+ return EINA_TRUE;
+ }
+ return EINA_FALSE;
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_test.c b/src/lib/ecore_x/xlib/ecore_x_test.c
new file mode 100644
index 0000000000..4eec6b74b3
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_test.c
@@ -0,0 +1,167 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+
+#ifdef ECORE_XTEST
+# include <X11/extensions/XTest.h>
+#endif /* ifdef ECORE_XTEST */
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include <string.h>
+
+EAPI Eina_Bool
+#ifdef ECORE_XTEST
+ecore_x_test_fake_key_down(const char *key)
+#else
+ecore_x_test_fake_key_down(const char *key EINA_UNUSED)
+#endif
+{
+#ifdef ECORE_XTEST
+ KeyCode keycode = 0;
+ KeySym keysym;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol)
+ return EINA_FALSE;
+
+ keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
+ }
+
+ if (keycode == 0)
+ return EINA_FALSE;
+
+ return XTestFakeKeyEvent(_ecore_x_disp, keycode, 1, 0) ? EINA_TRUE : EINA_FALSE;
+#else /* ifdef ECORE_XTEST */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XTEST */
+}
+
+EAPI Eina_Bool
+#ifdef ECORE_XTEST
+ecore_x_test_fake_key_up(const char *key)
+#else
+ecore_x_test_fake_key_up(const char *key EINA_UNUSED)
+#endif
+{
+#ifdef ECORE_XTEST
+ KeyCode keycode = 0;
+ KeySym keysym;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol)
+ return EINA_FALSE;
+
+ keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
+ }
+
+ if (keycode == 0)
+ return EINA_FALSE;
+
+ return XTestFakeKeyEvent(_ecore_x_disp, keycode, 0, 0) ? EINA_TRUE : EINA_FALSE;
+#else /* ifdef ECORE_XTEST */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XTEST */
+}
+
+EAPI Eina_Bool
+#ifdef ECORE_XTEST
+ecore_x_test_fake_key_press(const char *key)
+#else
+ecore_x_test_fake_key_press(const char *key EINA_UNUSED)
+#endif
+{
+#ifdef ECORE_XTEST
+ KeyCode keycode = 0;
+ KeySym keysym = 0;
+ int shift = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol)
+ return EINA_FALSE;
+
+ keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
+ if (_ecore_x_XKeycodeToKeysym(_ecore_x_disp, keycode, 0) != keysym)
+ {
+ if (_ecore_x_XKeycodeToKeysym(_ecore_x_disp, keycode, 1) == keysym)
+ shift = 1;
+ else
+ keycode = 0;
+ }
+ else
+ shift = 0;
+ }
+
+ if (keycode == 0)
+ {
+ static int mod = 0;
+ KeySym *keysyms;
+ int keycode_min, keycode_max, keycode_num;
+ int i;
+
+ XDisplayKeycodes(_ecore_x_disp, &keycode_min, &keycode_max);
+ keysyms = XGetKeyboardMapping(_ecore_x_disp, keycode_min,
+ keycode_max - keycode_min + 1,
+ &keycode_num);
+ mod = (mod + 1) & 0x7;
+ i = (keycode_max - keycode_min - mod - 1) * keycode_num;
+
+ keysyms[i] = keysym;
+ XChangeKeyboardMapping(_ecore_x_disp, keycode_min, keycode_num,
+ keysyms, (keycode_max - keycode_min));
+ XFree(keysyms);
+ XSync(_ecore_x_disp, False);
+ keycode = keycode_max - mod - 1;
+ }
+
+ if (shift)
+ XTestFakeKeyEvent(_ecore_x_disp,
+ XKeysymToKeycode(_ecore_x_disp, XK_Shift_L), 1, 0);
+
+ XTestFakeKeyEvent(_ecore_x_disp, keycode, 1, 0);
+ XTestFakeKeyEvent(_ecore_x_disp, keycode, 0, 0);
+ if (shift)
+ XTestFakeKeyEvent(_ecore_x_disp,
+ XKeysymToKeycode(_ecore_x_disp, XK_Shift_L), 0, 0);
+
+ return EINA_TRUE;
+#else /* ifdef ECORE_XTEST */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XTEST */
+}
+
+EAPI const char *
+ecore_x_keysym_string_get(int keysym)
+{
+ return XKeysymToString(keysym);
+}
+
+EAPI int
+ecore_x_keysym_keycode_get(const char *keyname)
+{
+ int keycode = 0;
+
+ if (!strncmp(keyname, "Keycode-", 8))
+ keycode = atoi(keyname + 8);
+ else
+ keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(keyname));
+
+ return keycode;
+}
diff --git a/src/lib/ecore_x/xlib/ecore_x_vsync.c b/src/lib/ecore_x/xlib/ecore_x_vsync.c
new file mode 100644
index 0000000000..a316a33c45
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_vsync.c
@@ -0,0 +1,351 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define ECORE_X_VSYNC_DRI2 1
+
+#ifdef ECORE_X_VSYNC_DRI2
+// 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;
+ long tval_usec;
+} drmVBlankReply;
+
+typedef union _drmVBlank
+{
+ drmVBlankReq request;
+ drmVBlankReply reply;
+} drmVBlank;
+
+#define DRM_EVENT_CONTEXT_VERSION 2
+
+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;
+
+//// dri
+
+static Bool (*sym_DRI2QueryExtension)(Display *display,
+ int *eventBase,
+ int *errorBase) = NULL;
+static Bool (*sym_DRI2QueryVersion)(Display *display,
+ int *major,
+ int *minor) = NULL;
+static Bool (*sym_DRI2Connect)(Display *display,
+ XID window,
+ char **driverName,
+ char **deviceName) = NULL;
+static Bool (*sym_DRI2Authenticate)(Display *display,
+ XID window,
+ drm_magic_t magic) = NULL;
+
+//// dri/drm data needed
+static int dri2_event = 0;
+static int dri2_error = 0;
+static int dri2_major = 0;
+static int dri2_minor = 0;
+static char *device_name = 0;
+static char *driver_name = 0;
+static drm_magic_t drm_magic;
+
+static int drm_fd = -1;
+static int drm_event_is_busy = 0;
+static int drm_animators_interval = 1;
+static drmEventContext drm_evctx;
+static Ecore_Fd_Handler *dri_drm_fdh = NULL;
+
+static void *dri_lib = NULL;
+static void *drm_lib = NULL;
+
+static Window dri_drm_vsync_root = 0;
+
+static void
+_dri_drm_tick_schedule(void)
+{
+ drmVBlank vbl;
+
+ vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT;
+ vbl.request.sequence = drm_animators_interval;
+ vbl.request.signal = 0;
+ sym_drmWaitVBlank(drm_fd, &vbl);
+}
+
+static void
+_dri_drm_tick_begin(void *data EINA_UNUSED)
+{
+ drm_event_is_busy = 1;
+ _dri_drm_tick_schedule();
+}
+
+static void
+_dri_drm_tick_end(void *data EINA_UNUSED)
+{
+ drm_event_is_busy = 0;
+}
+
+static void
+_dri_drm_vblank_handler(int fd EINA_UNUSED,
+ unsigned int frame EINA_UNUSED,
+ unsigned int sec EINA_UNUSED,
+ unsigned int usec EINA_UNUSED,
+ void *data EINA_UNUSED)
+{
+ ecore_animator_custom_tick();
+ if (drm_event_is_busy) _dri_drm_tick_schedule();
+}
+
+static Eina_Bool
+_dri_drm_cb(void *data EINA_UNUSED,
+ Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+ sym_drmHandleEvent(drm_fd, &drm_evctx);
+ return ECORE_CALLBACK_RENEW;
+}
+
+// yes. most evil. we dlopen libdrm and libGL etc. to manually find smbols
+// so we can be as compatible as possible given the whole mess of the
+// gl/dri/drm etc. world. and handle graceful failure at runtime not
+// compile time
+static int
+_dri_drm_link(void)
+{
+ const char *drm_libs[] =
+ {
+ "libdrm.so.2",
+ "libdrm.so.1",
+ "libdrm.so.0",
+ "libdrm.so",
+ NULL,
+ };
+ const char *dri_libs[] =
+ {
+ "libdri2.so.2",
+ "libdri2.so.1",
+ "libdri2.so.0",
+ "libdri2.so",
+ "libGL.so.4",
+ "libGL.so.3",
+ "libGL.so.2",
+ "libGL.so.1",
+ "libGL.so.0",
+ "libGL.so",
+ NULL,
+ };
+ int i, fail;
+#define SYM(lib, xx) \
+ do { \
+ sym_ ## xx = dlsym(lib, #xx); \
+ if (!(sym_ ## xx)) { \
+ fprintf(stderr, "%s\n", dlerror()); \
+ fail = 1; \
+ } \
+ } while (0)
+
+ if (dri_lib) return 1;
+ 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, drmWaitVBlank);
+ SYM(drm_lib, drmHandleEvent);
+ if (fail)
+ {
+ dlclose(drm_lib);
+ drm_lib = NULL;
+ }
+ else break;
+ }
+ }
+ if (!drm_lib) return 0;
+ for (i = 0; dri_libs[i]; i++)
+ {
+ dri_lib = dlopen(dri_libs[i], RTLD_LOCAL | RTLD_LAZY);
+ if (dri_lib)
+ {
+ fail = 0;
+ SYM(dri_lib, DRI2QueryExtension);
+ SYM(dri_lib, DRI2QueryVersion);
+ SYM(dri_lib, DRI2Connect);
+ SYM(dri_lib, DRI2Authenticate);
+ if (fail)
+ {
+ dlclose(dri_lib);
+ dri_lib = NULL;
+ }
+ else break;
+ }
+ }
+ if (!dri_lib)
+ {
+ dlclose(drm_lib);
+ drm_lib = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+static int
+_dri_drm_init(void)
+{
+ if (!sym_DRI2QueryExtension(_ecore_x_disp, &dri2_event, &dri2_error))
+ return 0;
+ if (!sym_DRI2QueryVersion(_ecore_x_disp, &dri2_major, &dri2_minor))
+ return 0;
+ if (dri2_major < 2)
+ return 0;
+ if (!sym_DRI2Connect(_ecore_x_disp, dri_drm_vsync_root, &driver_name, &device_name))
+ return 0;
+ drm_fd = open(device_name, O_RDWR);
+ if (drm_fd < 0)
+ return 0;
+ sym_drmGetMagic(drm_fd, &drm_magic);
+ if (!sym_DRI2Authenticate(_ecore_x_disp, dri_drm_vsync_root, drm_magic))
+ {
+ close(drm_fd);
+ drm_fd = -1;
+ return 0;
+ }
+ memset(&drm_evctx, 0, sizeof(drm_evctx));
+ drm_evctx.version = DRM_EVENT_CONTEXT_VERSION;
+ drm_evctx.vblank_handler = _dri_drm_vblank_handler;
+ drm_evctx.page_flip_handler = NULL;
+
+ dri_drm_fdh = ecore_main_fd_handler_add(drm_fd, ECORE_FD_READ,
+ _dri_drm_cb, NULL, NULL, NULL);
+ if (!dri_drm_fdh)
+ {
+ close(drm_fd);
+ drm_fd = -1;
+ return 0;
+ }
+ return 1;
+}
+
+static void
+_dri_drm_shutdown(void)
+{
+ if (drm_fd >= 0)
+ {
+ close(drm_fd);
+ drm_fd = -1;
+ }
+ if (dri_drm_fdh)
+ {
+ ecore_main_fd_handler_del(dri_drm_fdh);
+ dri_drm_fdh = NULL;
+ }
+}
+
+#endif
+
+EAPI Eina_Bool
+ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win)
+{
+#ifdef ECORE_X_VSYNC_DRI2
+ Ecore_X_Window root;
+
+ root = ecore_x_window_root_get(win);
+ if (root != dri_drm_vsync_root)
+ {
+ dri_drm_vsync_root = root;
+ if (dri_drm_vsync_root)
+ {
+ if (!_dri_drm_link())
+ {
+ ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER);
+ return EINA_FALSE;
+ }
+ _dri_drm_shutdown();
+ if (!_dri_drm_init())
+ {
+ dri_drm_vsync_root = 0;
+ ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER);
+ return EINA_FALSE;
+ }
+ ecore_animator_custom_source_tick_begin_callback_set
+ (_dri_drm_tick_begin, NULL);
+ ecore_animator_custom_source_tick_end_callback_set
+ (_dri_drm_tick_end, NULL);
+ ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM);
+ }
+ else
+ {
+ if (drm_fd >= 0)
+ {
+ _dri_drm_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
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_window.c b/src/lib/ecore_x/xlib/ecore_x_window.c
new file mode 100644
index 0000000000..36fc5cc53a
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_window.c
@@ -0,0 +1,1727 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+static int ignore_num = 0;
+static Ecore_X_Window *ignore_list = NULL;
+
+/**
+ * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
+ *
+ * Functions that can be used to create an X window.
+ */
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @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 w,
+ int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (parent == 0)
+ parent = DefaultRootWindow(_ecore_x_disp);
+
+ attr.backing_store = NotUseful;
+ attr.override_redirect = False;
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.bit_gravity = NorthWestGravity;
+ attr.win_gravity = NorthWestGravity;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ CopyFromParent, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ InputOutput,
+ CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ CWBackingStore |
+ CWOverrideRedirect |
+/* CWColormap | */
+ CWBorderPixel |
+ CWBackPixmap |
+ CWSaveUnder |
+ CWDontPropagate |
+ CWEventMask |
+ CWBitGravity |
+ CWWinGravity,
+ &attr);
+
+ if (parent == DefaultRootWindow(_ecore_x_disp))
+ ecore_x_window_defaults_set(win);
+
+ return win;
+}
+
+/**
+ * Creates a window with the override redirect attribute set to @c True.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @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_new(Ecore_X_Window parent,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (parent == 0)
+ parent = DefaultRootWindow(_ecore_x_disp);
+
+ attr.backing_store = NotUseful;
+ attr.override_redirect = True;
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.bit_gravity = NorthWestGravity;
+ attr.win_gravity = NorthWestGravity;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ CopyFromParent, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ InputOutput,
+ CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ CWBackingStore |
+ CWOverrideRedirect |
+/* CWColormap | */
+ CWBorderPixel |
+ CWBackPixmap |
+ CWSaveUnder |
+ CWDontPropagate |
+ CWEventMask |
+ CWBitGravity |
+ CWWinGravity,
+ &attr);
+ return win;
+}
+
+/**
+ * Creates a new input window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @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 w,
+ int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (parent == 0)
+ parent = DefaultRootWindow(_ecore_x_disp);
+
+ attr.override_redirect = True;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ CopyFromParent,
+ InputOnly,
+ CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ CWOverrideRedirect |
+ CWDontPropagate |
+ CWEventMask,
+ &attr);
+
+ if (parent == DefaultRootWindow(_ecore_x_disp))
+ {
+ }
+
+ return win;
+}
+
+/**
+ * @defgroup Ecore_X_Window_Properties_Group X Window Property Functions
+ *
+ * Functions that set window properties.
+ */
+
+/**
+ * Sets the default properties for the given window.
+ *
+ * The default properties set for the window are @c WM_CLIENT_MACHINE and
+ * @c _NET_WM_PID.
+ *
+ * @param win The given window.
+ * @ingroup Ecore_X_Window_Properties_Group
+ */
+EAPI void
+ecore_x_window_defaults_set(Ecore_X_Window win)
+{
+ long pid;
+ char buf[MAXHOSTNAMELEN];
+ char *hostname[1];
+ int argc;
+ char **argv;
+ XTextProperty xprop;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /*
+ * Set WM_CLIENT_MACHINE.
+ */
+ gethostname(buf, MAXHOSTNAMELEN);
+ buf[MAXHOSTNAMELEN - 1] = '\0';
+ hostname[0] = buf;
+ /* The ecore function uses UTF8 which Xlib may not like (especially
+ * with older clients) */
+ /* ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_CLIENT_MACHINE,
+ (char *)buf); */
+ if (XStringListToTextProperty(hostname, 1, &xprop))
+ {
+ XSetWMClientMachine(_ecore_x_disp, win, &xprop);
+ XFree(xprop.value);
+ }
+
+ /*
+ * Set _NET_WM_PID
+ */
+ 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(win, argc, argv);
+}
+
+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)
+{
+ XWindowChanges xwc;
+
+ if (!win)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xwc.x = x;
+ xwc.y = y;
+ xwc.width = w;
+ xwc.height = h;
+ xwc.border_width = border_width;
+ xwc.sibling = sibling;
+ xwc.stack_mode = stack_mode;
+
+ XConfigureWindow(_ecore_x_disp, win, mask, &xwc);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions
+ *
+ * Functions to destroy X windows.
+ */
+
+/**
+ * Deletes the given window.
+ * @param win The given window.
+ * @ingroup Ecore_X_Window_Destroy_Group
+ */
+EAPI void
+ecore_x_window_free(Ecore_X_Window win)
+{
+ /* sorry sir, deleting the root window doesn't sound like
+ * a smart idea.
+ */
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win)
+ XDestroyWindow(_ecore_x_disp, win);
+}
+
+/**
+ * Set if a window should be ignored.
+ * @param win The given window.
+ * @param ignore if to ignore
+ */
+EAPI void
+ecore_x_window_ignore_set(Ecore_X_Window win,
+ int ignore)
+{
+ int i, j, cnt;
+ Ecore_X_Window *t;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (ignore)
+ {
+ if (ignore_list)
+ {
+ for (i = 0; i < ignore_num; i++)
+ {
+ if (win == ignore_list[i])
+ return;
+ }
+ t = realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
+ if (!t) return;
+ ignore_list = t;
+ ignore_list[ignore_num++] = win;
+ }
+ else
+ {
+ ignore_num = 0;
+ ignore_list = malloc(sizeof(Ecore_X_Window));
+ if (ignore_list)
+ ignore_list[ignore_num++] = win;
+ }
+ }
+ else
+ {
+ if (!ignore_list)
+ return;
+
+ for (cnt = ignore_num, i = 0, j = 0; i < cnt; 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;
+ }
+ t = realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
+ if (t) ignore_list = t;
+ }
+}
+
+/**
+ * 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;
+
+ return ignore_list;
+}
+
+/**
+ * Sends a delete request to 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 win)
+{
+ XEvent xev;
+
+ /* sorry sir, deleting the root window doesn't sound like
+ * a smart idea.
+ */
+ if (!win)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = ECORE_X_ATOM_WM_DELETE_WINDOW;
+ xev.xclient.data.l[1] = CurrentTime;
+
+ XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
+ *
+ * Functions to access and change the visibility of X windows.
+ */
+
+/**
+ * Shows a window.
+ *
+ * Synonymous to "mapping" a window in X Window System terminology.
+ *
+ * @param win The window to show.
+ * @ingroup Ecore_X_Window_Visibility
+ */
+EAPI void
+ecore_x_window_show(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XMapWindow(_ecore_x_disp, win);
+}
+
+/**
+ * Hides a window.
+ *
+ * Synonymous to "unmapping" a window in X Window System terminology.
+ *
+ * @param win The window to hide.
+ * @ingroup Ecore_X_Window_Visibility
+ */
+EAPI void
+ecore_x_window_hide(Ecore_X_Window win)
+{
+ XEvent xev;
+ Window root;
+ int idum;
+ unsigned int uidum;
+
+ /* ICCCM: SEND unmap event... */
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ root = win;
+ if (ScreenCount(_ecore_x_disp) == 1)
+ root = DefaultRootWindow(_ecore_x_disp);
+ else
+ XGetGeometry(_ecore_x_disp,
+ win,
+ &root,
+ &idum,
+ &idum,
+ &uidum,
+ &uidum,
+ &uidum,
+ &uidum);
+
+ XUnmapWindow(_ecore_x_disp, win);
+ xev.xunmap.type = UnmapNotify;
+ xev.xunmap.serial = 0;
+ xev.xunmap.send_event = True;
+ xev.xunmap.display = _ecore_x_disp;
+ xev.xunmap.event = root;
+ xev.xunmap.window = win;
+ xev.xunmap.from_configure = False;
+ XSendEvent(_ecore_x_disp, xev.xunmap.event, False,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
+ *
+ * Functions that change or retrieve the geometry of X windows.
+ */
+
+/**
+ * Moves a window to the position @p x, @p y.
+ *
+ * The position is relative to the upper left hand corner of the
+ * parent window.
+ *
+ * @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 win,
+ int x,
+ int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XMoveWindow(_ecore_x_disp, win, x, y);
+}
+
+/**
+ * Resizes a window.
+ * @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 win,
+ int w,
+ int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (w < 1)
+ w = 1;
+
+ if (h < 1)
+ h = 1;
+
+ XResizeWindow(_ecore_x_disp, win, w, h);
+}
+
+/**
+ * Moves and resizes a window.
+ * @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 win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (w < 1)
+ w = 1;
+
+ if (h < 1)
+ h = 1;
+
+ XMoveResizeWindow(_ecore_x_disp, win, x, y, w, h);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions
+ *
+ * Functions that give the focus to an X Window.
+ */
+
+/**
+ * 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 win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0)
+ win = DefaultRootWindow(_ecore_x_disp); // XSetInputFocus(_ecore_x_disp, win, RevertToNone, CurrentTime);
+
+// XSetInputFocus(_ecore_x_disp, win, RevertToPointerRoot, CurrentTime);
+ XSetInputFocus(_ecore_x_disp, win, RevertToParent, CurrentTime);
+}
+
+/**
+ * Sets the focus to the given window at a specific time.
+ * @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 win,
+ Ecore_X_Time t)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0)
+ win = DefaultRootWindow(_ecore_x_disp); // XSetInputFocus(_ecore_x_disp, win, RevertToNone, t);
+
+// XSetInputFocus(_ecore_x_disp, win, PointerRoot, t);
+ XSetInputFocus(_ecore_x_disp, win, RevertToParent, t);
+}
+
+/**
+ * gets the window that has focus.
+ * @return The window that has focus.
+ * @ingroup Ecore_X_Window_Focus_Functions
+ */
+EAPI Ecore_X_Window
+ecore_x_window_focus_get(void)
+{
+ Window win;
+ int revert_mode;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ win = 0;
+ XGetInputFocus(_ecore_x_disp, &win, &revert_mode);
+ return win;
+}
+
+/**
+ * @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 win The window to raise.
+ * @ingroup Ecore_X_Window_Z_Order_Group
+ */
+EAPI void
+ecore_x_window_raise(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XRaiseWindow(_ecore_x_disp, win);
+}
+
+/**
+ * Lowers the given window.
+ * @param win The window to lower.
+ * @ingroup Ecore_X_Window_Z_Order_Group
+ */
+EAPI void
+ecore_x_window_lower(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XLowerWindow(_ecore_x_disp, win);
+}
+
+/**
+ * @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 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_Parent_Group
+ */
+EAPI void
+ecore_x_window_reparent(Ecore_X_Window win,
+ Ecore_X_Window new_parent,
+ int x,
+ int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (new_parent == 0)
+ new_parent = DefaultRootWindow(_ecore_x_disp);
+
+ XReparentWindow(_ecore_x_disp, win, new_parent, x, y);
+}
+
+/**
+ * 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_window_size_get(Ecore_X_Window win,
+ int *w,
+ int *h)
+{
+ int dummy_x, dummy_y;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0)
+ win = DefaultRootWindow(_ecore_x_disp);
+
+ ecore_x_drawable_geometry_get(win, &dummy_x, &dummy_y, w, h);
+}
+
+/**
+ * Retrieves the geometry of the given window.
+ *
+ * Note that the x & y coordinates 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 = DefaultRootWindow(_ecore_x_disp);
+
+ ecore_x_drawable_geometry_get(win, x, y, w, h);
+}
+
+/**
+ * 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__);
+ /* doesn't make sense to call this on a root window */
+ if (!win)
+ return 0;
+
+ return ecore_x_drawable_border_width_get(win);
+}
+
+/**
+ * Sets the width of the border of the given window.
+ * @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 win,
+ int width)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* doesn't make sense to call this on a root window */
+ if (!win)
+ return;
+
+ XSetWindowBorderWidth (_ecore_x_disp, win, width);
+}
+
+/**
+ * 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__);
+ return ecore_x_drawable_depth_get(win);
+}
+
+/**
+ * @brief Show the cursor on a window of type Ecore_X_Window.
+ * @param win The window for which the cursor will be showed.
+ * @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE.
+ */
+EAPI void
+ecore_x_window_cursor_show(Ecore_X_Window win,
+ Eina_Bool show)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0)
+ win = DefaultRootWindow(_ecore_x_disp);
+
+ if (!show)
+ {
+ Cursor c;
+ XColor cl;
+ Pixmap p, m;
+ GC gc;
+ XGCValues gcv;
+
+ p = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1);
+ m = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1);
+ gc = XCreateGC(_ecore_x_disp, m, 0, &gcv);
+ XSetForeground(_ecore_x_disp, gc, 0);
+ XDrawPoint(_ecore_x_disp, m, gc, 0, 0);
+ XFreeGC(_ecore_x_disp, gc);
+ c = XCreatePixmapCursor(_ecore_x_disp, p, m, &cl, &cl, 0, 0);
+ XDefineCursor(_ecore_x_disp, win, c);
+ XFreeCursor(_ecore_x_disp, c);
+ XFreePixmap(_ecore_x_disp, p);
+ XFreePixmap(_ecore_x_disp, m);
+ }
+ else
+ XDefineCursor(_ecore_x_disp, win, 0);
+}
+
+EAPI void
+ecore_x_window_cursor_set(Ecore_X_Window win,
+ Ecore_X_Cursor c)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (c == 0)
+ XUndefineCursor(_ecore_x_disp, win);
+ else
+ XDefineCursor(_ecore_x_disp, win, c);
+}
+
+/**
+ * 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)
+{
+ XWindowAttributes attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XGetWindowAttributes(_ecore_x_disp, win, &attr) &&
+ (attr.map_state == IsViewable);
+}
+
+typedef struct _Shadow Shadow;
+struct _Shadow
+{
+ Shadow *parent;
+ Shadow **children;
+ Window win;
+ int children_num;
+ short x, y;
+ unsigned short w, h;
+};
+
+static Shadow **shadow_base = NULL;
+static int shadow_num = 0;
+
+static Shadow *
+_ecore_x_window_tree_walk(Window win)
+{
+ Window *list = NULL;
+ Window parent_win = 0, root_win = 0;
+ unsigned int num;
+ Shadow *s, **sl;
+ XWindowAttributes att;
+
+ if (!XGetWindowAttributes(_ecore_x_disp, win, &att))
+ return NULL; // if (att.class == InputOnly) return NULL;
+
+ if (att.map_state != IsViewable)
+ return NULL;
+
+ s = calloc(1, sizeof(Shadow));
+ if (!s)
+ return NULL;
+
+ s->win = win;
+ s->x = att.x;
+ s->y = att.y;
+ s->w = att.width;
+ s->h = att.height;
+ if (XQueryTree(_ecore_x_disp, s->win, &root_win, &parent_win,
+ &list, &num))
+ {
+ s->children = calloc(1, sizeof(Shadow *) * num);
+ if (s->children)
+ {
+ size_t i, j;
+ s->children_num = num;
+ for (i = 0; i < num; i++)
+ {
+ s->children[i] = _ecore_x_window_tree_walk(list[i]);
+ if (s->children[i])
+ s->children[i]->parent = s;
+ }
+ /* compress list down */
+ j = 0;
+ for (i = 0; i < num; i++)
+ {
+ if (s->children[i])
+ {
+ s->children[j] = s->children[i];
+ j++;
+ }
+ }
+ if (j == 0)
+ {
+ free(s->children);
+ s->children = NULL;
+ s->children_num = 0;
+ }
+ else
+ {
+ s->children_num = j;
+ sl = realloc(s->children, sizeof(Shadow *) * j);
+ if (sl)
+ s->children = sl;
+ }
+ }
+ }
+
+ if (list)
+ XFree(list);
+
+ return s;
+}
+
+static void
+_ecore_x_window_tree_shadow_free1(Shadow *s)
+{
+ int i;
+
+ 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]);
+ }
+ free(s->children);
+ }
+
+ free(s);
+}
+
+static void
+_ecore_x_window_tree_shadow_free(void)
+{
+ int i;
+
+ if (!shadow_base)
+ return;
+
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i])
+ continue;
+
+ _ecore_x_window_tree_shadow_free1(shadow_base[i]);
+ }
+ free(shadow_base);
+ shadow_base = NULL;
+ shadow_num = 0;
+}
+
+static void
+_ecore_x_window_tree_shadow_populate(void)
+{
+ Ecore_X_Window *roots;
+ int i, num;
+
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ 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]);
+ }
+
+ free(roots);
+ }
+}
+
+/*
+ static int shadow_count = 0;
+
+ static void
+ _ecore_x_window_tree_shadow_start(void)
+ {
+ shadow_count++;
+ if (shadow_count > 1) return;
+ _ecore_x_window_tree_shadow_populate();
+ }
+
+ static void
+ _ecore_x_window_tree_shadow_stop(void)
+ {
+ shadow_count--;
+ if (shadow_count != 0) return;
+ _ecore_x_window_tree_shadow_free();
+ }
+ */
+
+static Shadow *
+_ecore_x_window_shadow_tree_find_shadow(Shadow *s,
+ Window win)
+{
+ Shadow *ss;
+ int i;
+
+ if (s->win == win)
+ return s;
+
+ if (s->children)
+ for (i = 0; i < s->children_num; i++)
+ {
+ if (!s->children[i])
+ continue;
+
+ if ((ss =
+ _ecore_x_window_shadow_tree_find_shadow(s->children[i], win)))
+ return ss;
+ }
+
+ return NULL;
+}
+
+static Shadow *
+_ecore_x_window_shadow_tree_find(Window base)
+{
+ Shadow *s;
+ int i;
+
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i])
+ continue;
+
+ if ((s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], base)))
+ return s;
+ }
+ return NULL;
+}
+
+static int
+_inside_rects(Shadow *s,
+ int x,
+ int y,
+ int bx,
+ int by,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+ int i, inside;
+
+ if (!rects) return 0;
+ inside = 0;
+ for (i = 0; i < num; i++)
+ {
+ if ((x >= s->x + bx + rects[i].x) &&
+ (y >= s->y + by + rects[i].y) &&
+ (x < (int)(s->x + bx + rects[i].x + rects[i].width)) &&
+ (y < (int)(s->y + by + rects[i].y + rects[i].height)))
+ {
+ inside = 1;
+ break;
+ }
+ }
+ free(rects);
+ return inside;
+}
+
+static 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)
+{
+ Window child;
+ int i, j;
+ int wx, wy;
+
+ wx = s->x + bx;
+ wy = s->y + by;
+ if (!((x >= wx) && (y >= wy) && (x < (wx + s->w)) && (y < (wy + s->h))))
+ return 0;
+
+ /* FIXME: get shape */
+ {
+ int num;
+ Ecore_X_Rectangle *rects;
+
+ num = 0;
+ rects = ecore_x_window_shape_rectangles_get(s->win, &num);
+ if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0;
+ num = 0;
+ rects = ecore_x_window_shape_input_rectangles_get(s->win, &num);
+ if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0;
+ }
+
+ if (s->children)
+ {
+ int skipit = 0;
+
+ for (i = s->children_num - 1; i >= 0; --i)
+ {
+ if (!s->children[i])
+ continue;
+
+ skipit = 0;
+ if (skip)
+ for (j = 0; j < skip_num; j++)
+ {
+ if (s->children[i]->win == skip[j])
+ {
+ skipit = 1;
+ goto onward;
+ }
+ }
+
+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;
+ }
+ }
+
+ return s->win;
+}
+
+static Window
+_ecore_x_window_shadow_tree_at_xy_get(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;
+ }
+
+ s = _ecore_x_window_shadow_tree_find(base);
+ if (!s)
+ return 0;
+
+ return _ecore_x_window_shadow_tree_at_xy_get_shadow(s,
+ bx,
+ by,
+ x,
+ y,
+ skip,
+ skip_num);
+}
+
+/**
+ * Retrieves the top, visible window at the given location,
+ * but skips the windows in the list. This uses a shadow tree built from the
+ * window tree that is only updated the first time
+ * ecore_x_window_shadow_tree_at_xy_with_skip_get() is called, or the next time
+ * it is called after a ecore_x_window_shadow_tree_flush()
+ * @param base The base window to start searching from (normally root).
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @param skip The list of windows to be skipped.
+ * @param skip_num The number of windows to be skipped.
+ * @return The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_window_shadow_tree_at_xy_get(base,
+ 0,
+ 0,
+ x,
+ y,
+ skip,
+ skip_num);
+}
+
+/**
+ * Retrieves the parent window a given window has. This uses the shadow window
+ * tree.
+ * @param root The root window of @p win - if 0, this will be automatically determined with extra processing overhead
+ * @param win The window to get the parent window of
+ * @return The parent window of @p win
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_shadow_parent_get(Ecore_X_Window root EINA_UNUSED,
+ Ecore_X_Window win)
+{
+ Shadow *s;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!shadow_base)
+ {
+ _ecore_x_window_tree_shadow_populate();
+ if (!shadow_base)
+ return 0;
+ }
+
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i])
+ continue;
+
+ s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], win);
+ if (s)
+ {
+ if (!s->parent)
+ return 0;
+
+ return s->parent->win;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Flushes the window shadow tree so nothing is stored.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_shadow_tree_flush(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_tree_shadow_free();
+}
+
+/**
+ * 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)
+{
+ XWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWindowAttributes(_ecore_x_disp, win, &att))
+ return 0;
+
+ return att.root;
+}
+
+static Window
+_ecore_x_window_at_xy_get(Window base,
+ int bx,
+ int by,
+ int x,
+ int y,
+ Ecore_X_Window *skip,
+ int skip_num)
+{
+ Window *list = NULL;
+ Window parent_win = 0, child = 0, root_win = 0;
+ int i, j, wx, wy, ww, wh;
+ unsigned int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_visible_get(base))
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ 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;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XQueryTree(_ecore_x_disp, base, &root_win, &parent_win, &list, &num))
+ return base;
+
+ if (list)
+ {
+ int skipit = 0;
+
+ for (i = num - 1; i >= 0; --i)
+ {
+ skipit = 0;
+
+ if (skip)
+ for (j = 0; j < skip_num; j++)
+ {
+ if (list[i] == skip[j])
+ {
+ skipit = 1;
+ goto onward;
+ }
+ }
+
+onward:
+ if (!skipit)
+ if ((child =
+ _ecore_x_window_at_xy_get(list[i], wx, wy, x, y, skip,
+ skip_num)))
+ {
+ XFree(list);
+ return child;
+ }
+ }
+ XFree(list);
+ }
+
+ return base;
+}
+
+/**
+ * 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.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_get(int x,
+ int y)
+{
+ Ecore_X_Window win, root;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* FIXME: Proper function to determine current root/virtual root
+ * window missing here */
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ ecore_x_grab();
+ win = _ecore_x_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
+ ecore_x_ungrab();
+
+ 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.
+ * @param skip The list of windows to be skipped.
+ * @param skip_num The number of windows to be skipped.
+ * @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)
+{
+ Ecore_X_Window win, root;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* FIXME: Proper function to determine current root/virtual root
+ * window missing here */
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ ecore_x_grab();
+ win = _ecore_x_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
+ ecore_x_ungrab();
+
+ return win ? win : root;
+}
+
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,
+ int x,
+ int y)
+{
+ Ecore_X_Window win;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_grab();
+ win = _ecore_x_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
+ ecore_x_ungrab();
+
+ return win ? win : begin;
+}
+
+/**
+ * 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)
+{
+ Window root, parent, *children = NULL;
+ unsigned int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XQueryTree(_ecore_x_disp, win, &root, &parent, &children, &num))
+ return 0;
+
+ if (children)
+ XFree(children);
+
+ return parent;
+}
+
+/**
+ * Sets the background color of the given window.
+ * @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 win,
+ unsigned short r,
+ unsigned short g,
+ unsigned short b)
+{
+ XSetWindowAttributes attr;
+ Colormap map;
+ XColor col;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ col.red = r;
+ col.green = g;
+ col.blue = b;
+
+ map = DefaultColormap(_ecore_x_disp, DefaultScreen(_ecore_x_disp));
+ XAllocColor(_ecore_x_disp, map, &col);
+
+ attr.background_pixel = col.pixel;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWBackPixel, &attr);
+}
+
+EAPI void
+ecore_x_window_gravity_set(Ecore_X_Window win,
+ Ecore_X_Gravity grav)
+{
+ XSetWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ att.win_gravity = grav;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWWinGravity, &att);
+}
+
+EAPI void
+ecore_x_window_pixel_gravity_set(Ecore_X_Window win,
+ Ecore_X_Gravity grav)
+{
+ XSetWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ att.bit_gravity = grav;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWBitGravity, &att);
+}
+
+EAPI void
+ecore_x_window_pixmap_set(Ecore_X_Window win,
+ Ecore_X_Pixmap pmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetWindowBackgroundPixmap(_ecore_x_disp, win, pmap);
+}
+
+EAPI void
+ecore_x_window_area_clear(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XClearArea(_ecore_x_disp, win, x, y, w, h, False);
+}
+
+EAPI void
+ecore_x_window_area_expose(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XClearArea(_ecore_x_disp, win, x, y, w, h, True);
+}
+
+EAPI void
+ecore_x_window_override_set(Ecore_X_Window win,
+ Eina_Bool override)
+{
+ XSetWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ att.override_redirect = override;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWOverrideRedirect, &att);
+}
+
+#ifdef ECORE_XRENDER
+static Ecore_X_Window
+_ecore_x_window_argb_internal_new(Ecore_X_Window parent,
+ int x,
+ int y,
+ int w,
+ int h,
+ Eina_Bool override,
+ Eina_Bool saveunder)
+{
+ Window win;
+ XSetWindowAttributes attr;
+ XWindowAttributes att;
+ XVisualInfo *xvi;
+ XVisualInfo vi_in;
+ int nvi, i, scr = 0;
+ XRenderPictFormat *fmt;
+ Visual *vis;
+
+ if (parent == 0)
+ {
+ parent = DefaultRootWindow(_ecore_x_disp);
+ scr = DefaultScreen(_ecore_x_disp);
+ }
+ else
+ {
+ /* ewww - round trip */
+ XGetWindowAttributes(_ecore_x_disp, parent, &att);
+ for (i = 0; i < ScreenCount(_ecore_x_disp); i++)
+ {
+ if (att.screen == ScreenOfDisplay(_ecore_x_disp, i))
+ {
+ scr = i;
+ break;
+ }
+ }
+ }
+
+ vi_in.screen = scr;
+ vi_in.depth = 32;
+ vi_in.class = TrueColor;
+ xvi = XGetVisualInfo(_ecore_x_disp,
+ VisualScreenMask |
+ VisualDepthMask |
+ VisualClassMask,
+ &vi_in,
+ &nvi);
+ if (!xvi)
+ return 0;
+
+ vis = NULL;
+ for (i = 0; i < nvi; i++)
+ {
+ fmt = XRenderFindVisualFormat(_ecore_x_disp, xvi[i].visual);
+ if ((fmt->type == PictTypeDirect) && (fmt->direct.alphaMask))
+ {
+ vis = xvi[i].visual;
+ break;
+ }
+ }
+ XFree (xvi);
+
+ attr.backing_store = NotUseful;
+ attr.override_redirect = override;
+ attr.colormap = XCreateColormap(_ecore_x_disp, parent,
+ vis, AllocNone);
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.bit_gravity = NorthWestGravity;
+ attr.win_gravity = NorthWestGravity;
+ attr.save_under = saveunder;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ 32,
+ InputOutput,
+ vis,
+ CWBackingStore |
+ CWOverrideRedirect |
+ CWColormap |
+ CWBorderPixel |
+ CWBackPixmap |
+ CWSaveUnder |
+ CWDontPropagate |
+ CWEventMask |
+ CWBitGravity |
+ CWWinGravity,
+ &attr);
+ XFreeColormap(_ecore_x_disp, attr.colormap);
+
+ if (parent == DefaultRootWindow(_ecore_x_disp))
+ ecore_x_window_defaults_set(win);
+
+ return win;
+}
+
+#endif /* ifdef ECORE_XRENDER */
+
+EAPI int
+ecore_x_window_argb_get(Ecore_X_Window win)
+{
+#ifdef ECORE_XRENDER
+ XWindowAttributes att;
+ XRenderPictFormat *fmt;
+
+ att.visual = 0;
+ if (!XGetWindowAttributes(_ecore_x_disp, win, &att))
+ return 0;
+
+ fmt = XRenderFindVisualFormat(_ecore_x_disp, att.visual);
+ if (!fmt)
+ return 0;
+
+ if ((fmt->type == PictTypeDirect) && (fmt->direct.alphaMask))
+ return 1;
+
+ return 0;
+#else /* ifdef ECORE_XRENDER */
+ return 0;
+#endif /* ifdef ECORE_XRENDER */
+}
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @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 w,
+ int h)
+{
+#ifdef ECORE_XRENDER
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_window_argb_internal_new(parent, x, y, w, h, 1, 0);
+#else /* ifdef ECORE_XRENDER */
+ return 0;
+#endif /* ifdef ECORE_XRENDER */
+}
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @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 w,
+ int h)
+{
+#ifdef ECORE_XRENDER
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_window_argb_internal_new(parent, x, y, w, h, 0, 0);
+#else /* ifdef ECORE_XRENDER */
+ return 0;
+#endif /* ifdef ECORE_XRENDER */
+}
+
+/**
+ * Creates a window with the override redirect attribute set to @c True.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @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 w,
+ int h)
+{
+#ifdef ECORE_XRENDER
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_window_argb_internal_new(parent, x, y, w, h, 1, 0);
+#else /* ifdef ECORE_XRENDER */
+ return 0;
+#endif /* ifdef ECORE_XRENDER */
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_window_prop.c b/src/lib/ecore_x/xlib/ecore_x_window_prop.c
new file mode 100644
index 0000000000..535c521941
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_window_prop.c
@@ -0,0 +1,760 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+#include <inttypes.h>
+#include <limits.h>
+
+#define _ATOM_SET_CARD32(win, atom, p_val, cnt) \
+ XChangeProperty(_ecore_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace, \
+ (unsigned char *)p_val, cnt)
+
+/*
+ * 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)
+{
+#if SIZEOF_INT == SIZEOF_LONG
+ _ATOM_SET_CARD32(win, atom, val, num);
+#else /* if SIZEOF_INT == SIZEOF_LONG */
+ long *v2;
+ unsigned int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ v2 = malloc(num * sizeof(long));
+ if (!v2)
+ return;
+
+ for (i = 0; i < num; i++)
+ v2[i] = val[i];
+ _ATOM_SET_CARD32(win, atom, v2, num);
+ free(v2);
+#endif /* if SIZEOF_INT == SIZEOF_LONG */
+}
+
+/*
+ * 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,
+ Ecore_X_Atom atom,
+ unsigned int *val,
+ unsigned int len)
+{
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ unsigned int i;
+ int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ prop_ret = NULL;
+ if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ XA_CARDINAL, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret) != Success)
+ return -1;
+
+ if (type_ret != XA_CARDINAL || format_ret != 32)
+ num = -1;
+ else if (num_ret == 0 || !prop_ret)
+ num = 0;
+ else
+ {
+ if (num_ret < len)
+ len = num_ret;
+
+ for (i = 0; i < len; i++)
+ val[i] = ((unsigned long *)prop_ret)[i];
+ num = len;
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+/*
+ * 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,
+ Ecore_X_Atom atom,
+ unsigned int **plst)
+{
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ unsigned int i, *val;
+ int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ *plst = NULL;
+ prop_ret = NULL;
+ if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ XA_CARDINAL, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret) != Success)
+ return -1;
+
+ if ((type_ret != XA_CARDINAL) || (format_ret != 32))
+ num = -1;
+ else if ((num_ret == 0) || (!prop_ret))
+ num = 0;
+ else
+ {
+ val = malloc(num_ret * sizeof(unsigned int));
+ if (!val)
+ {
+ if (prop_ret) XFree(prop_ret);
+ return -1;
+ }
+ for (i = 0; i < num_ret; i++)
+ val[i] = ((unsigned long *)prop_ret)[i];
+ num = num_ret;
+ *plst = val;
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+/*
+ * 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 *lst,
+ unsigned int num)
+{
+#if SIZEOF_INT == SIZEOF_LONG
+ XChangeProperty(_ecore_x_disp, win, atom, type, 32, PropModeReplace,
+ (unsigned char *)lst, num);
+#else /* if SIZEOF_INT == SIZEOF_LONG */
+ unsigned long *pl;
+ unsigned int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ pl = malloc(num * sizeof(long));
+ if (!pl)
+ return;
+
+ for (i = 0; i < num; i++)
+ pl[i] = lst[i];
+ XChangeProperty(_ecore_x_disp, win, atom, type, 32, PropModeReplace,
+ (unsigned char *)pl, num);
+ free(pl);
+#endif /* if SIZEOF_INT == SIZEOF_LONG */
+}
+
+/*
+ * 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,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type,
+ Ecore_X_ID *lst,
+ unsigned int len)
+{
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ int num;
+ unsigned i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ prop_ret = NULL;
+ if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ type, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret) != Success)
+ return -1;
+
+ if (type_ret != type || format_ret != 32)
+ num = -1;
+ else if (num_ret == 0 || !prop_ret)
+ num = 0;
+ else
+ {
+ if (num_ret < len)
+ len = num_ret;
+
+ for (i = 0; i < len; i++)
+ lst[i] = ((unsigned long *)prop_ret)[i];
+ num = len;
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+/*
+ * 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,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type,
+ Ecore_X_ID **val)
+{
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ Ecore_X_Atom *alst;
+ int num;
+ unsigned i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ *val = NULL;
+ prop_ret = NULL;
+ if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ type, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret) != Success)
+ return -1;
+
+ if (type_ret != type || format_ret != 32)
+ num = -1;
+ else if (num_ret == 0 || !prop_ret)
+ num = 0;
+ else
+ {
+ alst = malloc(num_ret * sizeof(Ecore_X_ID));
+ for (i = 0; i < num_ret; i++)
+ alst[i] = ((unsigned long *)prop_ret)[i];
+ num = num_ret;
+ *val = alst;
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+/*
+ * 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, num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst);
+ if (num < 0)
+ {
+ return; /* Error - assuming invalid window */
+ }
+
+ /* Is it there? */
+ for (i = 0; i < num; i++)
+ {
+ if (lst[i] == item)
+ break;
+ }
+
+ if (i < num)
+ {
+ /* Was in list */
+ if (op == ECORE_X_PROP_LIST_ADD)
+ goto done; /* 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; /* Add it */
+
+ num++;
+ lst = realloc(lst, num * sizeof(Ecore_X_ID));
+ lst[i] = item;
+ }
+
+ ecore_x_window_prop_xid_set(win, atom, type, lst, num);
+
+done:
+ if (lst)
+ free(lst);
+}
+
+/*
+ * Set Atom (array) property
+ */
+EAPI void
+ecore_x_window_prop_atom_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom *lst,
+ unsigned int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_xid_set(win, atom, XA_ATOM, lst, num);
+}
+
+/*
+ * 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 *lst,
+ unsigned int len)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_xid_get(win, atom, XA_ATOM, lst, len);
+}
+
+/*
+ * 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 **plst)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_xid_list_get(win, atom, XA_ATOM, plst);
+}
+
+/*
+ * 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)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_xid_list_change(win, atom, XA_ATOM, item, op);
+}
+
+/*
+ * Set Window (array) property
+ */
+EAPI void
+ecore_x_window_prop_window_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Window *lst,
+ unsigned int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_xid_set(win, atom, XA_WINDOW, lst, num);
+}
+
+/*
+ * 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 *lst,
+ unsigned int len)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_xid_get(win, atom, XA_WINDOW, lst, len);
+}
+
+/*
+ * 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 **plst)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_xid_list_get(win, atom, XA_WINDOW, plst);
+}
+
+EAPI Ecore_X_Atom
+ecore_x_window_prop_any_type(void)
+{
+ return AnyPropertyType;
+}
+
+/**
+ * @brief Set a property of Ecore_X_Window.
+ * @param win The window for which the property will be set.
+ * @param property The property of the window to be set.
+ * @param type The type of the property that will be set.
+ * @param size The size of the property that will be set.
+ * @param data The data of the property that will be set.
+ * @param number The size of data.
+ */
+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 number)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0)
+ win = DefaultRootWindow(_ecore_x_disp);
+
+ if (size != 32)
+ XChangeProperty(_ecore_x_disp,
+ win,
+ property,
+ type,
+ size,
+ PropModeReplace,
+ (unsigned char *)data,
+ number);
+ else
+ {
+ unsigned long *dat;
+ int i, *ptr;
+
+ dat = malloc(sizeof(unsigned long) * number);
+ if (dat)
+ {
+ for (ptr = (int *)data, i = 0; i < number; i++)
+ dat[i] = ptr[i];
+ XChangeProperty(_ecore_x_disp, win, property, type, size,
+ PropModeReplace, (unsigned char *)dat, number);
+ free(dat);
+ }
+ }
+}
+
+/**
+ * @brief Get a property of Ecore_X_Window.
+ * @note If there aren't any data to be got the function return NULL.
+ * If the function can't allocate the memory then 0 is returned.
+ * @param win The window for which the property will be got.
+ * @param property The property of the window that will be gotten.
+ * @param type The type of the property that will be gotten.
+ * @param size This parameter isn't in use.
+ * @param data The data of the property that will be gotten.
+ * @param num The size of property.
+ * @return size_ret The size of array that contains the property.
+ */
+EAPI int
+ecore_x_window_prop_property_get(Ecore_X_Window win,
+ Ecore_X_Atom property,
+ Ecore_X_Atom type,
+ int size EINA_UNUSED,
+ unsigned char **data,
+ int *num)
+{
+ Atom type_ret = 0;
+ int ret, size_ret = 0;
+ unsigned long num_ret = 0, bytes = 0, i;
+ unsigned char *prop_ret = NULL;
+
+ /* make sure these are initialized */
+ if (num)
+ *num = 0;
+
+ if (data)
+ *data = NULL;
+ else /* we can't store the retrieved data, so just return */
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!win)
+ win = DefaultRootWindow(_ecore_x_disp);
+
+ ret = XGetWindowProperty(_ecore_x_disp, win, property, 0, LONG_MAX,
+ False, type, &type_ret, &size_ret,
+ &num_ret, &bytes, &prop_ret);
+
+ if (ret != Success)
+ return 0;
+
+ if (!num_ret)
+ {
+ XFree(prop_ret);
+ return 0;
+ }
+
+ if (!(*data = malloc(num_ret * size_ret / 8)))
+ {
+ XFree(prop_ret);
+ return 0;
+ }
+
+ switch (size_ret) {
+ case 8:
+ for (i = 0; i < num_ret; i++)
+ (*data)[i] = prop_ret[i];
+ break;
+
+ case 16:
+ for (i = 0; i < num_ret; i++)
+ ((unsigned short *)*data)[i] = ((unsigned short *)prop_ret)[i];
+ break;
+
+ case 32:
+ for (i = 0; i < num_ret; i++)
+ ((unsigned int *)*data)[i] = ((unsigned long *)prop_ret)[i];
+ break;
+ }
+
+ XFree(prop_ret);
+
+ if (num)
+ *num = num_ret;
+
+ return size_ret;
+}
+
+EAPI void
+ecore_x_window_prop_property_del(Ecore_X_Window win,
+ Ecore_X_Atom property)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XDeleteProperty(_ecore_x_disp, win, property);
+}
+
+EAPI Ecore_X_Atom *
+ecore_x_window_prop_list(Ecore_X_Window win,
+ int *num_ret)
+{
+ Ecore_X_Atom *atoms;
+ Atom *atom_ret;
+ int num = 0, i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num_ret)
+ *num_ret = 0;
+
+ atom_ret = XListProperties(_ecore_x_disp, win, &num);
+ if (!atom_ret)
+ return NULL;
+
+ atoms = malloc(num * sizeof(Ecore_X_Atom));
+ if (atoms)
+ {
+ for (i = 0; i < num; i++)
+ atoms[i] = atom_ret[i];
+ if (num_ret)
+ *num_ret = num;
+ }
+
+ XFree(atom_ret);
+ return atoms;
+}
+
+/**
+ * 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)
+{
+ XTextProperty xtp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0)
+ win = DefaultRootWindow(_ecore_x_disp);
+
+ xtp.value = (unsigned char *)str;
+ xtp.format = 8;
+ xtp.encoding = ECORE_X_ATOM_UTF8_STRING;
+ xtp.nitems = strlen(str);
+ XSetTextProperty(_ecore_x_disp, win, &xtp, type);
+}
+
+/**
+ * Get a window string property.
+ * @param win The window
+ * @param type The property
+ * @return Window string property of a window. String must be free'd when done.
+ */
+EAPI char *
+ecore_x_window_prop_string_get(Ecore_X_Window win,
+ Ecore_X_Atom type)
+{
+ XTextProperty xtp;
+ char *str = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0)
+ win = DefaultRootWindow(_ecore_x_disp);
+
+ if (XGetTextProperty(_ecore_x_disp, win, &xtp, type))
+ {
+ int items;
+ char **list = NULL;
+ Status s;
+
+ if (xtp.encoding == ECORE_X_ATOM_UTF8_STRING)
+ str = strdup((char *)xtp.value);
+ else
+ {
+#ifdef X_HAVE_UTF8_STRING
+ s = Xutf8TextPropertyToTextList(_ecore_x_disp, &xtp,
+ &list, &items);
+#else /* ifdef X_HAVE_UTF8_STRING */
+ s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp,
+ &list, &items);
+#endif /* ifdef X_HAVE_UTF8_STRING */
+ 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);
+ }
+
+ XFree(xtp.value);
+ }
+
+ return str;
+}
+
+EAPI Eina_Bool
+ecore_x_window_prop_protocol_isset(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol)
+{
+ Atom proto, *protos = NULL;
+ int i, protos_count = 0;
+ Eina_Bool ret = EINA_FALSE;
+
+ /* check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ proto = _ecore_x_atoms_wm_protocols[protocol];
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ return ret;
+
+ for (i = 0; i < protos_count; i++)
+ if (protos[i] == proto)
+ {
+ ret = EINA_TRUE;
+ break;
+ }
+
+ XFree(protos);
+
+ return ret;
+}
+
+/**
+ * @brief Get a array containing the protocols of @a win
+ * @note If there aren't any properties to be counted or any protocols to get
+ * then the function returns NULL.
+ * @param win The window for which protocol list will be got.
+ * @param num_ret Contains the number of elements of the array to be returned.
+ * @return The array that contains the protocols.
+ */
+EAPI Ecore_X_WM_Protocol *
+ecore_x_window_prop_protocol_list_get(Ecore_X_Window win,
+ int *num_ret)
+{
+ Atom *protos = NULL;
+ int i, protos_count = 0;
+ Ecore_X_WM_Protocol *prot_ret = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ return NULL;
+
+ if ((!protos) || (protos_count <= 0))
+ return NULL;
+
+ prot_ret = calloc(1, protos_count * sizeof(Ecore_X_WM_Protocol));
+ if (!prot_ret)
+ {
+ XFree(protos);
+ return NULL;
+ }
+
+ for (i = 0; i < protos_count; i++)
+ {
+ Ecore_X_WM_Protocol j;
+
+ prot_ret[i] = -1;
+ for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++)
+ {
+ if (_ecore_x_atoms_wm_protocols[j] == protos[i])
+ prot_ret[i] = j;
+ }
+ }
+ XFree(protos);
+ *num_ret = protos_count;
+ return prot_ret;
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_window_shape.c b/src/lib/ecore_x/xlib/ecore_x_window_shape.c
new file mode 100644
index 0000000000..71718cfa3a
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_window_shape.c
@@ -0,0 +1,658 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+/**
+ * @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 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__);
+ XShapeCombineMask(_ecore_x_disp, win, ShapeBounding, 0, 0, mask, ShapeSet);
+}
+
+/**
+ * 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 ShapeInput
+ XShapeCombineMask(_ecore_x_disp, win, ShapeInput, 0, 0, mask, ShapeSet);
+#else /* ifdef ShapeInput */
+ return;
+ win = mask = 0;
+#endif /* ifdef ShapeInput */
+}
+
+EAPI void
+ecore_x_window_shape_window_set(Ecore_X_Window win,
+ Ecore_X_Window shape_win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineShape(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ 0,
+ 0,
+ shape_win,
+ ShapeBounding,
+ ShapeSet);
+}
+
+EAPI void
+ecore_x_window_shape_input_window_set(Ecore_X_Window win,
+ Ecore_X_Window shape_win)
+{
+#ifdef ShapeInput
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineShape(_ecore_x_disp,
+ win,
+ ShapeInput,
+ 0,
+ 0,
+ shape_win,
+ ShapeInput,
+ ShapeSet);
+#else
+ return;
+ win = 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__);
+ XShapeCombineShape(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ x,
+ y,
+ shape_win,
+ ShapeBounding,
+ ShapeSet);
+}
+
+EAPI void
+ecore_x_window_shape_input_window_set_xy(Ecore_X_Window win,
+ Ecore_X_Window shape_win,
+ int x,
+ int y)
+{
+#ifdef ShapeInput
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineShape(_ecore_x_disp,
+ win,
+ ShapeInput,
+ x,
+ y,
+ shape_win,
+ ShapeInput,
+ ShapeSet);
+#else
+ return;
+ win = shape_win = x = y = 0;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_rectangle_set(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ 0,
+ 0,
+ &rect,
+ 1,
+ ShapeSet,
+ Unsorted);
+}
+
+EAPI void
+ecore_x_window_shape_input_rectangle_set(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+#ifdef ShapeInput
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeInput,
+ 0,
+ 0,
+ &rect,
+ 1,
+ ShapeSet,
+ Unsorted);
+#else
+ return;
+ win = x = y = w = h = 0;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_rectangles_set(Ecore_X_Window win,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+#ifdef ShapeInput
+ XRectangle *rect = NULL;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!rects) return;
+ if (num > 0)
+ {
+ rect = malloc(sizeof(XRectangle) * num);
+ if (!rect) return;
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ 0,
+ 0,
+ rect,
+ num,
+ ShapeSet,
+ Unsorted);
+ if (rect) free(rect);
+#else
+ return;
+ win = rects = num = 0;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+#ifdef ShapeInput
+ XRectangle *rect = NULL;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!rects) return;
+ if (num > 0)
+ {
+ rect = malloc(sizeof(XRectangle) * num);
+ if (!rect) return;
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeInput,
+ 0,
+ 0,
+ rect,
+ num,
+ ShapeSet,
+ Unsorted);
+ if (rect) free(rect);
+#else
+ return;
+ win = rects = num = 0;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_rectangle_subtract(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ 0,
+ 0,
+ &rect,
+ 1,
+ ShapeSubtract,
+ Unsorted);
+}
+
+EAPI void
+ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+#ifdef ShapeInput
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeInput,
+ 0,
+ 0,
+ &rect,
+ 1,
+ ShapeSubtract,
+ Unsorted);
+#else
+ return;
+ win = x = y = w = h = 0;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_window_add(Ecore_X_Window win,
+ Ecore_X_Window shape_win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineShape(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ 0,
+ 0,
+ shape_win,
+ ShapeBounding,
+ ShapeUnion);
+}
+
+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__);
+ XShapeCombineShape(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ x,
+ y,
+ shape_win,
+ ShapeBounding,
+ ShapeUnion);
+}
+
+EAPI void
+ecore_x_window_shape_input_window_add_xy(Ecore_X_Window win,
+ Ecore_X_Window shape_win,
+ int x,
+ int y)
+{
+#ifdef ShapeInput
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineShape(_ecore_x_disp,
+ win,
+ ShapeInput,
+ x,
+ y,
+ shape_win,
+ ShapeInput,
+ ShapeUnion);
+#else
+ return;
+ win = shape_win = x = y = 0;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_rectangle_add(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ 0,
+ 0,
+ &rect,
+ 1,
+ ShapeUnion,
+ Unsorted);
+}
+
+EAPI void
+ecore_x_window_shape_input_rectangle_add(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+#ifdef ShapeInput
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeInput,
+ 0,
+ 0,
+ &rect,
+ 1,
+ ShapeUnion,
+ Unsorted);
+#else
+ return;
+ win = x = y = w = h = 0;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_rectangle_clip(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ 0,
+ 0,
+ &rect,
+ 1,
+ ShapeIntersect,
+ Unsorted);
+}
+
+EAPI void
+ecore_x_window_shape_input_rectangle_clip(Ecore_X_Window win,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+#ifdef ShapeInput
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeInput,
+ 0,
+ 0,
+ &rect,
+ 1,
+ ShapeIntersect,
+ Unsorted);
+#else
+ return;
+ win = x = y = w = h = 0;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_rectangles_add(Ecore_X_Window win,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+ XRectangle *rect = NULL;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num > 0)
+ {
+ rect = malloc(sizeof(XRectangle) * num);
+ if (!rect) return;
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeBounding,
+ 0,
+ 0,
+ rect,
+ num,
+ ShapeUnion,
+ Unsorted);
+ if (rect) free(rect);
+}
+
+EAPI void
+ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+#ifdef ShapeInput
+ XRectangle *rect = NULL;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num > 0)
+ {
+ rect = malloc(sizeof(XRectangle) * num);
+ if (!rect) return;
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+
+ XShapeCombineRectangles(_ecore_x_disp,
+ win,
+ ShapeInput,
+ 0,
+ 0,
+ rect,
+ num,
+ ShapeUnion,
+ Unsorted);
+ if (rect) free(rect);
+#else
+ return;
+ win = rects = num = 0;
+#endif
+}
+
+EAPI Ecore_X_Rectangle *
+ecore_x_window_shape_rectangles_get(Ecore_X_Window win,
+ int *num_ret)
+{
+ XRectangle *rect;
+ Ecore_X_Rectangle *rects = NULL;
+ int i, num = 0, ord;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect = XShapeGetRectangles(_ecore_x_disp, win, ShapeBounding, &num, &ord);
+ if (rect)
+ {
+ if (num < 1)
+ {
+ XFree(rect);
+ if (num_ret) *num_ret = 0;
+ return NULL;
+ }
+ rects = malloc(sizeof(Ecore_X_Rectangle) * num);
+ if (!rects)
+ {
+ XFree(rect);
+ if (num_ret) *num_ret = 0;
+ return NULL;
+ }
+ for (i = 0; i < num; i++)
+ {
+ rects[i].x = rect[i].x;
+ rects[i].y = rect[i].y;
+ rects[i].width = rect[i].width;
+ rects[i].height = rect[i].height;
+ }
+ XFree(rect);
+ }
+ if (num_ret) *num_ret = num;
+ return rects;
+}
+
+EAPI Ecore_X_Rectangle *
+ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win,
+ int *num_ret)
+{
+ Ecore_X_Rectangle *rects = NULL;
+#ifdef ShapeInput
+ XRectangle *rect;
+ int i, num = 0, ord;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect = XShapeGetRectangles(_ecore_x_disp, win, ShapeInput, &num, &ord);
+ if (rect)
+ {
+ if (num < 1)
+ {
+ XFree(rect);
+ if (num_ret) *num_ret = 0;
+ return NULL;
+ }
+ rects = malloc(sizeof(Ecore_X_Rectangle) * num);
+ if (!rects)
+ {
+ XFree(rect);
+ if (num_ret) *num_ret = 0;
+ return NULL;
+ }
+ for (i = 0; i < num; i++)
+ {
+ rects[i].x = rect[i].x;
+ rects[i].y = rect[i].y;
+ rects[i].width = rect[i].width;
+ rects[i].height = rect[i].height;
+ }
+ XFree(rect);
+ }
+ if (num_ret) *num_ret = num;
+ return rects;
+#else
+ // have to return fake shape input rect of size of window
+ Window dw;
+ unsigned int di;
+
+ if (num_ret) *num_ret = 0;
+ rects = malloc(sizeof(Ecore_X_Rectangle));
+ if (!rects) return NULL;
+ if (!XGetGeometry(_ecore_x_disp, win, &dw,
+ &(rects[0].x), &(rects[0].y),
+ &(rects[0].width), &(rects[0].height),
+ &di, &di))
+ {
+ free(rects);
+ return NULL;
+ }
+ if (num_ret) *num_ret = 1;
+ return rects;
+#endif
+}
+
+EAPI void
+ecore_x_window_shape_events_select(Ecore_X_Window win,
+ Eina_Bool on)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (on)
+ XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
+ else
+ XShapeSelectInput(_ecore_x_disp, win, 0);
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_xi2.c b/src/lib/ecore_x/xlib/ecore_x_xi2.c
new file mode 100644
index 0000000000..04d1023ec7
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_xi2.c
@@ -0,0 +1,336 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+#ifdef ECORE_XI2
+#include "Ecore_Input.h"
+#endif /* ifdef ECORE_XI2 */
+
+int _ecore_x_xi2_opcode = -1;
+
+#ifndef XIPointerEmulated
+#define XIPointerEmulated (1 << 16)
+#endif
+
+#ifdef ECORE_XI2
+static XIDeviceInfo *_ecore_x_xi2_devs = NULL;
+static int _ecore_x_xi2_num = 0;
+#endif /* ifdef ECORE_XI2 */
+
+void
+_ecore_x_input_init(void)
+{
+#ifdef ECORE_XI2
+ int event, error;
+ int major = 2, minor = 0;
+
+ if (!XQueryExtension(_ecore_x_disp, "XInputExtension",
+ &_ecore_x_xi2_opcode, &event, &error))
+ {
+ _ecore_x_xi2_opcode = -1;
+ return;
+ }
+
+ if (XIQueryVersion(_ecore_x_disp, &major, &minor) == BadRequest)
+ {
+ _ecore_x_xi2_opcode = -1;
+ return;
+ }
+
+ _ecore_x_xi2_devs = XIQueryDevice(_ecore_x_disp, XIAllDevices,
+ &_ecore_x_xi2_num);
+#endif /* ifdef ECORE_XI2 */
+}
+
+void
+_ecore_x_input_shutdown(void)
+{
+#ifdef ECORE_XI2
+ if (_ecore_x_xi2_devs)
+ {
+ XIFreeDeviceInfo(_ecore_x_xi2_devs);
+ _ecore_x_xi2_devs = NULL;
+ }
+
+ _ecore_x_xi2_num = 0;
+ _ecore_x_xi2_opcode = -1;
+#endif /* ifdef ECORE_XI2 */
+}
+
+void
+_ecore_x_input_handler(XEvent *xevent)
+{
+#ifdef ECORE_XI2
+ XIDeviceEvent *evd = (XIDeviceEvent *)(xevent->xcookie.data);
+ /* XIRawEvent *evr = (XIRawEvent *)(xevent->xcookie.data); */
+ int devid = evd->deviceid;
+ int i;
+
+ /* No filter for this events */
+ switch (xevent->xcookie.evtype)
+ {
+#ifdef XI_RawButtonPress
+ case XI_RawButtonPress:
+ ecore_event_add(ECORE_X_RAW_BUTTON_PRESS, NULL, NULL, NULL);
+ break;
+#endif
+#ifdef XI_RawButtonRelease
+ case XI_RawButtonRelease:
+ ecore_event_add(ECORE_X_RAW_BUTTON_RELEASE, NULL, NULL, NULL);
+ break;
+#endif
+#ifdef XI_RawMotion
+ case XI_RawMotion:
+ ecore_event_add(ECORE_X_RAW_MOTION, NULL, NULL, NULL);
+ break;
+#endif
+ }
+
+ if (_ecore_x_xi2_devs)
+ {
+ for (i = 0; i < _ecore_x_xi2_num; i++)
+ {
+ XIDeviceInfo *dev = &(_ecore_x_xi2_devs[i]);
+
+ if (devid == dev->deviceid)
+ {
+ if (dev->use == XIMasterPointer) return;
+ if ((dev->use == XISlavePointer) &&
+ (evd->flags & XIPointerEmulated)) return;
+ }
+ }
+ }
+ switch (xevent->xcookie.evtype)
+ {
+ case XI_Motion:
+ _ecore_mouse_move
+ (evd->time,
+ 0, // state
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y,
+ evd->event,
+ (evd->child ? evd->child : evd->event),
+ evd->root,
+ 1, // same_screen
+ devid, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y);
+ break;
+
+ case XI_ButtonPress:
+ _ecore_mouse_button
+ (ECORE_EVENT_MOUSE_BUTTON_DOWN,
+ evd->time,
+ 0, // state
+ 0, // button
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y,
+ evd->event,
+ (evd->child ? evd->child : evd->event),
+ evd->root,
+ 1, // same_screen
+ devid, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y);
+ break;
+
+ case XI_ButtonRelease:
+ _ecore_mouse_button
+ (ECORE_EVENT_MOUSE_BUTTON_UP,
+ evd->time,
+ 0, // state
+ 0, // button
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y,
+ evd->event,
+ (evd->child ? evd->child : evd->event),
+ evd->root,
+ 1, // same_screen
+ devid, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y);
+ break;
+
+#ifdef XI_TouchUpdate
+ case XI_TouchUpdate:
+ _ecore_mouse_move
+ (evd->time,
+ 0, // state
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y,
+ evd->event,
+ (evd->child ? evd->child : evd->event),
+ evd->root,
+ 1, // same_screen
+ devid, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y);
+ break;
+
+#endif
+#ifdef XI_TouchBegin
+ case XI_TouchBegin:
+ _ecore_mouse_button
+ (ECORE_EVENT_MOUSE_BUTTON_DOWN,
+ evd->time,
+ 0, // state
+ 0, // button
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y,
+ evd->event,
+ (evd->child ? evd->child : evd->event),
+ evd->root,
+ 1, // same_screen
+ devid, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y);
+ break;
+
+#endif
+#ifdef XI_TouchEnd
+ case XI_TouchEnd:
+ _ecore_mouse_button
+ (ECORE_EVENT_MOUSE_BUTTON_UP,
+ evd->time,
+ 0, // state
+ 0, // button
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y,
+ evd->event,
+ (evd->child ? evd->child : evd->event),
+ evd->root,
+ 1, // same_screen
+ devid, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y);
+ break;
+
+#endif
+ default:
+ break;
+ }
+#endif /* ifdef ECORE_XI2 */
+}
+
+EAPI Eina_Bool
+ecore_x_input_multi_select(Ecore_X_Window win)
+{
+#ifdef ECORE_XI2
+ int i;
+ Eina_Bool find = EINA_FALSE;
+
+ if (!_ecore_x_xi2_devs)
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ for (i = 0; i < _ecore_x_xi2_num; i++)
+ {
+ XIDeviceInfo *dev = &(_ecore_x_xi2_devs[i]);
+
+ if (dev->use == XIFloatingSlave)
+ {
+ XIEventMask eventmask;
+ unsigned char mask[4] = { 0 };
+
+ eventmask.deviceid = dev->deviceid;
+ eventmask.mask_len = sizeof(mask);
+ eventmask.mask = mask;
+ XISetMask(mask, XI_ButtonPress);
+ XISetMask(mask, XI_ButtonRelease);
+ XISetMask(mask, XI_Motion);
+ XISelectEvents(_ecore_x_disp, win, &eventmask, 1);
+ find = EINA_TRUE;
+ }
+ else if (dev->use == XISlavePointer)
+ {
+ XIDeviceInfo *atdev = NULL;
+ int j;
+
+ for (j = 0; j < _ecore_x_xi2_num; j++)
+ {
+ if (_ecore_x_xi2_devs[j].deviceid == dev->attachment)
+ atdev = &(_ecore_x_xi2_devs[j]);
+ }
+ if (((atdev) && (atdev->use != XIMasterPointer)) ||
+ (!atdev))
+ {
+ XIEventMask eventmask;
+ unsigned char mask[4] = { 0 };
+
+ eventmask.deviceid = dev->deviceid;
+ eventmask.mask_len = sizeof(mask);
+ eventmask.mask = mask;
+ XISetMask(mask, XI_ButtonPress);
+ XISetMask(mask, XI_ButtonRelease);
+ XISetMask(mask, XI_Motion);
+# ifdef XI_TouchUpdate
+ XISetMask(mask, XI_TouchUpdate);
+# endif
+# ifdef XI_TouchBegin
+ XISetMask(mask, XI_TouchBegin);
+# endif
+# ifdef XI_TouchEnd
+ XISetMask(mask, XI_TouchEnd);
+# endif
+ XISelectEvents(_ecore_x_disp, win, &eventmask, 1);
+ find = EINA_TRUE;
+ }
+ }
+ }
+
+ return find;
+#else /* ifdef ECORE_XI2 */
+ return EINA_FALSE;
+#endif /* ifdef ECORE_XI2 */
+}
+
+EAPI Eina_Bool
+ecore_x_input_raw_select(Ecore_X_Window win)
+{
+#ifdef ECORE_XI2
+ XIEventMask emask;
+ unsigned char mask[4] = { 0 };
+
+ if (!_ecore_x_xi2_devs)
+ return EINA_FALSE;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ emask.deviceid = XIAllMasterDevices;
+ emask.mask_len = sizeof(mask);
+ emask.mask = mask;
+#ifdef XI_RawButtonPress
+ XISetMask(emask.mask, XI_RawButtonPress);
+#endif
+#ifdef XI_RawButtonRelease
+ XISetMask(emask.mask, XI_RawButtonRelease);
+#endif
+#ifdef XI_RawMotion
+ XISetMask(emask.mask, XI_RawMotion);
+#endif
+
+ XISelectEvents(_ecore_x_disp, win, &emask, 1);
+
+ return EINA_TRUE;
+#else
+ return EINA_FALSE;
+#endif
+}
+
diff --git a/src/lib/ecore_x/xlib/ecore_x_xinerama.c b/src/lib/ecore_x/xlib/ecore_x_xinerama.c
new file mode 100644
index 0000000000..f49a4d348f
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_xinerama.c
@@ -0,0 +1,91 @@
+/*
+ * Xinerama code
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+#ifdef ECORE_XINERAMA
+static XineramaScreenInfo *_xin_info = NULL;
+static int _xin_scr_num = 0;
+#endif /* ifdef ECORE_XINERAMA */
+
+EAPI int
+ecore_x_xinerama_screen_count_get(void)
+{
+#ifdef ECORE_XINERAMA
+ int event_base, error_base;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (_xin_info)
+ XFree(_xin_info);
+
+ _xin_info = NULL;
+ if (XineramaQueryExtension(_ecore_x_disp, &event_base, &error_base))
+ {
+ _xin_info = XineramaQueryScreens(_ecore_x_disp, &_xin_scr_num);
+ if (_xin_info)
+ return _xin_scr_num;
+ }
+
+#endif /* ifdef ECORE_XINERAMA */
+ return 0;
+}
+
+EAPI Eina_Bool
+ecore_x_xinerama_screen_geometry_get(int screen,
+ int *x,
+ int *y,
+ int *w,
+ int *h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+#ifdef ECORE_XINERAMA
+ if (_xin_info)
+ {
+ int i;
+
+ for (i = 0; i < _xin_scr_num; i++)
+ {
+ if (_xin_info[i].screen_number == screen)
+ {
+ if (x)
+ *x = _xin_info[i].x_org;
+
+ if (y)
+ *y = _xin_info[i].y_org;
+
+ if (w)
+ *w = _xin_info[i].width;
+
+ if (h)
+ *h = _xin_info[i].height;
+
+ return EINA_TRUE;
+ }
+ }
+ }
+
+#endif /* ifdef ECORE_XINERAMA */
+ if (x)
+ *x = 0;
+
+ if (y)
+ *y = 0;
+
+ if (w)
+ *w = DisplayWidth(_ecore_x_disp, 0);
+
+ if (h)
+ *h = DisplayHeight(_ecore_x_disp, 0);
+
+ return EINA_FALSE;
+ screen = 0;
+}
+