From 3a44b0fd172f143c32a89ac8aac28cbad6f4d1e9 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 25 Oct 2016 10:47:15 -0400 Subject: [PATCH] Revert "ecore-wl2: Remove all references to wl_cursor usage" This reverts commit 173fda5c11fc083a0b274e404f0005a52b4bf128. Reverting this as we need to handle mouse pointers a different way. --- configure.ac | 2 +- src/lib/ecore_wl2/Ecore_Wl2.h | 1 + src/lib/ecore_wl2/ecore_wl2_input.c | 145 ++++++++++++++++++++++++++++++++-- src/lib/ecore_wl2/ecore_wl2_private.h | 12 ++- src/lib/ecore_wl2/ecore_wl2_window.c | 3 +- 5 files changed, 152 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index d90b516..c743063 100644 --- a/configure.ac +++ b/configure.ac @@ -3646,7 +3646,7 @@ EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [efl]) EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [eina]) EFL_DEPEND_PKG([ECORE_WL2], [WAYLAND], - [wayland-server >= 1.11.0 wayland-client >= 1.11.0 xkbcommon >= 0.6.0]) + [wayland-server >= 1.11.0 wayland-client >= 1.11.0 wayland-cursor >= 1.11.0 xkbcommon >= 0.6.0]) EFL_EVAL_PKGS([ECORE_WL2]) diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 27eca97..d45ed1a 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -4,6 +4,7 @@ # include # include # include +# include # include # define WL_HIDE_DEPRECATED diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c index 5600fed..919d424 100644 --- a/src/lib/ecore_wl2/ecore_wl2_input.c +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -35,7 +35,7 @@ typedef struct _Ecore_Wl2_Mouse_Down_Info static Eina_Inlist *_ecore_wl2_mouse_down_info_list = NULL; static void _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state); -/* static void _pointer_cb_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED); */ +static void _pointer_cb_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED); static Ecore_Wl2_Mouse_Down_Info * _ecore_wl2_input_mouse_down_info_get(int device) @@ -651,6 +651,41 @@ static const struct wl_pointer_listener _pointer_listener = NULL, /* axis_discrete */ }; +static const struct wl_callback_listener _pointer_surface_listener = +{ + _pointer_cb_frame +}; + +static void +_pointer_cb_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED) +{ + Ecore_Wl2_Input *input; + + input = data; + if (!input) return; + + if (callback) + { + if (callback != input->cursor.frame_cb) return; + wl_callback_destroy(callback); + input->cursor.frame_cb = NULL; + } + + if (!input->cursor.name) + { + _ecore_wl2_input_cursor_set(input, NULL); + return; + } + + if ((input->cursor.wl_cursor->image_count > 1) && + (!input->cursor.frame_cb)) + { + input->cursor.frame_cb = wl_surface_frame(input->cursor.surface); + wl_callback_add_listener(input->cursor.frame_cb, + &_pointer_surface_listener, input); + } +} + static void _keyboard_cb_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int format, int fd, unsigned int size) { @@ -1111,9 +1146,18 @@ _seat_cb_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability input->wl.pointer = wl_seat_get_pointer(seat); wl_pointer_set_user_data(input->wl.pointer, input); wl_pointer_add_listener(input->wl.pointer, &_pointer_listener, input); + + if (!input->cursor.surface) + { + input->cursor.surface = + wl_compositor_create_surface(input->display->wl.compositor); + } } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->wl.pointer)) { + if (input->cursor.surface) wl_surface_destroy(input->cursor.surface); + input->cursor.surface = NULL; + #ifdef WL_POINTER_RELEASE_SINCE_VERSION if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION) wl_pointer_release(input->wl.pointer); @@ -1180,19 +1224,74 @@ _ecore_wl2_input_cursor_setup(Ecore_Wl2_Input *input) input->cursor.size = 32; tmp = getenv("ECORE_WL_CURSOR_SIZE"); if (tmp) input->cursor.size = atoi(tmp); + + tmp = getenv("ECORE_WL_CURSOR_THEME_NAME"); + eina_stringshare_replace(&input->cursor.theme_name, tmp); + + if (!input->cursor.name) + input->cursor.name = eina_stringshare_add("left_ptr"); + + if (input->display->wl.shm) + { + input->cursor.theme = + wl_cursor_theme_load(input->cursor.theme_name, input->cursor.size, + input->display->wl.shm); + } } static Eina_Bool _ecore_wl2_input_cursor_update(void *data) { Ecore_Wl2_Input *input; + struct wl_cursor_image *image; + struct wl_buffer *buffer; + unsigned int delay = 0; input = data; if (!input) return EINA_FALSE; - if (input->wl.pointer) - wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial, - NULL, 0, 0); + image = input->cursor.wl_cursor->images[input->cursor.index]; + if (!image) return EINA_FALSE; + + buffer = wl_cursor_image_get_buffer(image); + if (buffer) + { + if (input->wl.pointer) + wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial, + input->cursor.surface, + image->hotspot_x, image->hotspot_y); + + wl_surface_attach(input->cursor.surface, buffer, 0, 0); +#ifdef WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION + if (input->display->wl.compositor_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) + wl_surface_damage_buffer(input->cursor.surface, + 0, 0, image->width, image->height); + else +#endif + wl_surface_damage(input->cursor.surface, + 0, 0, image->width, image->height); + wl_surface_commit(input->cursor.surface); + + if ((input->cursor.wl_cursor->image_count > 1) && + (!input->cursor.frame_cb)) + _pointer_cb_frame(input, NULL, 0); + } + + if (input->cursor.wl_cursor->image_count <= 1) + return ECORE_CALLBACK_CANCEL; + + delay = image->delay; + input->cursor.index = + (input->cursor.index + 1) % input->cursor.wl_cursor->image_count; + + if (!input->cursor.timer) + { + input->cursor.timer = + ecore_timer_loop_add(delay / 1000.0, + _ecore_wl2_input_cursor_update, input); + } + else + ecore_timer_interval_set(input->cursor.timer, delay / 1000.0); return ECORE_CALLBACK_RENEW; } @@ -1257,6 +1356,12 @@ _ecore_wl2_input_del(Ecore_Wl2_Input *input) _ecore_wl2_input_cursor_update_stop(input); + if (input->cursor.theme) wl_cursor_theme_destroy(input->cursor.theme); + if (input->cursor.surface) wl_surface_destroy(input->cursor.surface); + if (input->cursor.name) eina_stringshare_del(input->cursor.name); + if (input->cursor.theme_name) + eina_stringshare_del(input->cursor.theme_name); + if (input->data.types.data) { char **t; @@ -1287,11 +1392,37 @@ _ecore_wl2_input_del(Ecore_Wl2_Input *input) void _ecore_wl2_input_cursor_set(Ecore_Wl2_Input *input, const char *cursor) { + struct wl_cursor *wl_cursor; + _ecore_wl2_input_cursor_update_stop(input); - if (input->wl.pointer) - wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial, - NULL, 0, 0); + eina_stringshare_replace(&input->cursor.name, cursor); + if (!cursor) eina_stringshare_replace(&input->cursor.name, "left_ptr"); + + wl_cursor = + wl_cursor_theme_get_cursor(input->cursor.theme, input->cursor.name); + if (!wl_cursor) + { + wl_cursor = + wl_cursor_theme_get_cursor(input->cursor.theme, "left_ptr"); + } + + if (!wl_cursor) + { + ERR("Could not get Wayland Cursor from Cursor Theme: %s", + input->cursor.theme_name); + return; + } + + input->cursor.wl_cursor = wl_cursor; + + if ((!wl_cursor->images) || (!wl_cursor->images[0])) + { + if (input->wl.pointer) + wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial, + NULL, 0, 0); + return; + } input->cursor.index = 0; diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index 43ad1dd..f7055cf 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -220,8 +220,12 @@ struct _Ecore_Wl2_Pointer struct { - const char *name; + const char *name, *theme_name; unsigned int index, size; + struct wl_cursor *wl_cursor; + struct wl_cursor_theme *theme; + struct wl_surface *surface; + struct wl_callback *frame_cb; Ecore_Timer *timer; } cursor; @@ -349,8 +353,12 @@ struct _Ecore_Wl2_Input struct { - const char *name; + const char *name, *theme_name; unsigned int index, size; + struct wl_cursor *wl_cursor; + struct wl_cursor_theme *theme; + struct wl_surface *surface; + struct wl_callback *frame_cb; Ecore_Timer *timer; } cursor; diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c b/src/lib/ecore_wl2/ecore_wl2_window.c index a20dc89..cd796e9 100644 --- a/src/lib/ecore_wl2/ecore_wl2_window.c +++ b/src/lib/ecore_wl2/ecore_wl2_window.c @@ -951,7 +951,8 @@ ecore_wl2_window_pointer_set(Ecore_Wl2_Window *window, struct wl_surface *surfac if (input->wl.pointer) wl_pointer_set_cursor(input->wl.pointer, - input->pointer.enter_serial, surface, hot_x, hot_y); + input->pointer.enter_serial, + surface, hot_x, hot_y); } EAPI void -- 2.7.4