From: JengHyun Kang Date: Fri, 8 Dec 2017 08:54:51 +0000 (+0900) Subject: ecore_wl2: add functions to set client's custom cursors X-Git-Tag: submit/sandbox/upgrade/efl120/20180319.053334~762 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f4c9001f7cea3d7ddf3ded3101585bc5cf94678b;p=platform%2Fupstream%2Fefl.git ecore_wl2: add functions to set client's custom cursors Change-Id: I0017e31e31bf1ccd2c0b4afb5bf5badd48a00584 --- diff --git a/configure.ac b/configure.ac index 275604a..2531470 100755 --- a/configure.ac +++ b/configure.ac @@ -3790,7 +3790,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] tizen-extension-client wayland-tbm-client libtdm-client) + [wayland-server >= 1.11.0 wayland-client >= 1.11.0 wayland-cursor >= 1.8.0 xkbcommon >= 0.6.0] tizen-extension-client wayland-tbm-client libtdm-client) EFL_EVAL_PKGS([ECORE_WL2]) @@ -6027,7 +6027,7 @@ echo "Ethumb..........: yes" echo "Ethumb_Client...: yes" echo "Elua............: $have_elua" echo "Elementary......: yes (${features_elementary})" -echo +echo echo diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 571a6f9..f5f74ca 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -1696,6 +1696,19 @@ EAPI void ecore_wl2_input_pointer_set(Ecore_Wl2_Input *input, struct wl_surface */ EAPI void ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input *input, const char *cursor); +// TIZEN_ONLY(20171207): add functions to set client's custom cursors +EAPI void ecore_wl2_input_pointer_set(Ecore_Wl2_Input *input, struct wl_surface *surface, int hot_x, int hot_y); +EAPI struct wl_cursor *ecore_wl2_input_cursor_get(Ecore_Wl2_Input *input, const char *cursor_name); +EAPI void ecore_wl2_input_cursor_size_set(Ecore_Wl2_Input *input, const int size); +EAPI void ecore_wl2_input_cursor_theme_name_set(Ecore_Wl2_Input *input, const char *cursor_theme_name); +EAPI void ecore_wl2_input_cursor_default_restore(Ecore_Wl2_Input *input); + +EAPI void ecore_wl2_window_pointer_set(Ecore_Wl2_Window *win, struct wl_surface *surface, int hot_x, int hot_y); +EAPI void ecore_wl2_window_cursor_from_name_set(Ecore_Wl2_Window *win, const char *cursor_name); +EAPI void ecore_wl2_window_cursor_default_restore(Ecore_Wl2_Window *win); +// + + /** * @defgroup Ecore_Wl2_Dnd_Group Wayland Library Drag-n-Drop Functions * @ingroup Ecore_Wl2_Group diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c index 8939213..ed41482 100644 --- a/src/lib/ecore_wl2/ecore_wl2_input.c +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -81,6 +81,9 @@ static struct wl_array _ecore_wl2_keygrab_result_list; // 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); +// TIZEN_ONLY(20171207): add functions to set client's custom cursors +static void _cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED); +// // TIZEN ONLY(20160223) : Add back/menu/home key conversion support static int @@ -992,10 +995,18 @@ _pointer_cb_enter(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned i input->pointer.sx = wl_fixed_to_double(sx); input->pointer.sy = wl_fixed_to_double(sy); + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + /* The cursor on the surface is undefined until we set it */ + ecore_wl2_input_cursor_from_name_set(input, input->cursor.name); + // + /* find the window which this surface belongs to */ window = _ecore_wl2_display_window_surface_find(input->display, surface); if (!window) return; + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + window->pointer.device = input; + // input->focus.prev_pointer = NULL; input->focus.pointer = window; @@ -1029,6 +1040,10 @@ _pointer_cb_leave(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned i window = _ecore_wl2_display_window_surface_find(input->display, surface); if (!window) return; + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + window->pointer.device = NULL; + // + /* NB: Don't send a mouse out if we grabbed this window for moving */ if ((window->moving) && (input->grab.window == window)) return; @@ -1743,9 +1758,39 @@ _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); + + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + if (!input->cursor.surface) + { + input->cursor.surface = + wl_compositor_create_surface(input->display->wl.compositor); + + if (input->cursor.surface) + { + if (input->display->wl.tz_policy) + { + tizen_policy_set_role(input->display->wl.tz_policy, + input->cursor.surface, "wl_pointer-cursor"); + } + } + } + if (!input->cursor.theme) + { + input->cursor.theme = + wl_cursor_theme_load(input->cursor.theme_name, input->cursor.size, + input->display->wl.shm); + } + // } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->wl.pointer)) { + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + if (input->cursor.surface) wl_surface_destroy(input->cursor.surface); + input->cursor.surface = NULL; + if (input->cursor.theme) + wl_cursor_theme_destroy(input->cursor.theme); + input->cursor.theme = NULL; + // #ifdef WL_POINTER_RELEASE_SINCE_VERSION if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION) wl_pointer_release(input->wl.pointer); @@ -1852,14 +1897,67 @@ static void _ecore_wl2_input_cursor_setup(Ecore_Wl2_Input *input) { char *tmp; - + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + #if 0 input->cursor.size = 32; tmp = getenv("ECORE_WL_CURSOR_SIZE"); if (tmp) input->cursor.size = atoi(tmp); if (!input->cursor.name) input->cursor.name = eina_stringshare_add("left_ptr"); + #else + unsigned int cursor_size; + char *cursor_theme_name; + + tmp = getenv("ECORE_WL_CURSOR_SIZE"); + if (tmp) + cursor_size = atoi(tmp); + else + cursor_size = 32; + ecore_wl2_input_cursor_size_set(input, cursor_size); + + cursor_theme_name = getenv("ECORE_WL_CURSOR_THEME_NAME"); + ecore_wl2_input_cursor_theme_name_set(input, cursor_theme_name); + #endif + // +} + +// TIZEN_ONLY(20171207): add functions to set client's custom cursors +static const struct wl_callback_listener _pointer_surface_listener = +{ + _cb_pointer_frame +}; + +static void +_cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED) +{ + Ecore_Wl2_Input *input; + + if (!(input = data)) 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_pointer_set(input, NULL, 0, 0); + return; + } + + if ((input->cursor.cursor->image_count > 1) && (!input->cursor.frame_cb)) + { + input->cursor.frame_cb = wl_surface_frame(input->cursor.surface); + if (!input->cursor.frame_cb) return; + + wl_callback_add_listener(input->cursor.frame_cb, + &_pointer_surface_listener, input); + } } +// Eina_Bool _ecore_wl2_input_cursor_update(void *data) @@ -1869,12 +1967,56 @@ _ecore_wl2_input_cursor_update(void *data) input = data; if (!input) return EINA_FALSE; + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + #if 0 if (input->wl.pointer) wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial, input->cursor.surface, input->cursor.hot_x, input->cursor.hot_y); return ECORE_CALLBACK_RENEW; + #else + struct wl_cursor_image *cursor_image; + struct wl_buffer *buffer; + unsigned int delay; + + if ((!input) || (!input->cursor.cursor) || (!input->cursor.surface)) + return EINA_FALSE; + + cursor_image = input->cursor.cursor->images[input->cursor.current_index]; + if (!cursor_image) return ECORE_CALLBACK_RENEW; + + if ((buffer = wl_cursor_image_get_buffer(cursor_image))) + { + ecore_wl2_input_pointer_set(input, input->cursor.surface, + cursor_image->hotspot_x, + cursor_image->hotspot_y); + wl_surface_attach(input->cursor.surface, buffer, 0, 0); + wl_surface_damage(input->cursor.surface, 0, 0, + cursor_image->width, cursor_image->height); + wl_surface_commit(input->cursor.surface); + + if ((input->cursor.cursor->image_count > 1) && (!input->cursor.frame_cb)) + _cb_pointer_frame(input, NULL, 0); + } + + if (input->cursor.cursor->image_count <= 1) + return ECORE_CALLBACK_CANCEL; + + delay = cursor_image->delay; + input->cursor.current_index = + (input->cursor.current_index + 1) % input->cursor.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; + #endif + // } static void @@ -3202,34 +3344,137 @@ ecore_wl2_input_seat_device_get(const Ecore_Wl2_Input *input, const Ecore_Wl2_Wi return devices ? devices->seat_dev : NULL; } +// TIZEN_ONLY(20171207): add functions to set client's custom cursors +static void +_pointer_update_stop(Ecore_Wl2_Input *input) +{ + if (!input->cursor.timer) return; + + ecore_timer_del(input->cursor.timer); + input->cursor.timer = NULL; +} +// + EAPI void ecore_wl2_input_pointer_set(Ecore_Wl2_Input *input, struct wl_surface *surface, int hot_x, int hot_y) { EINA_SAFETY_ON_NULL_RETURN(input); + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + _pointer_update_stop(input); + if (input->wl.pointer) + wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial, + surface, hot_x, hot_y); + // + input->cursor.surface = surface; input->cursor.hot_x = hot_x; input->cursor.hot_y = hot_y; -// TIZEN_ONLY(20170522) : set cursor role - if (input->display && input->display->wl.tz_policy) - { - if (input->cursor.surface) - { - tizen_policy_set_role(input->display->wl.tz_policy, - input->cursor.surface, "wl_pointer-cursor"); - } - } -// + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + #if 0 _ecore_wl2_input_cursor_update(input); + #endif + // +} + +// TIZEN_ONLY(20171207): add functions to set client's custom cursors +EAPI struct wl_cursor * +ecore_wl2_input_cursor_get(Ecore_Wl2_Input *input, const char *cursor_name) +{ + if ((!input) || (!input->cursor.theme)) + return NULL; + + return wl_cursor_theme_get_cursor(input->cursor.theme, + cursor_name); } +// EAPI void -ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input *input, const char *cursor) +ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input *input, const char *cursor_name) { EINA_SAFETY_ON_NULL_RETURN(input); + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + #if 0 _ecore_wl2_input_cursor_set(input, cursor); + #else + struct wl_cursor *cursor; + + /* No pointer device. Don't need to set cursor and update it */ + if (!input->wl.pointer) return; + + _pointer_update_stop(input); + + eina_stringshare_replace(&input->cursor.name, cursor_name); + + /* No cursor. Set to default Left Pointer */ + if (!cursor_name) + eina_stringshare_replace(&input->cursor.name, "left_ptr"); + + /* try to get this cursor from the theme */ + if (!(cursor = ecore_wl2_input_cursor_get(input, input->cursor.name))) + { + /* if the theme does not have this cursor, default to left pointer */ + if (!(cursor = ecore_wl2_input_cursor_get(input, "left_ptr"))) + return; + } + + input->cursor.cursor = cursor; + + if ((!cursor->images) || (!cursor->images[0])) + { + ecore_wl2_input_pointer_set(input, NULL, 0, 0); + return; + } + + input->cursor.current_index = 0; + + _ecore_wl2_input_cursor_update(input); + #endif +} + +// TIZEN_ONLY(20171207): add functions to set client's custom cursors +EAPI void +ecore_wl2_input_cursor_size_set(Ecore_Wl2_Input *input, const int size) +{ + if (!input) return; + + input->cursor.size = size; + + EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm); + + if (input->cursor.theme) + wl_cursor_theme_destroy(input->cursor.theme); + + input->cursor.theme = + wl_cursor_theme_load(NULL, input->cursor.size, input->display->wl.shm); +} + +EAPI void +ecore_wl2_input_cursor_theme_name_set(Ecore_Wl2_Input *input, const char *cursor_theme_name) +{ + if (!input) return; + + eina_stringshare_replace(&input->cursor.theme_name, cursor_theme_name); + + EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm); + + if (input->cursor.theme) + wl_cursor_theme_destroy(input->cursor.theme); + input->cursor.theme = + wl_cursor_theme_load(input->cursor.theme_name, input->cursor.size, + input->display->wl.shm); +} + +EAPI void +ecore_wl2_input_cursor_default_restore(Ecore_Wl2_Input *input) +{ + if (!input) return; + + /* Restore to default wayland cursor */ + ecore_wl2_input_cursor_from_name_set(input, "left_ptr"); } +// EAPI Eina_Bool ecore_wl2_input_pointer_xy_get(const Ecore_Wl2_Input *input, int *x, int *y) diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index 6f00e4c..b001654 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -351,6 +351,17 @@ struct _Ecore_Wl2_Window void (*cb_rot_changed)(Ecore_Wl2_Window *win, int rot, Eina_Bool resize, int w, int h, void *data); void *cb_rot_changed_data; // + + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + struct + { + struct wl_surface *surface; + int hot_x, hot_y; + Eina_Bool set : 1; + Ecore_Wl2_Input *device; + const char *cursor_name; + } pointer; + // }; struct _Ecore_Wl2_Output @@ -559,6 +570,14 @@ struct _Ecore_Wl2_Input unsigned int size; struct wl_surface *surface; int hot_x, hot_y; + // TIZEN_ONLY(20171207): add functions to set client's custom cursors + struct wl_cursor *cursor; + struct wl_callback *frame_cb; + Ecore_Timer *timer; + unsigned int current_index; + const char *theme_name; + struct wl_cursor_theme *theme; + // } cursor; struct diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c b/src/lib/ecore_wl2/ecore_wl2_window.c index 6b62ac5..bd5ed27 100644 --- a/src/lib/ecore_wl2/ecore_wl2_window.c +++ b/src/lib/ecore_wl2/ecore_wl2_window.c @@ -2913,3 +2913,52 @@ ecore_wl2_window_ignore_output_transform_get(Ecore_Wl2_Window *window) return window->ignore_output_transform; } // + +// TIZEN_ONLY(20171207): add functions to set client's custom cursors +EAPI void +ecore_wl2_window_pointer_set(Ecore_Wl2_Window *win, struct wl_surface *surface, int hot_x, int hot_y) +{ + Ecore_Wl2_Input *input; + + if (!win) return; + + win->pointer.surface = surface; + win->pointer.hot_x = hot_x; + win->pointer.hot_y = hot_y; + win->pointer.set = EINA_TRUE; + + if ((input = win->pointer.device)) + ecore_wl2_input_pointer_set(input, surface, hot_x, hot_y); +} + +EAPI void +ecore_wl2_window_cursor_from_name_set(Ecore_Wl2_Window *win, const char *cursor_name) +{ + Ecore_Wl2_Input *input; + + if (!win) return; + + win->pointer.set = EINA_FALSE; + + if (!(input = win->pointer.device)) + return; + + eina_stringshare_replace(&win->pointer.cursor_name, cursor_name); + + if ((input->cursor.name) && (strcmp(input->cursor.name, win->pointer.cursor_name))) + ecore_wl2_input_cursor_from_name_set(input, cursor_name); +} + +EAPI void +ecore_wl2_window_cursor_default_restore(Ecore_Wl2_Window *win) +{ + Ecore_Wl2_Input *input; + + if (!win) return; + + win->pointer.set = EINA_FALSE; + + if ((input = win->pointer.device)) + ecore_wl2_input_cursor_default_restore(input); +} +//