e_output: support intercept_hook functions 20/158620/2
authorBoram Park <boram1288.park@samsung.com>
Thu, 2 Nov 2017 07:24:19 +0000 (16:24 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Fri, 3 Nov 2017 04:37:32 +0000 (04:37 +0000)
Change-Id: I88ee11c901554964e043a456730bfa20418e3df3

src/bin/e_output.c
src/bin/e_output.h

index aec99a26c94f41032b649c14780a06bb8da7d81a..8bada5a6c036a49b984b80fe777392ca4bd119d9 100644 (file)
@@ -23,6 +23,17 @@ static Eina_Inlist *_e_output_hooks[] =
    [E_OUTPUT_HOOK_DPMS_CHANGE] = NULL,
 };
 
+static int _e_output_intercept_hooks_delete = 0;
+static int _e_output_intercept_hooks_walking = 0;
+
+static Eina_Inlist *_e_output_intercept_hooks[] =
+{
+   [E_OUTPUT_INTERCEPT_HOOK_DPMS_ON] = NULL,
+   [E_OUTPUT_INTERCEPT_HOOK_DPMS_STANDBY] = NULL,
+   [E_OUTPUT_INTERCEPT_HOOK_DPMS_SUSPEND] = NULL,
+   [E_OUTPUT_INTERCEPT_HOOK_DPMS_OFF] = NULL,
+};
+
 static Eina_Bool _e_output_capture(E_Output *output, tbm_surface_h tsurface, Eina_Bool auto_rotate);
 static void _e_output_vblank_handler(tdm_output *output, unsigned int sequence,
                                      unsigned int tv_sec, unsigned int tv_usec, void *data);
@@ -59,6 +70,41 @@ _e_output_hook_call(E_Output_Hook_Point hookpoint, E_Output *output)
      _e_output_hooks_clean();
 }
 
+static void
+_e_output_intercept_hooks_clean(void)
+{
+   Eina_Inlist *l;
+   E_Output_Intercept_Hook *ch;
+   unsigned int x;
+   for (x = 0; x < E_OUTPUT_INTERCEPT_HOOK_LAST; x++)
+     EINA_INLIST_FOREACH_SAFE(_e_output_intercept_hooks[x], l, ch)
+       {
+          if (!ch->delete_me) continue;
+          _e_output_intercept_hooks[x] = eina_inlist_remove(_e_output_intercept_hooks[x], EINA_INLIST_GET(ch));
+         free(ch);
+       }
+}
+
+static Eina_Bool
+_e_output_intercept_hook_call(E_Output_Intercept_Hook_Point hookpoint, E_Output *output)
+{
+   E_Output_Intercept_Hook *ch;
+   Eina_Bool res = EINA_TRUE;
+
+   _e_output_intercept_hooks_walking++;
+   EINA_INLIST_FOREACH(_e_output_intercept_hooks[hookpoint], ch)
+     {
+        if (ch->delete_me) continue;
+        res = ch->func(ch->data, output);
+        if (res == EINA_FALSE) break;
+     }
+   _e_output_intercept_hooks_walking--;
+   if ((_e_output_intercept_hooks_walking == 0) && (_e_output_intercept_hooks_delete > 0))
+     _e_output_intercept_hooks_clean();
+
+   return res;
+}
+
 static E_Client *
 _e_output_zoom_top_visible_ec_get()
 {
@@ -2060,24 +2106,16 @@ e_output_connected(E_Output *output)
 EINTERN Eina_Bool
 e_output_dpms_set(E_Output *output, E_OUTPUT_DPMS val)
 {
+   E_Output_Intercept_Hook_Point hookpoint;
    tdm_output_dpms tval;
-   Eina_Bool ret = EINA_TRUE;
    tdm_error error;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
 
-   if (val == E_OUTPUT_DPMS_OFF) tval = TDM_OUTPUT_DPMS_OFF;
-   else if (val == E_OUTPUT_DPMS_ON) tval = TDM_OUTPUT_DPMS_ON;
-   else if (val == E_OUTPUT_DPMS_STANDBY) tval = TDM_OUTPUT_DPMS_STANDBY;
-   else if (val == E_OUTPUT_DPMS_SUSPEND) tval = TDM_OUTPUT_DPMS_SUSPEND;
-   else ret = EINA_FALSE;
-
-   if (!ret) return EINA_FALSE;
-
    if (val == E_OUTPUT_DPMS_OFF)
      {
-        Eina_List *l;
         E_Plane *ep;
+        Eina_List *l;
 
         EINA_LIST_FOREACH(output->planes, l, ep)
           {
@@ -2085,6 +2123,19 @@ e_output_dpms_set(E_Output *output, E_OUTPUT_DPMS val)
           }
      }
 
+   if (val == E_OUTPUT_DPMS_ON) hookpoint = E_OUTPUT_INTERCEPT_HOOK_DPMS_ON;
+   else if (val == E_OUTPUT_DPMS_STANDBY) hookpoint = E_OUTPUT_INTERCEPT_HOOK_DPMS_STANDBY;
+   else if (val == E_OUTPUT_DPMS_SUSPEND) hookpoint = E_OUTPUT_INTERCEPT_HOOK_DPMS_SUSPEND;
+   else hookpoint = E_OUTPUT_INTERCEPT_HOOK_DPMS_OFF;
+
+   if (!_e_output_intercept_hook_call(hookpoint, output))
+     return EINA_TRUE;
+
+   if (val == E_OUTPUT_DPMS_ON) tval = TDM_OUTPUT_DPMS_ON;
+   else if (val == E_OUTPUT_DPMS_STANDBY) tval = TDM_OUTPUT_DPMS_STANDBY;
+   else if (val == E_OUTPUT_DPMS_SUSPEND) tval = TDM_OUTPUT_DPMS_SUSPEND;
+   else tval = TDM_OUTPUT_DPMS_OFF;
+
    error = tdm_output_set_dpms(output->toutput, tval);
    if (error != TDM_ERROR_NONE)
      {
@@ -2604,6 +2655,34 @@ e_output_hook_del(E_Output_Hook *ch)
      _e_output_hooks_delete++;
 }
 
+E_API E_Output_Intercept_Hook *
+e_output_intercept_hook_add(E_Output_Intercept_Hook_Point hookpoint, E_Output_Intercept_Hook_Cb func, const void *data)
+{
+   E_Output_Intercept_Hook *ch;
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_OUTPUT_INTERCEPT_HOOK_LAST, NULL);
+   ch = E_NEW(E_Output_Intercept_Hook, 1);
+   if (!ch) return NULL;
+   ch->hookpoint = hookpoint;
+   ch->func = func;
+   ch->data = (void*)data;
+   _e_output_intercept_hooks[hookpoint] = eina_inlist_append(_e_output_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
+   return ch;
+}
+
+E_API void
+e_output_intercept_hook_del(E_Output_Intercept_Hook *ch)
+{
+   ch->delete_me = 1;
+   if (_e_output_intercept_hooks_walking == 0)
+     {
+        _e_output_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_output_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
+        free(ch);
+     }
+   else
+     _e_output_intercept_hooks_delete++;
+}
+
 EINTERN Eina_Bool
 e_output_capture(E_Output *output, tbm_surface_h tsurface, Eina_Bool auto_rotate, Eina_Bool sync, E_Output_Capture_Cb func, void *data)
 {
index 779764b8fd3f8024255bb63e6392765f5eebb0e6..7fdbc0258411f553f6ee116eed05f5744b4d95a8 100644 (file)
@@ -10,6 +10,10 @@ typedef struct _E_Output_Hook       E_Output_Hook;
 typedef enum   _E_Output_Hook_Point E_Output_Hook_Point;
 typedef void (*E_Output_Hook_Cb) (void *data, E_Output *output);
 
+typedef struct _E_Output_Intercept_Hook       E_Output_Intercept_Hook;
+typedef enum   _E_Output_Intercept_Hook_Point E_Output_Intercept_Hook_Point;
+typedef Eina_Bool (*E_Output_Intercept_Hook_Cb) (void *data, E_Output *output);
+
 typedef void (*E_Output_Capture_Cb) (E_Output *output, tbm_surface_h surface, void *user_data);
 
 #else
@@ -119,6 +123,24 @@ struct _E_Output_Hook
    unsigned char delete_me : 1;
 };
 
+enum _E_Output_Intercept_Hook_Point
+{
+   E_OUTPUT_INTERCEPT_HOOK_DPMS_ON,
+   E_OUTPUT_INTERCEPT_HOOK_DPMS_STANDBY,
+   E_OUTPUT_INTERCEPT_HOOK_DPMS_SUSPEND,
+   E_OUTPUT_INTERCEPT_HOOK_DPMS_OFF,
+   E_OUTPUT_INTERCEPT_HOOK_LAST
+};
+
+struct _E_Output_Intercept_Hook
+{
+   EINA_INLIST;
+   E_Output_Intercept_Hook_Point hookpoint;
+   E_Output_Intercept_Hook_Cb func;
+   void *data;
+   unsigned char delete_me : 1;
+};
+
 EINTERN Eina_Bool         e_output_init(void);
 EINTERN void              e_output_shutdown(void);
 EINTERN E_Output        * e_output_new(E_Comp_Screen *e_comp_screen, int index);
@@ -153,6 +175,8 @@ E_API E_Plane           * e_output_fb_target_get(E_Output *output);
 E_API E_Plane           * e_output_plane_get_by_zpos(E_Output *output, int zpos);
 E_API E_Output_Hook     * e_output_hook_add(E_Output_Hook_Point hookpoint, E_Output_Hook_Cb func, const void *data);
 E_API void                e_output_hook_del(E_Output_Hook *ch);
+E_API E_Output_Intercept_Hook * e_output_intercept_hook_add(E_Output_Intercept_Hook_Point hookpoint, E_Output_Intercept_Hook_Cb func, const void *data);
+E_API void                e_output_intercept_hook_del(E_Output_Intercept_Hook *ch);
 
 
 #endif