From: Derek Foreman Date: Mon, 14 Aug 2017 22:46:49 +0000 (-0500) Subject: ecore_wl2: Add new APIs ecore_wl2_window_frame_callback_add/del() X-Git-Tag: submit/sandbox/upgrade/efl120/20180319.053334~3102 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8f038b25914b9df738809a4150cf3aa5c6d0798e;p=platform%2Fupstream%2Fefl.git ecore_wl2: Add new APIs ecore_wl2_window_frame_callback_add/del() Abstract frame callbacks through ecore_wl2_window so we can add them in multiple places without having the wayland compositor generate more than one. Also allows us to keep a callback registered over hide/unhide of a window easily. --- diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index dad9652..21b623e 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -361,6 +361,8 @@ typedef struct Ecore_Wl2_Event_Aux_Message typedef void (*Ecore_Wl2_Bind_Cb)(struct wl_client *client, void *data, uint32_t version, uint32_t id); typedef void (*Ecore_Wl2_Unbind_Cb)(struct wl_resource *resource); +typedef void (*Ecore_Wl2_Frame_Cb)(Ecore_Wl2_Window *win, uint32_t timestamp, void *data); +typedef struct _Ecore_Wl2_Frame_Cb_Handle Ecore_Wl2_Frame_Cb_Handle; EAPI extern int ECORE_WL2_EVENT_DISCONNECT; /** @since 1.18 */ EAPI extern int ECORE_WL2_EVENT_CONNECT; /** @since 1.18 */ @@ -1902,6 +1904,27 @@ EAPI void ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush); */ EAPI Eina_Bool ecore_wl2_window_pending_get(Ecore_Wl2_Window *window); +/** + * Add a callback that fires when the window's surface_frame callback fires + * + * @window the window to add a callback on + * @cb The callback + * @data user data to provide to the callback handler + * + * @since 1.20 + */ +EAPI Ecore_Wl2_Frame_Cb_Handle *ecore_wl2_window_frame_callback_add(Ecore_Wl2_Window *window, Ecore_Wl2_Frame_Cb cb, void *data); + +/** + * delete a callback that fires when the window's surface_frame callback fires + * + * @window the window to add a callback on + * @cb The callback handle + * + * @since 1.20 + */ +EAPI void ecore_wl2_window_frame_callback_del(Ecore_Wl2_Frame_Cb_Handle *handle); + # endif # undef EAPI diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index 4ee2975..240e906 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -140,6 +140,13 @@ struct _Ecore_Wl2_Aux_Hint const char *hint, *val; }; +struct _Ecore_Wl2_Frame_Cb_Handle +{ + Ecore_Wl2_Window *win; + Ecore_Wl2_Frame_Cb cb; + void *data; +}; + struct _Ecore_Wl2_Window { EINA_INLIST; @@ -184,6 +191,7 @@ struct _Ecore_Wl2_Window Eina_Inlist *subsurfs; Eina_List *supported_aux_hints; + Eina_List *frame_callbacks; Eina_Bool moving : 1; Eina_Bool minimized : 1; diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c b/src/lib/ecore_wl2/ecore_wl2_window.c index 23eaafc..c6d0ed4 100644 --- a/src/lib/ecore_wl2/ecore_wl2_window.c +++ b/src/lib/ecore_wl2/ecore_wl2_window.c @@ -538,6 +538,12 @@ ecore_wl2_window_hide(Ecore_Wl2_Window *window) window->commit_pending = EINA_FALSE; } + if (window->callback) + { + wl_callback_destroy(window->callback); + window->callback = NULL; + } + window->configure_serial = 0; window->zxdg_configure_ack = NULL; window->zxdg_set_min_size = NULL; @@ -573,6 +579,9 @@ ecore_wl2_window_free(Ecore_Wl2_Window *window) _ecore_wl2_window_aux_hint_free(window); + if (window->callback) wl_callback_destroy(window->callback); + window->callback = NULL; + if (window->uuid && window->surface && window->display->wl.session_recovery) zwp_e_session_recovery_destroy_uuid(window->display->wl.session_recovery, window->surface, window->uuid); @@ -1344,6 +1353,26 @@ ecore_wl2_window_aspect_set(Ecore_Wl2_Window *window, int w, int h, unsigned int efl_hints_set_aspect(window->display->wl.efl_hints, window->zxdg_toplevel, w, h, aspect); } +static void +_frame_cb(void *data, struct wl_callback *callback, uint32_t timestamp) +{ + Ecore_Wl2_Frame_Cb_Handle *cb; + Ecore_Wl2_Window *window; + Eina_List *l, *ll; + + window = data; + window->commit_pending = EINA_FALSE; + wl_callback_destroy(callback); + window->callback = NULL; + EINA_LIST_FOREACH_SAFE(window->frame_callbacks, l, ll, cb) + cb->cb(window, timestamp, cb->data); +} + +static struct wl_callback_listener _frame_listener = +{ + _frame_cb +}; + EAPI void ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush) { EINA_SAFETY_ON_NULL_RETURN(window); @@ -1364,3 +1393,27 @@ EAPI Eina_Bool ecore_wl2_window_pending_get(Ecore_Wl2_Window *window) return window->commit_pending; } + +EAPI Ecore_Wl2_Frame_Cb_Handle *ecore_wl2_window_frame_callback_add(Ecore_Wl2_Window *window, Ecore_Wl2_Frame_Cb cb, void *data) +{ + Ecore_Wl2_Frame_Cb_Handle *callback; + + EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL); + + callback = malloc(sizeof(*callback)); + EINA_SAFETY_ON_NULL_RETURN_VAL(callback, NULL); + callback->cb = cb; + callback->data = data; + callback->win = window; + window->frame_callbacks = eina_list_append(window->frame_callbacks, callback); + return callback; +} + +EAPI void ecore_wl2_window_frame_callback_del(Ecore_Wl2_Frame_Cb_Handle *handle) +{ + EINA_SAFETY_ON_NULL_RETURN(handle); + + handle->win->frame_callbacks = eina_list_remove(handle->win->frame_callbacks, handle); + free(handle); +}