aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_wayland/ecore_wl.c')
-rw-r--r--libraries/ecore/src/lib/ecore_wayland/ecore_wl.c1322
1 files changed, 330 insertions, 992 deletions
diff --git a/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c b/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c
index f62503b..5f1b20d 100644
--- a/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c
+++ b/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c
@@ -1,16 +1,11 @@
1#ifdef HAVE_CONFIG_H 1#ifdef HAVE_CONFIG_H
2# include "config.h" 2# include <config.h>
3#endif 3#endif
4 4
5#include "Ecore.h" 5#include <fcntl.h>
6#include "ecore_private.h"
7#include "Ecore_Input.h"
8#include "ecore_wl_private.h"
9#include "Ecore_Wayland.h"
10 6
11/* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... 7/* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ...
12 * What about other OSs ?? */ 8 * What about other OSs ?? */
13#include <fcntl.h>
14#ifdef __linux__ 9#ifdef __linux__
15# include <linux/input.h> 10# include <linux/input.h>
16#else 11#else
@@ -23,150 +18,86 @@
23# define BTN_BACK 0x116 18# define BTN_BACK 0x116
24#endif 19#endif
25 20
26#include <X11/extensions/XKBcommon.h> 21#include "Ecore.h"
22#include "ecore_private.h"
23#include "Ecore_Input.h"
24#include "ecore_wl_private.h"
25#include "Ecore_Wayland.h"
27 26
28/* local function prototypes */ 27/* local function prototypes */
29static Eina_Bool _ecore_wl_shutdown(Eina_Bool close_display); 28static Eina_Bool _ecore_wl_shutdown(Eina_Bool close);
30static void _ecore_wl_cb_disp_handle_global(struct wl_display *disp, uint32_t id, const char *interface, uint32_t version __UNUSED__, void *data __UNUSED__); 29static int _ecore_wl_cb_event_mask_update(unsigned int mask, void *data);
31static int _ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__); 30static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl __UNUSED__);
32static 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__); 31static void _ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char *interface, unsigned int version __UNUSED__, void *data);
33static 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__); 32static Eina_Bool _ecore_wl_egl_init(Ecore_Wl_Display *ewd);
34static Eina_Bool _ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__); 33static Eina_Bool _ecore_wl_egl_shutdown(Ecore_Wl_Display *ewd);
35static void _ecore_wl_cb_handle_motion(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, int32_t x, int32_t y, int32_t sx, int32_t sy); 34static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd);
36static void _ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state); 35static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd);
37static void _ecore_wl_cb_handle_key(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, uint32_t key, uint32_t state);
38static void _ecore_wl_cb_handle_pointer_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, struct wl_surface *surface, int32_t x, int32_t y, int32_t sx, int32_t sy);
39static 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);
40static 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);
41static void _ecore_wl_cb_handle_touch_up(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__, uint32_t timestamp, int32_t id);
42static 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);
43static void _ecore_wl_cb_handle_touch_frame(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__);
44static void _ecore_wl_cb_handle_touch_cancel(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__);
45static void _ecore_wl_cb_source_target(void *data, struct wl_data_source *source __UNUSED__, const char *mime_type __UNUSED__);
46static void _ecore_wl_cb_source_send(void *data, struct wl_data_source *source, const char *mime_type, int32_t fd);
47static void _ecore_wl_cb_source_cancelled(void *data, struct wl_data_source *source __UNUSED__);
48static void _ecore_wl_cb_source_offer(void *data, struct wl_data_offer *offer __UNUSED__, const char *type);
49static void _ecore_wl_cb_data_offer(void *data, struct wl_data_device *data_dev, uint32_t id);
50static 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);
51static void _ecore_wl_cb_data_leave(void *data __UNUSED__, struct wl_data_device *data_dev);
52static void _ecore_wl_cb_data_motion(void *data __UNUSED__, struct wl_data_device *data_dev, uint32_t timestamp, int32_t x, int32_t y);
53static void _ecore_wl_cb_data_drop(void *data __UNUSED__, struct wl_data_device *data_dev);
54static void _ecore_wl_cb_data_selection(void *data, struct wl_data_device *data_dev, struct wl_data_offer *offer);
55
56static void _ecore_wl_mouse_move_send(uint32_t timestamp);
57static void _ecore_wl_mouse_out_send(struct wl_surface *surface, uint32_t timestamp);
58static void _ecore_wl_mouse_in_send(struct wl_surface *surface, uint32_t timestamp);
59static void _ecore_wl_mouse_up_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp);
60static void _ecore_wl_mouse_down_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp);
61static void _ecore_wl_focus_out_send(struct wl_surface *surface, uint32_t timestamp);
62static void _ecore_wl_focus_in_send(struct wl_surface *surface, uint32_t timestamp);
63 36
64/* local variables */ 37/* local variables */
65static int _ecore_wl_init_count = 0; 38static int _ecore_wl_init_count = 0;
66static struct wl_display *_ecore_wl_disp = NULL;
67static uint32_t _ecore_wl_disp_mask = 0;
68static uint32_t _ecore_wl_disp_format = WL_SHM_FORMAT_ARGB8888;
69static Eina_Rectangle _ecore_wl_screen;
70static Ecore_Fd_Handler *_ecore_wl_fd_hdl = NULL;
71static int _ecore_wl_screen_x = 0;
72static int _ecore_wl_screen_y = 0;
73static int _ecore_wl_surface_x = 0;
74static int _ecore_wl_surface_y = 0;
75static int _ecore_wl_touch_x = 0;
76static int _ecore_wl_touch_y = 0;
77static int _ecore_wl_input_modifiers = 0;
78static struct xkb_desc *_ecore_wl_xkb;
79static uint32_t _ecore_wl_input_button = 0;
80
81static struct wl_compositor *_ecore_wl_comp;
82static struct wl_shm *_ecore_wl_shm;
83static struct wl_shell *_ecore_wl_shell;
84static struct wl_output *_ecore_wl_output;
85static struct wl_input_device *_ecore_wl_input_dev;
86static struct wl_surface *_ecore_wl_input_surface;
87static struct wl_surface *_ecore_wl_touch_surface;
88static struct wl_data_device_manager *_ecore_wl_data_manager;
89static struct wl_data_device *_ecore_wl_data_dev;
90
91static const struct wl_output_listener _ecore_wl_output_listener =
92{
93 _ecore_wl_cb_disp_handle_geometry,
94 _ecore_wl_cb_disp_handle_mode
95};
96static const struct wl_input_device_listener _ecore_wl_input_listener =
97{
98 _ecore_wl_cb_handle_motion,
99 _ecore_wl_cb_handle_button,
100 _ecore_wl_cb_handle_key,
101 _ecore_wl_cb_handle_pointer_focus,
102 _ecore_wl_cb_handle_keyboard_focus,
103 _ecore_wl_cb_handle_touch_down,
104 _ecore_wl_cb_handle_touch_up,
105 _ecore_wl_cb_handle_touch_motion,
106 _ecore_wl_cb_handle_touch_frame,
107 _ecore_wl_cb_handle_touch_cancel,
108};
109static const struct wl_data_source_listener _ecore_wl_source_listener =
110{
111 _ecore_wl_cb_source_target,
112 _ecore_wl_cb_source_send,
113 _ecore_wl_cb_source_cancelled
114};
115static const struct wl_data_device_listener _ecore_wl_data_listener =
116{
117 _ecore_wl_cb_data_offer,
118 _ecore_wl_cb_data_enter,
119 _ecore_wl_cb_data_leave,
120 _ecore_wl_cb_data_motion,
121 _ecore_wl_cb_data_drop,
122 _ecore_wl_cb_data_selection
123};
124static const struct wl_data_offer_listener _ecore_wl_offer_listener =
125{
126 _ecore_wl_cb_source_offer,
127};
128 39
129/* external variables */ 40/* external variables */
130int _ecore_wl_log_dom = -1; 41int _ecore_wl_log_dom = -1;
42Ecore_Wl_Display *_ecore_wl_disp = NULL;
43
131EAPI int ECORE_WL_EVENT_MOUSE_IN = 0; 44EAPI int ECORE_WL_EVENT_MOUSE_IN = 0;
132EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0; 45EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0;
133EAPI int ECORE_WL_EVENT_FOCUS_IN = 0; 46EAPI int ECORE_WL_EVENT_FOCUS_IN = 0;
134EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0; 47EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0;
135EAPI int ECORE_WL_EVENT_DRAG_START = 0; 48EAPI int ECORE_WL_EVENT_WINDOW_CONFIGURE = 0;
136EAPI int ECORE_WL_EVENT_DRAG_STOP = 0; 49EAPI int ECORE_WL_EVENT_DND_ENTER = 0;
137 50EAPI int ECORE_WL_EVENT_DND_POSITION = 0;
51EAPI int ECORE_WL_EVENT_DND_LEAVE = 0;
52EAPI int ECORE_WL_EVENT_DND_DROP = 0;
53EAPI int ECORE_WL_EVENT_INTERFACES_BOUND = 0;
54
55/**
56 * @defgroup Ecore_Wl_Init_Group Wayland Library Init and Shutdown Functions
57 *
58 * Functions that start and shutdown the Ecore Wayland Library.
59 */
60
61/**
62 * Initialize the Wayland display connection to the given display.
63 *
64 * @param name Display target name. if @c NULL, the default display is
65 * assumed.
66 * @return The number of times the library has been initialized without being
67 * shut down. 0 is returned if an error occurs.
68 *
69 * @ingroup Ecore_Wl_Init_Group
70 */
138EAPI int 71EAPI int
139ecore_wl_init(const char *name) 72ecore_wl_init(const char *name)
140{ 73{
141 struct xkb_rule_names xkb_names;
142 int fd = 0;
143
144 if (++_ecore_wl_init_count != 1)
145 return _ecore_wl_init_count;
146
147 LOGFN(__FILE__, __LINE__, __FUNCTION__); 74 LOGFN(__FILE__, __LINE__, __FUNCTION__);
148 75
76 if (++_ecore_wl_init_count != 1) return _ecore_wl_init_count;
77
149 if (!eina_init()) return --_ecore_wl_init_count; 78 if (!eina_init()) return --_ecore_wl_init_count;
150 79
151 _ecore_wl_log_dom = 80 _ecore_wl_log_dom =
152 eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR); 81 eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR);
153 if (_ecore_wl_log_dom < 0) 82 if (_ecore_wl_log_dom < 0)
154 { 83 {
155 EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland."); 84 EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland");
156 eina_shutdown(); 85 eina_shutdown();
157 return --_ecore_wl_init_count; 86 return --_ecore_wl_init_count;
158 } 87 }
159 88
160 if (!ecore_init()) 89 if (!ecore_init())
161 { 90 {
91 ERR("Could not initialize ecore");
162 eina_log_domain_unregister(_ecore_wl_log_dom); 92 eina_log_domain_unregister(_ecore_wl_log_dom);
163 _ecore_wl_log_dom = -1; 93 _ecore_wl_log_dom = -1;
164 eina_shutdown(); 94 eina_shutdown();
165 return --_ecore_wl_init_count; 95 return --_ecore_wl_init_count;
166 } 96 }
167 97
168 if (!ecore_event_init()) 98 if (!ecore_event_init())
169 { 99 {
100 ERR("Could not initialize ecore_event");
170 eina_log_domain_unregister(_ecore_wl_log_dom); 101 eina_log_domain_unregister(_ecore_wl_log_dom);
171 _ecore_wl_log_dom = -1; 102 _ecore_wl_log_dom = -1;
172 ecore_shutdown(); 103 ecore_shutdown();
@@ -174,26 +105,23 @@ ecore_wl_init(const char *name)
174 return --_ecore_wl_init_count; 105 return --_ecore_wl_init_count;
175 } 106 }
176 107
177 if (!ECORE_WL_EVENT_MOUSE_IN) 108 if (!ECORE_WL_EVENT_MOUSE_IN)
178 { 109 {
179 ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new(); 110 ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new();
180 ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new(); 111 ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new();
181 ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new(); 112 ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new();
182 ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new(); 113 ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new();
183 ECORE_WL_EVENT_DRAG_START = ecore_event_type_new(); 114 ECORE_WL_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
184 ECORE_WL_EVENT_DRAG_STOP = ecore_event_type_new(); 115 ECORE_WL_EVENT_DND_ENTER = ecore_event_type_new();
116 ECORE_WL_EVENT_DND_POSITION = ecore_event_type_new();
117 ECORE_WL_EVENT_DND_LEAVE = ecore_event_type_new();
118 ECORE_WL_EVENT_DND_DROP = ecore_event_type_new();
119 ECORE_WL_EVENT_INTERFACES_BOUND = ecore_event_type_new();
185 } 120 }
186 121
187 /* init xkb */ 122 if (!(_ecore_wl_disp = malloc(sizeof(Ecore_Wl_Display))))
188 /* FIXME: Somehow make this portable to other languages/countries */
189 xkb_names.rules = "evdev";
190 xkb_names.model = "evdev";
191 xkb_names.layout = "us";
192 xkb_names.variant = "";
193 xkb_names.options = "";
194 if (!(_ecore_wl_xkb = xkb_compile_keymap_from_rules(&xkb_names)))
195 { 123 {
196 ERR("Could not compile keymap"); 124 ERR("Could not allocate memory for Ecore_Wl_Display structure");
197 eina_log_domain_unregister(_ecore_wl_log_dom); 125 eina_log_domain_unregister(_ecore_wl_log_dom);
198 _ecore_wl_log_dom = -1; 126 _ecore_wl_log_dom = -1;
199 ecore_event_shutdown(); 127 ecore_event_shutdown();
@@ -202,9 +130,11 @@ ecore_wl_init(const char *name)
202 return --_ecore_wl_init_count; 130 return --_ecore_wl_init_count;
203 } 131 }
204 132
205 /* connect to the wayland display */ 133 memset(_ecore_wl_disp, 0, sizeof(Ecore_Wl_Display));
206 if (!(_ecore_wl_disp = wl_display_connect(name))) 134
135 if (!(_ecore_wl_disp->wl.display = wl_display_connect(name)))
207 { 136 {
137 ERR("Could not connect to Wayland display");
208 eina_log_domain_unregister(_ecore_wl_log_dom); 138 eina_log_domain_unregister(_ecore_wl_log_dom);
209 _ecore_wl_log_dom = -1; 139 _ecore_wl_log_dom = -1;
210 ecore_event_shutdown(); 140 ecore_event_shutdown();
@@ -213,23 +143,48 @@ ecore_wl_init(const char *name)
213 return --_ecore_wl_init_count; 143 return --_ecore_wl_init_count;
214 } 144 }
215 145
216 /* setup handler for wayland interfaces */ 146 _ecore_wl_disp->fd =
217 wl_display_add_global_listener(_ecore_wl_disp, 147 wl_display_get_fd(_ecore_wl_disp->wl.display,
218 _ecore_wl_cb_disp_handle_global, NULL); 148 _ecore_wl_cb_event_mask_update, _ecore_wl_disp);
149
150 _ecore_wl_disp->fd_hdl =
151 ecore_main_fd_handler_add(_ecore_wl_disp->fd, ECORE_FD_READ,
152 _ecore_wl_cb_handle_data, _ecore_wl_disp,
153 NULL, NULL);
154
155 wl_list_init(&_ecore_wl_disp->inputs);
156 wl_list_init(&_ecore_wl_disp->outputs);
157
158 wl_display_add_global_listener(_ecore_wl_disp->wl.display,
159 _ecore_wl_cb_handle_global, _ecore_wl_disp);
160
161 /* FIXME: Process connection events ?? */
162 wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_READABLE);
163
164 /* if (!_ecore_wl_egl_init(_ecore_wl_disp)) */
165 /* { */
166 /* ERR("Could not initialize EGL"); */
167 /* free(_ecore_wl_disp); */
168 /* eina_log_domain_unregister(_ecore_wl_log_dom); */
169 /* _ecore_wl_log_dom = -1; */
170 /* ecore_event_shutdown(); */
171 /* ecore_shutdown(); */
172 /* eina_shutdown(); */
173 /* return --_ecore_wl_init_count; */
174 /* } */
219 175
220 /* process connection events */ 176 /* _ecore_wl_disp->create_image = */
221 wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE); 177 /* (void *)eglGetProcAddress("eglCreateImageKHR"); */
178 /* _ecore_wl_disp->destroy_image = */
179 /* (void *)eglGetProcAddress("eglDestroyImageKHR"); */
222 180
223 fd = wl_display_get_fd(_ecore_wl_disp, 181 /* TODO: create pointer surfaces */
224 _ecore_wl_cb_disp_event_mask_update, NULL);
225 182
226 _ecore_wl_fd_hdl = 183 if (!_ecore_wl_xkb_init(_ecore_wl_disp))
227 ecore_main_fd_handler_add(fd, ECORE_FD_READ, _ecore_wl_cb_fd_handle,
228 _ecore_wl_disp, NULL, NULL);
229 if (!_ecore_wl_fd_hdl)
230 { 184 {
231 wl_display_destroy(_ecore_wl_disp); 185 ERR("Could not initialize XKB");
232 _ecore_wl_disp = NULL; 186 _ecore_wl_egl_shutdown(_ecore_wl_disp);
187 free(_ecore_wl_disp);
233 eina_log_domain_unregister(_ecore_wl_log_dom); 188 eina_log_domain_unregister(_ecore_wl_log_dom);
234 _ecore_wl_log_dom = -1; 189 _ecore_wl_log_dom = -1;
235 ecore_event_shutdown(); 190 ecore_event_shutdown();
@@ -238,976 +193,359 @@ ecore_wl_init(const char *name)
238 return --_ecore_wl_init_count; 193 return --_ecore_wl_init_count;
239 } 194 }
240 195
196 _ecore_wl_window_init();
197
241 return _ecore_wl_init_count; 198 return _ecore_wl_init_count;
242} 199}
243 200
201/**
202 * Shuts down the Ecore Wayland Library
203 *
204 * In shutting down the library, the Wayland display connection is terminated
205 * and any event handlers for it are removed.
206 *
207 * @return The number of times the library has been initialized without
208 * being shut down.
209 *
210 * @ingroup Ecore_Wl_Init_Group
211 */
244EAPI int 212EAPI int
245ecore_wl_shutdown(void) 213ecore_wl_shutdown(void)
246{ 214{
247 return _ecore_wl_shutdown(EINA_TRUE); 215 LOGFN(__FILE__, __LINE__, __FUNCTION__);
248}
249
250EAPI struct wl_display *
251ecore_wl_display_get(void)
252{
253 return _ecore_wl_disp;
254}
255
256EAPI struct wl_shm *
257ecore_wl_shm_get(void)
258{
259 return _ecore_wl_shm;
260}
261
262EAPI struct wl_compositor *
263ecore_wl_compositor_get(void)
264{
265 return _ecore_wl_comp;
266}
267 216
268EAPI struct wl_shell * 217 return _ecore_wl_shutdown(EINA_TRUE);
269ecore_wl_shell_get(void)
270{
271 return _ecore_wl_shell;
272} 218}
273 219
274EAPI struct wl_input_device * 220/**
275ecore_wl_input_device_get(void) 221 * @defgroup Ecore_Wl_Flush_Group Wayland Synchronization Functions
276{ 222 *
277 return _ecore_wl_input_dev; 223 * Functions that ensure that all commands which have been issued by the
278} 224 * Ecore Wayland library have been sent to the server.
225 */
279 226
227/**
228 * Sends all Wayland commands to the Wayland Display.
229 *
230 * @ingroup Ecore_Wl_Flush_Group
231 * @since 1.2
232 */
280EAPI void 233EAPI void
281ecore_wl_screen_size_get(int *w, int *h) 234ecore_wl_flush(void)
282{ 235{
283 if (w) *w = _ecore_wl_screen.w; 236 LOGFN(__FILE__, __LINE__, __FUNCTION__);
284 if (h) *h = _ecore_wl_screen.h;
285}
286
287EAPI unsigned int
288ecore_wl_format_get(void)
289{
290 return _ecore_wl_disp_format;
291}
292 237
293EAPI void 238 while (_ecore_wl_disp->mask & WL_DISPLAY_WRITABLE)
294ecore_wl_flush(void) 239 wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_WRITABLE);
295{ 240// wl_display_flush(_ecore_wl_disp->wl.display); // old flush code
296 wl_display_flush(_ecore_wl_disp);
297} 241}
298 242
243/**
244 * Flushes the command buffer and waits until all requests have been
245 * processed by the server.
246 *
247 * @ingroup Ecore_Wl_Flush_Group
248 * @since 1.2
249 */
299EAPI void 250EAPI void
300ecore_wl_sync(void) 251ecore_wl_sync(void)
301{ 252{
302 wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE); 253 LOGFN(__FILE__, __LINE__, __FUNCTION__);
303}
304 254
305EAPI void 255 wl_display_roundtrip(_ecore_wl_disp->wl.display);
306ecore_wl_pointer_xy_get(int *x, int *y) 256 // old sync code
257// wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_READABLE);
258}
259
260/**
261 * @defgroup Ecore_Wl_Display_Group Wayland Display Functions
262 *
263 * Functions that set and retrieve various information about the Wayland Display.
264 */
265
266/**
267 * Retrieves the Wayland Shm Interface used for the current Wayland connection.
268 *
269 * @return The current wayland shm interface
270 *
271 * @ingroup Ecore_Wl_Display_Group
272 * @since 1.2
273 */
274EAPI struct wl_shm *
275ecore_wl_shm_get(void)
307{ 276{
308 if (x) *x = _ecore_wl_screen_x; 277 return _ecore_wl_disp->wl.shm;
309 if (y) *y = _ecore_wl_screen_y;
310} 278}
311 279
312EAPI Ecore_Wl_Drag_Source * 280/**
313ecore_wl_drag_source_create(int hotspot_x, int hotspot_y, int offset_x, int offset_y, const char *mimetype, unsigned int timestamp, void *data) 281 * Retrieves the Wayland Display Interface used for the current Wayland connection.
282 *
283 * @return The current wayland display interface
284 *
285 * @ingroup Ecore_Wl_Display_Group
286 * @since 1.2
287 */
288EAPI struct wl_display *
289ecore_wl_display_get(void)
314{ 290{
315 Ecore_Wl_Drag_Source *source; 291 return _ecore_wl_disp->wl.display;
316
317 if (!(source = calloc(1, sizeof(Ecore_Wl_Drag_Source)))) return NULL;
318
319 source->data_dev = _ecore_wl_data_dev;
320 source->hotspot_x = hotspot_x;
321 source->hotspot_y = hotspot_y;
322 source->offset_x = offset_x;
323 source->offset_y = offset_y;
324 source->mimetype = mimetype;
325 source->timestamp = timestamp;
326 source->data = data;
327
328 source->data_source =
329 wl_data_device_manager_create_data_source(_ecore_wl_data_manager);
330
331 wl_data_source_add_listener(source->data_source,
332 &_ecore_wl_source_listener, source);
333
334 wl_data_source_offer(source->data_source, source->mimetype);
335
336 /* NB: Do we add some default mimetypes here ?? */
337 /* text/plain, etc */
338
339 return source;
340} 292}
341 293
294/**
295 * Retrieves the size of the current screen.
296 *
297 * @param w where to return the width. May be NULL. Returns 0 on error.
298 * @param h where to return the height. May be NULL. Returns 0 on error.
299 *
300 * @ingroup Ecore_Wl_Display_Group
301 * @since 1.2
302 */
342EAPI void 303EAPI void
343ecore_wl_drag_start(Ecore_Wl_Drag_Source *source, struct wl_surface *surface, struct wl_buffer *buffer) 304ecore_wl_screen_size_get(int *w, int *h)
344{ 305{
345 source->buffer = buffer; 306 LOGFN(__FILE__, __LINE__, __FUNCTION__);
346 307
347 wl_data_device_start_drag(source->data_dev, source->data_source, 308 if (w) *w = _ecore_wl_disp->output->allocation.w;
348 surface, source->timestamp); 309 if (h) *h = _ecore_wl_disp->output->allocation.h;
349} 310}
350 311
312/* @since 1.2 */
351EAPI void 313EAPI void
352ecore_wl_drag_stop(void) 314ecore_wl_pointer_xy_get(int *x, int *y)
353{ 315{
316 LOGFN(__FILE__, __LINE__, __FUNCTION__);
354 317
318 _ecore_wl_input_pointer_xy_get(x, y);
355} 319}
356 320
357/* local functions */ 321/* local functions */
358static Eina_Bool 322static Eina_Bool
359_ecore_wl_shutdown(Eina_Bool close_display) 323_ecore_wl_shutdown(Eina_Bool close)
360{ 324{
361 LOGFN(__FILE__, __LINE__, __FUNCTION__); 325 LOGFN(__FILE__, __LINE__, __FUNCTION__);
362 326
363 if (--_ecore_wl_init_count != 0) 327 if (--_ecore_wl_init_count != 0) return _ecore_wl_init_count;
364 return _ecore_wl_init_count;
365
366 if (!_ecore_wl_disp) return _ecore_wl_init_count; 328 if (!_ecore_wl_disp) return _ecore_wl_init_count;
367 329
368 if (_ecore_wl_xkb) free(_ecore_wl_xkb); 330 _ecore_wl_window_shutdown();
369 331
370 if (_ecore_wl_fd_hdl) ecore_main_fd_handler_del(_ecore_wl_fd_hdl); 332 if (_ecore_wl_disp->fd_hdl)
371 _ecore_wl_fd_hdl = NULL; 333 ecore_main_fd_handler_del(_ecore_wl_disp->fd_hdl);
372 334
373 if (close_display) 335 if (close)
374 { 336 {
375 if (_ecore_wl_data_dev) wl_data_device_destroy(_ecore_wl_data_dev); 337 Ecore_Wl_Output *out, *tout;
376 if (_ecore_wl_input_dev) wl_input_device_destroy(_ecore_wl_input_dev); 338 Ecore_Wl_Input *in, *tin;
377 if (_ecore_wl_data_manager) 339
378 wl_data_device_manager_destroy(_ecore_wl_data_manager); 340 wl_list_for_each_safe(out, tout, &_ecore_wl_disp->outputs, link)
379 if (_ecore_wl_shell) wl_shell_destroy(_ecore_wl_shell); 341 _ecore_wl_output_del(out);
380 if (_ecore_wl_shm) wl_shm_destroy(_ecore_wl_shm); 342
381 if (_ecore_wl_comp) wl_compositor_destroy(_ecore_wl_comp); 343 wl_list_for_each_safe(in, tin, &_ecore_wl_disp->inputs, link)
382 if (_ecore_wl_disp) 344 _ecore_wl_input_del(in);
345
346 _ecore_wl_xkb_shutdown(_ecore_wl_disp);
347 /* _ecore_wl_egl_shutdown(_ecore_wl_disp); */
348
349 if (_ecore_wl_disp->wl.shell)
350 wl_shell_destroy(_ecore_wl_disp->wl.shell);
351 if (_ecore_wl_disp->wl.shm) wl_shm_destroy(_ecore_wl_disp->wl.shm);
352 if (_ecore_wl_disp->wl.data_device_manager)
353 wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager);
354 if (_ecore_wl_disp->wl.compositor)
355 wl_compositor_destroy(_ecore_wl_disp->wl.compositor);
356 if (_ecore_wl_disp->wl.display)
383 { 357 {
384 wl_display_flush(_ecore_wl_disp); 358 wl_display_flush(_ecore_wl_disp->wl.display);
385 wl_display_destroy(_ecore_wl_disp); 359 wl_display_disconnect(_ecore_wl_disp->wl.display);
386 } 360 }
387 _ecore_wl_disp = NULL; 361 free(_ecore_wl_disp);
388 } 362 }
389 363
390 eina_log_domain_unregister(_ecore_wl_log_dom);
391 _ecore_wl_log_dom = -1;
392
393 ecore_event_shutdown(); 364 ecore_event_shutdown();
394 ecore_shutdown(); 365 ecore_shutdown();
366
367 eina_log_domain_unregister(_ecore_wl_log_dom);
368 _ecore_wl_log_dom = -1;
395 eina_shutdown(); 369 eina_shutdown();
396 370
397 return _ecore_wl_init_count; 371 return _ecore_wl_init_count;
398} 372}
399 373
400static void
401_ecore_wl_cb_disp_handle_global(struct wl_display *disp, uint32_t id, const char *interface, uint32_t version __UNUSED__, void *data __UNUSED__)
402{
403// LOGFN(__FILE__, __LINE__, __FUNCTION__);
404
405 if (disp != _ecore_wl_disp) return;
406 if (!strcmp(interface, "wl_compositor"))
407 {
408 _ecore_wl_comp =
409 wl_display_bind(_ecore_wl_disp, id, &wl_compositor_interface);
410 }
411 else if (!strcmp(interface, "wl_shm"))
412 {
413 _ecore_wl_shm =
414 wl_display_bind(_ecore_wl_disp, id, &wl_shm_interface);
415 }
416 else if (!strcmp(interface, "wl_output"))
417 {
418 _ecore_wl_output =
419 wl_display_bind(_ecore_wl_disp, id, &wl_output_interface);
420 wl_output_add_listener(_ecore_wl_output,
421 &_ecore_wl_output_listener, NULL);
422 }
423 else if (!strcmp(interface, "wl_shell"))
424 {
425 _ecore_wl_shell =
426 wl_display_bind(_ecore_wl_disp, id, &wl_shell_interface);
427 }
428 else if (!strcmp(interface, "wl_input_device"))
429 {
430 _ecore_wl_input_dev =
431 wl_display_bind(_ecore_wl_disp, id, &wl_input_device_interface);
432 wl_input_device_add_listener(_ecore_wl_input_dev,
433 &_ecore_wl_input_listener, NULL);
434 }
435 else if (!strcmp(interface, "wl_data_device_manager"))
436 {
437 _ecore_wl_data_manager =
438 wl_display_bind(_ecore_wl_disp, id,
439 &wl_data_device_manager_interface);
440 }
441
442 if ((_ecore_wl_input_dev) && (_ecore_wl_data_manager) && (!_ecore_wl_data_dev))
443 {
444 _ecore_wl_data_dev =
445 wl_data_device_manager_get_data_device(_ecore_wl_data_manager,
446 _ecore_wl_input_dev);
447 wl_data_device_add_listener(_ecore_wl_data_dev,
448 &_ecore_wl_data_listener, NULL);
449 }
450}
451
452static int 374static int
453_ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__) 375_ecore_wl_cb_event_mask_update(unsigned int mask, void *data)
454{ 376{
455// LOGFN(__FILE__, __LINE__, __FUNCTION__); 377 Ecore_Wl_Display *ewd;
456 378
457 _ecore_wl_disp_mask = mask; 379 LOGFN(__FILE__, __LINE__, __FUNCTION__);
458 380
381 ewd = data;
382 ewd->mask = mask;
459 return 0; 383 return 0;
460} 384}
461 385
462static void
463_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__)
464{
465 _ecore_wl_screen.x = x;
466 _ecore_wl_screen.y = y;
467}
468
469static void
470_ecore_wl_cb_disp_handle_mode(void *data __UNUSED__, struct wl_output *output __UNUSED__, uint32_t flags, int w, int h, int refresh __UNUSED__)
471{
472 if (flags & WL_OUTPUT_MODE_CURRENT)
473 {
474 _ecore_wl_screen.w = w;
475 _ecore_wl_screen.h = h;
476 }
477}
478
479static Eina_Bool 386static Eina_Bool
480_ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__) 387_ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl __UNUSED__)
481{ 388{
482 struct wl_display *disp; 389 Ecore_Wl_Display *ewd;
483
484// LOGFN(__FILE__, __LINE__, __FUNCTION__);
485
486 if (!(disp = data)) return ECORE_CALLBACK_RENEW;
487 if (disp != _ecore_wl_disp) return ECORE_CALLBACK_RENEW;
488 390
489 if (_ecore_wl_disp_mask & WL_DISPLAY_WRITABLE) 391 LOGFN(__FILE__, __LINE__, __FUNCTION__);
490 wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_WRITABLE);
491
492 if (_ecore_wl_disp_mask & WL_DISPLAY_READABLE)
493 wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
494 392
393 if (!(ewd = data)) return ECORE_CALLBACK_RENEW;
394 wl_display_iterate(ewd->wl.display, ewd->mask);
495 return ECORE_CALLBACK_RENEW; 395 return ECORE_CALLBACK_RENEW;
496} 396}
497 397
498static void 398static void
499_ecore_wl_cb_handle_motion(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, int32_t x, int32_t y, int32_t sx, int32_t sy) 399_ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char *interface, unsigned int version __UNUSED__, void *data)
500{
501 if (dev != _ecore_wl_input_dev) return;
502
503 _ecore_wl_screen_x = x;
504 _ecore_wl_screen_y = y;
505 _ecore_wl_surface_x = sx;
506 _ecore_wl_surface_y = sy;
507
508 _ecore_wl_mouse_move_send(t);
509}
510
511static void
512_ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state)
513{
514 if (dev != _ecore_wl_input_dev) return;
515
516 if ((btn >= BTN_SIDE) && (btn <= BTN_BACK))
517 {
518 Ecore_Event_Mouse_Wheel *ev;
519
520 if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return;
521
522 ev->timestamp = t;
523 ev->x = _ecore_wl_surface_x;
524 ev->y = _ecore_wl_surface_y;
525 ev->root.x = _ecore_wl_screen_x;
526 ev->root.y = _ecore_wl_screen_y;
527 ev->modifiers = _ecore_wl_input_modifiers;
528 ev->direction = 0;
529
530 if (_ecore_wl_input_surface)
531 {
532 unsigned int id = 0;
533
534 if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface)))
535 {
536 ev->window = id;
537 ev->event_window = id;
538 }
539 }
540
541 /* NB: (FIXME) Currently Wayland provides no measure of how much the
542 * wheel has scrolled (read: delta of movement). So for now, we will
543 * just assume that the amount scrolled is 1 */
544 if ((btn == BTN_EXTRA) || (btn == BTN_FORWARD)) // down
545 ev->z = 1;
546 else if ((btn == BTN_SIDE) || (btn == BTN_BACK)) // up
547 ev->z = -1;
548
549 ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
550 }
551 else
552 {
553 if (state)
554 {
555 _ecore_wl_input_button = btn;
556 _ecore_wl_mouse_down_send(_ecore_wl_input_surface, btn, t);
557 /* NB: Ideally, this is not the place to check for drags.
558 * IMO, drags should be handled by the client. EG: we raise the
559 * mouse_down to the client, and the client can 'request' a
560 * drag_start from ecore_wl */
561 if ((_ecore_wl_input_surface) || (_ecore_wl_touch_surface))
562 {
563 /* record item which was grabbed.
564 * create drag source. start drag */
565 }
566 }
567 else
568 {
569 if ((_ecore_wl_input_surface) || (_ecore_wl_touch_surface))
570 {
571 /* release grabbed button and finish drag */
572 if ((_ecore_wl_input_button) &&
573 (_ecore_wl_input_button == btn))
574 {
575
576 }
577 }
578 _ecore_wl_input_button = 0;
579 _ecore_wl_mouse_up_send(_ecore_wl_input_surface, btn, t);
580 }
581 }
582}
583
584static void
585_ecore_wl_cb_handle_key(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, uint32_t key, uint32_t state)
586{ 400{
587 unsigned int keycode = 0; 401 Ecore_Wl_Display *ewd;
588 402
589 if (dev != _ecore_wl_input_dev) return; 403 LOGFN(__FILE__, __LINE__, __FUNCTION__);
590 404
591 keycode = key + _ecore_wl_xkb->min_key_code; 405 if ((!strcmp(interface, "wl_display")) ||
406 (!strcmp(interface, "wl_drm")) ||
407 (!strcmp(interface, "desktop_shell")))
408 return;
592 409
593 if (state) 410 ewd = data;
594 _ecore_wl_input_modifiers |= _ecore_wl_xkb->map->modmap[keycode];
595 else
596 _ecore_wl_input_modifiers &= ~_ecore_wl_xkb->map->modmap[keycode];
597}
598 411
599static void 412 if (!strcmp(interface, "wl_compositor"))
600_ecore_wl_cb_handle_pointer_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, struct wl_surface *surface, int32_t x, int32_t y, int32_t sx, int32_t sy) 413 ewd->wl.compositor = wl_display_bind(disp, id, &wl_compositor_interface);
601{ 414 else if (!strcmp(interface, "wl_output"))
602 if (dev != _ecore_wl_input_dev) return; 415 _ecore_wl_output_add(ewd, id);
603 416 else if (!strcmp(interface, "wl_input_device"))
604 /* NB: Wayland pointer focus is weird. It's not pointer focus in the normal 417 _ecore_wl_input_add(ewd, id);
605 * sense...Wayland 'moving/resizing' (and maybe other stuff) has a habit 418 else if (!strcmp(interface, "wl_shell"))
606 * of stealing the pointer focus and thus this cannot be used to control 419 ewd->wl.shell = wl_display_bind(disp, id, &wl_shell_interface);
607 * normal pointer focus. On mouse down, the 'active' surface is stolen 420 else if (!strcmp(interface, "wl_shm"))
608 * by Wayland for the grab, so 'surface' here ends up being NULL. When a 421 ewd->wl.shm = wl_display_bind(disp, id, &wl_shm_interface);
609 * move or resize is finished, we get this event again, but this time 422 else if (!strcmp(interface, "wl_data_device_manager"))
610 * with an active surface */
611 _ecore_wl_screen_x = x;
612 _ecore_wl_screen_y = y;
613 _ecore_wl_surface_x = sx;
614 _ecore_wl_surface_y = sy;
615
616 if ((_ecore_wl_input_surface) && (_ecore_wl_input_surface != surface))
617 { 423 {
618 if (!_ecore_wl_input_button) 424 ewd->wl.data_device_manager =
619 _ecore_wl_mouse_out_send(_ecore_wl_input_surface, t); 425 wl_display_bind(disp, id, &wl_data_device_manager_interface);
620 } 426 }
621 427
622 if (surface) 428 if ((ewd->wl.compositor) && (ewd->wl.shm) && (ewd->wl.shell))
623 { 429 {
624 if (_ecore_wl_input_button) 430 Ecore_Wl_Event_Interfaces_Bound *ev;
625 {
626 _ecore_wl_mouse_up_send(surface, _ecore_wl_input_button, t);
627 _ecore_wl_input_button = 0;
628 }
629 else
630 _ecore_wl_mouse_in_send(surface, t);
631 }
632}
633
634static void
635_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)
636{
637 unsigned int *keyend = 0, *i = 0;
638
639 if (dev != _ecore_wl_input_dev) return;
640
641 /* NB: Remove old keyboard focus */
642 if ((_ecore_wl_input_surface) && (_ecore_wl_input_surface != surface))
643 _ecore_wl_focus_out_send(_ecore_wl_input_surface, t);
644 431
645 _ecore_wl_input_surface = NULL; 432 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Interfaces_Bound))))
433 return;
646 434
647 keyend = keys->data + keys->size; 435 ev->compositor = (ewd->wl.compositor != NULL);
648 _ecore_wl_input_modifiers = 0; 436 ev->shm = (ewd->wl.shm != NULL);
649 for (i = keys->data; i < keyend; i++) 437 ev->shell = (ewd->wl.shell != NULL);
650 _ecore_wl_input_modifiers |= _ecore_wl_xkb->map->modmap[*i];
651 438
652 if (surface) 439 ecore_event_add(ECORE_WL_EVENT_INTERFACES_BOUND, ev, NULL, NULL);
653 {
654 /* set new input surface */
655 _ecore_wl_input_surface = surface;
656
657 /* send mouse in to new surface */
658 /* _ecore_wl_mouse_in_send(surface, t); */
659
660 /* send focus to new surface */
661 _ecore_wl_focus_in_send(surface, t);
662 } 440 }
663} 441}
664 442
665static void 443static Eina_Bool
666_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) 444_ecore_wl_egl_init(Ecore_Wl_Display *ewd)
667{ 445{
668 Ecore_Event_Mouse_Button *ev; 446 EGLint major, minor, n;
669 447 static const EGLint context_attribs[] =
670 LOGFN(__FILE__, __LINE__, __FUNCTION__);
671
672 _ecore_wl_touch_surface = surface;
673 _ecore_wl_touch_x = x;
674 _ecore_wl_touch_y = y;
675
676 if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
677
678 ev->timestamp = timestamp;
679
680 /* NB: Need to verify using x,y for these */
681 ev->x = x;
682 ev->y = y;
683 ev->root.x = x;
684 ev->root.y = y;
685 ev->modifiers = 0;
686 ev->buttons = 0;
687 ev->same_screen = 1;
688
689 /* FIXME: Need to get these from Wayland somehow */
690 ev->double_click = 0;
691 ev->triple_click = 0;
692
693 ev->multi.device = id;
694 ev->multi.radius = 1;
695 ev->multi.radius_x = 1;
696 ev->multi.radius_y = 1;
697 ev->multi.pressure = 1.0;
698 ev->multi.angle = 0.0;
699 /* NB: Need to verify using x,y for these */
700 ev->multi.x = x;
701 ev->multi.y = y;
702 ev->multi.root.x = x;
703 ev->multi.root.y = y;
704
705 { 448 {
706 unsigned int id = 0; 449 EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
707 450 };
708 if ((id = (unsigned int)wl_surface_get_user_data(surface))) 451 static const EGLint argb_attribs[] =
709 { 452 {
710 ev->window = id; 453 EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
711 ev->event_window = id; 454 EGL_ALPHA_SIZE, 1, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0,
712 } 455 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE,
713 } 456 EGL_WINDOW_BIT, EGL_NONE
714 457 };
715 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
716}
717
718static void
719_ecore_wl_cb_handle_touch_up(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__, uint32_t timestamp, int32_t id)
720{
721 Ecore_Event_Mouse_Button *ev;
722 458
723 LOGFN(__FILE__, __LINE__, __FUNCTION__); 459 LOGFN(__FILE__, __LINE__, __FUNCTION__);
724 460
725 if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return; 461 ewd->egl.display = eglGetDisplay(ewd->wl.display);
726 462 if (!eglInitialize(ewd->egl.display, &major, &minor))
727 ev->timestamp = timestamp;
728
729 /* TODO: Need to verify using x,y for these */
730 ev->x = _ecore_wl_touch_x;
731 ev->y = _ecore_wl_touch_y;
732 ev->root.x = _ecore_wl_touch_x;
733 ev->root.y = _ecore_wl_touch_y;
734 ev->modifiers = 0;
735 ev->buttons = 0;
736 ev->same_screen = 1;
737
738 /* FIXME: Need to get these from Wayland somehow */
739 ev->double_click = 0;
740 ev->triple_click = 0;
741
742 ev->multi.device = id;
743 ev->multi.radius = 1;
744 ev->multi.radius_x = 1;
745 ev->multi.radius_y = 1;
746 ev->multi.pressure = 1.0;
747 ev->multi.angle = 0.0;
748
749 /* TODO: Need to verify using x,y for these */
750 ev->multi.x = _ecore_wl_touch_x;
751 ev->multi.y = _ecore_wl_touch_y;
752 ev->multi.root.x = _ecore_wl_touch_x;
753 ev->multi.root.y = _ecore_wl_touch_y;
754
755 { 463 {
756 unsigned int id = 0; 464 ERR("Failed to initialize EGL display");
757 465 return EINA_FALSE;
758 if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_touch_surface)))
759 {
760 ev->window = id;
761 ev->event_window = id;
762 }
763 } 466 }
764 467
765 _ecore_wl_touch_surface = NULL; 468 if (!eglBindAPI(EGL_OPENGL_ES_API))
766
767 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
768}
769
770static void
771_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)
772{
773 Ecore_Event_Mouse_Move *ev;
774
775 LOGFN(__FILE__, __LINE__, __FUNCTION__);
776
777 if (!_ecore_wl_touch_surface) return;
778
779 if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
780
781 ev->timestamp = timestamp;
782 /* TODO: Need to verify using x,y for these */
783 ev->x = x;
784 ev->y = y;
785 ev->root.x = x;
786 ev->root.y = y;
787 ev->modifiers = 0; //_ecore_wl_input_modifiers;
788 ev->same_screen = 1;
789
790 ev->multi.device = id;
791 ev->multi.radius = 1;
792 ev->multi.radius_x = 1;
793 ev->multi.radius_y = 1;
794 ev->multi.pressure = 1.0;
795 ev->multi.angle = 0.0;
796
797 /* TODO: Need to verify using x,y for these */
798 ev->multi.x = x;
799 ev->multi.y = y;
800 ev->multi.root.x = x;
801 ev->multi.root.y = y;
802
803 { 469 {
804 unsigned int id = 0; 470 ERR("Failed to bind EGL Api");
805 471 return EINA_FALSE;
806 if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_touch_surface)))
807 {
808 ev->window = id;
809 ev->event_window = id;
810 }
811 } 472 }
812 473
813 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); 474 if ((!eglChooseConfig(ewd->egl.display, argb_attribs, &ewd->egl.argb_config,
814} 475 1, &n)) || (n == 0))
815
816static void
817_ecore_wl_cb_handle_touch_frame(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__)
818{
819 LOGFN(__FILE__, __LINE__, __FUNCTION__);
820
821 /* FIXME: Need to get a device and actually test what happens here */
822}
823
824static void
825_ecore_wl_cb_handle_touch_cancel(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__)
826{
827 LOGFN(__FILE__, __LINE__, __FUNCTION__);
828
829 /* FIXME: Need to get a device and actually test what happens here */
830 _ecore_wl_touch_surface = NULL;
831}
832
833static void
834_ecore_wl_cb_source_target(void *data, struct wl_data_source *source __UNUSED__, const char *mime_type __UNUSED__)
835{
836 Ecore_Wl_Drag_Source *s;
837
838 LOGFN(__FILE__, __LINE__, __FUNCTION__);
839
840 printf("Ecore_Wl Source Target\n");
841 if (!(s = data)) return;
842 printf("\tHave Drag Source\n");
843
844 /* FIXME: buffer here should really be the mouse cursor buffer */
845 wl_data_device_attach(s->data_dev, s->timestamp, s->buffer,
846 s->hotspot_x, s->hotspot_y);
847}
848
849static void
850_ecore_wl_cb_source_send(void *data, struct wl_data_source *source, const char *mime_type, int32_t fd)
851{
852 Ecore_Wl_Drag_Source *s;
853
854 LOGFN(__FILE__, __LINE__, __FUNCTION__);
855
856 printf("Ecore_Wl Source Send\n");
857 if (!(s = data)) return;
858 printf("\tHave Drag Source\n");
859
860 /* FIXME: write message to fd */
861
862 /* NB: Wayland really sucks in this regard. Why should selection stuff
863 * require an 'fd' ?? */
864}
865
866static void
867_ecore_wl_cb_source_cancelled(void *data, struct wl_data_source *source __UNUSED__)
868{
869 Ecore_Wl_Drag_Source *s;
870
871 LOGFN(__FILE__, __LINE__, __FUNCTION__);
872
873 /* The cancelled event usually means source is no longer in use by
874 * the drag (or selection). */
875
876 printf("Ecore_Wl Source Cancel\n");
877 if (!(s = data)) return;
878 printf("\tHave Drag Source\n");
879
880 /* FIXME: raise this to ecore_evas so the surface/buffer
881 * of the drag can be destroyed */
882
883 if (s->data_source) wl_data_source_destroy(s->data_source);
884 s->data_source = NULL;
885
886 free(s);
887}
888
889static void
890_ecore_wl_cb_source_offer(void *data, struct wl_data_offer *offer __UNUSED__, const char *type)
891{
892 Ecore_Wl_Dnd_Source *s;
893
894 if (!(s = data)) return;
895 eina_array_push(s->types, strdup(type));
896}
897
898static void
899_ecore_wl_cb_data_offer(void *data, struct wl_data_device *data_dev, uint32_t id)
900{
901 Ecore_Wl_Dnd_Source *source;
902
903 /* create a new 'data offer' structure and setup a listener for it */
904 if (!(source = calloc(1, sizeof(Ecore_Wl_Dnd_Source)))) return;
905
906 source->types = eina_array_new(1);
907 source->data = data;
908 source->refs = 1;
909
910 /* FIXME: This will need to change when Wayland has typesafe wrappers for this */
911 source->offer = (struct wl_data_offer *)
912 wl_proxy_create_for_id((struct wl_proxy *)data_dev,
913 id, &wl_data_offer_interface);
914
915 wl_data_device_set_user_data(data_dev, source);
916 wl_data_offer_add_listener(source->offer, &_ecore_wl_offer_listener, source);
917}
918
919static void
920_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)
921{
922 Ecore_Wl_Dnd_Source *source;
923
924 if (!(source = wl_data_device_get_user_data(data_dev))) return;
925
926 /* TODO: maybe set pointer focus here ?? */
927
928 source->timestamp = timestamp;
929}
930
931static void
932_ecore_wl_cb_data_leave(void *data __UNUSED__, struct wl_data_device *data_dev)
933{
934 Ecore_Wl_Dnd_Source *source;
935
936 if (!(source = wl_data_device_get_user_data(data_dev))) return;
937
938 /* destroy drag offer */
939 wl_data_offer_destroy(source->offer);
940
941 while (eina_array_count(source->types))
942 free(eina_array_pop(source->types));
943
944 eina_array_free(source->types);
945 free(source);
946
947 wl_data_device_set_user_data(data_dev, NULL);
948}
949
950static void
951_ecore_wl_cb_data_motion(void *data __UNUSED__, struct wl_data_device *data_dev, uint32_t timestamp, int32_t x, int32_t y)
952{
953 Ecore_Wl_Dnd_Source *source;
954
955 if (!(source = wl_data_device_get_user_data(data_dev))) return;
956 /* TODO: Here we should raise motion events for dragging */
957}
958
959static void
960_ecore_wl_cb_data_drop(void *data __UNUSED__, struct wl_data_device *data_dev)
961{
962 Ecore_Wl_Dnd_Source *source;
963
964 if (!(source = wl_data_device_get_user_data(data_dev))) return;
965
966 /* TODO: Raise event for drop */
967
968 wl_data_offer_accept(source->offer, source->timestamp, NULL);
969// eina_array_data_get(source->types, 0));
970}
971
972static void
973_ecore_wl_cb_data_selection(void *data, struct wl_data_device *data_dev, struct wl_data_offer *offer)
974{
975 Ecore_Wl_Dnd_Source *source;
976
977 printf("Ecore_Wl Data Selection\n");
978 if ((source = wl_data_device_get_user_data(data_dev)))
979 { 476 {
980 /* destroy old source */ 477 ERR("Failed to choose ARGB config");
981 wl_data_offer_destroy(source->offer); 478 return EINA_FALSE;
982
983 while (eina_array_count(source->types))
984 free(eina_array_pop(source->types));
985
986 eina_array_free(source->types);
987 free(source);
988
989 wl_data_device_set_user_data(data_dev, NULL);
990 } 479 }
991}
992
993static void
994_ecore_wl_mouse_move_send(uint32_t timestamp)
995{
996 Ecore_Event_Mouse_Move *ev;
997
998// if (!_ecore_wl_input_surface) return;
999
1000 if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
1001
1002 ev->timestamp = timestamp;
1003 ev->x = _ecore_wl_surface_x;
1004 ev->y = _ecore_wl_surface_y;
1005 ev->root.x = _ecore_wl_screen_x;
1006 ev->root.y = _ecore_wl_screen_y;
1007 ev->modifiers = _ecore_wl_input_modifiers;
1008
1009 ev->multi.device = 0;
1010 ev->multi.radius = 1;
1011 ev->multi.radius_x = 1;
1012 ev->multi.radius_y = 1;
1013 ev->multi.pressure = 1.0;
1014 ev->multi.angle = 0.0;
1015 ev->multi.x = _ecore_wl_surface_x;
1016 ev->multi.y = _ecore_wl_surface_y;
1017 ev->multi.root.x = _ecore_wl_screen_x;
1018 ev->multi.root.y = _ecore_wl_screen_y;
1019 480
481 ewd->egl.argb_context =
482 eglCreateContext(ewd->egl.display, ewd->egl.argb_config,
483 EGL_NO_CONTEXT, context_attribs);
484 if (!ewd->egl.argb_context)
1020 { 485 {
1021 unsigned int id = 0; 486 ERR("Failed to create ARGB context");
1022 487 return EINA_FALSE;
1023 if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface)))
1024 {
1025 ev->window = id;
1026 ev->event_window = id;
1027 }
1028 } 488 }
1029 489
1030 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); 490 if (!eglMakeCurrent(ewd->egl.display, EGL_NO_SURFACE,
1031} 491 EGL_NO_SURFACE, ewd->egl.argb_context))
1032
1033static void
1034_ecore_wl_mouse_out_send(struct wl_surface *surface, uint32_t timestamp)
1035{
1036 Ecore_Wl_Event_Mouse_Out *ev;
1037
1038 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_Out)))) return;
1039
1040 ev->x = _ecore_wl_surface_x;
1041 ev->y = _ecore_wl_surface_y;
1042 ev->root.x = _ecore_wl_screen_x;
1043 ev->root.y = _ecore_wl_screen_y;
1044 ev->modifiers = _ecore_wl_input_modifiers;
1045 ev->time = timestamp;
1046
1047 if (surface)
1048 { 492 {
1049 unsigned int id = 0; 493 ERR("Failed to make ARGB context current");
1050 494 return EINA_FALSE;
1051 if ((id = (unsigned int)wl_surface_get_user_data(surface)))
1052 ev->window = id;
1053 } 495 }
1054 496
1055 ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL); 497 return EINA_TRUE;
1056} 498}
1057 499
1058static void 500static Eina_Bool
1059_ecore_wl_mouse_in_send(struct wl_surface *surface, uint32_t timestamp) 501_ecore_wl_egl_shutdown(Ecore_Wl_Display *ewd)
1060{ 502{
1061 Ecore_Wl_Event_Mouse_In *ev; 503 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1062
1063 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) return;
1064
1065 ev->x = _ecore_wl_surface_x;
1066 ev->y = _ecore_wl_surface_y;
1067 ev->root.x = _ecore_wl_screen_x;
1068 ev->root.y = _ecore_wl_screen_y;
1069 ev->modifiers = _ecore_wl_input_modifiers;
1070 ev->time = timestamp;
1071 504
1072 if (surface) 505 eglMakeCurrent(ewd->egl.display,
1073 { 506 EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1074 unsigned int id = 0;
1075 507
1076 if ((id = (unsigned int)wl_surface_get_user_data(surface))) 508 eglDestroyContext(ewd->egl.display, ewd->egl.argb_context);
1077 ev->window = id;
1078 }
1079
1080 ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL);
1081}
1082 509
1083static void 510 /* NB: This is hanging when we run elm apps as wayland clients
1084_ecore_wl_mouse_up_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp) 511 * inside the weston compositor */
1085{
1086 Ecore_Event_Mouse_Button *ev;
1087
1088 if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
1089
1090 if (button == BTN_LEFT)
1091 ev->buttons = 1;
1092 else if (button == BTN_MIDDLE)
1093 ev->buttons = 2;
1094 else if (button == BTN_RIGHT)
1095 ev->buttons = 3;
1096
1097 ev->timestamp = timestamp;
1098 ev->x = _ecore_wl_surface_x;
1099 ev->y = _ecore_wl_surface_y;
1100 ev->root.x = _ecore_wl_screen_x;
1101 ev->root.y = _ecore_wl_screen_y;
1102 ev->modifiers = _ecore_wl_input_modifiers;
1103
1104 /* FIXME: Need to get these from Wayland somehow */
1105 ev->double_click = 0;
1106 ev->triple_click = 0;
1107
1108 ev->multi.device = 0;
1109 ev->multi.radius = 1;
1110 ev->multi.radius_x = 1;
1111 ev->multi.radius_y = 1;
1112 ev->multi.pressure = 1.0;
1113 ev->multi.angle = 0.0;
1114 ev->multi.x = _ecore_wl_surface_x;
1115 ev->multi.y = _ecore_wl_surface_y;
1116 ev->multi.root.x = _ecore_wl_screen_x;
1117 ev->multi.root.y = _ecore_wl_screen_y;
1118 512
1119 { 513 /* printf("Egl Terminate\n"); */
1120 unsigned int id = 0; 514 /* eglTerminate(ewd->egl.display); */
515 /* printf("Egl Terminate Done\n"); */
1121 516
1122 if ((id = (unsigned int)wl_surface_get_user_data(surface))) 517 eglReleaseThread();
1123 {
1124 ev->window = id;
1125 ev->event_window = id;
1126 }
1127 }
1128 518
1129 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); 519 return EINA_TRUE;
1130} 520}
1131 521
1132static void 522static Eina_Bool
1133_ecore_wl_mouse_down_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp) 523_ecore_wl_xkb_init(Ecore_Wl_Display *ewd)
1134{ 524{
1135 Ecore_Event_Mouse_Button *ev; 525 struct xkb_rule_names names;
1136
1137 if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
1138
1139 if (button == BTN_LEFT)
1140 ev->buttons = 1;
1141 else if (button == BTN_MIDDLE)
1142 ev->buttons = 2;
1143 else if (button == BTN_RIGHT)
1144 ev->buttons = 3;
1145
1146 ev->timestamp = timestamp;
1147 ev->x = _ecore_wl_surface_x;
1148 ev->y = _ecore_wl_surface_y;
1149 ev->root.x = _ecore_wl_screen_x;
1150 ev->root.y = _ecore_wl_screen_y;
1151 ev->modifiers = _ecore_wl_input_modifiers;
1152
1153 /* FIXME: Need to get these from Wayland somehow */
1154 ev->double_click = 0;
1155 ev->triple_click = 0;
1156
1157 ev->multi.device = 0;
1158 ev->multi.radius = 1;
1159 ev->multi.radius_x = 1;
1160 ev->multi.radius_y = 1;
1161 ev->multi.pressure = 1.0;
1162 ev->multi.angle = 0.0;
1163 ev->multi.x = _ecore_wl_surface_x;
1164 ev->multi.y = _ecore_wl_surface_y;
1165 ev->multi.root.x = _ecore_wl_screen_x;
1166 ev->multi.root.y = _ecore_wl_screen_y;
1167 526
1168 { 527 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1169 unsigned int id = 0;
1170
1171 if ((id = (unsigned int)wl_surface_get_user_data(surface)))
1172 {
1173 ev->window = id;
1174 ev->event_window = id;
1175 }
1176 }
1177 528
1178 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); 529 names.rules = "evdev";
1179} 530 names.model = "evdev";
531 names.layout = "us";
532 names.variant = "";
533 names.options = "";
1180 534
1181static void 535 if (!(ewd->xkb = xkb_compile_keymap_from_rules(&names)))
1182_ecore_wl_focus_out_send(struct wl_surface *surface, uint32_t timestamp)
1183{
1184 Ecore_Wl_Event_Focus_Out *ev;
1185
1186 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return;
1187 ev->time = timestamp;
1188 if (surface)
1189 { 536 {
1190 unsigned int id = 0; 537 ERR("Failed to compile keymap");
1191 538 return EINA_FALSE;
1192 if ((id = (unsigned int)wl_surface_get_user_data(surface)))
1193 ev->window = id;
1194 } 539 }
1195 ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL); 540
541 return EINA_TRUE;
1196} 542}
1197 543
1198static void 544static Eina_Bool
1199_ecore_wl_focus_in_send(struct wl_surface *surface, uint32_t timestamp) 545_ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd)
1200{ 546{
1201 Ecore_Wl_Event_Focus_In *ev; 547 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1202
1203 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return;
1204 ev->time = timestamp;
1205 if (surface)
1206 {
1207 unsigned int id = 0;
1208 548
1209 if ((id = (unsigned int)wl_surface_get_user_data(surface))) 549 if (ewd->xkb) xkb_free_keymap(ewd->xkb);
1210 ev->window = id; 550 return EINA_TRUE;
1211 }
1212 ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL);
1213} 551}