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.c1213
1 files changed, 1213 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c b/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c
new file mode 100644
index 0000000..f62503b
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c
@@ -0,0 +1,1213 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include "Ecore.h"
6#include "ecore_private.h"
7#include "Ecore_Input.h"
8#include "ecore_wl_private.h"
9#include "Ecore_Wayland.h"
10
11/* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ...
12 * What about other OSs ?? */
13#include <fcntl.h>
14#ifdef __linux__
15# include <linux/input.h>
16#else
17# define BTN_LEFT 0x110
18# define BTN_RIGHT 0x111
19# define BTN_MIDDLE 0x112
20# define BTN_SIDE 0x113
21# define BTN_EXTRA 0x114
22# define BTN_FORWARD 0x115
23# define BTN_BACK 0x116
24#endif
25
26#include <X11/extensions/XKBcommon.h>
27
28/* local function prototypes */
29static Eina_Bool _ecore_wl_shutdown(Eina_Bool close_display);
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__);
31static int _ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __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__);
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__);
34static Eina_Bool _ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__);
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);
36static void _ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state);
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
64/* local variables */
65static 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
129/* external variables */
130int _ecore_wl_log_dom = -1;
131EAPI int ECORE_WL_EVENT_MOUSE_IN = 0;
132EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0;
133EAPI int ECORE_WL_EVENT_FOCUS_IN = 0;
134EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0;
135EAPI int ECORE_WL_EVENT_DRAG_START = 0;
136EAPI int ECORE_WL_EVENT_DRAG_STOP = 0;
137
138EAPI int
139ecore_wl_init(const char *name)
140{
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__);
148
149 if (!eina_init()) return --_ecore_wl_init_count;
150
151 _ecore_wl_log_dom =
152 eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR);
153 if (_ecore_wl_log_dom < 0)
154 {
155 EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland.");
156 eina_shutdown();
157 return --_ecore_wl_init_count;
158 }
159
160 if (!ecore_init())
161 {
162 eina_log_domain_unregister(_ecore_wl_log_dom);
163 _ecore_wl_log_dom = -1;
164 eina_shutdown();
165 return --_ecore_wl_init_count;
166 }
167
168 if (!ecore_event_init())
169 {
170 eina_log_domain_unregister(_ecore_wl_log_dom);
171 _ecore_wl_log_dom = -1;
172 ecore_shutdown();
173 eina_shutdown();
174 return --_ecore_wl_init_count;
175 }
176
177 if (!ECORE_WL_EVENT_MOUSE_IN)
178 {
179 ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new();
180 ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new();
181 ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new();
182 ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new();
183 ECORE_WL_EVENT_DRAG_START = ecore_event_type_new();
184 ECORE_WL_EVENT_DRAG_STOP = ecore_event_type_new();
185 }
186
187 /* init xkb */
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 {
196 ERR("Could not compile keymap");
197 eina_log_domain_unregister(_ecore_wl_log_dom);
198 _ecore_wl_log_dom = -1;
199 ecore_event_shutdown();
200 ecore_shutdown();
201 eina_shutdown();
202 return --_ecore_wl_init_count;
203 }
204
205 /* connect to the wayland display */
206 if (!(_ecore_wl_disp = wl_display_connect(name)))
207 {
208 eina_log_domain_unregister(_ecore_wl_log_dom);
209 _ecore_wl_log_dom = -1;
210 ecore_event_shutdown();
211 ecore_shutdown();
212 eina_shutdown();
213 return --_ecore_wl_init_count;
214 }
215
216 /* setup handler for wayland interfaces */
217 wl_display_add_global_listener(_ecore_wl_disp,
218 _ecore_wl_cb_disp_handle_global, NULL);
219
220 /* process connection events */
221 wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
222
223 fd = wl_display_get_fd(_ecore_wl_disp,
224 _ecore_wl_cb_disp_event_mask_update, NULL);
225
226 _ecore_wl_fd_hdl =
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 {
231 wl_display_destroy(_ecore_wl_disp);
232 _ecore_wl_disp = NULL;
233 eina_log_domain_unregister(_ecore_wl_log_dom);
234 _ecore_wl_log_dom = -1;
235 ecore_event_shutdown();
236 ecore_shutdown();
237 eina_shutdown();
238 return --_ecore_wl_init_count;
239 }
240
241 return _ecore_wl_init_count;
242}
243
244EAPI int
245ecore_wl_shutdown(void)
246{
247 return _ecore_wl_shutdown(EINA_TRUE);
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
268EAPI struct wl_shell *
269ecore_wl_shell_get(void)
270{
271 return _ecore_wl_shell;
272}
273
274EAPI struct wl_input_device *
275ecore_wl_input_device_get(void)
276{
277 return _ecore_wl_input_dev;
278}
279
280EAPI void
281ecore_wl_screen_size_get(int *w, int *h)
282{
283 if (w) *w = _ecore_wl_screen.w;
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
293EAPI void
294ecore_wl_flush(void)
295{
296 wl_display_flush(_ecore_wl_disp);
297}
298
299EAPI void
300ecore_wl_sync(void)
301{
302 wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
303}
304
305EAPI void
306ecore_wl_pointer_xy_get(int *x, int *y)
307{
308 if (x) *x = _ecore_wl_screen_x;
309 if (y) *y = _ecore_wl_screen_y;
310}
311
312EAPI Ecore_Wl_Drag_Source *
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)
314{
315 Ecore_Wl_Drag_Source *source;
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}
341
342EAPI void
343ecore_wl_drag_start(Ecore_Wl_Drag_Source *source, struct wl_surface *surface, struct wl_buffer *buffer)
344{
345 source->buffer = buffer;
346
347 wl_data_device_start_drag(source->data_dev, source->data_source,
348 surface, source->timestamp);
349}
350
351EAPI void
352ecore_wl_drag_stop(void)
353{
354
355}
356
357/* local functions */
358static Eina_Bool
359_ecore_wl_shutdown(Eina_Bool close_display)
360{
361 LOGFN(__FILE__, __LINE__, __FUNCTION__);
362
363 if (--_ecore_wl_init_count != 0)
364 return _ecore_wl_init_count;
365
366 if (!_ecore_wl_disp) return _ecore_wl_init_count;
367
368 if (_ecore_wl_xkb) free(_ecore_wl_xkb);
369
370 if (_ecore_wl_fd_hdl) ecore_main_fd_handler_del(_ecore_wl_fd_hdl);
371 _ecore_wl_fd_hdl = NULL;
372
373 if (close_display)
374 {
375 if (_ecore_wl_data_dev) wl_data_device_destroy(_ecore_wl_data_dev);
376 if (_ecore_wl_input_dev) wl_input_device_destroy(_ecore_wl_input_dev);
377 if (_ecore_wl_data_manager)
378 wl_data_device_manager_destroy(_ecore_wl_data_manager);
379 if (_ecore_wl_shell) wl_shell_destroy(_ecore_wl_shell);
380 if (_ecore_wl_shm) wl_shm_destroy(_ecore_wl_shm);
381 if (_ecore_wl_comp) wl_compositor_destroy(_ecore_wl_comp);
382 if (_ecore_wl_disp)
383 {
384 wl_display_flush(_ecore_wl_disp);
385 wl_display_destroy(_ecore_wl_disp);
386 }
387 _ecore_wl_disp = NULL;
388 }
389
390 eina_log_domain_unregister(_ecore_wl_log_dom);
391 _ecore_wl_log_dom = -1;
392
393 ecore_event_shutdown();
394 ecore_shutdown();
395 eina_shutdown();
396
397 return _ecore_wl_init_count;
398}
399
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
453_ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__)
454{
455// LOGFN(__FILE__, __LINE__, __FUNCTION__);
456
457 _ecore_wl_disp_mask = mask;
458
459 return 0;
460}
461
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
480_ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__)
481{
482 struct wl_display *disp;
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
489 if (_ecore_wl_disp_mask & WL_DISPLAY_WRITABLE)
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
495 return ECORE_CALLBACK_RENEW;
496}
497
498static 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)
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{
587 unsigned int keycode = 0;
588
589 if (dev != _ecore_wl_input_dev) return;
590
591 keycode = key + _ecore_wl_xkb->min_key_code;
592
593 if (state)
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
599static void
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)
601{
602 if (dev != _ecore_wl_input_dev) return;
603
604 /* NB: Wayland pointer focus is weird. It's not pointer focus in the normal
605 * sense...Wayland 'moving/resizing' (and maybe other stuff) has a habit
606 * of stealing the pointer focus and thus this cannot be used to control
607 * normal pointer focus. On mouse down, the 'active' surface is stolen
608 * by Wayland for the grab, so 'surface' here ends up being NULL. When a
609 * move or resize is finished, we get this event again, but this time
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 {
618 if (!_ecore_wl_input_button)
619 _ecore_wl_mouse_out_send(_ecore_wl_input_surface, t);
620 }
621
622 if (surface)
623 {
624 if (_ecore_wl_input_button)
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
645 _ecore_wl_input_surface = NULL;
646
647 keyend = keys->data + keys->size;
648 _ecore_wl_input_modifiers = 0;
649 for (i = keys->data; i < keyend; i++)
650 _ecore_wl_input_modifiers |= _ecore_wl_xkb->map->modmap[*i];
651
652 if (surface)
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 }
663}
664
665static void
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)
667{
668 Ecore_Event_Mouse_Button *ev;
669
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 {
706 unsigned int id = 0;
707
708 if ((id = (unsigned int)wl_surface_get_user_data(surface)))
709 {
710 ev->window = id;
711 ev->event_window = id;
712 }
713 }
714
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
723 LOGFN(__FILE__, __LINE__, __FUNCTION__);
724
725 if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
726
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 {
756 unsigned int id = 0;
757
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 }
764
765 _ecore_wl_touch_surface = NULL;
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 {
804 unsigned int id = 0;
805
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 }
812
813 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
814}
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 {
980 /* destroy old source */
981 wl_data_offer_destroy(source->offer);
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 }
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
1020 {
1021 unsigned int id = 0;
1022
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 }
1029
1030 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
1031}
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 {
1049 unsigned int id = 0;
1050
1051 if ((id = (unsigned int)wl_surface_get_user_data(surface)))
1052 ev->window = id;
1053 }
1054
1055 ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL);
1056}
1057
1058static void
1059_ecore_wl_mouse_in_send(struct wl_surface *surface, uint32_t timestamp)
1060{
1061 Ecore_Wl_Event_Mouse_In *ev;
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
1072 if (surface)
1073 {
1074 unsigned int id = 0;
1075
1076 if ((id = (unsigned int)wl_surface_get_user_data(surface)))
1077 ev->window = id;
1078 }
1079
1080 ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL);
1081}
1082
1083static void
1084_ecore_wl_mouse_up_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp)
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
1119 {
1120 unsigned int id = 0;
1121
1122 if ((id = (unsigned int)wl_surface_get_user_data(surface)))
1123 {
1124 ev->window = id;
1125 ev->event_window = id;
1126 }
1127 }
1128
1129 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
1130}
1131
1132static void
1133_ecore_wl_mouse_down_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp)
1134{
1135 Ecore_Event_Mouse_Button *ev;
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
1168 {
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
1178 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
1179}
1180
1181static void
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 {
1190 unsigned int id = 0;
1191
1192 if ((id = (unsigned int)wl_surface_get_user_data(surface)))
1193 ev->window = id;
1194 }
1195 ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL);
1196}
1197
1198static void
1199_ecore_wl_focus_in_send(struct wl_surface *surface, uint32_t timestamp)
1200{
1201 Ecore_Wl_Event_Focus_In *ev;
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
1209 if ((id = (unsigned int)wl_surface_get_user_data(surface)))
1210 ev->window = id;
1211 }
1212 ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL);
1213}