efl/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c

1096 lines
33 KiB
C

#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 ?? */
#include <fcntl.h>
#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
#include <X11/extensions/XKBcommon.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 x, int32_t y, 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 x, int32_t y, 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, const char *mime_type);
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);
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, 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, struct wl_data_device *data_dev __UNUSED__);
static void _ecore_wl_cb_data_motion(void *data, struct wl_data_device *data_dev, uint32_t timestamp, int32_t x, int32_t y);
static void _ecore_wl_cb_data_drop(void *data, 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_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);
/* 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;
static uint32_t _ecore_wl_input_button = 0;
static struct wl_compositor *_ecore_wl_comp;
static struct wl_shm *_ecore_wl_shm;
static struct wl_shell *_ecore_wl_shell;
static struct wl_output *_ecore_wl_output;
static struct wl_input_device *_ecore_wl_input_dev;
static struct wl_surface *_ecore_wl_input_surface;
static struct wl_surface *_ecore_wl_touch_surface;
static struct wl_data_device_manager *_ecore_wl_data_manager;
static struct wl_data_device *_ecore_wl_data_dev;
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;
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_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 (!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)
{
EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland.");
eina_shutdown();
return --_ecore_wl_init_count;
}
if (!ecore_init())
{
eina_log_domain_unregister(_ecore_wl_log_dom);
_ecore_wl_log_dom = -1;
eina_shutdown();
return --_ecore_wl_init_count;
}
if (!ecore_event_init())
{
eina_log_domain_unregister(_ecore_wl_log_dom);
_ecore_wl_log_dom = -1;
ecore_shutdown();
eina_shutdown();
return --_ecore_wl_init_count;
}
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();
}
/* 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)))
{
ERR("Could not compile keymap");
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;
}
/* connect to the wayland display */
if (!(_ecore_wl_disp = wl_display_connect(name)))
{
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;
}
/* setup handler for wayland interfaces */
wl_display_add_global_listener(_ecore_wl_disp,
_ecore_wl_cb_disp_handle_global, NULL);
/* process connection events */
wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
fd = wl_display_get_fd(_ecore_wl_disp,
_ecore_wl_cb_disp_event_mask_update, NULL);
_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_destroy(_ecore_wl_disp);
_ecore_wl_disp = NULL;
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;
}
return _ecore_wl_init_count;
}
EAPI int
ecore_wl_shutdown(void)
{
return _ecore_wl_shutdown(EINA_TRUE);
}
EAPI struct wl_display *
ecore_wl_display_get(void)
{
return _ecore_wl_disp;
}
EAPI struct wl_shm *
ecore_wl_shm_get(void)
{
return _ecore_wl_shm;
}
EAPI struct wl_compositor *
ecore_wl_compositor_get(void)
{
return _ecore_wl_comp;
}
EAPI struct wl_shell *
ecore_wl_shell_get(void)
{
return _ecore_wl_shell;
}
EAPI struct wl_input_device *
ecore_wl_input_device_get(void)
{
return _ecore_wl_input_dev;
}
EAPI void
ecore_wl_screen_size_get(int *w, int *h)
{
if (w) *w = _ecore_wl_screen.w;
if (h) *h = _ecore_wl_screen.h;
}
EAPI unsigned int
ecore_wl_format_get(void)
{
return _ecore_wl_disp_format;
}
EAPI void
ecore_wl_flush(void)
{
wl_display_flush(_ecore_wl_disp);
}
EAPI void
ecore_wl_sync(void)
{
wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
}
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;
}
/* local functions */
static Eina_Bool
_ecore_wl_shutdown(Eina_Bool close_display)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
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);
if (_ecore_wl_fd_hdl) ecore_main_fd_handler_del(_ecore_wl_fd_hdl);
_ecore_wl_fd_hdl = NULL;
if (close_display)
{
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)
{
wl_display_flush(_ecore_wl_disp);
wl_display_destroy(_ecore_wl_disp);
}
_ecore_wl_disp = NULL;
}
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;
}
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);
_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);
}
else if (!strcmp(interface, "wl_data_device_manager"))
{
_ecore_wl_data_manager =
wl_display_bind(_ecore_wl_disp, id,
&wl_data_device_manager_interface);
}
}
static int
_ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__)
{
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
_ecore_wl_disp_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__)
{
struct wl_display *disp;
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!(disp = data)) return ECORE_CALLBACK_RENEW;
if (disp != _ecore_wl_disp) return ECORE_CALLBACK_RENEW;
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);
return ECORE_CALLBACK_RENEW;
}
static 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)
{
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);
}
static void
_ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state)
{
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
{
if (state)
{
_ecore_wl_input_button = btn;
_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;
_ecore_wl_mouse_up_send(_ecore_wl_input_surface, btn, t);
}
}
}
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 (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 x, int32_t y, int32_t sx, int32_t sy)
{
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))
{
if (!_ecore_wl_input_button)
_ecore_wl_mouse_out_send(_ecore_wl_input_surface, t);
}
if (surface)
{
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;
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)
{
/* 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);
}
}
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;
_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;
{
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_cb_handle_touch_up(void *data __UNUSED__, struct wl_input_device *dev __UNUSED__, uint32_t timestamp, int32_t id)
{
Ecore_Event_Mouse_Button *ev;
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;
{
unsigned int id = 0;
if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_touch_surface)))
{
ev->window = id;
ev->event_window = id;
}
}
_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;
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;
{
unsigned int id = 0;
if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_touch_surface)))
{
ev->window = id;
ev->event_window = id;
}
}
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__)
{
/* 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__)
{
/* 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, const char *mime_type)
{
Ecore_Wl_Event_Drag_Start *ev;
if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Drag_Start)))) return;
// wl_data_device_set_user_data(data_dev, source);
/* ev->device = ; */
/* ev->surface = ; */
/* ev->mime_type = mime_type; */
/* ev->timestamp = ; */
/* will need to pass the device to the callback/event */
/* raise a callback/event to have Ecore_Evas do: */
/* create a surface & buffer to represent the dragging object */
/* attach buffer to the surface */
/* attach to device */
ecore_event_add(ECORE_WL_EVENT_DRAG_START, ev, NULL, NULL);
}
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)
{
/* raise this to ecore_evas so the surface/buffer
* of the drag can be destroyed */
/* The cancelled event usually means source is no longer in use by
* the drag (or selection). */
}
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;
/* data being offered. Could be dnd, or selection */
/* 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;
/* NB: 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, 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 __UNUSED__)
{
}
static void
_ecore_wl_cb_data_motion(void *data, struct wl_data_device *data_dev, uint32_t timestamp, int32_t x, int32_t y)
{
}
static void
_ecore_wl_cb_data_drop(void *data, 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_mouse_move_send(uint32_t timestamp)
{
Ecore_Event_Mouse_Move *ev;
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;
{
unsigned int id = 0;
if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface)))
{
ev->window = id;
ev->event_window = id;
}
}
ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
}
static void
_ecore_wl_mouse_out_send(struct wl_surface *surface, uint32_t timestamp)
{
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;
}
ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL);
}
static void
_ecore_wl_mouse_in_send(struct wl_surface *surface, uint32_t timestamp)
{
Ecore_Wl_Event_Mouse_In *ev;
if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) 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;
}
ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL);
}
static void
_ecore_wl_mouse_up_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp)
{
Ecore_Event_Mouse_Button *ev;
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;
{
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_UP, ev, NULL, NULL);
}
static void
_ecore_wl_mouse_down_send(struct wl_surface *surface, uint32_t button, uint32_t timestamp)
{
Ecore_Event_Mouse_Button *ev;
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;
{
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);
}