virtual output: Add implementation for set_available_modes, connect and disconnect. 14/184614/1
authorSeunghun Lee <shiin.lee@samsung.com>
Thu, 19 Jul 2018 07:17:14 +0000 (16:17 +0900)
committerSeunghun Lee <shiin.lee@samsung.com>
Thu, 19 Jul 2018 07:17:14 +0000 (16:17 +0900)
Change-Id: Ic85238c5833286ae22fc698d3d8b3fe2fc903e24

client/tdm_client.c
client/tdm_client_types.h
haltests/src/tc_tdm_client.cpp
protocol/tdm.xml
src/tdm_server.c

index 8d17c94..4c05811 100644 (file)
@@ -92,6 +92,13 @@ typedef struct _tdm_private_client_output {
 typedef struct _tdm_private_client_voutput {
     tdm_private_client_output base;
        struct wl_tdm_voutput *wl_voutput;
+
+       struct
+       {
+               int count;
+               tdm_client_output_mode *modes;
+       } available_modes;
+
        uint32_t msg;
 } tdm_private_client_voutput;
 
@@ -1679,7 +1686,6 @@ tdm_client_create_voutput(tdm_client *client, const char *name, tdm_error *error
 
        private_voutput->base.private_client = private_client;
 
-       snprintf(private_voutput->base.name, TDM_NAME_LEN, "%s", name);
        private_voutput->wl_voutput = wl_tdm_create_voutput((struct wl_tdm *)wrapper, private_voutput->base.name);
        wl_proxy_wrapper_destroy(wrapper);
        if (!private_voutput->wl_voutput) {
@@ -1731,15 +1737,36 @@ tdm_client_voutput_destroy(tdm_client_voutput *voutput)
        if (!private_voutput)
                return;
 
+       wl_tdm_voutput_destroy(private_voutput->wl_voutput);
+
        free(private_voutput);
 }
 
 tdm_error
 tdm_client_voutput_set_available_modes(tdm_client_voutput *voutput, const tdm_client_output_mode *modes, int count)
 {
+       tdm_private_client_voutput *private_voutput;
+
        TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
-       TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
-       TDM_RETURN_VAL_IF_FAIL(count > 0, TDM_ERROR_INVALID_PARAMETER);
+
+       if ((count > 0) && (modes == NULL))
+               return TDM_ERROR_INVALID_PARAMETER;
+
+       private_voutput = (tdm_private_client_voutput *)voutput;
+
+       if (private_voutput->base.connection == TDM_OUTPUT_CONN_STATUS_CONNECTED)
+               return TDM_ERROR_BAD_REQUEST;
+
+       if (private_voutput->available_modes.modes)
+               free(private_voutput->available_modes.modes);
+
+       private_voutput->available_modes.count = count;
+
+       if (count != 0)
+       {
+               private_voutput->available_modes.modes = calloc(count, sizeof(tdm_client_output_mode));
+               memcpy(private_voutput->available_modes.modes, modes, sizeof(tdm_client_output_mode) * count);
+       }
 
        return TDM_ERROR_NONE;
 }
@@ -1807,14 +1834,57 @@ tdm_client_output_set_mode(tdm_client_output *output, const tdm_client_output_mo
 tdm_error
 tdm_client_output_connect(tdm_client_output *output)
 {
+       tdm_private_client_output *private_output;
+       tdm_private_client_voutput *private_voutput;
+       tdm_client_output_mode *modes;
+       int i;
+
        TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
 
+       private_output = (tdm_private_client_output *)output;
+       private_voutput = (tdm_private_client_voutput *)output;
+
+       TDM_RETURN_VAL_IF_FAIL(private_output->connection != TDM_OUTPUT_CONN_STATUS_CONNECTED,
+                                                  TDM_ERROR_BAD_REQUEST);
+
+       private_output->connection = TDM_OUTPUT_CONN_STATUS_CONNECTED;
+
+       modes = private_voutput->available_modes.modes;
+       for (i = 0; i < private_voutput->available_modes.count; i++)
+       {
+               wl_tdm_voutput_set_available_modes(private_voutput->wl_voutput, i,
+                                                                                  modes[i].clock, modes[i].hdisplay,
+                                                                                  modes[i].hsync_start, modes[i].hsync_end,
+                                                                                  modes[i].htotal, modes[i].hskew,
+                                                                                  modes[i].vdisplay, modes[i].vsync_start,
+                                                                                  modes[i].vsync_end, modes[i].vtotal,
+                                                                                  modes[i].vscan, modes[i].vrefresh,
+                                                                                  modes[i].flags, modes[i].type,
+                                                                                  modes[i].name);
+       }
+
+       wl_tdm_voutput_connect(private_voutput->wl_voutput);
+
        return TDM_ERROR_NONE;
 }
 
 tdm_error
 tdm_client_output_disconnect(tdm_client_output *output)
 {
+       tdm_private_client_voutput *private_voutput;
+       tdm_private_client_output *private_output;
+
        TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       private_output = (tdm_private_client_output *)output;
+       private_voutput = (tdm_private_client_voutput *)output;
+
+       TDM_RETURN_VAL_IF_FAIL(private_output->connection != TDM_OUTPUT_CONN_STATUS_DISCONNECTED,
+                                                  TDM_ERROR_BAD_REQUEST);
+
+       private_output->connection = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+       wl_tdm_voutput_disconnect(private_voutput->wl_voutput);
+
        return TDM_ERROR_NONE;
 }
index cb4e96d..096b44f 100644 (file)
@@ -110,13 +110,15 @@ typedef void
                                                         void *user_data);
 
 /* Virtual Output */
+/* this is a copy of server side's tdm_output_mode */
 typedef struct _tdm_client_output_mode {
-    char name[TDM_NAME_LEN];        /**< The output name */
-    unsigned int mode_count;        /**< The count of available modes */
-    unsigned int prop_count;        /**< The count of available properties */
-    unsigned int mmWidth;           /**< The physical width (milimeter) */
-    unsigned int mmHeight;          /**< The physical height (milimeter) */
-    unsigned int subpixel;          /**< The subpixel */
+       unsigned int clock;
+       unsigned int hdisplay, hsync_start, hsync_end, htotal, hskew;
+       unsigned int vdisplay, vsync_start, vsync_end, vtotal, vscan;
+       unsigned int vrefresh;
+       unsigned int flags;
+       unsigned int type;
+       char name[TDM_NAME_LEN];
 } tdm_client_output_mode;
 
 typedef void tdm_client_voutput;
index f7ff9f8..1909ff0 100644 (file)
@@ -1412,7 +1412,7 @@ public:
 protected:
        static tdm_client *client;
        static tdm_client_voutput *voutput;
-       const int MODE_COUNT = 1;
+       const int MODE_COUNT = 2;
 
 private:
        static pid_t server_pid;
@@ -1522,12 +1522,21 @@ TEST_F(TDMVirtualOutput, SetAvailableModes)
 
        for (i = 0; i < count; i++)
        {
-               modes[i].mmHeight = 1234;
-               modes[i].mmWidth = 1234;
-               modes[i].mode_count = 0;
-               modes[i].prop_count = 0;
-               modes[i].subpixel = 0;
-               snprintf(modes[i].name, TDM_NAME_LEN, "TestModeSetting");
+               modes[i].clock = 1;
+               modes[i].hdisplay = 2;
+               modes[i].hsync_start = 3;
+               modes[i].hsync_end = 4;
+               modes[i].htotal = 5;
+               modes[i].hskew = 6;
+               modes[i].vdisplay = 7;
+               modes[i].vsync_start = 8;
+               modes[i].vsync_end = 9;
+               modes[i].vtotal = 10;
+               modes[i].vscan = 11;
+               modes[i].vrefresh = 12;
+               modes[i].flags = 13;
+               modes[i].type = 14;
+               snprintf(modes[i].name, TDM_NAME_LEN, "TestModeSetting %d", i);
        }
 
        ret = tdm_client_voutput_set_available_modes(this->voutput, modes, count);
@@ -1545,9 +1554,6 @@ TEST_F(TDMVirtualOutput, FailTestSetAvailableModes)
 
        ret = tdm_client_voutput_set_available_modes(this->voutput, NULL, count);
        ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
-
-       ret = tdm_client_voutput_set_available_modes(this->voutput, modes, 0);
-       ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
 }
 
 TEST_F(TDMVirtualOutput, SetPhysicalSize)
@@ -1578,6 +1584,36 @@ TEST_F(TDMVirtualOutput, GetClientOutput)
        ASSERT_NE(output, NULL);
 }
 
+TEST_F(TDMVirtualOutput, Connect)
+{
+       tdm_error ret;
+       tdm_client_output *output;
+
+       output = tdm_client_voutput_get_client_output(this->voutput, &ret);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+       ASSERT_NE(output, NULL);
+
+       ret = tdm_client_output_connect(output);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+
+       tdm_client_handle_events_timeout(this->client, 0);
+}
+
+TEST_F(TDMVirtualOutput, Disconnect)
+{
+       tdm_error ret;
+       tdm_client_output *output;
+
+       output = tdm_client_voutput_get_client_output(this->voutput, &ret);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+       ASSERT_NE(output, NULL);
+
+       ret = tdm_client_output_disconnect(output);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+
+       tdm_client_handle_events_timeout(this->client, 0);
+}
+
 #if 0
 TEST_F(TDMVirtualOutput, FailTestGetClientOutput)
 {
index 58422cf..1248920 100644 (file)
 
         <request name="destroy" type="destructor"/>
 
+        <request name="set_available_modes">
+            <arg name="index" type="uint" summary=""/>
+            <arg name="clock" type="uint" summary=""/>
+            <arg name="hdisplay" type="uint" summary=""/>
+            <arg name="hsync_start" type="uint" summary=""/>
+            <arg name="hsync_end" type="uint" summary=""/>
+            <arg name="htotal" type="uint" summary=""/>
+            <arg name="hskew" type="uint" summary=""/>
+            <arg name="vdisplay" type="uint" summary=""/>
+            <arg name="vsync_start" type="uint" summary=""/>
+            <arg name="vsync_end" type="uint" summary=""/>
+            <arg name="vtotal" type="uint" summary=""/>
+            <arg name="vscan" type="uint" summary=""/>
+            <arg name="vrefresh" type="uint" summary=""/>
+            <arg name="flags" type="uint" summary=""/>
+            <arg name="type" type="uint" summary=""/>
+            <arg name="name" type="string" summary=""/>
+        </request>
+
+        <request name="connect"/>
+
+        <request name="disconnect"/>
+
         <event name="ack_message">
             <arg name="msg" type="uint" enum="message" summary=""/>
         </event>
index d98339c..ed4ddff 100644 (file)
@@ -703,6 +703,132 @@ _tdm_server_cb_create_output(struct wl_client *client, struct wl_resource *resou
        }
 }
 
+typedef struct _tdm_server_voutput_info {
+       tdm_private_server *private_server;
+       tdm_output_conn_status status;
+       struct
+       {
+               int count;
+               tdm_output_mode *modes;
+       } available_modes;
+} tdm_server_voutput_info;
+
+static void _tdm_voutput_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+       wl_resource_destroy(resource);
+}
+
+static void
+_tdm_voutput_cb_set_available_modes(struct wl_client *client,
+                                                                       struct wl_resource *resource,
+                                                                       uint32_t index,
+                                                                       uint32_t clock,
+                                                                       uint32_t hdisplay,
+                                                                       uint32_t hsync_start,
+                                                                       uint32_t hsync_end,
+                                                                       uint32_t htotal,
+                                                                       uint32_t hskew,
+                                                                       uint32_t vdisplay,
+                                                                       uint32_t vsync_start,
+                                                                       uint32_t vsync_end,
+                                                                       uint32_t vtotal,
+                                                                       uint32_t vscan,
+                                                                       uint32_t vrefresh,
+                                                                       uint32_t flags,
+                                                                       uint32_t type,
+                                                                       const char *name)
+{
+       tdm_server_voutput_info *voutput_info;
+       tdm_output_mode *tmp_modes, *old_modes;
+       tdm_output_mode *new_mode;
+       int count, len;
+
+       voutput_info = wl_resource_get_user_data(resource);
+
+       count = voutput_info->available_modes.count;
+       old_modes = voutput_info->available_modes.modes;
+       if (index >= count)
+       {
+               if (count > 0)
+               {
+                       tmp_modes = malloc(count * sizeof(*tmp_modes));
+                       memcpy(tmp_modes, old_modes, count * sizeof(tdm_output_mode));
+               }
+
+               voutput_info->available_modes.count = index + 1;
+               voutput_info->available_modes.modes =
+                       realloc(voutput_info->available_modes.modes,
+                                       sizeof(tdm_output_mode) * (index + 1));
+
+               if (count > 0)
+               {
+                       memcpy(voutput_info->available_modes.modes, tmp_modes, count * sizeof(tdm_output_mode));
+                       free(tmp_modes);
+               }
+       }
+
+       new_mode = &voutput_info->available_modes.modes[index];
+       new_mode->clock = clock;
+       new_mode->hdisplay = hdisplay;
+       new_mode->hsync_start = hsync_start;
+       new_mode->hsync_end = hsync_end;
+       new_mode->htotal = htotal;
+       new_mode->hskew= hskew;
+       new_mode->vdisplay= vdisplay;
+       new_mode->vsync_start= vsync_start;
+       new_mode->vsync_end = vsync_end;
+       new_mode->vtotal = vtotal;
+       new_mode->vscan = vscan;
+       new_mode->vrefresh = vrefresh;
+       new_mode->flags = flags;
+       new_mode->type = type;
+
+       len = strlen(name);
+       strncpy(new_mode->name, name, len);
+       new_mode->name[len] = '\0';
+}
+
+static void
+_tdm_voutput_cb_connect(struct wl_client *client, struct wl_resource *resource)
+{
+       tdm_server_voutput_info *voutput_info;
+
+       voutput_info = wl_resource_get_user_data(resource);
+       voutput_info->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
+}
+
+static void
+_tdm_voutput_cb_disconnect(struct wl_client *client, struct wl_resource *resource)
+{
+       tdm_server_voutput_info *voutput_info;
+
+       voutput_info = wl_resource_get_user_data(resource);
+       voutput_info->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+       /* Do free resources when it's being disconnected */
+       free(voutput_info->available_modes.modes);
+       voutput_info->available_modes.modes = NULL;
+       voutput_info->available_modes.count = 0;
+}
+
+static const struct wl_tdm_voutput_interface tdm_voutput_implementation = {
+       _tdm_voutput_cb_destroy,
+       _tdm_voutput_cb_set_available_modes,
+       _tdm_voutput_cb_connect,
+       _tdm_voutput_cb_disconnect
+};
+
+void
+tdm_voutput_cb_resource_destroy(struct wl_resource *resource)
+{
+       tdm_server_voutput_info *voutput_info;
+
+       voutput_info = wl_resource_get_user_data(resource);
+
+       /* Do free your own resource */
+       free(voutput_info);
+}
+
 static void
 _tdm_server_cb_create_virtual_output(struct wl_client *client, struct wl_resource *resource, const char *name, uint32_t id)
 {
@@ -758,10 +884,12 @@ _tdm_server_cb_create_virtual_output(struct wl_client *client, struct wl_resourc
        voutput_info->resource = voutput_resource;
        voutput_info->output = output;
        LIST_INITHEAD(&voutput_info->output_list);
-#if 0
-       wl_resource_set_implementation(voutput_resource, &tdm_voutput_implementation,
-                                                                  voutput_info, destroy_voutput_callback);
-#endif
+
+       wl_resource_set_implementation(voutput_resource,
+                                                                  &tdm_voutput_implementation,
+                                                                  voutput_info,
+                                                                  tdm_voutput_cb_resource_destroy);
+
        wl_tdm_voutput_send_ack_message(voutput_resource, WL_TDM_VOUTPUT_MESSAGE_ADDED);
 }