From bcd949fa03a6c8ab28f3dd5c8180f62609ea4dbe Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 10 Sep 2015 11:03:23 -0400 Subject: [PATCH] ecore-wl2: Add start of Ecore_Wl2_Input code Signed-off-by: Chris Michael --- src/Makefile_Ecore_Wl2.am | 1 + src/lib/ecore_wl2/Ecore_Wl2.h | 1 + src/lib/ecore_wl2/ecore_wl2_display.c | 2 + src/lib/ecore_wl2/ecore_wl2_input.c | 145 ++++++++++++++++++++++++++ src/lib/ecore_wl2/ecore_wl2_private.h | 75 +++++++++++++ 5 files changed, 224 insertions(+) create mode 100644 src/lib/ecore_wl2/ecore_wl2_input.c diff --git a/src/Makefile_Ecore_Wl2.am b/src/Makefile_Ecore_Wl2.am index d3a6369ae3..1b73f71dee 100644 --- a/src/Makefile_Ecore_Wl2.am +++ b/src/Makefile_Ecore_Wl2.am @@ -11,6 +11,7 @@ lib_ecore_wl2_libecore_wl2_la_SOURCES = \ lib/ecore_wl2/xdg-shell-client-protocol.h \ lib/ecore_wl2/xdg-shell-protocol.c \ lib/ecore_wl2/ecore_wl2_window.c \ +lib/ecore_wl2/ecore_wl2_input.c \ lib/ecore_wl2/ecore_wl2_output.c \ lib/ecore_wl2/ecore_wl2_display.c \ lib/ecore_wl2/ecore_wl2.c \ diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index db97ce4f0c..2abbad5c98 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -34,6 +34,7 @@ typedef struct _Ecore_Wl2_Window Ecore_Wl2_Window; typedef struct _Ecore_Wl2_Display Ecore_Wl2_Display; typedef struct _Ecore_Wl2_Output Ecore_Wl2_Output; +typedef struct _Ecore_Wl2_Input Ecore_Wl2_Input; typedef struct _Ecore_Wl2_Global { diff --git a/src/lib/ecore_wl2/ecore_wl2_display.c b/src/lib/ecore_wl2/ecore_wl2_display.c index 07e6a9d6d4..8fea4fcf10 100644 --- a/src/lib/ecore_wl2/ecore_wl2_display.c +++ b/src/lib/ecore_wl2/ecore_wl2_display.c @@ -89,6 +89,8 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const } else if (!strcmp(interface, "wl_output")) _ecore_wl2_output_add(ewd, id); + else if (!strcmp(interface, "wl_seat")) + _ecore_wl2_input_add(ewd, id); /* allocate space for event structure */ ev = calloc(1, sizeof(Ecore_Wl2_Event_Global)); diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c new file mode 100644 index 0000000000..dc62ae27ba --- /dev/null +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -0,0 +1,145 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "ecore_wl2_private.h" + +static const struct wl_data_device_listener _data_listener = +{ + NULL, // data offer + NULL, // data enter + NULL, // data leave + NULL, // data motion + NULL, // data drop + NULL, // data selection +}; + +static void +_seat_cb_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) +{ + Ecore_Wl2_Input *input; + + input = data; + if (!input) return; + + if ((caps & WL_SEAT_CAPABILITY_POINTER) && (!input->wl.pointer)) + { + input->wl.pointer = wl_seat_get_pointer(seat); + wl_pointer_set_user_data(input->wl.pointer, input); + /* TODO: pointer listener */ + /* TODO: pointer surface */ + } + else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->wl.pointer)) + { + if (input->cursor.surface) wl_surface_destroy(input->cursor.surface); + input->cursor.surface = NULL; + + wl_pointer_destroy(input->wl.pointer); + input->wl.pointer = NULL; + } + else if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && (!input->wl.keyboard)) + { + input->wl.keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_set_user_data(input->wl.keyboard, input); + /* TODO: keyboard listener */ + } + else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (input->wl.keyboard)) + { + wl_keyboard_destroy(input->wl.keyboard); + input->wl.keyboard = NULL; + } + else if ((caps & WL_SEAT_CAPABILITY_TOUCH) && (!input->wl.touch)) + { + input->wl.touch = wl_seat_get_touch(seat); + wl_touch_set_user_data(input->wl.touch, input); + /* TODO: touch listener */ + } + else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && (input->wl.touch)) + { + wl_touch_destroy(input->wl.touch); + input->wl.touch = NULL; + } +} + +static const struct wl_seat_listener _seat_listener = +{ + _seat_cb_capabilities, + NULL +}; + +void +_ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id) +{ + Ecore_Wl2_Input *input; + + input = calloc(1, sizeof(Ecore_Wl2_Input)); + if (!input) return; + + input->display = display; + + input->repeat.rate = 0.025; + input->repeat.delay = 0.4; + input->repeat.enabled = EINA_TRUE; + + wl_array_init(&input->data.types); + + /* TODO: setup cursor size and theme */ + + input->wl.seat = + wl_registry_bind(wl_display_get_registry(display->wl.display), + id, &wl_seat_interface, 1); + + display->inputs = + eina_inlist_append(display->inputs, EINA_INLIST_GET(input)); + + wl_seat_add_listener(input->wl.seat, &_seat_listener, input); + wl_seat_set_user_data(input->wl.seat, input); + + if (!display->wl.data_device_manager) return; + + input->data.device = + wl_data_device_manager_get_data_device(display->wl.data_device_manager, + input->wl.seat); + wl_data_device_add_listener(input->data.device, &_data_listener, input); +} + +void +_ecore_wl2_input_del(Ecore_Wl2_Input *input) +{ + Ecore_Wl2_Display *display; + + if (!input) return; + + display = input->display; + + if (input->repeat.timer) ecore_timer_del(input->repeat.timer); + + if (input->cursor.surface) wl_surface_destroy(input->cursor.surface); + if (input->cursor.name) eina_stringshare_del(input->cursor.name); + if (input->cursor.theme) eina_stringshare_del(input->cursor.theme); + + if (input->data.types.data) + { + char **t; + + wl_array_for_each(t, &input->data.types) + free(*t); + + wl_array_release(&input->data.types); + } + + if (input->data.source) wl_data_source_destroy(input->data.source); + /* TODO: cleanup dnd */ + /* TODO: cleanup selection */ + if (input->data.device) wl_data_device_destroy(input->data.device); + + if (input->xkb.state) xkb_state_unref(input->xkb.state); + if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap); + + if (input->wl.seat) wl_seat_destroy(input->wl.seat); + + display->inputs = + eina_inlist_remove(display->inputs, EINA_INLIST_GET(input)); + + free(input); +} diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index 18c851a7ab..0f1741a01d 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -61,6 +61,7 @@ struct _Ecore_Wl2_Display Eina_Hash *globals; Eina_Inlist *outputs; + Eina_Inlist *inputs; Eina_Bool sync_done : 1; }; @@ -103,7 +104,81 @@ struct _Ecore_Wl2_Output Eina_Rectangle geometry; }; +struct _Ecore_Wl2_Input +{ + EINA_INLIST; + + Ecore_Wl2_Display *display; + + struct + { + struct wl_seat *seat; + struct wl_pointer *pointer; + struct wl_keyboard *keyboard; + struct wl_touch *touch; + } wl; + + struct + { + struct wl_data_device *device; + struct wl_data_source *source; + struct wl_array types; + } data; + + struct + { + const char *name, *theme; + unsigned int index, size; + struct wl_cursor *wl_cursor; + struct wl_surface *surface; + struct wl_callback *frame_cb; + Ecore_Timer *timer; + } cursor; + + struct + { + Ecore_Wl2_Window *pointer; + Ecore_Wl2_Window *keyboard; + Ecore_Wl2_Window *touch; + } focus; + + struct + { + unsigned int button, count, timestamp; + Ecore_Wl2_Window *window; + } grab; + + struct + { + struct xkb_keymap *keymap; + struct xkb_state *state; + xkb_mod_mask_t control_mask; + xkb_mod_mask_t alt_mask; + xkb_mod_mask_t shift_mask; + xkb_mod_mask_t win_mask; + xkb_mod_mask_t scroll_mask; + xkb_mod_mask_t num_mask; + xkb_mod_mask_t caps_mask; + xkb_mod_mask_t altgr_mask; + unsigned int mods_depressed; + unsigned int mods_latched; + unsigned int mods_locked; + unsigned int mods_group; + } xkb; + + struct + { + Ecore_Timer *timer; + unsigned int sym, key, time; + double rate, delay; + Eina_Bool enabled : 1; + } repeat; +}; + void _ecore_wl2_output_add(Ecore_Wl2_Display *display, unsigned int id); void _ecore_wl2_output_del(Ecore_Wl2_Output *output); +void _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id); +void _ecore_wl2_input_del(Ecore_Wl2_Input *input); + #endif