ecore_wl2: Add new APIs ecore_wl2_window_frame_callback_add/del()
authorDerek Foreman <derekf@osg.samsung.com>
Mon, 14 Aug 2017 22:46:49 +0000 (17:46 -0500)
committerDerek Foreman <derekf@osg.samsung.com>
Fri, 18 Aug 2017 19:27:32 +0000 (14:27 -0500)
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
src/lib/ecore_wl2/ecore_wl2_private.h
src/lib/ecore_wl2/ecore_wl2_window.c

index dad9652..21b623e 100644 (file)
@@ -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
index 4ee2975..240e906 100644 (file)
@@ -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;
index 23eaafc..c6d0ed4 100644 (file)
@@ -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);
+}