diff --git a/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h b/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h index 15f6b7fc4a..b664e4bd32 100644 --- a/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h +++ b/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h @@ -9,6 +9,7 @@ # include # include +# include # include # ifdef EAPI @@ -97,6 +98,8 @@ struct _Ecore_Wl_Display xkb_mod_mask_t shift_mask; } xkb; + struct wl_cursor_theme *cursor_theme; + Ecore_Wl_Output *output; Ecore_Wl_Input *input; @@ -303,9 +306,13 @@ EAPI void ecore_wl_screen_size_get(int *w, int *h); EAPI void ecore_wl_pointer_xy_get(int *x, int *y); EAPI int ecore_wl_dpi_get(void); EAPI void ecore_wl_display_iterate(void); +EAPI struct wl_cursor *ecore_wl_cursor_get(const char *cursor_name); EAPI void ecore_wl_input_grab(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button); EAPI void ecore_wl_input_ungrab(Ecore_Wl_Input *input); +EAPI void ecore_wl_input_pointer_set(Ecore_Wl_Input *input, struct wl_buffer *buffer, int hot_x, int hot_y); +EAPI void ecore_wl_input_cursor_from_name_set(Ecore_Wl_Input *input, const char *cursor_name); +EAPI void ecore_wl_input_cursor_default_restore(Ecore_Wl_Input *input); EAPI struct wl_list ecore_wl_outputs_get(void); @@ -327,7 +334,9 @@ EAPI struct wl_surface *ecore_wl_window_surface_get(Ecore_Wl_Window *win); EAPI struct wl_shell_surface *ecore_wl_window_shell_surface_get(Ecore_Wl_Window *win); EAPI Ecore_Wl_Window *ecore_wl_window_find(unsigned int id); EAPI void ecore_wl_window_type_set(Ecore_Wl_Window *win, Ecore_Wl_Window_Type type); -EAPI void ecore_wl_window_pointer_set(Ecore_Wl_Window *win, struct wl_buffer *buffer, int hot_x, int hot_y, unsigned int timestamp); +EAPI void ecore_wl_window_pointer_set(Ecore_Wl_Window *win, struct wl_buffer *buffer, int hot_x, int hot_y); +EAPI void ecore_wl_window_cursor_from_name_set(Ecore_Wl_Window *win, const char *cursor_name); +EAPI void ecore_wl_window_cursor_default_restore(Ecore_Wl_Window *win); EAPI void ecore_wl_window_parent_set(Ecore_Wl_Window *win, Ecore_Wl_Window *parent); #endif diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c b/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c index 5abbd24730..5f04108276 100644 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c +++ b/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c @@ -316,6 +316,24 @@ ecore_wl_display_iterate(void) wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_READABLE); } +/** + * Retrieves the requested cursor from the cursor theme + * + * @param cursor_name The desired cursor name to be looked up in the theme + * @return the cursor or NULL if the cursor cannot be found + * + * @since 1.2 + */ +EAPI struct wl_cursor * +ecore_wl_cursor_get(const char *cursor_name) +{ + if ((!_ecore_wl_disp) || (!_ecore_wl_disp->cursor_theme)) + return NULL; + + return wl_cursor_theme_get_cursor(_ecore_wl_disp->cursor_theme, + cursor_name); +} + /* local functions */ static Eina_Bool _ecore_wl_shutdown(Eina_Bool close) @@ -385,7 +403,7 @@ _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl __UNUSED__) { Ecore_Wl_Display *ewd; - LOGFN(__FILE__, __LINE__, __FUNCTION__); + /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ if (!(ewd = data)) return ECORE_CALLBACK_RENEW; wl_display_iterate(ewd->wl.display, ewd->mask); @@ -414,7 +432,10 @@ _ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char /* else if (!strcmp(interface, "desktop_shell")) */ /* ewd->wl.desktop_shell = wl_display_bind(disp, id, &wl_shell_interface); */ else if (!strcmp(interface, "wl_shm")) - ewd->wl.shm = wl_display_bind(disp, id, &wl_shm_interface); + { + ewd->wl.shm = wl_display_bind(disp, id, &wl_shm_interface); + ewd->cursor_theme = wl_cursor_theme_load(NULL, 32, ewd->wl.shm); + } else if (!strcmp(interface, "wl_data_device_manager")) { ewd->wl.data_device_manager = diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_input.c b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_input.c index 0fc888b3d9..3bd12b61d0 100644 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_input.c +++ b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_input.c @@ -18,6 +18,7 @@ **/ #include "ecore_wl_private.h" +#include /* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... * What about other OSs ?? */ @@ -48,9 +49,11 @@ static void _ecore_wl_input_cb_pointer_leave(void *data, struct wl_pointer *poin static void _ecore_wl_input_cb_pointer_motion(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy); static void _ecore_wl_input_cb_pointer_button(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state); static void _ecore_wl_input_cb_pointer_axis(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int timestamp, unsigned int axis, int value); +static void _ecore_wl_input_cb_keyboard_keymap(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int format, int fd, unsigned int size); static void _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, struct wl_surface *surface, struct wl_array *keys __UNUSED__); static void _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, struct wl_surface *surface); static void _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, unsigned int timestamp, unsigned int key, unsigned int state); +static void _ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial __UNUSED__, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group); static void _ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch __UNUSED__, unsigned int serial, unsigned int timestamp, struct wl_surface *surface __UNUSED__, int id __UNUSED__, wl_fixed_t x, wl_fixed_t y); static void _ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch __UNUSED__, unsigned int serial, unsigned int timestamp, int id __UNUSED__); static void _ecore_wl_input_cb_touch_motion(void *data, struct wl_touch *touch __UNUSED__, unsigned int timestamp, int id __UNUSED__, wl_fixed_t x, wl_fixed_t y); @@ -81,14 +84,16 @@ static const struct wl_pointer_listener pointer_listener = _ecore_wl_input_cb_pointer_leave, _ecore_wl_input_cb_pointer_motion, _ecore_wl_input_cb_pointer_button, - _ecore_wl_input_cb_pointer_axis + _ecore_wl_input_cb_pointer_axis, }; static const struct wl_keyboard_listener keyboard_listener = { + _ecore_wl_input_cb_keyboard_keymap, _ecore_wl_input_cb_keyboard_enter, _ecore_wl_input_cb_keyboard_leave, - _ecore_wl_input_cb_keyboard_key + _ecore_wl_input_cb_keyboard_key, + _ecore_wl_input_cb_keyboard_modifiers, }; static const struct wl_touch_listener touch_listener = @@ -124,6 +129,7 @@ ecore_wl_input_grab(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int bu { LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!input) return; input->grab = win; input->grab_button = button; } @@ -133,10 +139,62 @@ ecore_wl_input_ungrab(Ecore_Wl_Input *input) { LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!input) return; input->grab = NULL; input->grab_button = 0; } +EAPI void +ecore_wl_input_pointer_set(Ecore_Wl_Input *input, struct wl_buffer *buffer, int hot_x, int hot_y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (input) + wl_pointer_attach(input->pointer, input->timestamp, buffer, hot_x, hot_y); +} + +EAPI void +ecore_wl_input_cursor_from_name_set(Ecore_Wl_Input *input, const char *cursor_name) +{ + struct wl_cursor_image *cursor_image; + struct wl_buffer *buffer; + struct wl_cursor *cursor; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!input) return; + + /* No cursor */ + if (!cursor_name) + { + ecore_wl_input_pointer_set(input, NULL, 0, 0); + return; + } + + if (!(cursor = ecore_wl_cursor_get(cursor_name))) + return; + + if ((!cursor->images) || (!cursor->images[0])) + return; + + cursor_image = cursor->images[0]; + if ((buffer = wl_cursor_image_get_buffer(cursor_image))) + ecore_wl_input_pointer_set(input, buffer, + cursor_image->hotspot_x, + cursor_image->hotspot_y); +} + +EAPI void +ecore_wl_input_cursor_default_restore(Ecore_Wl_Input *input) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!input) return; + + /* Restore to default wayland cursor */ + ecore_wl_input_cursor_from_name_set(input, "left_ptr"); +} + void _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id) { @@ -241,15 +299,12 @@ _ecore_wl_input_cb_pointer_motion(void *data, struct wl_pointer *pointer __UNUSE { Ecore_Wl_Input *input; - LOGFN(__FILE__, __LINE__, __FUNCTION__); + /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ if (!(input = data)) return; - _pointer_x = sx; - _pointer_y = sy; - - input->sx = wl_fixed_to_int(sx); - input->sy = wl_fixed_to_int(sy); + _pointer_x = input->sx = wl_fixed_to_int(sx); + _pointer_y = input->sy = wl_fixed_to_int(sy); input->timestamp = timestamp; @@ -270,7 +325,7 @@ _ecore_wl_input_cb_pointer_button(void *data, struct wl_pointer *pointer __UNUSE input->timestamp = timestamp; input->display->serial = serial; -// _ecore_wl_input_mouse_move_send(input, timestamp); +// _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp); if (state) { @@ -305,6 +360,56 @@ _ecore_wl_input_cb_pointer_axis(void *data, struct wl_pointer *pointer __UNUSED_ _ecore_wl_input_mouse_wheel_send(input, axis, value, timestamp); } +static void +_ecore_wl_input_cb_keyboard_keymap(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int format, int fd, unsigned int size) +{ + Ecore_Wl_Input *input; + char *map = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) + { + close(fd); + return; + } + + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) + { + close(fd); + return; + } + + map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) + { + close(fd); + return; + } + + input->display->xkb.keymap = + xkb_map_new_from_string(input->display->xkb.context, map, + XKB_KEYMAP_FORMAT_TEXT_V1, 0); + + munmap(map, size); + close(fd); + + if (!(input->display->xkb.keymap)) return; + if (!(input->display->xkb.state = xkb_state_new(input->display->xkb.keymap))) + { + xkb_map_unref(input->display->xkb.keymap); + input->display->xkb.keymap = NULL; + return; + } + + input->display->xkb.control_mask = + 1 << xkb_map_mod_get_index(input->display->xkb.keymap, "Control"); + input->display->xkb.alt_mask = + 1 << xkb_map_mod_get_index(input->display->xkb.keymap, "Mod1"); + input->display->xkb.shift_mask = + 1 << xkb_map_mod_get_index(input->display->xkb.keymap, "Shift"); +} + /* * _ecore_wl_input_keysym_to_string: Translate a symbol to its printable form * @@ -435,6 +540,18 @@ _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard __UNUSE /* input->modifiers &= ~_ecore_wl_disp->xkb->map->modmap[keycode]; */ } +static void +_ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial __UNUSED__, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + xkb_state_update_mask(input->display->xkb.state, depressed, latched, + locked, 0, 0, group); +} + static void _ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) { @@ -463,9 +580,12 @@ _ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer __UNUSED win->pointer_device = input; input->pointer_focus = win; - _ecore_wl_input_mouse_move_send(input, win, input->timestamp); + /* _ecore_wl_input_mouse_move_send(input, win, input->timestamp); */ _ecore_wl_input_mouse_in_send(input, win, input->timestamp); + /* The cursor on the surface is undefined until we set it */ + ecore_wl_window_cursor_default_restore(win); + /* NB: This whole 'if' below is a major HACK due to wayland's stupidness * of not sending a mouse_up (or any notification at all for that matter) * when a move or resize grab is finished */ @@ -518,7 +638,7 @@ _ecore_wl_input_cb_pointer_leave(void *data, struct wl_pointer *pointer __UNUSED win->pointer_device = NULL; input->pointer_focus = NULL; - _ecore_wl_input_mouse_move_send(input, win, input->timestamp); + /* _ecore_wl_input_mouse_move_send(input, win, input->timestamp); */ _ecore_wl_input_mouse_out_send(input, win, input->timestamp); if (input->grab) @@ -554,7 +674,6 @@ _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *keyboard __UNU win->keyboard_device = input; input->keyboard_focus = win; - /* FIXME: NB: This may need to be 'serial' */ _ecore_wl_input_focus_in_send(input, win, input->timestamp); } @@ -824,7 +943,7 @@ _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, uns ev->y = input->sy; /* ev->root.x = input->sx; */ /* ev->root.y = input->sy; */ - printf("Input Modifiers: %d\n", input->modifiers); + /* printf("Input Modifiers: %d\n", input->modifiers); */ ev->modifiers = input->modifiers; /* FIXME: Need to get these from wayland somehow */ diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h index 98690eb46f..20d7626144 100644 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h +++ b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h @@ -2,6 +2,7 @@ # define _ECORE_WAYLAND_PRIVATE_H # include +# include # include "Ecore.h" # include "Ecore_Input.h" diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_window.c b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_window.c index 9cf7d1a2a2..7a97d06b03 100644 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_window.c +++ b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_window.c @@ -11,6 +11,7 @@ static void _ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface * static void _ecore_wl_window_cb_surface_enter(void *data, struct wl_surface *surface, struct wl_output *output); static void _ecore_wl_window_cb_surface_leave(void *data, struct wl_surface *surface, struct wl_output *output); static void _ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h, unsigned int timestamp); +static char *_ecore_wl_window_id_str_get(unsigned int win_id); /* local variables */ static Eina_Hash *_windows = NULL; @@ -33,7 +34,8 @@ static const struct wl_shell_surface_listener _ecore_wl_shell_surface_listener = void _ecore_wl_window_init(void) { - if (!_windows) _windows = eina_hash_pointer_new(free); + if (!_windows) + _windows = eina_hash_string_superfast_new(NULL); } void @@ -89,11 +91,12 @@ ecore_wl_window_new(Ecore_Wl_Window *parent, int x, int y, int w, int h, int buf win->allocation.h = h; win->saved_allocation = win->allocation; win->transparent = EINA_FALSE; + /* win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; */ win->type = ECORE_WL_WINDOW_TYPE_NONE; win->buffer_type = buffer_type; win->id = _win_id++; - eina_hash_add(_windows, &win->id, win); + eina_hash_add(_windows, _ecore_wl_window_id_str_get(win->id), win); return win; } @@ -114,7 +117,7 @@ ecore_wl_window_free(Ecore_Wl_Window *win) if (!win) return; - eina_hash_del(_windows, &win->id, NULL); + eina_hash_del(_windows, _ecore_wl_window_id_str_get(win->id), win); wl_list_for_each(input, &_ecore_wl_disp->inputs, link) { @@ -134,7 +137,8 @@ ecore_wl_window_free(Ecore_Wl_Window *win) if (win->surface) wl_surface_destroy(win->surface); win->surface = NULL; -// free(win); + /* HMMM, why was this disabled ? */ + free(win); } /** @@ -340,8 +344,6 @@ ecore_wl_window_show(Ecore_Wl_Window *win) wl_shell_surface_set_popup(win->shell_surface, _ecore_wl_disp->input->seat, _ecore_wl_disp->serial, - /* win->parent->pointer_device->input_device, */ - /* win->parent->pointer_device->timestamp, */ win->parent->shell_surface, win->allocation.x, win->allocation.y, 0); break; @@ -523,12 +525,10 @@ ecore_wl_window_shell_surface_get(Ecore_Wl_Window *win) EAPI Ecore_Wl_Window * ecore_wl_window_find(unsigned int id) { - Ecore_Wl_Window *win; + Ecore_Wl_Window *win = NULL; - if (!id) return NULL; - win = eina_hash_find(_windows, &id); - if (win) return win; - return NULL; + win = eina_hash_find(_windows, _ecore_wl_window_id_str_get(id)); + return win; } EAPI void @@ -541,7 +541,7 @@ ecore_wl_window_type_set(Ecore_Wl_Window *win, Ecore_Wl_Window_Type type) } EAPI void -ecore_wl_window_pointer_set(Ecore_Wl_Window *win, struct wl_buffer *buffer, int hot_x, int hot_y, unsigned int timestamp) +ecore_wl_window_pointer_set(Ecore_Wl_Window *win, struct wl_buffer *buffer, int hot_x, int hot_y) { Ecore_Wl_Input *input; @@ -549,8 +549,34 @@ ecore_wl_window_pointer_set(Ecore_Wl_Window *win, struct wl_buffer *buffer, int if (!win) return; - if ((input = _ecore_wl_disp->input)) - wl_pointer_attach(input->pointer, timestamp, buffer, hot_x, hot_y); + if ((input = win->pointer_device)) + ecore_wl_input_pointer_set(input, buffer, hot_x, hot_y); +} + +EAPI void +ecore_wl_window_cursor_from_name_set(Ecore_Wl_Window *win, const char *cursor_name) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + if ((input = win->pointer_device)) + ecore_wl_input_cursor_from_name_set(input, cursor_name); +} + +EAPI void +ecore_wl_window_cursor_default_restore(Ecore_Wl_Window *win) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + if ((input = win->pointer_device)) + ecore_wl_input_cursor_default_restore(input); } /* @since 1.2 */ @@ -641,3 +667,24 @@ _ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h, unsigned int ev->timestamp = timestamp; ecore_event_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL); } + +static char * +_ecore_wl_window_id_str_get(unsigned int win_id) +{ + const char *vals = "qWeRtYuIoP5$&<~"; + static char id[9]; + unsigned int val; + + val = win_id; + id[0] = vals[(val >> 28) & 0xf]; + id[1] = vals[(val >> 24) & 0xf]; + id[2] = vals[(val >> 20) & 0xf]; + id[3] = vals[(val >> 16) & 0xf]; + id[4] = vals[(val >> 12) & 0xf]; + id[5] = vals[(val >> 8) & 0xf]; + id[6] = vals[(val >> 4) & 0xf]; + id[7] = vals[(val) & 0xf]; + id[8] = 0; + + return id; +}