# 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;
};
/**
* @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
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 \
#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();
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();
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();
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();
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;
}
--- /dev/null
+#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);
+}
--- /dev/null
+#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);
+}
--- /dev/null
+#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);
+ }
+}
# 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>
# 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
# 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
--- /dev/null
+#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);
+}