Ecore_Wayland: Refactor all the ecore_wayland code to improve running
authordevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 28 Feb 2012 21:55:51 +0000 (21:55 +0000)
committerdevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 28 Feb 2012 21:55:51 +0000 (21:55 +0000)
EFL applications as Wayland Clients.

NB: This (along with the ecore_evas changes) fixes most (if not all)
outstanding issues what I am aware of, including the nasty resize bug
with wayland_egl.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@68515 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore_wayland/Ecore_Wayland.h
src/lib/ecore_wayland/Makefile.am
src/lib/ecore_wayland/ecore_wl.c
src/lib/ecore_wayland/ecore_wl_dnd.c [new file with mode: 0644]
src/lib/ecore_wayland/ecore_wl_input.c [new file with mode: 0644]
src/lib/ecore_wayland/ecore_wl_output.c [new file with mode: 0644]
src/lib/ecore_wayland/ecore_wl_private.h
src/lib/ecore_wayland/ecore_wl_window.c [new file with mode: 0644]

index 2d04cff..ca048b2 100644 (file)
@@ -3,6 +3,10 @@
 
 # include <Eina.h>
 # include <wayland-client.h>
+# include <wayland-egl.h> // NB: already includes wayland-client.h
+# include <GL/gl.h>
+# include <EGL/egl.h>
+# include <EGL/eglext.h>
 
 # ifdef EAPI
 #  undef EAPI
 #  define EAPI
 # endif
 
+typedef enum _Ecore_Wl_Window_Type Ecore_Wl_Window_Type;
+typedef enum _Ecore_Wl_Window_Buffer_Type Ecore_Wl_Window_Buffer_Type;
+
+typedef struct _Ecore_Wl_Display Ecore_Wl_Display;
+typedef struct _Ecore_Wl_Output Ecore_Wl_Output;
+typedef struct _Ecore_Wl_Input Ecore_Wl_Input;
+# ifndef _ECORE_WAYLAND_WINDOW_PREDEF
+typedef struct _Ecore_Wl_Window Ecore_Wl_Window;
+# endif
+typedef struct _Ecore_Wl_Dnd_Source Ecore_Wl_Dnd_Source;
+typedef struct _Ecore_Wl_Dnd_Target Ecore_Wl_Dnd_Target;
+
 typedef struct _Ecore_Wl_Event_Mouse_In Ecore_Wl_Event_Mouse_In;
 typedef struct _Ecore_Wl_Event_Mouse_Out Ecore_Wl_Event_Mouse_Out;
 typedef struct _Ecore_Wl_Event_Focus_In Ecore_Wl_Event_Focus_In;
 typedef struct _Ecore_Wl_Event_Focus_Out Ecore_Wl_Event_Focus_Out;
+typedef struct _Ecore_Wl_Event_Window_Configure Ecore_Wl_Event_Window_Configure;
+typedef struct _Ecore_Wl_Event_Dnd_Enter Ecore_Wl_Event_Dnd_Enter;
+typedef struct _Ecore_Wl_Event_Dnd_Position Ecore_Wl_Event_Dnd_Position;
+typedef struct _Ecore_Wl_Event_Dnd_Leave Ecore_Wl_Event_Dnd_Leave;
+typedef struct _Ecore_Wl_Event_Dnd_Drop Ecore_Wl_Event_Dnd_Drop;
 
-typedef struct _Ecore_Wl_Drag_Source Ecore_Wl_Drag_Source;
+enum _Ecore_Wl_Window_Type
+{
+   ECORE_WL_WINDOW_TYPE_TOPLEVEL,
+   ECORE_WL_WINDOW_TYPE_FULLSCREEN,
+   ECORE_WL_WINDOW_TYPE_MAXIMIZED,
+   ECORE_WL_WINDOW_TYPE_TRANSIENT,
+   ECORE_WL_WINDOW_TYPE_MENU,
+   ECORE_WL_WINDOW_TYPE_CUSTOM
+};
 
-typedef struct _Ecore_Wl_Event_Drag_Start Ecore_Wl_Event_Drag_Start;
-typedef struct _Ecore_Wl_Event_Drag_Stop Ecore_Wl_Event_Drag_Stop;
+enum _Ecore_Wl_Window_Buffer_Type
+{
+   ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW,
+   ECORE_WL_WINDOW_BUFFER_TYPE_EGL_IMAGE,
+   ECORE_WL_WINDOW_BUFFER_TYPE_SHM
+};
 
-struct _Ecore_Wl_Event_Mouse_In 
+struct _Ecore_Wl_Display
 {
-   int modifiers;
-   int x, y;
+   struct 
+     {
+        struct wl_display *display;
+        struct wl_compositor *compositor;
+        struct wl_shell *shell;
+        struct wl_shm *shm;
+        struct wl_data_device_manager *data_device_manager;
+     } wl;
 
    struct 
      {
-        int x, y;
-     } root;
+        EGLDisplay display;
+        EGLConfig rgb_config;
+        EGLConfig argb_config;
+        EGLContext rgb_context;
+        EGLContext argb_context;
+     } egl;
+
+   int fd;
+   unsigned int mask;
+   Ecore_Fd_Handler *fd_hdl;
+
+   struct wl_list inputs;
+   struct wl_list outputs;
+
+   struct xkb_desc *xkb;
+
+   Ecore_Wl_Output *output;
+
+   PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
+   PFNEGLCREATEIMAGEKHRPROC create_image;
+   PFNEGLDESTROYIMAGEKHRPROC destroy_image;
+
+   void (*output_configure)(Ecore_Wl_Output *output, void *data);
+   void *data;
+};
+
+struct _Ecore_Wl_Output
+{
+   Ecore_Wl_Display *display;
+   struct wl_output *output;
+   Eina_Rectangle allocation;
+   struct wl_list link;
+
+   void (*destroy) (Ecore_Wl_Output *output, void *data);
+   void *data;
+};
+
+struct _Ecore_Wl_Input
+{
+   Ecore_Wl_Display *display;
+   struct wl_input_device *input_device;
+   struct wl_data_device *data_device;
+
+   Ecore_Wl_Window *pointer_focus;
+   Ecore_Wl_Window *keyboard_focus;
+
+   unsigned int button;
+   unsigned int timestamp;
+   unsigned int modifiers;
+   int sx, sy;
+
+   struct wl_list link;
+
+   /* TODO: grab */
+   unsigned int grab_button;
+
+   Ecore_Wl_Dnd_Source *drag_source;
+   Ecore_Wl_Dnd_Source *selection_source;
+};
+
+struct _Ecore_Wl_Window
+{
+   Ecore_Wl_Display *display;
+   Ecore_Wl_Window *parent;
+
+   struct wl_surface *surface;
+   struct wl_shell_surface *shell_surface;
+
+   int id;
+   int x, y;
+   int edges;
+
+   Eina_Rectangle allocation, pending_allocation;
+   Eina_Rectangle saved_allocation, server_allocation;
+
+   Eina_Bool redraw_scheduled : 1;
+   Eina_Bool resize_scheduled : 1;
+   Eina_Bool transparent : 1;
+
+   Ecore_Wl_Window_Type type;
+   Ecore_Wl_Window_Buffer_Type buffer_type;
 
-   unsigned int window;
+   Ecore_Wl_Input *pointer_device;
+   Ecore_Wl_Input *keyboard_device;
 
-   unsigned int time;
+   void *data;
 };
 
-struct _Ecore_Wl_Event_Mouse_Out 
+struct _Ecore_Wl_Event_Mouse_In
 {
    int modifiers;
    int x, y;
+   struct 
+     {
+        int x, y;
+     } root;
+   unsigned int win;
+   unsigned int event_win;
+   unsigned int root_win;
+   unsigned int timestamp;
+};
 
+struct _Ecore_Wl_Event_Mouse_Out
+{
+   int modifiers;
+   int x, y;
    struct 
      {
         int x, y;
      } root;
+   unsigned int win;
+   unsigned int event_win;
+   unsigned int root_win;
+   unsigned int timestamp;
+};
 
-   unsigned int window;
+struct _Ecore_Wl_Event_Focus_In
+{
+   unsigned int win;
+   unsigned int timestamp;
+};
 
-   unsigned int time;
+struct _Ecore_Wl_Event_Focus_Out
+{
+   unsigned int win;
+   unsigned int timestamp;
 };
 
-struct _Ecore_Wl_Event_Focus_In 
+struct _Ecore_Wl_Event_Window_Configure
 {
-   unsigned int window;
-   /* TODO: mode & detail */
-   unsigned int time;
+   unsigned int win;
+   unsigned int event_win;
+   int x, y, w, h;
+   unsigned int timestamp;
 };
 
-struct _Ecore_Wl_Event_Focus_Out 
+struct _Ecore_Wl_Event_Dnd_Enter
 {
-   unsigned int window;
-   /* TODO: mode & detail */
-   unsigned int time;
+   unsigned int win, source;
+   char **types;
+   int num_types;
+   struct 
+     {
+        int x, y;
+     } position;
 };
 
-struct _Ecore_Wl_Event_Drag_Start
+struct _Ecore_Wl_Event_Dnd_Position
 {
-   struct wl_data_device *device;
-   struct wl_surface *surface;
-   const char *mime_type;
-   uint32_t timestamp;
+   unsigned int win, source;
+   struct 
+     {
+        int x, y;
+     } position;
 };
 
-struct _Ecore_Wl_Event_Drag_Stop
+struct _Ecore_Wl_Event_Dnd_Leave
 {
+   unsigned int win, source;
+};
 
+struct _Ecore_Wl_Event_Dnd_Drop
+{
+   unsigned int win, source;
+   struct 
+     {
+        int x, y;
+     } position;
 };
 
 /**
@@ -95,30 +254,37 @@ struct _Ecore_Wl_Event_Drag_Stop
  * @li @ref Ecore_Wl_Init_Group
  */
 
+EAPI extern int ECORE_WL_EVENT_MOUSE_IN;
+EAPI extern int ECORE_WL_EVENT_MOUSE_OUT;
+EAPI extern int ECORE_WL_EVENT_FOCUS_IN;
+EAPI extern int ECORE_WL_EVENT_FOCUS_OUT;
+EAPI extern int ECORE_WL_EVENT_WINDOW_CONFIGURE;
+EAPI extern int ECORE_WL_EVENT_DND_ENTER;
+EAPI extern int ECORE_WL_EVENT_DND_POSITION;
+EAPI extern int ECORE_WL_EVENT_DND_LEAVE;
+EAPI extern int ECORE_WL_EVENT_DND_DROP;
+
 EAPI int ecore_wl_init(const char *name);
 EAPI int ecore_wl_shutdown(void);
-
-EAPI struct wl_display *ecore_wl_display_get(void);
-EAPI struct wl_shm *ecore_wl_shm_get(void);
-EAPI struct wl_compositor *ecore_wl_compositor_get(void);
-EAPI struct wl_shell *ecore_wl_shell_get(void);
-EAPI struct wl_input_device *ecore_wl_input_device_get(void);
-EAPI void ecore_wl_screen_size_get(int *w, int *h);
-EAPI unsigned int ecore_wl_format_get(void);
 EAPI void ecore_wl_flush(void);
 EAPI void ecore_wl_sync(void);
-EAPI void ecore_wl_pointer_xy_get(int *x, int *y);
-EAPI unsigned int ecore_wl_input_timestamp_get(void);
-
-EAPI Ecore_Wl_Drag_Source *ecore_wl_drag_source_create(int hotspot_x, int hotspot_y, int offset_x, int offset_y, const char *mimetype, unsigned int timestamp, void *data);
-EAPI void ecore_wl_drag_start(Ecore_Wl_Drag_Source *source, struct wl_surface *surface, struct wl_buffer *buffer);
-EAPI void ecore_wl_drag_stop(void);
+EAPI struct wl_shm *ecore_wl_shm_get(void);
+EAPI struct wl_display *ecore_wl_display_get(void);
+EAPI void ecore_wl_screen_size_get(int *w, int *h);
 
-EAPI extern int ECORE_WL_EVENT_MOUSE_IN;
-EAPI extern int ECORE_WL_EVENT_MOUSE_OUT;
-EAPI extern int ECORE_WL_EVENT_FOCUS_IN;
-EAPI extern int ECORE_WL_EVENT_FOCUS_OUT;
-EAPI extern int ECORE_WL_EVENT_DRAG_START;
-EAPI extern int ECORE_WL_EVENT_DRAG_STOP;
+EAPI Ecore_Wl_Window *ecore_wl_window_new(Ecore_Wl_Window *parent, int x, int y, int w, int h, int buffer_type);
+EAPI void ecore_wl_window_free(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y);
+EAPI void ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location);
+EAPI void ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h);
+EAPI void ecore_wl_window_buffer_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer, int x, int y);
+EAPI void ecore_wl_window_show(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_hide(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_raise(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_maximized_set(Ecore_Wl_Window *win, Eina_Bool maximized);
+EAPI void ecore_wl_window_fullscreen_set(Ecore_Wl_Window *win, Eina_Bool fullscreen);
+EAPI void ecore_wl_window_update_size(Ecore_Wl_Window *win, int w, int h);
+EAPI struct wl_surface *ecore_wl_window_surface_get(Ecore_Wl_Window *win);
+EAPI Ecore_Wl_Window *ecore_wl_window_find(unsigned int id);
 
 #endif
index ea005b2..f6b801d 100644 (file)
@@ -14,9 +14,11 @@ includes_HEADERS = Ecore_Wayland.h
 includesdir = $(includedir)/ecore-@VMAJ@
 
 libecore_wayland_la_SOURCES = \
-ecore_wl.c
-
-## ecore_wl_window.c
+ecore_wl.c \
+ecore_wl_output.c \
+ecore_wl_input.c \
+ecore_wl_window.c \
+ecore_wl_dnd.c
 
 libecore_wayland_la_LIBADD = \
 $(top_builddir)/src/lib/ecore/libecore.la \
index df25ee4..9b28ab4 100644 (file)
@@ -1,16 +1,11 @@
 #ifdef HAVE_CONFIG_H
-# include "config.h"
+# include <config.h>
 #endif
 
-#include "Ecore.h"
-#include "ecore_private.h"
-#include "Ecore_Input.h"
-#include "ecore_wl_private.h"
-#include "Ecore_Wayland.h"
+#include <fcntl.h>
 
 /* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... 
  *        What about other OSs ?? */
-#include <fcntl.h>
 #ifdef __linux__
 # include <linux/input.h>
 #else
 # define BTN_BACK 0x116
 #endif
 
-#include <xkbcommon/xkbcommon.h>
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Input.h"
+#include "ecore_wl_private.h"
+#include "Ecore_Wayland.h"
 
 /* local function prototypes */
-static Eina_Bool _ecore_wl_shutdown(Eina_Bool close_display);
-static void _ecore_wl_cb_disp_handle_global(struct wl_display *disp, uint32_t id, const char *interface, uint32_t version __UNUSED__, void *data __UNUSED__);
-static int _ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__);
-static void _ecore_wl_cb_disp_handle_geometry(void *data __UNUSED__, struct wl_output *output __UNUSED__, int x, int y, int pw __UNUSED__, int ph __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__);
-static void _ecore_wl_cb_disp_handle_mode(void *data __UNUSED__, struct wl_output *output __UNUSED__, uint32_t flags, int w, int h, int refresh __UNUSED__);
-static Eina_Bool _ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__);
-static void _ecore_wl_cb_handle_motion(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, int32_t sx, int32_t sy);
-static void _ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state);
-static void _ecore_wl_cb_handle_key(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, uint32_t key, uint32_t state);
-static void _ecore_wl_cb_handle_pointer_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, struct wl_surface *surface, int32_t sx, int32_t sy);
-static void _ecore_wl_cb_handle_keyboard_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, struct wl_surface *surface, struct wl_array *keys);
-static void _ecore_wl_cb_handle_touch_down(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__, uint32_t timestamp, struct wl_surface *surface, int32_t id, int32_t x, int32_t y);
-static void _ecore_wl_cb_handle_touch_up(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__, uint32_t timestamp, int32_t id);
-static void _ecore_wl_cb_handle_touch_motion(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__, uint32_t timestamp, int32_t id, int32_t x, int32_t y);
-static void _ecore_wl_cb_handle_touch_frame(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__);
-static void _ecore_wl_cb_handle_touch_cancel(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__);
-static void _ecore_wl_cb_source_target(void *data, struct wl_data_source *source __UNUSED__, const char *mime_type __UNUSED__);
-static void _ecore_wl_cb_source_send(void *data, struct wl_data_source *source, const char *mime_type, int32_t fd);
-static void _ecore_wl_cb_source_cancelled(void *data, struct wl_data_source *source __UNUSED__);
-static void _ecore_wl_cb_source_offer(void *data, struct wl_data_offer *offer __UNUSED__, const char *type);
-static void _ecore_wl_cb_data_offer(void *data, struct wl_data_device *data_dev, uint32_t id);
-static void _ecore_wl_cb_data_enter(void *data __UNUSED__, struct wl_data_device *data_dev, uint32_t timestamp, struct wl_surface *surface, int32_t x, int32_t y, struct wl_data_offer *offer);
-static void _ecore_wl_cb_data_leave(void *data __UNUSED__, struct wl_data_device *data_dev);
-static void _ecore_wl_cb_data_motion(void *data __UNUSED__, struct wl_data_device *data_dev, uint32_t timestamp, int32_t x, int32_t y);
-static void _ecore_wl_cb_data_drop(void *data __UNUSED__, struct wl_data_device *data_dev);
-static void _ecore_wl_cb_data_selection(void *data, struct wl_data_device *data_dev, struct wl_data_offer *offer);
-static void _ecore_wl_cb_mouse_move_free(void *data __UNUSED__, void *event);
-
-static void _ecore_wl_mouse_move_send(uint32_t timestamp);
-static void _ecore_wl_mouse_out_send(struct wl_surface *surface, uint32_t timestamp);
-static void _ecore_wl_mouse_in_send(struct wl_surface *surface, uint32_t timestamp);
-static void _ecore_wl_mouse_up_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp);
-static void _ecore_wl_mouse_down_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp);
-static void _ecore_wl_focus_out_send(struct wl_surface *surface, uint32_t timestamp);
-static void _ecore_wl_focus_in_send(struct wl_surface *surface, uint32_t timestamp);
+static Eina_Bool _ecore_wl_shutdown(Eina_Bool close);
+static int _ecore_wl_cb_event_mask_update(unsigned int mask, void *data);
+static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl __UNUSED__);
+static void _ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char *interface, unsigned int version __UNUSED__, void *data);
+static Eina_Bool _ecore_wl_egl_init(Ecore_Wl_Display *ewd);
+static Eina_Bool _ecore_wl_egl_shutdown(Ecore_Wl_Display *ewd);
+static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd);
+static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd);
 
 /* local variables */
 static int _ecore_wl_init_count = 0;
-static struct wl_display *_ecore_wl_disp = NULL;
-static uint32_t _ecore_wl_disp_mask = 0;
-static uint32_t _ecore_wl_disp_format = WL_SHM_FORMAT_ARGB8888;
-static Eina_Rectangle _ecore_wl_screen;
-static Ecore_Fd_Handler *_ecore_wl_fd_hdl = NULL;
-static int _ecore_wl_screen_x = 0;
-static int _ecore_wl_screen_y = 0;
-static int _ecore_wl_surface_x = 0;
-static int _ecore_wl_surface_y = 0;
-static int _ecore_wl_touch_x = 0;
-static int _ecore_wl_touch_y = 0;
-static int _ecore_wl_input_modifiers = 0;
-static struct xkb_desc *_ecore_wl_xkb = NULL;
-static uint32_t _ecore_wl_input_button = 0;
-static uint32_t _ecore_wl_input_timestamp = 0;
-
-static struct wl_compositor *_ecore_wl_comp = NULL;
-static struct wl_shm *_ecore_wl_shm = NULL;
-static struct wl_shell *_ecore_wl_shell = NULL;
-static struct wl_output *_ecore_wl_output = NULL;
-static struct wl_input_device *_ecore_wl_input_dev = NULL;
-static struct wl_surface *_ecore_wl_input_surface = NULL;
-static struct wl_surface *_ecore_wl_touch_surface = NULL;
-static struct wl_data_device_manager *_ecore_wl_data_manager = NULL;
-static struct wl_data_device *_ecore_wl_data_dev = NULL;
-
-static const struct wl_output_listener _ecore_wl_output_listener = 
-{
-   _ecore_wl_cb_disp_handle_geometry, 
-   _ecore_wl_cb_disp_handle_mode
-};
-static const struct wl_input_device_listener _ecore_wl_input_listener = 
-{
-   _ecore_wl_cb_handle_motion, 
-   _ecore_wl_cb_handle_button, 
-   _ecore_wl_cb_handle_key, 
-   _ecore_wl_cb_handle_pointer_focus, 
-   _ecore_wl_cb_handle_keyboard_focus, 
-   _ecore_wl_cb_handle_touch_down, 
-   _ecore_wl_cb_handle_touch_up, 
-   _ecore_wl_cb_handle_touch_motion, 
-   _ecore_wl_cb_handle_touch_frame, 
-   _ecore_wl_cb_handle_touch_cancel,
-};
-static const struct wl_data_source_listener _ecore_wl_source_listener = 
-{
-   _ecore_wl_cb_source_target, 
-   _ecore_wl_cb_source_send, 
-   _ecore_wl_cb_source_cancelled
-};
-static const struct wl_data_device_listener _ecore_wl_data_listener = 
-{
-   _ecore_wl_cb_data_offer, 
-   _ecore_wl_cb_data_enter, 
-   _ecore_wl_cb_data_leave, 
-   _ecore_wl_cb_data_motion, 
-   _ecore_wl_cb_data_drop, 
-   _ecore_wl_cb_data_selection
-};
-static const struct wl_data_offer_listener _ecore_wl_offer_listener = 
-{
-   _ecore_wl_cb_source_offer,
-};
 
 /* external variables */
 int _ecore_wl_log_dom = -1;
+Ecore_Wl_Display *_ecore_wl_disp = NULL;
+
 EAPI int ECORE_WL_EVENT_MOUSE_IN = 0;
 EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0;
 EAPI int ECORE_WL_EVENT_FOCUS_IN = 0;
 EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0;
-EAPI int ECORE_WL_EVENT_DRAG_START = 0;
-EAPI int ECORE_WL_EVENT_DRAG_STOP = 0;
-
+EAPI int ECORE_WL_EVENT_WINDOW_CONFIGURE = 0;
+EAPI int ECORE_WL_EVENT_DND_ENTER = 0;
+EAPI int ECORE_WL_EVENT_DND_POSITION = 0;
+EAPI int ECORE_WL_EVENT_DND_LEAVE = 0;
+EAPI int ECORE_WL_EVENT_DND_DROP = 0;
+
+/**
+ * @defgroup Ecore_Wl_Init_Group Wayland Library Init and Shutdown Functions
+ * 
+ * Functions that start and shutdown the Ecore Wayland Library.
+ */
+
+/**
+ * Initialize the Wayland 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_Wl_Init_Group
+ */
 EAPI int 
-ecore_wl_init(const char *name) 
+ecore_wl_init(const char *name)
 {
-   struct xkb_rule_names xkb_names;
-   int fd = 0;
-
-   if (++_ecore_wl_init_count != 1)
-     return _ecore_wl_init_count;
-
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
+   if (++_ecore_wl_init_count != 1) return _ecore_wl_init_count;
+
    if (!eina_init()) return --_ecore_wl_init_count;
 
    _ecore_wl_log_dom = 
      eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR);
-   if (_ecore_wl_log_dom < 0) 
+   if (_ecore_wl_log_dom < 0)
      {
-        EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland.");
+        EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland");
         eina_shutdown();
         return --_ecore_wl_init_count;
      }
 
-   if (!ecore_init()) 
+   if (!ecore_init())
      {
+        ERR("Could not initialize ecore");
         eina_log_domain_unregister(_ecore_wl_log_dom);
         _ecore_wl_log_dom = -1;
         eina_shutdown();
         return --_ecore_wl_init_count;
      }
 
-   if (!ecore_event_init()) 
+   if (!ecore_event_init())
      {
+        ERR("Could not initialize ecore_event");
         eina_log_domain_unregister(_ecore_wl_log_dom);
         _ecore_wl_log_dom = -1;
         ecore_shutdown();
@@ -176,26 +104,22 @@ ecore_wl_init(const char *name)
         return --_ecore_wl_init_count;
      }
 
-   if (!ECORE_WL_EVENT_MOUSE_IN) 
+   if (!ECORE_WL_EVENT_MOUSE_IN)
      {
         ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new();
         ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new();
         ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new();
         ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new();
-        ECORE_WL_EVENT_DRAG_START = ecore_event_type_new();
-        ECORE_WL_EVENT_DRAG_STOP = ecore_event_type_new();
+        ECORE_WL_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
+        ECORE_WL_EVENT_DND_ENTER = ecore_event_type_new();
+        ECORE_WL_EVENT_DND_POSITION = ecore_event_type_new();
+        ECORE_WL_EVENT_DND_LEAVE = ecore_event_type_new();
+        ECORE_WL_EVENT_DND_DROP = ecore_event_type_new();
      }
 
-   /* init xkb */
-   /* FIXME: Somehow make this portable to other languages/countries */
-   xkb_names.rules = "evdev";
-   xkb_names.model = "evdev";
-   xkb_names.layout = "us";
-   xkb_names.variant = "";
-   xkb_names.options = "";
-   if (!(_ecore_wl_xkb = xkb_compile_keymap_from_rules(&xkb_names))) 
+   if (!(_ecore_wl_disp = malloc(sizeof(Ecore_Wl_Display))))
      {
-        ERR("Could not compile keymap");
+        ERR("Could not allocate memory for Ecore_Wl_Display structure");
         eina_log_domain_unregister(_ecore_wl_log_dom);
         _ecore_wl_log_dom = -1;
         ecore_event_shutdown();
@@ -204,10 +128,11 @@ ecore_wl_init(const char *name)
         return --_ecore_wl_init_count;
      }
 
-   /* connect to the wayland display */
-   if (!(_ecore_wl_disp = wl_display_connect(name))) 
+   memset(_ecore_wl_disp, 0, sizeof(Ecore_Wl_Display));
+
+   if (!(_ecore_wl_disp->wl.display = wl_display_connect(name)))
      {
-        ERR("Could not connect to display");
+        ERR("Could not connect to Wayland display");
         eina_log_domain_unregister(_ecore_wl_log_dom);
         _ecore_wl_log_dom = -1;
         ecore_event_shutdown();
@@ -216,23 +141,28 @@ ecore_wl_init(const char *name)
         return --_ecore_wl_init_count;
      }
 
-   /* setup handler for wayland interfaces */
-   wl_display_add_global_listener(_ecore_wl_disp
-                                  _ecore_wl_cb_disp_handle_global, NULL);
+   _ecore_wl_disp->fd = 
+     wl_display_get_fd(_ecore_wl_disp->wl.display
+                       _ecore_wl_cb_event_mask_update, _ecore_wl_disp);
 
-   /* process connection events */
-   wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
+   _ecore_wl_disp->fd_hdl = 
+     ecore_main_fd_handler_add(_ecore_wl_disp->fd, ECORE_FD_READ, 
+                               _ecore_wl_cb_handle_data, _ecore_wl_disp, 
+                               NULL, NULL);
 
-   fd = wl_display_get_fd(_ecore_wl_disp, 
-                          _ecore_wl_cb_disp_event_mask_update, NULL);
+   wl_list_init(&_ecore_wl_disp->inputs);
+   wl_list_init(&_ecore_wl_disp->outputs);
 
-   _ecore_wl_fd_hdl = 
-     ecore_main_fd_handler_add(fd, ECORE_FD_READ, _ecore_wl_cb_fd_handle, 
-                               _ecore_wl_disp, NULL, NULL);
-   if (!_ecore_wl_fd_hdl) 
+   wl_display_add_global_listener(_ecore_wl_disp->wl.display, 
+                                  _ecore_wl_cb_handle_global, _ecore_wl_disp);
+
+   /* FIXME: Process connection events ?? */
+   /* wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_READABLE); */
+
+   if (!_ecore_wl_egl_init(_ecore_wl_disp))
      {
-        wl_display_destroy(_ecore_wl_disp);
-        _ecore_wl_disp = NULL;
+        ERR("Could not initialize EGL");
+        free(_ecore_wl_disp);
         eina_log_domain_unregister(_ecore_wl_log_dom);
         _ecore_wl_log_dom = -1;
         ecore_event_shutdown();
@@ -241,1015 +171,302 @@ ecore_wl_init(const char *name)
         return --_ecore_wl_init_count;
      }
 
-   return _ecore_wl_init_count;
-}
+   _ecore_wl_disp->image_target_texture_2d = 
+     (void *)eglGetProcAddress("glEGLImageTargetTexture2DOES");
+   _ecore_wl_disp->create_image = 
+     (void *)eglGetProcAddress("eglCreateImageKHR");
+   _ecore_wl_disp->destroy_image = 
+     (void *)eglGetProcAddress("eglDestroyImageKHR");
 
-EAPI int 
-ecore_wl_shutdown(void) 
-{
-   return _ecore_wl_shutdown(EINA_TRUE);
-}
+   /* TODO: create pointer surfaces */
 
-EAPI struct wl_display *
-ecore_wl_display_get(void) 
-{
-   return _ecore_wl_disp;
-}
+   if (!_ecore_wl_xkb_init(_ecore_wl_disp))
+     {
+        ERR("Could not initialize XKB");
+        _ecore_wl_egl_shutdown(_ecore_wl_disp);
+        free(_ecore_wl_disp);
+        eina_log_domain_unregister(_ecore_wl_log_dom);
+        _ecore_wl_log_dom = -1;
+        ecore_event_shutdown();
+        ecore_shutdown();
+        eina_shutdown();
+        return --_ecore_wl_init_count;
+     }
 
-EAPI struct wl_shm *
-ecore_wl_shm_get(void) 
-{
-   return _ecore_wl_shm;
-}
+   _ecore_wl_window_init();
 
-EAPI struct wl_compositor *
-ecore_wl_compositor_get(void) 
-{
-   return _ecore_wl_comp;
+   return _ecore_wl_init_count;
 }
 
-EAPI struct wl_shell *
-ecore_wl_shell_get(void) 
+/**
+ * Shuts down the Ecore Wayland Library
+ * 
+ * In shutting down the library, the Wayland 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_Wl_Init_Group
+ */
+EAPI int 
+ecore_wl_shutdown(void)
 {
-   return _ecore_wl_shell;
-}
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-EAPI struct wl_input_device *
-ecore_wl_input_device_get(void) 
-{
-   return _ecore_wl_input_dev;
+   return _ecore_wl_shutdown(EINA_TRUE);
 }
 
 EAPI void 
-ecore_wl_screen_size_get(int *w, int *h) 
+ecore_wl_flush(void)
 {
-   if (w) *w = _ecore_wl_screen.w;
-   if (h) *h = _ecore_wl_screen.h;
-}
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-EAPI unsigned int 
-ecore_wl_format_get(void) 
-{
-   return _ecore_wl_disp_format;
-}
+   while (_ecore_wl_disp->mask & WL_DISPLAY_WRITABLE)
+     wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_WRITABLE);
 
-EAPI void 
-ecore_wl_flush(void) 
-{
-   wl_display_flush(_ecore_wl_disp);
+//   wl_display_flush(_ecore_wl_disp->wl.display); // old flush code
 }
 
 EAPI void 
-ecore_wl_sync(void) 
+ecore_wl_sync(void)
 {
-   wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
-}
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-EAPI void 
-ecore_wl_pointer_xy_get(int *x, int *y) 
-{
-   if (x) *x = _ecore_wl_screen_x;
-   if (y) *y = _ecore_wl_screen_y;
+   wl_display_roundtrip(_ecore_wl_disp->wl.display);
+   // old sync code
+//   wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_READABLE);
 }
 
-EAPI unsigned int 
-ecore_wl_input_timestamp_get(void)
-{
-   return _ecore_wl_input_timestamp;
-}
-
-EAPI Ecore_Wl_Drag_Source *
-ecore_wl_drag_source_create(int hotspot_x, int hotspot_y, int offset_x, int offset_y, const char *mimetype, unsigned int timestamp, void *data)
+EAPI struct wl_shm *
+ecore_wl_shm_get(void)
 {
-   Ecore_Wl_Drag_Source *source;
-
-   if (!(source = calloc(1, sizeof(Ecore_Wl_Drag_Source)))) return NULL;
-
-   source->data_dev = _ecore_wl_data_dev;
-   source->hotspot_x = hotspot_x;
-   source->hotspot_y = hotspot_y;
-   source->offset_x = offset_x;
-   source->offset_y = offset_y;
-   source->mimetype = mimetype;
-   source->timestamp = timestamp;
-   source->data = data;
-
-   source->data_source = 
-     wl_data_device_manager_create_data_source(_ecore_wl_data_manager);
-
-   wl_data_source_add_listener(source->data_source, 
-                               &_ecore_wl_source_listener, source);
-
-   wl_data_source_offer(source->data_source, source->mimetype);
-
-   /* NB: Do we add some default mimetypes here ?? */
-   /* text/plain, etc */
-
-   return source;
+   return _ecore_wl_disp->wl.shm;
 }
 
-EAPI void 
-ecore_wl_drag_start(Ecore_Wl_Drag_Source *source, struct wl_surface *surface, struct wl_buffer *buffer)
+EAPI struct wl_display *
+ecore_wl_display_get(void)
 {
-   source->buffer = buffer;
-
-   wl_data_device_start_drag(source->data_dev, source->data_source, 
-                             surface, surface, source->timestamp);
+   return _ecore_wl_disp->wl.display;
 }
 
 EAPI void 
-ecore_wl_drag_stop(void)
+ecore_wl_screen_size_get(int *w, int *h)
 {
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
+   if (w) *w = _ecore_wl_disp->output->allocation.w;
+   if (h) *h = _ecore_wl_disp->output->allocation.h;
 }
 
 /* local functions */
 static Eina_Bool 
-_ecore_wl_shutdown(Eina_Bool close_display) 
+_ecore_wl_shutdown(Eina_Bool close)
 {
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-   if (--_ecore_wl_init_count != 0)
-     return _ecore_wl_init_count;
-
+   if (--_ecore_wl_init_count != 0) return _ecore_wl_init_count;
    if (!_ecore_wl_disp) return _ecore_wl_init_count;
 
-   if (_ecore_wl_xkb) free(_ecore_wl_xkb);
+   _ecore_wl_window_shutdown();
 
-   if (_ecore_wl_fd_hdl) ecore_main_fd_handler_del(_ecore_wl_fd_hdl);
-   _ecore_wl_fd_hdl = NULL;
+   if (_ecore_wl_disp->fd_hdl) 
+     ecore_main_fd_handler_del(_ecore_wl_disp->fd_hdl);
 
-   if (close_display
+   if (close) 
      {
-        if (_ecore_wl_data_dev) wl_data_device_destroy(_ecore_wl_data_dev);
-        if (_ecore_wl_input_dev) wl_input_device_destroy(_ecore_wl_input_dev);
-        if (_ecore_wl_data_manager) 
-          wl_data_device_manager_destroy(_ecore_wl_data_manager);
-        if (_ecore_wl_shell) wl_shell_destroy(_ecore_wl_shell);
-        if (_ecore_wl_shm) wl_shm_destroy(_ecore_wl_shm);
-        if (_ecore_wl_comp) wl_compositor_destroy(_ecore_wl_comp);
-        if (_ecore_wl_disp)
+        Ecore_Wl_Output *out, *tout;
+        Ecore_Wl_Input *in, *tin;
+
+        wl_list_for_each_safe(out, tout, &_ecore_wl_disp->outputs, link)
+          _ecore_wl_output_del(out);
+
+        wl_list_for_each_safe(in, tin, &_ecore_wl_disp->inputs, link)
+          _ecore_wl_input_del(in);
+
+        _ecore_wl_xkb_shutdown(_ecore_wl_disp);
+        _ecore_wl_egl_shutdown(_ecore_wl_disp);
+
+        if (_ecore_wl_disp->wl.shell) 
+          wl_shell_destroy(_ecore_wl_disp->wl.shell);
+        if (_ecore_wl_disp->wl.shm) wl_shm_destroy(_ecore_wl_disp->wl.shm);
+        if (_ecore_wl_disp->wl.data_device_manager)
+          wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager);
+        if (_ecore_wl_disp->wl.compositor)
+          wl_compositor_destroy(_ecore_wl_disp->wl.compositor);
+        if (_ecore_wl_disp->wl.display)
           {
-             wl_display_flush(_ecore_wl_disp);
-             wl_display_destroy(_ecore_wl_disp);
+             wl_display_flush(_ecore_wl_disp->wl.display);
+             wl_display_destroy(_ecore_wl_disp->wl.display);
           }
-        _ecore_wl_disp = NULL;
+        free(_ecore_wl_disp);
      }
 
-   eina_log_domain_unregister(_ecore_wl_log_dom);
-   _ecore_wl_log_dom = -1;
-
    ecore_event_shutdown();
    ecore_shutdown();
+
+   eina_log_domain_unregister(_ecore_wl_log_dom);
+   _ecore_wl_log_dom = -1;
    eina_shutdown();
 
    return _ecore_wl_init_count;
 }
 
-static void 
-_ecore_wl_cb_disp_handle_global(struct wl_display *disp, uint32_t id, const char *interface, uint32_t version __UNUSED__, void *data __UNUSED__) 
-{
-//   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   if (disp != _ecore_wl_disp) return;
-   if (!strcmp(interface, "wl_compositor")) 
-     {
-        _ecore_wl_comp = 
-          wl_display_bind(_ecore_wl_disp, id, &wl_compositor_interface);
-     }
-   else if (!strcmp(interface, "wl_shm")) 
-     {
-        _ecore_wl_shm = 
-          wl_display_bind(_ecore_wl_disp, id, &wl_shm_interface);
-     }
-   else if (!strcmp(interface, "wl_output")) 
-     {
-        _ecore_wl_output = 
-          wl_display_bind(_ecore_wl_disp, id, &wl_output_interface);
-        wl_output_add_listener(_ecore_wl_output, 
-                               &_ecore_wl_output_listener, NULL);
-     }
-   else if (!strcmp(interface, "wl_shell")) 
-     {
-        _ecore_wl_shell = 
-          wl_display_bind(_ecore_wl_disp, id, &wl_shell_interface);
-     }
-   else if (!strcmp(interface, "wl_input_device")) 
-     {
-        _ecore_wl_input_dev = 
-          wl_display_bind(_ecore_wl_disp, id, &wl_input_device_interface);
-        wl_input_device_add_listener(_ecore_wl_input_dev, 
-                                     &_ecore_wl_input_listener, NULL);
-     }
-   else if (!strcmp(interface, "wl_data_device_manager")) 
-     {
-        _ecore_wl_data_manager = 
-          wl_display_bind(_ecore_wl_disp, id, 
-                          &wl_data_device_manager_interface);
-     }
-
-   if ((_ecore_wl_input_dev) && (_ecore_wl_data_manager) && (!_ecore_wl_data_dev))
-     {
-        _ecore_wl_data_dev = 
-          wl_data_device_manager_get_data_device(_ecore_wl_data_manager, 
-                                                 _ecore_wl_input_dev);
-        wl_data_device_add_listener(_ecore_wl_data_dev, 
-                                    &_ecore_wl_data_listener, NULL);
-     }
-}
-
 static int 
-_ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__) 
+_ecore_wl_cb_event_mask_update(unsigned int mask, void *data)
 {
-//   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+   Ecore_Wl_Display *ewd;
 
-   _ecore_wl_disp_mask = mask;
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
+   ewd = data;
+   ewd->mask = mask;
    return 0;
 }
 
-static void 
-_ecore_wl_cb_disp_handle_geometry(void *data __UNUSED__, struct wl_output *output __UNUSED__, int x, int y, int pw __UNUSED__, int ph __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__) 
-{
-   _ecore_wl_screen.x = x;
-   _ecore_wl_screen.y = y;
-}
-
-static void 
-_ecore_wl_cb_disp_handle_mode(void *data __UNUSED__, struct wl_output *output __UNUSED__, uint32_t flags, int w, int h, int refresh __UNUSED__) 
-{
-   if (flags & WL_OUTPUT_MODE_CURRENT) 
-     {
-        _ecore_wl_screen.w = w;
-        _ecore_wl_screen.h = h;
-     }
-}
-
 static Eina_Bool 
-_ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__) 
+_ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl __UNUSED__)
 {
-   struct wl_display *disp;
-
-//   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   if (!(disp = data)) return ECORE_CALLBACK_RENEW;
-   if (disp != _ecore_wl_disp) return ECORE_CALLBACK_RENEW;
+   Ecore_Wl_Display *ewd;
 
-   if (_ecore_wl_disp_mask & WL_DISPLAY_WRITABLE)
-     wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_WRITABLE);
-
-   if (_ecore_wl_disp_mask & WL_DISPLAY_READABLE)
-     wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
+   if (!(ewd = data)) return ECORE_CALLBACK_RENEW;
+   wl_display_iterate(ewd->wl.display, ewd->mask);
    return ECORE_CALLBACK_RENEW;
 }
 
 static void 
-_ecore_wl_cb_handle_motion(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, int32_t sx, int32_t sy) 
+_ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char *interface, unsigned int version __UNUSED__, void *data)
 {
-//   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   if (dev != _ecore_wl_input_dev) return;
-
-   /* _ecore_wl_screen_x = x; */
-   /* _ecore_wl_screen_y = y; */
-   _ecore_wl_surface_x = sx;
-   _ecore_wl_surface_y = sy;
-
-   _ecore_wl_mouse_move_send(t);
-}
+   Ecore_Wl_Display *ewd;
 
-static void 
-_ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state) 
-{
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-   if (dev != _ecore_wl_input_dev) return;
-
-   if ((btn >= BTN_SIDE) && (btn <= BTN_BACK))
-     {
-        Ecore_Event_Mouse_Wheel *ev;
-
-        if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return;
-
-        ev->timestamp = t;
-        ev->x = _ecore_wl_surface_x;
-        ev->y = _ecore_wl_surface_y;
-        /* ev->root.x = _ecore_wl_screen_x; */
-        /* ev->root.y = _ecore_wl_screen_y; */
-        ev->modifiers = _ecore_wl_input_modifiers;
-        ev->direction = 0;
-
-        if (_ecore_wl_input_surface) 
-          {
-             unsigned int id = 0;
-
-             if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface)))
-               {
-                  ev->window = id;
-                  ev->event_window = id;
-               }
-          }
-
-        /* NB: (FIXME) Currently Wayland provides no measure of how much the 
-         * wheel has scrolled (read: delta of movement). So for now, we will 
-         * just assume that the amount scrolled is 1 */
-        if ((btn == BTN_EXTRA) || (btn == BTN_FORWARD)) // down
-          ev->z = 1;
-        else if ((btn == BTN_SIDE) || (btn == BTN_BACK)) // up
-          ev->z = -1;
-
-        ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
-     }
-   else 
+   ewd = data;
+   if (!strcmp(interface, "wl_compositor"))
+     ewd->wl.compositor = wl_display_bind(disp, id, &wl_compositor_interface);
+   else if (!strcmp(interface, "wl_output"))
+     _ecore_wl_output_add(ewd, id);
+   else if (!strcmp(interface, "wl_input_device"))
+     _ecore_wl_input_add(ewd, id);
+   else if (!strcmp(interface, "wl_shell"))
+     ewd->wl.shell = wl_display_bind(disp, id, &wl_shell_interface);
+   else if (!strcmp(interface, "wl_shm"))
+     ewd->wl.shm = wl_display_bind(disp, id, &wl_shm_interface);
+   else if (!strcmp(interface, "wl_data_device_manager"))
      {
-        _ecore_wl_mouse_move_send(t);
-
-        if (state)
-          {
-             _ecore_wl_input_button = btn;
-             if (_ecore_wl_input_surface) 
-               _ecore_wl_mouse_down_send(_ecore_wl_input_surface, btn, t);
-
-             /* NB: Ideally, this is not the place to check for drags.
-              * IMO, drags should be handled by the client. EG: we raise the 
-              * mouse_down to the client, and the client can 'request' a 
-              * drag_start from ecore_wl */
-             if ((_ecore_wl_input_surface) || (_ecore_wl_touch_surface))
-               {
-                  /* record item which was grabbed. 
-                   * create drag source. start drag */
-               }
-          }
-        else
-          {
-             if ((_ecore_wl_input_surface) || (_ecore_wl_touch_surface))
-               {
-                  /* release grabbed button and finish drag */
-                  if ((_ecore_wl_input_button) && 
-                      (_ecore_wl_input_button == btn))
-                    {
-                       
-                    }
-               }
-             _ecore_wl_input_button = 0;
-             if (_ecore_wl_input_surface) 
-               _ecore_wl_mouse_up_send(_ecore_wl_input_surface, btn, t);
-          }
+        ewd->wl.data_device_manager = 
+          wl_display_bind(disp, id, &wl_data_device_manager_interface);
      }
 }
 
-static void 
-_ecore_wl_cb_handle_key(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, uint32_t key, uint32_t state) 
-{
-   unsigned int keycode = 0;
-
-   if ((!_ecore_wl_input_surface) || (dev != _ecore_wl_input_dev)) return;
-
-   keycode = key + _ecore_wl_xkb->min_key_code;
-
-   if (state)
-     _ecore_wl_input_modifiers |= _ecore_wl_xkb->map->modmap[keycode];
-   else
-     _ecore_wl_input_modifiers &= ~_ecore_wl_xkb->map->modmap[keycode];
-}
-
-static void 
-_ecore_wl_cb_handle_pointer_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, struct wl_surface *surface, int32_t sx, int32_t sy) 
+static Eina_Bool 
+_ecore_wl_egl_init(Ecore_Wl_Display *ewd)
 {
-   if (dev != _ecore_wl_input_dev) return;
-
-   /* NB: Wayland pointer focus is weird. It's not pointer focus in the normal 
-    * sense...Wayland 'moving/resizing' (and maybe other stuff) has a habit 
-    * of stealing the pointer focus and thus this cannot be used to control 
-    * normal pointer focus. On mouse down, the 'active' surface is stolen 
-    * by Wayland for the grab, so 'surface' here ends up being NULL. When a 
-    * move or resize is finished, we get this event again, but this time 
-    * with an active surface */
-
-   /* _ecore_wl_screen_x = x; */
-   /* _ecore_wl_screen_y = y; */
-   _ecore_wl_surface_x = sx;
-   _ecore_wl_surface_y = sy;
-
-   if ((_ecore_wl_input_surface) && (_ecore_wl_input_surface != surface)) 
+   EGLint major, minor, n;
+   static const EGLint context_attribs[] = 
      {
-        if (!_ecore_wl_input_button)
-          _ecore_wl_mouse_out_send(_ecore_wl_input_surface, t);
-     }
-
-   if (surface) 
+        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
+     };
+   static const EGLint argb_attribs[] = 
      {
-        if (_ecore_wl_input_button)
-          {
-             _ecore_wl_mouse_up_send(surface, _ecore_wl_input_button, t);
-             _ecore_wl_input_button = 0;
-          }
-        else
-          _ecore_wl_mouse_in_send(surface, t);
-     }
-}
-
-static void 
-_ecore_wl_cb_handle_keyboard_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, struct wl_surface *surface, struct wl_array *keys) 
-{
-   unsigned int *keyend = 0, *i = 0;
+        EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, 
+        EGL_ALPHA_SIZE, 1, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, 
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, 
+        EGL_WINDOW_BIT, EGL_NONE
+     };
 
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-   if (dev != _ecore_wl_input_dev) return;
-
-   /* NB: Remove old keyboard focus */
-   if ((_ecore_wl_input_surface) && (_ecore_wl_input_surface != surface))
-     _ecore_wl_focus_out_send(_ecore_wl_input_surface, t);
-
-   _ecore_wl_input_surface = NULL;
-
-   keyend = keys->data + keys->size;
-   _ecore_wl_input_modifiers = 0;
-   for (i = keys->data; i < keyend; i++)
-     _ecore_wl_input_modifiers |= _ecore_wl_xkb->map->modmap[*i];
-
-   if (surface) 
+   ewd->egl.display = eglGetDisplay(ewd->wl.display);
+   if (!eglInitialize(ewd->egl.display, &major, &minor))
      {
-        /* set new input surface */
-        _ecore_wl_input_surface = surface;
-
-        /* send mouse in to new surface */
-        /* _ecore_wl_mouse_in_send(surface, t); */
-
-        /* send focus to new surface */
-        _ecore_wl_focus_in_send(surface, t);
+        ERR("Failed to initialize EGL display");
+        return EINA_FALSE;
      }
-}
-
-static void 
-_ecore_wl_cb_handle_touch_down(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__, uint32_t timestamp, struct wl_surface *surface, int32_t id, int32_t x, int32_t y)
-{
-   Ecore_Event_Mouse_Button *ev;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   _ecore_wl_touch_surface = surface;
-   _ecore_wl_touch_x = x;
-   _ecore_wl_touch_y = y;
-
-   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
-
-   ev->timestamp = timestamp;
-
-   /* NB: Need to verify using x,y for these */
-   ev->x = x;
-   ev->y = y;
-   ev->root.x = x;
-   ev->root.y = y;
-   ev->modifiers = 0;
-   ev->buttons = 0;
-   ev->same_screen = 1;
-
-   /* FIXME: Need to get these from Wayland somehow */
-   ev->double_click = 0;
-   ev->triple_click = 0;
-
-   ev->multi.device = id;
-   ev->multi.radius = 1;
-   ev->multi.radius_x = 1;
-   ev->multi.radius_y = 1;
-   ev->multi.pressure = 1.0;
-   ev->multi.angle = 0.0;
-   /* NB: Need to verify using x,y for these */
-   ev->multi.x = x;
-   ev->multi.y = y;
-   ev->multi.root.x = x;
-   ev->multi.root.y = y;
 
+   if (!eglBindAPI(EGL_OPENGL_ES_API))
      {
-        unsigned int id = 0;
-
-        if ((id = (unsigned int)wl_surface_get_user_data(surface))) 
-          {
-             ev->window = id;
-             ev->event_window = id;
-          }
+        ERR("Failed to bind EGL Api");
+        return EINA_FALSE;
      }
 
-   ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
-}
-
-static void 
-_ecore_wl_cb_handle_touch_up(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__, uint32_t timestamp, int32_t id)
-{
-   Ecore_Event_Mouse_Button *ev;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
-
-   ev->timestamp = timestamp;
-
-   /* TODO: Need to verify using x,y for these */
-   ev->x = _ecore_wl_touch_x;
-   ev->y = _ecore_wl_touch_y;
-   ev->root.x = _ecore_wl_touch_x;
-   ev->root.y = _ecore_wl_touch_y;
-   ev->modifiers = 0;
-   ev->buttons = 0;
-   ev->same_screen = 1;
-
-   /* FIXME: Need to get these from Wayland somehow */
-   ev->double_click = 0;
-   ev->triple_click = 0;
-
-   ev->multi.device = id;
-   ev->multi.radius = 1;
-   ev->multi.radius_x = 1;
-   ev->multi.radius_y = 1;
-   ev->multi.pressure = 1.0;
-   ev->multi.angle = 0.0;
-
-   /* TODO: Need to verify using x,y for these */
-   ev->multi.x = _ecore_wl_touch_x;
-   ev->multi.y = _ecore_wl_touch_y;
-   ev->multi.root.x = _ecore_wl_touch_x;
-   ev->multi.root.y = _ecore_wl_touch_y;
-
+   if ((!eglChooseConfig(ewd->egl.display, argb_attribs, &ewd->egl.argb_config,
+                        1, &n)) || (n == 0))
      {
-        unsigned int id = 0;
-
-        if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_touch_surface))) 
-          {
-             ev->window = id;
-             ev->event_window = id;
-          }
+        ERR("Failed to choose ARGB config");
+        return EINA_FALSE;
      }
 
-   _ecore_wl_touch_surface = NULL;
-
-   ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
-}
-
-static void 
-_ecore_wl_cb_handle_touch_motion(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__, uint32_t timestamp, int32_t id, int32_t x, int32_t y)
-{
-   Ecore_Event_Mouse_Move *ev;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   if (!_ecore_wl_touch_surface) return;
-
-   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
-
-   ev->timestamp = timestamp;
-   /* TODO: Need to verify using x,y for these */
-   ev->x = x;
-   ev->y = y;
-   ev->root.x = x;
-   ev->root.y = y;
-   ev->modifiers = 0; //_ecore_wl_input_modifiers;
-   ev->same_screen = 1;
-
-   ev->multi.device = id;
-   ev->multi.radius = 1;
-   ev->multi.radius_x = 1;
-   ev->multi.radius_y = 1;
-   ev->multi.pressure = 1.0;
-   ev->multi.angle = 0.0;
-
-   /* TODO: Need to verify using x,y for these */
-   ev->multi.x = x;
-   ev->multi.y = y;
-   ev->multi.root.x = x;
-   ev->multi.root.y = y;
-
+   ewd->egl.argb_context = 
+     eglCreateContext(ewd->egl.display, ewd->egl.argb_config, 
+                      EGL_NO_CONTEXT, context_attribs);
+   if (!ewd->egl.argb_context)
      {
-        unsigned int id = 0;
-
-        if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_touch_surface)))
-          {
-             ev->window = id;
-             ev->event_window = id;
-          }
+        ERR("Failed to create ARGB context");
+        return EINA_FALSE;
      }
 
-   ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
-}
-
-static void 
-_ecore_wl_cb_handle_touch_frame(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__)
-{
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   /* FIXME: Need to get a device and actually test what happens here */
-}
-
-static void 
-_ecore_wl_cb_handle_touch_cancel(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__)
-{
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   /* FIXME: Need to get a device and actually test what happens here */
-   _ecore_wl_touch_surface = NULL;
-}
-
-static void 
-_ecore_wl_cb_source_target(void *data, struct wl_data_source *source __UNUSED__, const char *mime_type __UNUSED__)
-{
-   Ecore_Wl_Drag_Source *s;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   printf("Ecore_Wl Source Target\n");
-   if (!(s = data)) return;
-   printf("\tHave Drag Source\n");
-
-   /* FIXME: buffer here should really be the mouse cursor buffer */
-   /* wl_data_device_attach(s->data_dev, s->timestamp, s->buffer,  */
-   /*                       s->hotspot_x, s->hotspot_y); */
-}
-
-static void 
-_ecore_wl_cb_source_send(void *data, struct wl_data_source *source, const char *mime_type, int32_t fd)
-{
-   Ecore_Wl_Drag_Source *s;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   printf("Ecore_Wl Source Send\n");
-   if (!(s = data)) return;
-   printf("\tHave Drag Source\n");
-
-   /* FIXME: write message to fd */
-
-   /* NB: Wayland really sucks in this regard. Why should selection stuff 
-    * require an 'fd' ?? */
-}
-
-static void 
-_ecore_wl_cb_source_cancelled(void *data, struct wl_data_source *source __UNUSED__)
-{
-   Ecore_Wl_Drag_Source *s;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-   /* The cancelled event usually means source is no longer in use by 
-    * the drag (or selection). */
-
-   printf("Ecore_Wl Source Cancel\n");
-   if (!(s = data)) return;
-   printf("\tHave Drag Source\n");
-
-   /* FIXME: raise this to ecore_evas so the surface/buffer 
-    * of the drag can be destroyed */
-
-   if (s->data_source) wl_data_source_destroy(s->data_source);
-   s->data_source = NULL;
-
-   free(s);
-}
-
-static void 
-_ecore_wl_cb_source_offer(void *data, struct wl_data_offer *offer __UNUSED__, const char *type)
-{
-   Ecore_Wl_Dnd_Source *s;
-
-   if (!(s = data)) return;
-   eina_array_push(s->types, strdup(type));
-}
-
-static void 
-_ecore_wl_cb_data_offer(void *data, struct wl_data_device *data_dev, uint32_t id)
-{
-   Ecore_Wl_Dnd_Source *source;
-
-   /* create a new 'data offer' structure and setup a listener for it */
-   if (!(source = calloc(1, sizeof(Ecore_Wl_Dnd_Source)))) return;
-
-   source->types = eina_array_new(1);
-   source->data = data;
-   source->refs = 1;
-
-   /* FIXME: This will need to change when Wayland has typesafe wrappers for this */
-   source->offer = (struct wl_data_offer *)
-     wl_proxy_create_for_id((struct wl_proxy *)data_dev, 
-                            id, &wl_data_offer_interface);
-
-   wl_data_device_set_user_data(data_dev, source);
-   wl_data_offer_add_listener(source->offer, &_ecore_wl_offer_listener, source);
-}
-
-static void 
-_ecore_wl_cb_data_enter(void *data __UNUSED__, struct wl_data_device *data_dev, uint32_t timestamp, struct wl_surface *surface, int32_t x, int32_t y, struct wl_data_offer *offer)
-{
-   Ecore_Wl_Dnd_Source *source;
-
-   if (!(source = wl_data_device_get_user_data(data_dev))) return;
-
-   /* TODO: maybe set pointer focus here ?? */
-
-   source->timestamp = timestamp;
-}
-
-static void 
-_ecore_wl_cb_data_leave(void *data __UNUSED__, struct wl_data_device *data_dev)
-{
-   Ecore_Wl_Dnd_Source *source;
-
-   if (!(source = wl_data_device_get_user_data(data_dev))) return;
-
-   /* destroy drag offer */
-   wl_data_offer_destroy(source->offer);
-
-   while (eina_array_count(source->types))
-     free(eina_array_pop(source->types));
-
-   eina_array_free(source->types);
-   free(source);
-
-   wl_data_device_set_user_data(data_dev, NULL);
-}
-
-static void 
-_ecore_wl_cb_data_motion(void *data __UNUSED__, struct wl_data_device *data_dev, uint32_t timestamp, int32_t x, int32_t y)
-{
-   Ecore_Wl_Dnd_Source *source;
-
-   if (!(source = wl_data_device_get_user_data(data_dev))) return;
-   /* TODO: Here we should raise motion events for dragging */
-}
-
-static void 
-_ecore_wl_cb_data_drop(void *data __UNUSED__, struct wl_data_device *data_dev)
-{
-   Ecore_Wl_Dnd_Source *source;
-
-   if (!(source = wl_data_device_get_user_data(data_dev))) return;
-
-   /* TODO: Raise event for drop */
-
-   wl_data_offer_accept(source->offer, source->timestamp, NULL);
-//                        eina_array_data_get(source->types, 0));
-}
-
-static void 
-_ecore_wl_cb_data_selection(void *data, struct wl_data_device *data_dev, struct wl_data_offer *offer)
-{
-   Ecore_Wl_Dnd_Source *source;
-
-   printf("Ecore_Wl Data Selection\n");
-   if ((source = wl_data_device_get_user_data(data_dev)))
-     {
-        /* destroy old source */
-        wl_data_offer_destroy(source->offer);
-
-        while (eina_array_count(source->types))
-          free(eina_array_pop(source->types));
-
-        eina_array_free(source->types);
-        free(source);
-
-        wl_data_device_set_user_data(data_dev, NULL);
-     }
-}
-
-static void 
-_ecore_wl_cb_mouse_move_free(void *data __UNUSED__, void *event)
-{
-   Ecore_Event_Mouse_Move *ev;
-
-   if ((ev = event)) free(ev);
-}
-
-static void 
-_ecore_wl_mouse_move_send(uint32_t timestamp)
-{
-   Ecore_Event_Mouse_Move *ev;
-   Ecore_Event *event;
-
-//   if (!_ecore_wl_input_surface) return;
-
-   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
-
-   ev->timestamp = timestamp;
-
-   ev->x = _ecore_wl_surface_x;
-   ev->y = _ecore_wl_surface_y;
-   /* ev->root.x = _ecore_wl_screen_x; */
-   /* ev->root.y = _ecore_wl_screen_y; */
-   ev->modifiers = _ecore_wl_input_modifiers;
-
-   ev->multi.device = 0;
-   ev->multi.radius = 1;
-   ev->multi.radius_x = 1;
-   ev->multi.radius_y = 1;
-   ev->multi.pressure = 1.0;
-   ev->multi.angle = 0.0;
-   ev->multi.x = _ecore_wl_surface_x;
-   ev->multi.y = _ecore_wl_surface_y;
-   /* ev->multi.root.x = _ecore_wl_screen_x; */
-   /* ev->multi.root.y = _ecore_wl_screen_y; */
-
+   if (!eglMakeCurrent(ewd->egl.display, EGL_NO_SURFACE, 
+                       EGL_NO_SURFACE, ewd->egl.argb_context))
      {
-        unsigned int id = 0;
-
-        if (_ecore_wl_input_surface) 
-          {
-             LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
-             if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface)))
-               {
-                  ev->window = id;
-                  ev->event_window = id;
-               }
-          }
+        ERR("Failed to make ARGB context current");
+        return EINA_FALSE;
      }
 
-   event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, 
-                           _ecore_wl_cb_mouse_move_free, NULL);
+   return EINA_TRUE;
 }
 
-static void 
-_ecore_wl_mouse_out_send(struct wl_surface *surface, uint32_t timestamp) 
+static Eina_Bool 
+_ecore_wl_egl_shutdown(Ecore_Wl_Display *ewd)
 {
-   Ecore_Wl_Event_Mouse_Out *ev;
-
-   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_Out)))) return;
-
-   ev->x = _ecore_wl_surface_x;
-   ev->y = _ecore_wl_surface_y;
-   /* ev->root.x = _ecore_wl_screen_x; */
-   /* ev->root.y = _ecore_wl_screen_y; */
-   ev->modifiers = _ecore_wl_input_modifiers;
-   ev->time = timestamp;
-
-   if (surface) 
-     {
-        unsigned int id = 0;
-
-        if ((id = (unsigned int)wl_surface_get_user_data(surface))) 
-          ev->window = id;
-     }
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-   ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL);
-}
+   eglMakeCurrent(ewd->egl.display, 
+                  EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 
-static void 
-_ecore_wl_mouse_in_send(struct wl_surface *surface, uint32_t timestamp) 
-{
-   Ecore_Wl_Event_Mouse_In *ev;
+   eglDestroyContext(ewd->egl.display, ewd->egl.argb_context);
 
-   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) return;
+   /* NB: This is hanging when we run elm apps as wayland clients 
+    * inside the weston compositor */
 
-   ev->x = _ecore_wl_surface_x;
-   ev->y = _ecore_wl_surface_y;
-   /* ev->root.x = _ecore_wl_screen_x; */
-   /* ev->root.y = _ecore_wl_screen_y; */
-   ev->modifiers = _ecore_wl_input_modifiers;
-   ev->time = timestamp;
+   /* printf("Egl Terminate\n"); */
+   /* eglTerminate(ewd->egl.display); */
+   /* printf("Egl Terminate Done\n"); */
 
-   if (surface) 
-     {
-        unsigned int id = 0;
+   eglReleaseThread();
 
-        if ((id = (unsigned int)wl_surface_get_user_data(surface))) 
-          ev->window = id;
-     }
-
-   ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL);
+   return EINA_TRUE;
 }
 
-static void 
-_ecore_wl_mouse_up_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp)
+static Eina_Bool 
+_ecore_wl_xkb_init(Ecore_Wl_Display *ewd)
 {
-   Ecore_Event_Mouse_Button *ev;
+   struct xkb_rule_names names;
 
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
-
-   if (button == BTN_LEFT)
-     ev->buttons = 1;
-   else if (button == BTN_MIDDLE)
-     ev->buttons = 2;
-   else if (button == BTN_RIGHT)
-     ev->buttons = 3;
-
-   ev->timestamp = timestamp;
-   ev->x = _ecore_wl_surface_x;
-   ev->y = _ecore_wl_surface_y;
-   /* ev->root.x = _ecore_wl_screen_x; */
-   /* ev->root.y = _ecore_wl_screen_y; */
-   ev->modifiers = _ecore_wl_input_modifiers;
-
-   /* FIXME: Need to get these from Wayland somehow */
-   ev->double_click = 0;
-   ev->triple_click = 0;
-
-   ev->multi.device = 0;
-   ev->multi.radius = 1;
-   ev->multi.radius_x = 1;
-   ev->multi.radius_y = 1;
-   ev->multi.pressure = 1.0;
-   ev->multi.angle = 0.0;
-   ev->multi.x = _ecore_wl_surface_x;
-   ev->multi.y = _ecore_wl_surface_y;
-   /* ev->multi.root.x = _ecore_wl_screen_x; */
-   /* ev->multi.root.y = _ecore_wl_screen_y; */
+   names.rules = "evdev";
+   names.model = "evdev";
+   names.layout = "us";
+   names.variant = "";
+   names.options = "";
 
+   if (!(ewd->xkb = xkb_compile_keymap_from_rules(&names)))
      {
-        unsigned int id = 0;
-
-        if ((id = (unsigned int)wl_surface_get_user_data(surface))) 
-          {
-             ev->window = id;
-             ev->event_window = id;
-          }
+        ERR("Failed to compile keymap");
+        return EINA_FALSE;
      }
 
-   ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
+   return EINA_TRUE;
 }
 
-static void 
-_ecore_wl_mouse_down_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp)
+static Eina_Bool 
+_ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd)
 {
-   Ecore_Event_Mouse_Button *ev;
-
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
-
-   if (button == BTN_LEFT)
-     ev->buttons = 1;
-   else if (button == BTN_MIDDLE)
-     ev->buttons = 2;
-   else if (button == BTN_RIGHT)
-     ev->buttons = 3;
-
-   _ecore_wl_input_timestamp = timestamp;
-   ev->timestamp = timestamp;
-   ev->x = _ecore_wl_surface_x;
-   ev->y = _ecore_wl_surface_y;
-   /* ev->root.x = _ecore_wl_screen_x; */
-   /* ev->root.y = _ecore_wl_screen_y; */
-   ev->modifiers = _ecore_wl_input_modifiers;
-
-   /* FIXME: Need to get these from Wayland somehow */
-   ev->double_click = 0;
-   ev->triple_click = 0;
-
-   ev->multi.device = 0;
-   ev->multi.radius = 1;
-   ev->multi.radius_x = 1;
-   ev->multi.radius_y = 1;
-   ev->multi.pressure = 1.0;
-   ev->multi.angle = 0.0;
-   ev->multi.x = _ecore_wl_surface_x;
-   ev->multi.y = _ecore_wl_surface_y;
-   /* ev->multi.root.x = _ecore_wl_screen_x; */
-   /* ev->multi.root.y = _ecore_wl_screen_y; */
-
-     {
-        unsigned int id = 0;
-
-        if ((id = (unsigned int)wl_surface_get_user_data(surface))) 
-          {
-             ev->window = id;
-             ev->event_window = id;
-          }
-     }
-
-   ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
-}
-
-static void 
-_ecore_wl_focus_out_send(struct wl_surface *surface, uint32_t timestamp) 
-{
-   Ecore_Wl_Event_Focus_Out *ev;
-
-   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return;
-   ev->time = timestamp;
-   if (surface) 
-     {
-        unsigned int id = 0;
-
-        if ((id = (unsigned int)wl_surface_get_user_data(surface))) 
-          ev->window = id;
-     }
-   ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL);
-}
-
-static void 
-_ecore_wl_focus_in_send(struct wl_surface *surface, uint32_t timestamp) 
-{
-   Ecore_Wl_Event_Focus_In *ev;
-
-   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return;
-   ev->time = timestamp;
-   if (surface) 
-     {
-        unsigned int id = 0;
-
-        if ((id = (unsigned int)wl_surface_get_user_data(surface))) 
-          ev->window = id;
-     }
-   ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL);
+   if (ewd->xkb) xkb_free_keymap(ewd->xkb);
+   return EINA_TRUE;
 }
diff --git a/src/lib/ecore_wayland/ecore_wl_dnd.c b/src/lib/ecore_wayland/ecore_wl_dnd.c
new file mode 100644 (file)
index 0000000..5d81225
--- /dev/null
@@ -0,0 +1,189 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_wl_private.h"
+#include "Ecore_Wayland.h"
+
+/* local function prototypes */
+static void _ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer __UNUSED__, const char *type);
+static void _ecore_wl_dnd_cb_enter_free(void *data __UNUSED__, void *event);
+
+/* wayland listeners */
+static const struct wl_data_offer_listener _ecore_wl_data_offer_listener = 
+{
+   _ecore_wl_dnd_offer,
+};
+
+void 
+_ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device, unsigned int id)
+{
+   Ecore_Wl_Dnd_Source *source;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source)))) return;
+   wl_array_init(&source->types);
+   source->refcount = 1;
+   source->input = input;
+   /* FIXME: Change this when wayland has typesafe wrapper for it */
+   source->offer = (struct wl_data_offer *)
+     wl_proxy_create_for_id((struct wl_proxy *)data_device, 
+                            id, &wl_data_offer_interface);
+   wl_data_offer_add_listener(source->offer, 
+                              &_ecore_wl_data_offer_listener, source);
+}
+
+void 
+_ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device __UNUSED__, unsigned int timestamp __UNUSED__, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer)
+{
+   Ecore_Wl_Event_Dnd_Enter *event;
+   Ecore_Wl_Input *input;
+   Ecore_Wl_Window *win;
+   char **p;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   input->drag_source = wl_data_offer_get_user_data(offer);
+
+   win = wl_surface_get_user_data(surface);
+//   input->pointer_focus = win;
+
+   p = wl_array_add(&input->drag_source->types, sizeof(*p));
+   *p = NULL;
+
+   if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return;
+
+   event->win = win->id;
+   event->source = input->drag_source->input->keyboard_focus->id;
+   event->position.x = x;
+   event->position.y = y;
+   event->num_types = input->drag_source->types.size;
+   event->types = input->drag_source->types.data;
+
+   ecore_event_add(ECORE_WL_EVENT_DND_ENTER, event, 
+                   _ecore_wl_dnd_cb_enter_free, NULL);
+}
+
+void 
+_ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device __UNUSED__)
+{
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+   _ecore_wl_dnd_del(input->drag_source);
+   input->drag_source = NULL;
+}
+
+void 
+_ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device __UNUSED__, unsigned int timestamp __UNUSED__, int x, int y)
+{
+   Ecore_Wl_Event_Dnd_Position *event;
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   input->sx = x;
+   input->sy = y;
+
+   if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return;
+
+   event->win = input->drag_source->input->pointer_focus->id;
+   event->source = input->drag_source->input->keyboard_focus->id;
+   event->position.x = x;
+   event->position.y = y;
+
+   ecore_event_add(ECORE_WL_EVENT_DND_POSITION, event, NULL, NULL);
+}
+
+void 
+_ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device __UNUSED__)
+{
+   Ecore_Wl_Event_Dnd_Drop *event;
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return;
+
+   event->win = input->drag_source->input->pointer_focus->id;
+   event->source = input->drag_source->input->keyboard_focus->id;
+   event->position.x = input->sx;
+   event->position.y = input->sy;
+
+   ecore_event_add(ECORE_WL_EVENT_DND_DROP, event, NULL, NULL);
+}
+
+void 
+_ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device __UNUSED__, struct wl_data_offer *offer)
+{
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+   if (input->selection_source) _ecore_wl_dnd_del(input->selection_source);
+   input->selection_source = NULL;
+   if (offer)
+     {
+        char **p;
+
+        input->selection_source = wl_data_offer_get_user_data(offer);
+        p = wl_array_add(&input->selection_source->types, sizeof(*p));
+        *p = NULL;
+     }
+}
+
+void 
+_ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!source) return;
+   source->refcount--;
+   if (source->refcount == 0)
+     {
+        char **p;
+
+        wl_data_offer_destroy(source->offer);
+        for (p = source->types.data; *p; p++)
+          free(*p);
+        wl_array_release(&source->types);
+        free(source);
+     }
+}
+
+/* local functions */
+static void 
+_ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer __UNUSED__, const char *type)
+{
+   Ecore_Wl_Dnd_Source *source;
+   char **p;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(source = data)) return;
+   p = wl_array_add(&source->types, sizeof(*p));
+   *p = strdup(type);
+}
+
+static void 
+_ecore_wl_dnd_cb_enter_free(void *data __UNUSED__, void *event)
+{
+   Ecore_Wl_Event_Dnd_Enter *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(ev = event)) return;
+   free(ev);
+}
diff --git a/src/lib/ecore_wayland/ecore_wl_input.c b/src/lib/ecore_wayland/ecore_wl_input.c
new file mode 100644 (file)
index 0000000..d99c708
--- /dev/null
@@ -0,0 +1,622 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Input.h"
+#include "ecore_wl_private.h"
+#include "Ecore_Wayland.h"
+
+/* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... 
+ *        What about other OSs ?? */
+#ifdef __linux__
+# include <linux/input.h>
+#else
+# define BTN_LEFT 0x110
+# define BTN_RIGHT 0x111
+# define BTN_MIDDLE 0x112
+# define BTN_SIDE 0x113
+# define BTN_EXTRA 0x114
+# define BTN_FORWARD 0x115
+# define BTN_BACK 0x116
+#endif
+
+/* local function prototypes */
+static void _ecore_wl_input_cb_motion(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int sx, int sy);
+static void _ecore_wl_input_cb_button(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, unsigned int button, unsigned int state);
+static void _ecore_wl_input_cb_key(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp __UNUSED__, unsigned int key, unsigned int state);
+static void _ecore_wl_input_cb_pointer_focus(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface, int sx, int sy);
+static void _ecore_wl_input_cb_keyboard_focus(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface, struct wl_array *keys);
+static void _ecore_wl_input_cb_touch_down(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface __UNUSED__, int id __UNUSED__, int x, int y);
+static void _ecore_wl_input_cb_touch_up(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int id __UNUSED__);
+static void _ecore_wl_input_cb_touch_motion(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int id __UNUSED__, int x, int y);
+static void _ecore_wl_input_cb_touch_frame(void *data __UNUSED__, struct wl_input_device *input_device __UNUSED__);
+static void _ecore_wl_input_cb_touch_cancel(void *data __UNUSED__, struct wl_input_device *input_device __UNUSED__);
+static void _ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, unsigned int id);
+static void _ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer);
+static void _ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device);
+static void _ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, int x, int y);
+static void _ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device);
+static void _ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer);
+
+static void _ecore_wl_input_keyboard_focus_remove(Ecore_Wl_Input *input, unsigned int timestamp);
+static void _ecore_wl_input_pointer_focus_remove(Ecore_Wl_Input *input, unsigned int timestamp);
+static void _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, unsigned int timestamp);
+static void _ecore_wl_input_cb_mouse_move_free(void *data __UNUSED__, void *event);
+static void _ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, unsigned int timestamp);
+static void _ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, unsigned int timestamp);
+static void _ecore_wl_input_focus_in_send(Ecore_Wl_Input *input, unsigned int timestamp);
+static void _ecore_wl_input_focus_out_send(Ecore_Wl_Input *input, unsigned int timestamp);
+static void _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, unsigned int timestamp);
+static void _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, unsigned int timestamp);
+
+/* wayland interfaces */
+static const struct wl_input_device_listener _ecore_wl_input_listener = 
+{
+   _ecore_wl_input_cb_motion,
+   _ecore_wl_input_cb_button,
+   _ecore_wl_input_cb_key,
+   _ecore_wl_input_cb_pointer_focus,
+   _ecore_wl_input_cb_keyboard_focus,
+   _ecore_wl_input_cb_touch_down,
+   _ecore_wl_input_cb_touch_up,
+   _ecore_wl_input_cb_touch_motion,
+   _ecore_wl_input_cb_touch_frame,
+   _ecore_wl_input_cb_touch_cancel
+};
+
+static const struct wl_data_device_listener _ecore_wl_data_listener = 
+{
+   _ecore_wl_input_cb_data_offer,
+   _ecore_wl_input_cb_data_enter,
+   _ecore_wl_input_cb_data_leave,
+   _ecore_wl_input_cb_data_motion,
+   _ecore_wl_input_cb_data_drop,
+   _ecore_wl_input_cb_data_selection
+};
+
+void 
+_ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id)
+{
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = malloc(sizeof(Ecore_Wl_Input)))) return;
+
+   memset(input, 0, sizeof(Ecore_Wl_Input));
+
+   input->display = ewd;
+   input->pointer_focus = NULL;
+   input->keyboard_focus = NULL;
+
+   input->input_device = 
+     wl_display_bind(ewd->wl.display, id, &wl_input_device_interface);
+   wl_list_insert(ewd->inputs.prev, &input->link);
+   wl_input_device_add_listener(input->input_device, 
+                                &_ecore_wl_input_listener, input);
+   wl_input_device_set_user_data(input->input_device, input);
+
+   input->data_device = 
+     wl_data_device_manager_get_data_device(ewd->wl.data_device_manager, 
+                                            input->input_device);
+   wl_data_device_add_listener(input->data_device, 
+                               &_ecore_wl_data_listener, input);
+}
+
+void 
+_ecore_wl_input_del(Ecore_Wl_Input *input)
+{
+   if (!input) return;
+
+   _ecore_wl_input_keyboard_focus_remove(input, 0);
+   _ecore_wl_input_pointer_focus_remove(input, 0);
+
+   if (input->drag_source) _ecore_wl_dnd_del(input->drag_source);
+   input->drag_source = NULL;
+
+   if (input->selection_source) _ecore_wl_dnd_del(input->selection_source);
+   input->selection_source = NULL;
+
+   if (input->data_device) wl_data_device_destroy(input->data_device);
+   if (input->input_device) wl_input_device_destroy(input->input_device);
+   wl_list_remove(&input->link);
+   free(input);
+}
+
+/* local functions */
+static void 
+_ecore_wl_input_cb_motion(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int sx, int sy)
+{
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   input->sx = sx;
+   input->sy = sy;
+
+   /* TODO: FIXME: NB: Weston window code has set pointer image here also */
+   _ecore_wl_input_mouse_move_send(input, timestamp);
+}
+
+static void 
+_ecore_wl_input_cb_button(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, unsigned int button, unsigned int state)
+{
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   input->timestamp = timestamp;
+
+   _ecore_wl_input_mouse_move_send(input, timestamp);
+
+   if ((button >= BTN_SIDE) && (button <= BTN_BACK))
+     {
+        /* TODO: raise mouse wheel */
+        printf("Raise Mouse Wheel Event\n");
+     }
+   else
+     {
+        if (state)
+          {
+             input->button = button;
+             _ecore_wl_input_mouse_down_send(input, timestamp);
+          }
+        else
+          {
+             _ecore_wl_input_mouse_up_send(input, timestamp);
+             input->button = 0;
+          }
+     }
+}
+
+static void 
+_ecore_wl_input_cb_key(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp __UNUSED__, unsigned int key, unsigned int state)
+{
+   Ecore_Wl_Input *input;
+   Ecore_Wl_Window *win;
+   unsigned int keycode = 0;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   win = input->keyboard_focus;
+   if ((!win) || (win->keyboard_device != input)) return;
+
+   /* FIXME: NB: I believe this should be min_key_code rather than 8, 
+    * but weston code has it like this */
+   keycode = key + 8;
+
+   /* if ((input->modifiers & XKB_COMMON_SHIFT_MASK) &&  */
+   /*     (XkbKeyGroupWidth(_ecore_wl_disp->xkb, keycode, 0) > 1))  */
+   /*   level = 1; */
+   /* keysym = XkbKeySymEntry(_ecore_wl_disp->xkb, keycode, level, 0); */
+
+   if (state)
+     input->modifiers |= _ecore_wl_disp->xkb->map->modmap[keycode];
+   else
+     input->modifiers &= ~_ecore_wl_disp->xkb->map->modmap[keycode];
+}
+
+static void 
+_ecore_wl_input_cb_pointer_focus(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface, int sx, int sy)
+{
+   Ecore_Wl_Input *input;
+   Ecore_Wl_Window *win = NULL;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   input->sx = sx;
+   input->sy = sy;
+
+   _ecore_wl_input_mouse_move_send(input, timestamp);
+
+   win = input->pointer_focus;
+   if ((win) && (win->surface != surface))
+     _ecore_wl_input_pointer_focus_remove(input, timestamp);
+
+   if (surface)
+     {
+        if ((win = wl_surface_get_user_data(surface)))
+          {
+             input->pointer_focus = win;
+             win->pointer_device = input;
+          }
+        if (input->button)
+          {
+             _ecore_wl_input_mouse_up_send(input, timestamp);
+             input->button = 0;
+          }
+     }
+   else
+     _ecore_wl_input_mouse_in_send(input, timestamp);
+}
+
+static void 
+_ecore_wl_input_cb_keyboard_focus(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface, struct wl_array *keys)
+{
+   Ecore_Wl_Input *input;
+   Ecore_Wl_Window *win = NULL;
+   unsigned int *k, *end;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   win = input->keyboard_focus;
+   if ((win) && (win->surface != surface))
+     _ecore_wl_input_keyboard_focus_remove(input, timestamp);
+
+   end = keys->data + keys->size;
+   input->modifiers = 0;
+   for (k = keys->data; k < end; k++)
+     input->modifiers |= _ecore_wl_disp->xkb->map->modmap[*k];
+
+   if (surface)
+     {
+        if ((win = wl_surface_get_user_data(surface)))
+          {
+             input->keyboard_focus = win;
+             win->keyboard_device = input;
+          }
+        else
+          input->keyboard_focus = NULL;
+        _ecore_wl_input_focus_in_send(input, timestamp);
+     }
+}
+
+static void 
+_ecore_wl_input_cb_touch_down(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface __UNUSED__, int id __UNUSED__, int x, int y)
+{
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   /* FIXME: NB: Not sure yet if input->timestamp should be set here. 
+    * This needs to be tested with an actual touch device */
+   /* input->timestamp = timestamp; */
+   input->button = 0;
+   input->sx = x;
+   input->sy = y;
+   _ecore_wl_input_mouse_down_send(input, timestamp);
+}
+
+static void 
+_ecore_wl_input_cb_touch_up(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int id __UNUSED__)
+{
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   /* FIXME: NB: Not sure yet if input->timestamp should be set here. 
+    * This needs to be tested with an actual touch device */
+   /* input->timestamp = timestamp; */
+   input->button = 0;
+   _ecore_wl_input_mouse_up_send(input, timestamp);
+}
+
+static void 
+_ecore_wl_input_cb_touch_motion(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int id __UNUSED__, int x, int y)
+{
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(input = data)) return;
+
+   /* FIXME: NB: Not sure yet if input->timestamp should be set here. 
+    * This needs to be tested with an actual touch device */
+   /* input->timestamp = timestamp; */
+   input->sx = x;
+   input->sy = y;
+
+   _ecore_wl_input_mouse_move_send(input, timestamp);
+}
+
+static void 
+_ecore_wl_input_cb_touch_frame(void *data __UNUSED__, struct wl_input_device *input_device __UNUSED__)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+}
+
+static void 
+_ecore_wl_input_cb_touch_cancel(void *data __UNUSED__, struct wl_input_device *input_device __UNUSED__)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+}
+
+static void 
+_ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, unsigned int id)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   _ecore_wl_dnd_add(data, data_device, id);
+}
+
+static void 
+_ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   _ecore_wl_dnd_enter(data, data_device, timestamp, surface, x, y, offer);
+}
+
+static void 
+_ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   _ecore_wl_dnd_leave(data, data_device);
+}
+
+static void 
+_ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, int x, int y)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   _ecore_wl_dnd_motion(data, data_device, timestamp, x, y);
+}
+
+static void 
+_ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   _ecore_wl_dnd_drop(data, data_device);
+}
+
+static void 
+_ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   _ecore_wl_dnd_selection(data, data_device, offer);
+}
+
+static void 
+_ecore_wl_input_keyboard_focus_remove(Ecore_Wl_Input *input, unsigned int timestamp)
+{
+   Ecore_Wl_Window *win;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   _ecore_wl_input_focus_out_send(input, timestamp);
+   if ((win = input->keyboard_focus))
+     win->keyboard_device = NULL;
+   input->keyboard_focus = NULL;
+}
+
+static void 
+_ecore_wl_input_pointer_focus_remove(Ecore_Wl_Input *input, unsigned int timestamp)
+{
+   Ecore_Wl_Window *win;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!input->button)
+     _ecore_wl_input_mouse_out_send(input, timestamp);
+
+   if ((win = input->pointer_focus))
+     win->pointer_device = NULL;
+   input->pointer_focus = NULL;
+}
+
+static void 
+_ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, unsigned int timestamp)
+{
+   Ecore_Event_Mouse_Move *ev;
+   Ecore_Event *event;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
+
+   ev->timestamp = timestamp;
+   ev->x = input->sx;
+   ev->y = input->sy;
+   ev->modifiers = input->modifiers;
+   ev->multi.device = 0;
+   ev->multi.radius = 1;
+   ev->multi.radius_x = 1;
+   ev->multi.radius_y = 1;
+   ev->multi.pressure = 1.0;
+   ev->multi.angle = 0.0;
+   ev->multi.x = input->sx;
+   ev->multi.y = input->sy;
+
+   if (input->pointer_focus) 
+     {
+        ev->window = input->pointer_focus->id;
+        ev->event_window = input->pointer_focus->id;
+     }
+
+   event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, 
+                           _ecore_wl_input_cb_mouse_move_free, NULL);
+}
+
+static void 
+_ecore_wl_input_cb_mouse_move_free(void *data __UNUSED__, void *event)
+{
+   Ecore_Event_Mouse_Move *ev;
+
+   if ((ev = event)) free(ev);
+}
+
+static void 
+_ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, unsigned int timestamp)
+{
+   Ecore_Wl_Event_Mouse_In *ev;
+   Ecore_Event *event;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) return;
+
+   ev->x = input->sx;
+   ev->y = input->sy;
+   ev->modifiers = input->modifiers;
+   ev->timestamp = timestamp;
+
+   if (input->pointer_focus)
+     {
+        ev->win = input->pointer_focus->id;
+        ev->event_win = input->pointer_focus->id;
+     }
+
+   event = ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL);
+}
+
+static void 
+_ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, unsigned int timestamp)
+{
+   Ecore_Wl_Event_Mouse_Out *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_Out)))) return;
+
+   ev->x = input->sx;
+   ev->y = input->sy;
+   ev->modifiers = input->modifiers;
+   ev->timestamp = timestamp;
+
+   if (input->pointer_focus)
+     {
+        ev->win = input->pointer_focus->id;
+        ev->event_win = input->pointer_focus->id;
+     }
+
+   ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL);
+}
+
+static void 
+_ecore_wl_input_focus_in_send(Ecore_Wl_Input *input, unsigned int timestamp)
+{
+   Ecore_Wl_Event_Focus_In *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return;
+   ev->timestamp = timestamp;
+   if (input->keyboard_focus)
+     ev->win = input->keyboard_focus->id;
+   ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL);
+}
+
+static void 
+_ecore_wl_input_focus_out_send(Ecore_Wl_Input *input, unsigned int timestamp)
+{
+   Ecore_Wl_Event_Focus_Out *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return;
+   ev->timestamp = timestamp;
+   if (input->keyboard_focus)
+     ev->win = input->keyboard_focus->id;
+   ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL);
+}
+
+static void 
+_ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, unsigned int timestamp)
+{
+   Ecore_Event_Mouse_Button *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
+
+   if (input->button == BTN_LEFT)
+     ev->buttons = 1;
+   else if (input->button == BTN_MIDDLE)
+     ev->buttons = 2;
+   else if (input->button == BTN_RIGHT)
+     ev->buttons = 3;
+   else
+     ev->buttons = input->button;
+
+   ev->timestamp = timestamp;
+   ev->x = input->sx;
+   ev->y = input->sy;
+   ev->modifiers = input->modifiers;
+
+   /* FIXME: Need to get these from wayland somehow */
+   ev->double_click = 0;
+   ev->triple_click = 0;
+
+   ev->multi.device = 0;
+   ev->multi.radius = 1;
+   ev->multi.radius_x = 1;
+   ev->multi.radius_y = 1;
+   ev->multi.pressure = 1.0;
+   ev->multi.angle = 0.0;
+   ev->multi.x = input->sx;
+   ev->multi.y = input->sy;
+
+   if (input->pointer_focus)
+     {
+        ev->window = input->pointer_focus->id;
+        ev->event_window = input->pointer_focus->id;
+     }
+
+   /* NB: Hmmmm, smells like this could be a leak. No free function */
+   ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
+}
+
+static void 
+_ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, unsigned int timestamp)
+{
+   Ecore_Event_Mouse_Button *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
+
+   if (input->button == BTN_LEFT)
+     ev->buttons = 1;
+   else if (input->button == BTN_MIDDLE)
+     ev->buttons = 2;
+   else if (input->button == BTN_RIGHT)
+     ev->buttons = 3;
+   else
+     ev->buttons = input->button;
+
+   ev->timestamp = timestamp;
+   ev->x = input->sx;
+   ev->y = input->sy;
+   ev->modifiers = input->modifiers;
+
+   /* FIXME: Need to get these from wayland somehow */
+   ev->double_click = 0;
+   ev->triple_click = 0;
+
+   ev->multi.device = 0;
+   ev->multi.radius = 1;
+   ev->multi.radius_x = 1;
+   ev->multi.radius_y = 1;
+   ev->multi.pressure = 1.0;
+   ev->multi.angle = 0.0;
+   ev->multi.x = input->sx;
+   ev->multi.y = input->sy;
+
+   if (input->pointer_focus)
+     {
+        ev->window = input->pointer_focus->id;
+        ev->event_window = input->pointer_focus->id;
+     }
+
+   /* NB: Hmmmm, smells like this could be a leak. No free function */
+   ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
+}
diff --git a/src/lib/ecore_wayland/ecore_wl_output.c b/src/lib/ecore_wayland/ecore_wl_output.c
new file mode 100644 (file)
index 0000000..9f540d4
--- /dev/null
@@ -0,0 +1,79 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_wl_private.h"
+#include "Ecore_Wayland.h"
+
+/* local function prototypes */
+static void _ecore_wl_output_cb_geometry(void *data, struct wl_output *wl_output __UNUSED__, int x, int y, int w __UNUSED__, int h __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__);
+static void _ecore_wl_output_cb_mode(void *data, struct wl_output *wl_output __UNUSED__, unsigned int flags, int w, int h, int refresh __UNUSED__);
+
+/* wayland listeners */
+static const struct wl_output_listener _ecore_wl_output_listener = 
+{
+   _ecore_wl_output_cb_geometry,
+   _ecore_wl_output_cb_mode
+};
+
+void 
+_ecore_wl_output_add(Ecore_Wl_Display *ewd, unsigned int id)
+{
+   Ecore_Wl_Output *output;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(output = malloc(sizeof(Ecore_Wl_Output)))) return;
+
+   memset(output, 0, sizeof(Ecore_Wl_Output));
+
+   output->display = ewd;
+
+   output->output = wl_display_bind(ewd->wl.display, id, &wl_output_interface);
+   wl_list_insert(ewd->outputs.prev, &output->link);
+   wl_output_add_listener(output->output, &_ecore_wl_output_listener, output);
+}
+
+void 
+_ecore_wl_output_del(Ecore_Wl_Output *output) 
+{
+   if (!output) return;
+   if (output->destroy) (*output->destroy)(output, output->data);
+   if (output->output) wl_output_destroy(output->output);
+   wl_list_remove(&output->link);
+   free(output);
+}
+
+/* local functions */
+static void 
+_ecore_wl_output_cb_geometry(void *data, struct wl_output *wl_output __UNUSED__, int x, int y, int w __UNUSED__, int h __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__)
+{
+   Ecore_Wl_Output *output;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   output = data;
+   output->allocation.x = x;
+   output->allocation.y = y;
+}
+
+static void 
+_ecore_wl_output_cb_mode(void *data, struct wl_output *wl_output __UNUSED__, unsigned int flags, int w, int h, int refresh __UNUSED__)
+{
+   Ecore_Wl_Output *output;
+   Ecore_Wl_Display *ewd;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   output = data;
+   ewd = output->display;
+   if (flags & WL_OUTPUT_MODE_CURRENT)
+     {
+        output->allocation.w = w;
+        output->allocation.h = h;
+        _ecore_wl_disp->output = output;
+        if (ewd->output_configure) (*ewd->output_configure)(output, ewd->data);
+     }
+}
index eec5ffe..63d99f6 100644 (file)
@@ -2,8 +2,11 @@
 # define _ECORE_WAYLAND_PRIVATE_H
 
 # include <limits.h>
+# include <xkbcommon/xkbcommon.h>
 
-//# define LOGFNS 1
+# include "Ecore_Wayland.h"
+
+# define LOGFNS 1
 
 # ifdef LOGFNS
 #  include <stdio.h>
@@ -13,6 +16,7 @@
 # endif
 
 extern int _ecore_wl_log_dom;
+extern Ecore_Wl_Display *_ecore_wl_disp;
 
 # ifdef ECORE_WL_DEFAULT_LOG_COLOR
 #  undef ECORE_WL_DEFAULT_LOG_COLOR
@@ -44,42 +48,39 @@ extern int _ecore_wl_log_dom;
 # endif
 # define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_wl_log_dom, __VA_ARGS__)
 
-typedef struct _Ecore_Wl_Dnd_Source
+struct _Ecore_Wl_Dnd_Source
 {
    struct wl_data_offer *offer;
-   int refs;
-
-   Eina_Array *types;
+   Ecore_Wl_Input *input;
+   struct wl_array types;
+   int refcount;
+   int fd;
+   int x, y;
 
-   uint32_t timestamp;
+   /* TODO: task & data_func */
    void *data;
-} Ecore_Wl_Dnd_Source;
+};
 
-typedef struct _Ecore_Wl_Dnd_Target
+struct _Ecore_Wl_Dnd_Target
 {
-   /* NB: These are not the real fields for this structure, 
-    * and it is Bound to change....soon */
-   struct wl_data_offer *offer;
-   int refs;
-
-   Eina_Array *types;
+   Ecore_Wl_Dnd_Source *source;
+};
 
-   uint32_t timestamp;
-   void *data;
-} Ecore_Wl_Dnd_Target;
+void _ecore_wl_window_init(void);
+void _ecore_wl_window_shutdown(void);
 
-struct _Ecore_Wl_Drag_Source
-{
-   struct wl_data_device *data_dev;
-   struct wl_buffer *buffer;
+void _ecore_wl_output_add(Ecore_Wl_Display *ewd, unsigned int id);
+void _ecore_wl_output_del(Ecore_Wl_Output *output);
 
-   int32_t hotspot_x, hotspot_y;
-   int32_t offset_x, offset_y;
-   const char *mimetype;
-   uint32_t timestamp;
-   void *data;
+void _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id);
+void _ecore_wl_input_del(Ecore_Wl_Input *input);
 
-   struct wl_data_source *data_source;
-};
+void _ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device, unsigned int id);
+void _ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device __UNUSED__, unsigned int timestamp __UNUSED__, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer);
+void _ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device __UNUSED__);
+void _ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device __UNUSED__, unsigned int timestamp __UNUSED__, int x, int y);
+void _ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device __UNUSED__);
+void _ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device __UNUSED__, struct wl_data_offer *offer);
+void _ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source);
 
 #endif
diff --git a/src/lib/ecore_wayland/ecore_wl_window.c b/src/lib/ecore_wayland/ecore_wl_window.c
new file mode 100644 (file)
index 0000000..4fd9ba3
--- /dev/null
@@ -0,0 +1,356 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_wl_private.h"
+#include "Ecore_Wayland.h"
+
+/* local function prototypes */
+static void _ecore_wl_window_cb_configure(void *data, struct wl_shell_surface *shell_surface __UNUSED__, unsigned int timestamp, unsigned int edges, int w, int h);
+static void _ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surface __UNUSED__);
+static void _ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h, unsigned int timestamp);
+
+/* local variables */
+static Eina_Hash *_windows = NULL;
+
+/* wayland listeners */
+static const struct wl_shell_surface_listener _ecore_wl_shell_surface_listener = 
+{
+   _ecore_wl_window_cb_configure,
+   _ecore_wl_window_cb_popup_done
+};
+
+/* internal functions */
+void 
+_ecore_wl_window_init(void)
+{
+   if (!_windows) _windows = eina_hash_pointer_new(free);
+}
+
+void 
+_ecore_wl_window_shutdown(void)
+{
+   eina_hash_free(_windows);
+   _windows = NULL;
+}
+
+EAPI Ecore_Wl_Window *
+ecore_wl_window_new(Ecore_Wl_Window *parent, int x, int y, int w, int h, int buffer_type)
+{
+   Ecore_Wl_Window *win;
+   static int _win_id = 1;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(win = malloc(sizeof(Ecore_Wl_Window))))
+     {
+        ERR("Failed to allocate an Ecore Wayland Window");
+        return NULL;
+     }
+
+   memset(win, 0, sizeof(Ecore_Wl_Window));
+
+   win->display = _ecore_wl_disp;
+   win->parent = parent;
+   win->allocation.x = x;
+   win->allocation.y = y;
+   win->allocation.w = w;
+   win->allocation.h = h;
+   win->saved_allocation = win->allocation;
+   win->transparent = EINA_TRUE;
+   win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL;
+   win->buffer_type = buffer_type;
+   win->id = _win_id++;
+
+   eina_hash_add(_windows, &win->id, win);
+   return win;
+}
+
+EAPI void 
+ecore_wl_window_free(Ecore_Wl_Window *win)
+{
+   Ecore_Wl_Input *input;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+
+   eina_hash_del(_windows, &win->id, NULL);
+
+   wl_list_for_each(input, &_ecore_wl_disp->inputs, link)
+     {
+        if ((input->pointer_focus) && (input->pointer_focus == win))
+          input->pointer_focus = NULL;
+        if ((input->keyboard_focus) && (input->keyboard_focus == win))
+          input->keyboard_focus = NULL;
+     }
+
+   if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface);
+   win->shell_surface = NULL;
+
+   if (win->surface) wl_surface_destroy(win->surface);
+   win->surface = NULL;
+
+//   free(win);
+}
+
+EAPI void 
+ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   win->allocation.x = x;
+   win->allocation.y = y;
+   if (win->shell_surface)
+     {
+        Ecore_Wl_Input *input;
+
+        input = win->keyboard_device;
+        wl_shell_surface_move(win->shell_surface, input->input_device,
+                              input->timestamp);
+     }
+}
+
+EAPI void 
+ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   win->allocation.w = w;
+   win->allocation.h = h;
+   if (win->shell_surface)
+     {
+        Ecore_Wl_Input *input;
+
+        input = win->keyboard_device;
+        wl_shell_surface_resize(win->shell_surface, input->input_device, 
+                                input->timestamp, location);
+     }
+}
+
+EAPI void 
+ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (win->surface) 
+     wl_surface_damage(win->surface, x, y, w, h);
+}
+
+EAPI void 
+ecore_wl_window_buffer_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer, int x, int y)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if ((win->surface) && (buffer))
+     wl_surface_attach(win->surface, buffer, x, y);
+}
+
+EAPI void 
+ecore_wl_window_show(Ecore_Wl_Window *win)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (win->surface) return;
+
+   win->surface = wl_compositor_create_surface(_ecore_wl_disp->wl.compositor);
+   wl_surface_set_user_data(win->surface, win);
+
+   win->shell_surface = 
+     wl_shell_get_shell_surface(_ecore_wl_disp->wl.shell, win->surface);
+   wl_shell_surface_add_listener(win->shell_surface, 
+                                 &_ecore_wl_shell_surface_listener, win);
+
+   switch (win->type)
+     {
+      case ECORE_WL_WINDOW_TYPE_FULLSCREEN:
+        wl_shell_surface_set_fullscreen(win->shell_surface, 
+                                        WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+                                        0, NULL);
+        break;
+      case ECORE_WL_WINDOW_TYPE_MAXIMIZED:
+        wl_shell_surface_set_maximized(win->shell_surface, NULL);
+        break;
+      case ECORE_WL_WINDOW_TYPE_TRANSIENT:
+        wl_shell_surface_set_transient(win->shell_surface, 
+                                       win->parent->shell_surface, 
+                                       win->allocation.x, win->allocation.y, 0);
+        break;
+      case ECORE_WL_WINDOW_TYPE_MENU:
+        wl_shell_surface_set_popup(win->shell_surface, 
+                                   win->pointer_device->input_device, 
+                                   win->pointer_device->timestamp, 
+                                   win->parent->shell_surface, 
+                                   win->allocation.x, win->allocation.y, 0);
+        break;
+      case ECORE_WL_WINDOW_TYPE_TOPLEVEL:
+      default:
+        wl_shell_surface_set_toplevel(win->shell_surface);
+        break;
+     }
+}
+
+EAPI void 
+ecore_wl_window_hide(Ecore_Wl_Window *win)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface);
+   win->shell_surface = NULL;
+   if (win->surface) wl_surface_destroy(win->surface);
+   win->surface = NULL;
+}
+
+EAPI void 
+ecore_wl_window_raise(Ecore_Wl_Window *win)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (win->shell_surface) 
+     wl_shell_surface_set_toplevel(win->shell_surface);
+}
+
+EAPI void 
+ecore_wl_window_maximized_set(Ecore_Wl_Window *win, Eina_Bool maximized)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if ((win->type == ECORE_WL_WINDOW_TYPE_MAXIMIZED) == maximized) return;
+   if (win->type == ECORE_WL_WINDOW_TYPE_TOPLEVEL)
+     {
+        win->saved_allocation = win->allocation;
+        if (win->shell_surface) 
+          wl_shell_surface_set_maximized(win->shell_surface, NULL);
+        win->type = ECORE_WL_WINDOW_TYPE_MAXIMIZED;
+     }
+   else
+     {
+        Ecore_Wl_Input *input;
+
+        input = win->keyboard_device;
+
+        if (win->shell_surface) 
+          wl_shell_surface_set_toplevel(win->shell_surface);
+        win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL;
+        win->allocation = win->saved_allocation;
+        _ecore_wl_window_configure_send(win, win->allocation.w, 
+                                        win->allocation.h, input->timestamp);
+     }
+}
+
+EAPI void 
+ecore_wl_window_fullscreen_set(Ecore_Wl_Window *win, Eina_Bool fullscreen)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if ((win->type == ECORE_WL_WINDOW_TYPE_FULLSCREEN) == fullscreen) return;
+   if (fullscreen)
+     {
+        win->type = ECORE_WL_WINDOW_TYPE_FULLSCREEN;
+        win->saved_allocation = win->allocation;
+        if (win->shell_surface)
+          wl_shell_surface_set_fullscreen(win->shell_surface, 
+                                          WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+                                          0, NULL);
+     }
+   else 
+     {
+        Ecore_Wl_Input *input;
+
+        input = win->keyboard_device;
+
+        if (win->shell_surface)
+          wl_shell_surface_set_toplevel(win->shell_surface);
+        win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL;
+        win->allocation = win->saved_allocation;
+        _ecore_wl_window_configure_send(win, win->allocation.w, 
+                                        win->allocation.h, input->timestamp);
+     }
+}
+
+EAPI void 
+ecore_wl_window_update_size(Ecore_Wl_Window *win, int w, int h)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   win->allocation.w = w;
+   win->allocation.h = h;
+}
+
+EAPI struct wl_surface *
+ecore_wl_window_surface_get(Ecore_Wl_Window *win)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return NULL;
+   return win->surface;
+}
+
+EAPI Ecore_Wl_Window *
+ecore_wl_window_find(unsigned int id)
+{
+   Ecore_Wl_Window *win;
+
+   if (!id) return NULL;
+   win = eina_hash_find(_windows, &id);
+   if (win) return win;
+   return NULL;
+}
+
+/* local functions */
+static void 
+_ecore_wl_window_cb_configure(void *data, struct wl_shell_surface *shell_surface __UNUSED__, unsigned int timestamp, unsigned int edges, int w, int h)
+{
+   Ecore_Wl_Window *win;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(win = data)) return;
+   if ((w <= 0) || (h <= 0)) return;
+
+   win->edges = edges;
+   win->allocation.w = w;
+   win->allocation.h = h;
+   _ecore_wl_window_configure_send(win, w, h, timestamp);
+}
+
+static void 
+_ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surface __UNUSED__)
+{
+   Ecore_Wl_Window *win;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(win = data)) return;
+   /* TODO: handle popup destroy */
+}
+
+static void 
+_ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h, unsigned int timestamp)
+{
+   Ecore_Wl_Event_Window_Configure *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Window_Configure)))) return;
+   ev->win = win->id;
+   ev->event_win = win->id;
+   ev->x = win->allocation.x;
+   ev->y = win->allocation.y;
+   ev->w = w;
+   ev->h = h;
+   ev->timestamp = timestamp;
+   ecore_event_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL);
+}