derekf pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=8f038b25914b9df738809a4150cf3aa5c6d0798e

commit 8f038b25914b9df738809a4150cf3aa5c6d0798e
Author: Derek Foreman <der...@osg.samsung.com>
Date:   Mon Aug 14 17:46:49 2017 -0500

    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.
---
 src/lib/ecore_wl2/Ecore_Wl2.h         | 23 +++++++++++++++
 src/lib/ecore_wl2/ecore_wl2_private.h |  8 ++++++
 src/lib/ecore_wl2/ecore_wl2_window.c  | 53 +++++++++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+)

diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h
index dad9652709..21b623e24a 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 4ee29752e6..240e9062ad 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 23eaafc960..c6d0ed4709 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);
+}

-- 


Reply via email to