make external outputs list when server init 68/66168/6
authorJunkyeong Kim <jk0430.kim@samsung.com>
Fri, 15 Apr 2016 13:40:19 +0000 (22:40 +0900)
committerJunkyeong Kim <jk0430.kim@samsung.com>
Fri, 22 Apr 2016 11:13:07 +0000 (20:13 +0900)
send external outputs count and info to client when binding
add wl_eom protocol to send external outputs info

Change-Id: I6ae2491b6f5ae867ab5fc89a552f6439b259e816
Signed-off-by: Junkyeong Kim <jk0430.kim@samsung.com>
configure.ac
packaging/e-mod-tizen-eom.spec
protocol/eom-client-protocol.h
protocol/eom-protocol.c
protocol/eom-server-protocol.h
protocol/eom.xml
src/e_mod_main.c

index cec8ae1..e46bc02 100644 (file)
@@ -35,7 +35,7 @@ fi
 
 PKG_CHECK_MODULES(WAYLAND_SCANNER, wayland-scanner)
 PKG_CHECK_MODULES(WAYLAND, [wayland-server])
-PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment])
+PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment, eom])
 
 dnl ========================================================================
 # checks for wayland only argument
index 68312d1..02242d1 100644 (file)
@@ -10,6 +10,7 @@ Group: Graphics & UI Framework/Other
 Source0: %{name}-%{version}.tar.gz
 License: BSD-2-Clause
 BuildRequires: pkgconfig(enlightenment)
+BuildRequires: pkgconfig(eom)
 BuildRequires:  gettext
 %if %{with x}
 BuildRequires:  pkgconfig(x11)
index 8b295fe..d38e84a 100644 (file)
@@ -153,6 +153,35 @@ enum wl_eom_attribute_state {
  */
 struct wl_eom_listener {
        /**
+        * output_count - (none)
+        * @count: (none)
+        */
+       void (*output_count)(void *data,
+                           struct wl_eom *wl_eom,
+                           uint32_t count);
+       /**
+        * output_info - (none)
+        * @output_id: (none)
+        * @type: (none)
+        * @mode: (none)
+        * @w: (none)
+        * @h: (none)
+        * @w_mm: (none)
+        * @h_mm: (none)
+        * @connection: (none)
+        */
+       void (*output_info)(void *data,
+                               struct wl_eom *wl_eom,
+                               uint32_t output_id,
+                               uint32_t type,
+                               uint32_t mode,
+                               uint32_t w,
+                               uint32_t h,
+                               uint32_t w_mm,
+                               uint32_t h_mm,
+                               uint32_t connection);
+
+       /**
         * output_type - (none)
         * @output_id: (none)
         * @type: (none)
@@ -196,6 +225,7 @@ wl_eom_add_listener(struct wl_eom *wl_eom,
 }
 
 #define WL_EOM_SET_ATTRIBUTE   0
+#define WL_EOM_GET_INFO                        1
 
 #define WL_EOM_SET_ATTRIBUTE_SINCE_VERSION     1
 
@@ -230,6 +260,13 @@ wl_eom_set_attribute(struct wl_eom *wl_eom, uint32_t output_id, uint32_t attribu
                         WL_EOM_SET_ATTRIBUTE, output_id, attribute);
 }
 
+static inline void
+wl_eom_get_output_info(struct wl_eom *wl_eom, uint32_t output_id)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_eom,
+                       WL_EOM_GET_INFO, output_id);
+}
+
 #ifdef  __cplusplus
 }
 #endif
index 265c780..ed56ef6 100644 (file)
@@ -8,13 +8,19 @@ static const struct wl_interface *types[] = {
        NULL,
        NULL,
        NULL,
+       NULL,
+       NULL,
+       NULL,
 };
 
 static const struct wl_message wl_eom_requests[] = {
        { "set_attribute", "uu", types + 0 },
+       { "get_output_info", "u", types + 0 },
 };
 
 static const struct wl_message wl_eom_events[] = {
+       { "output_count", "u", types + 0 },
+       { "output_info", "uuuuuuuu", types + 0 },
        { "output_type", "uuu", types + 0 },
        { "output_mode", "uu", types + 0 },
        { "output_attribute", "uuuu", types + 0 },
@@ -22,7 +28,7 @@ static const struct wl_message wl_eom_events[] = {
 
 WL_EXPORT const struct wl_interface wl_eom_interface = {
        "wl_eom", 1,
-       1, wl_eom_requests,
-       3, wl_eom_events,
+       2, wl_eom_requests,
+       5, wl_eom_events,
 };
 
index 1fa8d74..8ee0777 100644 (file)
@@ -159,17 +159,39 @@ struct wl_eom_interface {
                              struct wl_resource *resource,
                              uint32_t output_id,
                              uint32_t attribute);
+       /**
+        * get_output_info - (none)
+        * @output_id: (none)
+        */
+       void (*get_output_info)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             uint32_t output_id);
 };
 
-#define WL_EOM_OUTPUT_TYPE     0
-#define WL_EOM_OUTPUT_MODE     1
-#define WL_EOM_OUTPUT_ATTRIBUTE        2
+#define WL_EOM_OUTPUT_COUNT    0
+#define WL_EOM_OUTPUT_INFO     1
+#define WL_EOM_OUTPUT_TYPE     2
+#define WL_EOM_OUTPUT_MODE     3
+#define WL_EOM_OUTPUT_ATTRIBUTE        4
 
 #define WL_EOM_OUTPUT_TYPE_SINCE_VERSION       1
 #define WL_EOM_OUTPUT_MODE_SINCE_VERSION       1
 #define WL_EOM_OUTPUT_ATTRIBUTE_SINCE_VERSION  1
 
 static inline void
+wl_eom_send_output_count(struct wl_resource *resource_, uint32_t output_id, uint32_t count)
+{
+       wl_resource_post_event(resource_, WL_EOM_OUTPUT_COUNT, output_id, count);
+}
+
+static inline void
+wl_eom_send_output_info(struct wl_resource *resource_, uint32_t output_id, uint32_t type, uint32_t mode,
+                                                               uint32_t w, uint32_t h, uint32_t w_mm, uint32_t h_mm, uint32_t connection)
+{
+       wl_resource_post_event(resource_, WL_EOM_OUTPUT_INFO, output_id, type, mode, w, h, w_mm, h_mm, connection);
+}
+
+static inline void
 wl_eom_send_output_type(struct wl_resource *resource_, uint32_t output_id, uint32_t type, uint32_t status)
 {
        wl_resource_post_event(resource_, WL_EOM_OUTPUT_TYPE, output_id, type, status);
index b84cf7c..32fff54 100644 (file)
       <arg name="attribute" type="uint"/>
     </request>
 
+    <request name="get_output_info">
+      <arg name="output_id" type="uint"/>
+    </request>
+
+    <event name="output_count">
+      <arg name="count" type="uint"/>
+    </event>
+
+    <event name="output_info">
+      <arg name="output_id" type="uint"/>
+      <arg name="type" type="uint"/>
+      <arg name="mode" type="uint"/>
+      <arg name="w" type="uint"/>
+      <arg name="h" type="uint"/>
+      <arg name="w_mm" type="uint"/>
+      <arg name="h_mm" type="uint"/>
+      <arg name="connection" type="uint"/>
+    </event>
+
     <event name="output_type">
       <arg name="output_id" type="uint"/>
       <arg name="type" type="uint"/>
index 8fc7773..668598e 100644 (file)
@@ -12,6 +12,7 @@
 #include <tbm_surface.h>
 
 #include <tdm.h>
+#include <eom.h>
 
 #define NUM_MAIN_BUF 2
 #define NUM_ATTR 3
@@ -19,6 +20,7 @@
 typedef struct _E_Eom E_Eom, *E_EomPtr;
 typedef struct _E_Eom_Out_Mode E_EomOutMode, *E_EomOutModePtr;
 typedef struct _E_Eom_Data E_EomData, *E_EomDataPtr;
+typedef struct _E_Eom_Output E_EomOutput, *E_EomOutputPtr;
 
 struct _E_Eom_Out_Mode
 {
@@ -26,6 +28,33 @@ struct _E_Eom_Out_Mode
    int h;
 };
 
+struct _E_Eom_Output
+{
+   unsigned int id;
+   eom_output_type_e type;
+   eom_output_mode_e mode;
+   unsigned int w;
+   unsigned int h;
+   unsigned int phys_width;
+   unsigned int phys_height;
+
+   tdm_output_conn_status status;
+   unsigned int mirror_run;
+   eom_output_attribute_e attribute;
+   eom_output_attribute_state_e attribute_state;
+
+   /* external output data */
+   char *ext_output_name;
+   int is_external_init;
+   E_EomOutMode src_mode;
+   E_Comp_Wl_Output *wl_output;
+
+   /* internal output data */
+   char *int_output_name;
+   int is_internal_grab;
+   E_EomOutMode dst_mode;
+};
+
 struct _E_Eom
 {
    struct wl_global *global;
@@ -36,6 +65,10 @@ struct _E_Eom
    tbm_bufmgr bufmgr;
    int fd;
 
+   Eina_List *outputs;
+   unsigned int output_count;
+
+#if 1
    /* eom state */
    enum wl_eom_mode eom_mode;
    enum wl_eom_attribute eom_attribute;
@@ -53,6 +86,7 @@ struct _E_Eom
    char *int_output_name;
    int is_internal_grab;
    E_EomOutMode dst_mode;
+#endif
 };
 
 struct _E_Eom_Data
@@ -727,7 +761,7 @@ _e_eom_root_internal_tdm_surface_get(const char *name)
         return NULL;
      }
 
-   //EOM_DBG("FRAMEBUFFER ECORE_DRM: is_client:%d mode%dx%d\n", fb->from_client, fb->w, fb->h);
+   /*EOM_DBG("FRAMEBUFFER ECORE_DRM: is_client:%d mode%dx%d\n", fb->from_client, fb->w, fb->h);*/
 
    return (tbm_surface_h)fb->hal_buffer;
 }
@@ -1092,9 +1126,34 @@ _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource
 
 }
 
+static void
+_e_eom_wl_request_get_output_info_cb(struct wl_client *client, struct wl_resource *resource, uint32_t output_id)
+{
+   EOM_DBG("output:%d\n", output_id);
+
+   if (g_eom->outputs)
+     {
+        Eina_List *l;
+        E_EomOutputPtr output;
+
+        EINA_LIST_FOREACH(g_eom->outputs, l, output)
+          {
+             if (output->id == output_id)
+               {
+                  EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n",
+                          output->id, output->type, output->mode, output->w, output->h,
+                          output->phys_width, output->phys_height, output->status);
+                  wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->w, output->h,
+                                          output->phys_width, output->phys_height, output->status);
+               }
+          }
+     }
+}
+
 static const struct wl_eom_interface _e_eom_wl_implementation =
 {
-   _e_eom_wl_request_set_attribute_cb
+   _e_eom_wl_request_set_attribute_cb,
+   _e_eom_wl_request_get_output_info_cb
 };
 
 /* wl_eom global object destroy function */
@@ -1108,8 +1167,8 @@ _e_eom_wl_resource_destory_cb(struct wl_resource *resource)
 static void
 _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 {
-   enum wl_eom_type eom_type = WL_EOM_TYPE_NONE;
-   E_Comp_Wl_Output *wl_output = NULL;
+/*   enum wl_eom_type eom_type = WL_EOM_TYPE_NONE;*/
+/*   E_Comp_Wl_Output *wl_output = NULL;*/
    struct wl_resource *resource;
    E_EomPtr eom = data;
 
@@ -1131,6 +1190,7 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32
 
    eom->resource = resource;
 
+#if 0
    wl_output = _e_eom_e_comp_wl_output_get(e_comp_wl->outputs, g_eom->ext_output_name);
    if (!wl_output)
      {
@@ -1159,7 +1219,26 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32
    wl_eom_send_output_mode(eom->resource,
                            eom->id,
                            _e_eom_get_eom_mode());
+#else
+   EOM_DBG("send - output count : %d\n", g_eom->output_count);
+   wl_eom_send_output_count(eom->resource,
+                            g_eom->output_count);
+
+   if (g_eom->outputs)
+     {
+        Eina_List *l;
+        E_EomOutputPtr output;
 
+        EINA_LIST_FOREACH(g_eom->outputs, l, output)
+          {
+             EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n",
+                     output->id, output->type, output->mode, output->w, output->h,
+                     output->phys_width, output->phys_height, output->status);
+             wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->w, output->h,
+                                     output->phys_width, output->phys_height, output->status);
+          }
+     }
+#endif
    EOM_DBG("create wl_eom global resource.\n");
 }
 
@@ -1182,46 +1261,199 @@ _e_eom_deinit()
         fullscreen_pre_hook = NULL;
      }
 
+   if (g_eom->dpy) tdm_display_deinit(g_eom->dpy);
+   if (g_eom->bufmgr) tbm_bufmgr_deinit(g_eom->bufmgr);
+
    if (g_eom->global) wl_global_destroy(g_eom->global);
 
    E_FREE(g_eom);
 }
 
-int
+static Eina_Bool
+_e_eom_output_info_get(tdm_display *dpy)
+{
+   int i, count;
+   tdm_error ret = TDM_ERROR_NONE;
+
+   ret = tdm_display_get_output_count(dpy, &count);
+   if (ret != TDM_ERROR_NONE)
+     {
+        EOM_ERR("tdm_display_get_output_count fail\n");
+        return EINA_FALSE;
+     }
+
+   if (count <= 1)
+     {
+        EOM_DBG("output count is 1. device doesn't support external outputs.\n");
+        return EINA_FALSE;
+     }
+
+   g_eom->output_count = count - 1;
+   EOM_DBG("external output count : %d\n", g_eom->output_count);
+
+   for (i = 0; i < count; i++)
+     {
+        tdm_output *output = NULL;
+        E_EomOutputPtr new_output;
+        tdm_output_type type;
+        tdm_output_conn_status status;
+        unsigned int mmWidth, mmHeight;
+        const tdm_output_mode *mode;
+
+        output = tdm_display_get_output(dpy, i, &ret);
+        if (ret != TDM_ERROR_NONE)
+          {
+             EOM_ERR("tdm_display_get_output fail(ret:%d)", ret);
+             goto err;
+          }
+
+        if (!output)
+          {
+             EOM_ERR("tdm_display_get_output fail(no output:%d)", ret);
+             goto err;
+          }
+
+        ret = tdm_output_get_output_type(output, &type);
+        if (ret != TDM_ERROR_NONE)
+          {
+             EOM_ERR("tdm_output_get_output_type fail(%d)", ret);
+             goto err;
+          }
+        /* skip main output */
+        /* TODO: need more check about main display*/
+        if ((type == TDM_OUTPUT_TYPE_DSI) || (type == TDM_OUTPUT_TYPE_LVDS))
+          continue;
+
+        new_output = E_NEW(E_EomOutput, 1);
+        if (!new_output)
+          {
+             EOM_ERR("calloc fail");
+             goto err;
+          }
+
+        ret = tdm_output_get_conn_status(output, &status);
+        if (ret != TDM_ERROR_NONE)
+          {
+             EOM_ERR("tdm_output_get_conn_status fail(%d)", ret);
+             free(new_output);
+             goto err;
+          }
+        new_output->id = i;
+        new_output->type = type;
+        new_output->status = status;
+        new_output->mode = EOM_OUTPUT_MODE_NONE;
+
+        if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
+          {
+             EOM_DBG("create(%d)output, type:%d, status:%d",
+                     new_output->id, new_output->type, new_output->status);
+             g_eom->outputs = eina_list_append(g_eom->outputs, new_output);
+             continue;
+          }
+        new_output->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
+
+        ret = tdm_output_get_mode(output, &mode);
+        if (ret != TDM_ERROR_NONE)
+          {
+             EOM_ERR("tdm_output_get_mode fail(%d)", ret);
+             free(new_output);
+             goto err;
+          }
+        if (mode == NULL)
+          {
+             new_output->w = 0;
+             new_output->h = 0;
+          }
+        else
+          {
+             new_output->w = mode->hdisplay;
+             new_output->h = mode->vdisplay;
+          }
+
+        ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight);
+        if (ret != TDM_ERROR_NONE)
+          {
+             EOM_ERR("tdm_output_get_conn_status fail(%d)", ret);
+             free(new_output);
+             goto err;
+          }
+        new_output->phys_width = mmWidth;
+        new_output->phys_height = mmHeight;
+
+        EOM_DBG("create(%d)output, type:%d, status:%d, w:%d, h:%d, mm_w:%d, mm_h:%d",
+                new_output->id, new_output->type, new_output->status,
+                new_output->w, new_output->h, new_output->phys_width, new_output->phys_height);
+
+        g_eom->outputs = eina_list_append(g_eom->outputs, new_output);
+     }
+
+   return EINA_TRUE;
+err:
+
+   if (g_eom->outputs)
+     {
+        Eina_List *l;
+        E_EomOutputPtr output;
+
+        EINA_LIST_FOREACH(g_eom->outputs, l, output)
+          {
+             free(output);
+          }
+        eina_list_free(g_eom->outputs);
+     }
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
 _e_eom_init_internal()
 {
-   tdm_error err = TDM_ERROR_NONE;
+   tdm_error ret = TDM_ERROR_NONE;
 
-   g_eom->dpy = tdm_display_init(&err);
-   if (err != TDM_ERROR_NONE)
+   g_eom->dpy = tdm_display_init(&ret);
+   if (ret != TDM_ERROR_NONE)
      {
-        EOM_DBG("failed initialize TDM\n");
+        EOM_ERR("tdm_display_init fail\n");
         goto err;
      }
 
-   err = tdm_display_get_fd(g_eom->dpy, &g_eom->fd);
-   if (err != TDM_ERROR_NONE)
+   ret = tdm_display_get_fd(g_eom->dpy, &g_eom->fd);
+   if (ret != TDM_ERROR_NONE)
      {
-        EOM_DBG("failed get FD\n");
+        EOM_ERR("tdm_display_get_fd fail\n");
         goto err;
      }
 
    g_eom->bufmgr = tbm_bufmgr_init(g_eom->fd);
    if (!g_eom->bufmgr)
      {
-        EOM_DBG("failed initialize buffer manager\n");
+        EOM_ERR("tbm_bufmgr_init fail\n");
         goto err;
      }
 
-   return 1;
+   if (_e_eom_output_info_get(g_eom->dpy) != EINA_TRUE)
+     {
+        EOM_ERR("_e_eom_output_info_get fail\n");
+        goto err;
+     }
+
+   return EINA_TRUE;
+
 err:
-   return 0;
+   if (g_eom->bufmgr)
+     tbm_bufmgr_deinit(g_eom->bufmgr);
+
+   if (g_eom->dpy)
+     tdm_display_deinit(g_eom->dpy);
+
+   return EINA_FALSE;
+
 }
 
 static Eina_Bool
 _e_eom_init()
 {
-   int ret = 0;
+   Eina_Bool ret = 0;
 
    EINA_SAFETY_ON_NULL_GOTO(e_comp_wl, err);
 
@@ -1237,7 +1469,7 @@ _e_eom_init()
    EINA_SAFETY_ON_NULL_GOTO(g_eom->global, err);
 
    ret = _e_eom_init_internal();
-   if (!ret)
+   if (ret == EINA_FALSE)
      {
         EOM_ERR("failed init_internal()");
         goto err;