hide external window from Enlightenment's compositting 33/79433/2
authorRoman Peresipkyn <r.peresipkyn@samsung.com>
Fri, 8 Jul 2016 16:33:55 +0000 (19:33 +0300)
committerRoman Peresipkyn <r.peresipkyn@samsung.com>
Tue, 12 Jul 2016 07:26:22 +0000 (10:26 +0300)
Change-Id: Ie66d91d58a1ad5e368da8407e5cd6c385d1e605a

src/e_mod_main.c
src/e_mod_main.h

index 24bb7d8e437f343fbb202aa7ffc40dff4821057c..8cf9ad05d45dbb501f1713aeba87c70ae5144ab0 100644 (file)
@@ -388,7 +388,7 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event)
                    "resource is NULL");
 
 /*
-   EOM_DBG(" wl_buff:%dx%d type:%d",
+   EOM_DBG("wl_buff:%dx%d type:%d",
             external_wl_buffer->w,
             external_wl_buffer->h,
             external_wl_buffer->type);
@@ -844,7 +844,7 @@ _e_eom_cb_wl_request_set_xdg_window(struct wl_client *client, struct wl_resource
    if (resource == NULL || output_id <= 0 || surface == NULL)
      return;
 
-   EOM_DBG(" 11111111 output id:%d resource:%p surface:%p",
+   EOM_DBG("set xdg output id:%d resource:%p surface:%p",
            output_id, resource, surface);
 
    if (!(ec = wl_resource_get_user_data(surface)))
@@ -865,7 +865,7 @@ _e_eom_cb_wl_request_set_shell_window(struct wl_client *client, struct wl_resour
    if (resource == NULL || output_id <= 0 || surface == NULL)
      return;
 
-   EOM_DBG("output id:%d resource:%p surface:%p",
+   EOM_DBG("set shell output id:%d resource:%p surface:%p",
            output_id, resource, surface);
 
    if (!(ec = wl_resource_get_user_data(surface)))
@@ -903,6 +903,34 @@ _e_eom_cb_wl_request_get_output_info(struct wl_client *client, struct wl_resourc
      }
 }
 
+static Eina_Bool
+_e_eom_cb_comp_object_redirected(void *data, E_Client *ec)
+{
+   E_EomCompObjectInterceptHookData *hook_data;
+
+   EOM_DBG("_e_eom_cb_comp_object_redirected");
+
+   RETURNVALIFTRUE(data == NULL, EINA_TRUE, "data is NULL");
+
+   hook_data = (E_EomCompObjectInterceptHookData* )data;
+
+   RETURNVALIFTRUE(hook_data->ec == NULL, EINA_TRUE, "hook_data->ec is NULL");
+   RETURNVALIFTRUE(hook_data->hook == NULL, EINA_TRUE, "hook_data->hook is NULL");
+   RETURNVALIFTRUE(hook_data->ec != ec, EINA_TRUE, "hook_data->ec != ec");
+
+   /* Hide the window from Enlightenment main screen */
+   e_comp_object_redirected_set(ec->frame, EINA_FALSE);
+
+   e_comp_object_intercept_hook_del(hook_data->hook);
+
+   g_eom->comp_object_intercept_hooks = eina_list_remove(g_eom->comp_object_intercept_hooks,
+                                                         hook_data);
+
+   free(hook_data);
+
+   return EINA_TRUE;
+}
+
 static Eina_Bool
 _e_eom_output_init(tdm_display *dpy)
 {
@@ -1345,28 +1373,31 @@ _e_eom_window_set_internal(struct wl_resource *resource, int output_id, E_Client
    E_EomOutputPtr eom_output = NULL;
    E_EomClientPtr eom_client = NULL;
    E_Comp_Client_Data *cdata = NULL;
+   Eina_Bool ret = EINA_FALSE;
 
    if (resource == NULL || output_id <= 0 || ec == NULL)
      return;
 
    cdata = ec->comp_data;
    RETURNIFTRUE(cdata == NULL, "cdata is NULL");
-   RETURNIFTRUE(cdata->shell.configure_send == NULL, " cdata->shell.configure_send  is NULL");
+   RETURNIFTRUE(cdata->shell.configure_send == NULL, "cdata->shell.configure_send  is NULL");
 
    eom_client = _e_eom_client_get_by_resource(resource);
    RETURNIFTRUE(eom_client == NULL, "eom_client is NULL");
 
-   RETURNIFTRUE(eom_client->current == EINA_FALSE, " not current client is going to set its window");
+   RETURNIFTRUE(eom_client->current == EINA_FALSE, "not current client is going to set its window");
 
    eom_output = _e_eom_output_get_by_id(output_id);
    RETURNIFTRUE(eom_output == NULL, "eom_output is NULL");
 
-   cdata->shell.configure_send(ec->comp_data->shell.surface, 0, eom_output->width, eom_output->height);
+   ret = _e_eom_util_add_comp_object_redirected_hook(ec);
+   RETURNIFTRUE(ret != EINA_TRUE, "Set redirect comp hook failed");
 
-   /* Hide the window from e compositing
-    * TODO: It is not work find other solution
-    */
-   e_comp_object_redirected_set(ec->frame, 0);
+   EOM_DBG("e_comp_object_redirected_set (ec->frame:%p)\n", ec->frame);
+
+   /* Send reconfigure event to a client which will resize its window to
+    * external output resolution in respond */
+   cdata->shell.configure_send(ec->comp_data->shell.surface, 0, eom_output->width, eom_output->height);
 
    /* ec is used in buffer_change callback for distinguishing external ec and its buffers */
    eom_client->ec = ec;
@@ -1472,6 +1503,7 @@ _e_eom_util_create_buffer(int width, int height, int format, int flags)
                        &buffer_info) != TBM_SURFACE_ERROR_NONE)
      {
         EOM_ERR("map buffer");
+        tbm_surface_destroy(buffer);
         return NULL;
      }
 
@@ -1604,6 +1636,36 @@ _e_eom_util_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_siz
      }
 }
 
+static Eina_Bool
+_e_eom_util_add_comp_object_redirected_hook(E_Client *ec)
+{
+   E_EomCompObjectInterceptHookData *hook_data = NULL;
+   E_Comp_Object_Intercept_Hook *hook = NULL;
+
+   hook_data = E_NEW(E_EomCompObjectInterceptHookData, 1);
+   GOTOIFTRUE(hook_data == NULL, err, "hook_data = NULL");
+
+   hook_data->ec = ec;
+
+   hook = e_comp_object_intercept_hook_add(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER,
+                                           _e_eom_cb_comp_object_redirected,
+                                           hook_data);
+   GOTOIFTRUE(hook == NULL, err, "hook = NULL");
+
+   hook_data->hook = hook;
+
+   g_eom->comp_object_intercept_hooks = eina_list_append(g_eom->comp_object_intercept_hooks,
+                                                         hook_data);
+
+   EOM_DBG("_e_eom_redirected_hook have been added");
+   return EINA_TRUE;
+
+err:
+   if (hook_data)
+     free(hook_data);
+   return EINA_FALSE;
+}
+
 static int
 _e_eom_util_get_stamp()
 {
index 7b0ff9a3f4ee00fb82c833f9573ecae9f045ea5d..7ebb4570b39eb525ba3a8769624fa5277215ce7d 100644 (file)
@@ -62,6 +62,7 @@ typedef struct _E_Eom_Out_Mode E_EomOutMode, *E_EomOutModePtr;
 typedef struct _E_Eom_Output E_EomOutput, *E_EomOutputPtr;
 typedef struct _E_Eom_Client_Buffer E_EomClientBuffer, *E_EomClientBufferPtr;
 typedef struct _E_Eom_Client E_EomClient, *E_EomClientPtr;
+typedef struct _E_Eom_Comp_Object_Intercept_Hook_Data E_EomCompObjectInterceptHookData;
 
 typedef enum
 {
@@ -128,10 +129,11 @@ struct _E_Eom
    int width;
    int height;
 
+   unsigned int output_count;
+   Eina_List *outputs;
    Eina_List *clients;
    Eina_List *handlers;
-   Eina_List *outputs;
-   unsigned int output_count;
+   Eina_List *comp_object_intercept_hooks;
 };
 
 struct _E_Eom_Client
@@ -158,6 +160,12 @@ struct _E_Eom_Client_Buffer
    unsigned long stamp;
 };
 
+struct _E_Eom_Comp_Object_Intercept_Hook_Data
+{
+   E_Client *ec;
+   E_Comp_Object_Intercept_Hook *hook;
+};
+
 static Eina_Bool _e_eom_init();
 static Eina_Bool _e_eom_init_internal();
 static void _e_eom_deinit();
@@ -188,6 +196,7 @@ static void _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequen
                              void *user_data);
 static void _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type type,
                                                tdm_value value, void *user_data);
+static Eina_Bool _e_eom_cb_comp_object_redirected(void *data, E_Client *ec);
 
 static Eina_Bool _e_eom_output_init(tdm_display *dpy);
 static const tdm_output_mode *_e_eom_output_get_best_mode(tdm_output *output);
@@ -212,6 +221,7 @@ static E_EomClientBufferPtr _e_eom_util_create_client_buffer(E_Comp_Wl_Buffer *w
 static void _e_eom_util_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v,
                                            int *dst_x, int *dst_y, int *dst_w, int *dst_h);
 static tbm_surface_h _e_eom_util_get_output_surface(const char *name);
+static Eina_Bool _e_eom_util_add_comp_object_redirected_hook(E_Client *ec);
 static int _e_eom_util_get_stamp();
 #if 0
 static void _e_eom_util_draw(tbm_surface_h surface);