From: Junkyeong Kim Date: Thu, 23 Aug 2018 09:02:10 +0000 (+0900) Subject: virtual: add get_available_modes and set_mode protocol. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F53%2F187453%2F2;p=platform%2Fcore%2Fuifw%2Flibtdm.git virtual: add get_available_modes and set_mode protocol. add tc for tdm_client_output_get_available_modes. Change-Id: Id5a4616b89ecf0c4b8a3f853f6a37fd27049f3e1 Signed-off-by: Junkyeong Kim --- diff --git a/client/tdm_client.c b/client/tdm_client.c index a187cb6..f5c69db 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -95,6 +95,11 @@ typedef struct _tdm_private_client_output { unsigned int req_id; unsigned int watch_output_changes; + struct { + int count; + tdm_client_output_mode *modes; + } available_modes; + tdm_private_client_voutput *voutput; } tdm_private_client_output; @@ -436,10 +441,41 @@ _tdm_client_output_cb_dpms(void *data, struct wl_tdm_output *wl_tdm_output, uint pthread_mutex_lock(&private_client->lock); } +static void +_tdm_client_output_cb_availablie_modes(void *data, struct wl_tdm_output *wl_tdm_output, struct wl_array *modes, uint32_t error) +{ + tdm_private_client_output *private_output = (tdm_private_client_output*)data; + tdm_output_mode *mode; + int size, count = 0, i = 0; + + if (error != TDM_ERROR_NONE) + TDM_INFO("get availablie_modes event error: %d", error); + + private_output->available_modes.count = 0; + if (private_output->available_modes.modes) + free(private_output->available_modes.modes); + + wl_array_for_each(mode, modes) + count++; + if (count == 0) { + TDM_INFO("no output mode"); + return; + } + + size = sizeof(tdm_output_mode); + + private_output->available_modes.modes = malloc(count * size); + private_output->available_modes.count = count; + + wl_array_for_each(mode, modes) + memcpy(&private_output->available_modes.modes[i++], mode, size); +} + static const struct wl_tdm_output_listener tdm_client_output_listener = { _tdm_client_output_cb_mode, _tdm_client_output_cb_connection, _tdm_client_output_cb_dpms, + _tdm_client_output_cb_availablie_modes, }; static void @@ -1144,6 +1180,72 @@ tdm_client_output_get_dpms(tdm_client_output *output, tdm_output_dpms *dpms) return TDM_ERROR_NONE; } +tdm_error +tdm_client_output_get_available_modes(tdm_client_output *output, tdm_client_output_mode **modes, int *count) +{ + tdm_private_client_output *private_output; + tdm_private_client *private_client; + + TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); + + + private_output = (tdm_private_client_output *)output; + private_client = private_output->private_client; + if (private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { + *modes = NULL; + *count = 0; + return TDM_ERROR_NONE; + } + + pthread_mutex_lock(&private_client->lock); + + if (CHECK_WL_PROTOCOL_ERROR(private_client)) { + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_PROTOCOL_ERROR; + } + + wl_proxy_set_queue((struct wl_proxy *)private_output->output, private_client->queue); + wl_tdm_output_get_available_modes(private_output->output); + wl_display_roundtrip_queue(private_client->display, private_client->queue); + wl_proxy_set_queue((struct wl_proxy *)private_output->output, NULL); + + if (CHECK_WL_PROTOCOL_ERROR(private_client)) { + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_PROTOCOL_ERROR; + } + + *modes = (tdm_client_output_mode *)private_output->available_modes.modes; + *count = private_output->available_modes.count; + + pthread_mutex_unlock(&private_client->lock); + + return TDM_ERROR_NONE; +} + +tdm_error +tdm_client_output_set_mode(tdm_client_output *output, int index) +{ + tdm_private_client_output *private_output; + + TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(index < 0, TDM_ERROR_INVALID_PARAMETER); + + private_output = (tdm_private_client_output*)output; + + if (private_output->available_modes.count - 1 < index) + return TDM_ERROR_INVALID_PARAMETER; + + if ((private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) || + (private_output->available_modes.count == 0)) + return TDM_ERROR_BAD_REQUEST; + + wl_tdm_output_set_mode(private_output->output, index); + + return TDM_ERROR_NONE; +} + tdm_client_vblank* tdm_client_output_create_vblank(tdm_client_output *output, tdm_error *error) { @@ -2311,25 +2413,6 @@ tdm_client_voutput_get_client_output(tdm_client_voutput *voutput, tdm_error *err return private_output; } -tdm_error -tdm_client_output_get_available_modes(tdm_client_output *output, tdm_client_output_mode **modes, int *count) -{ - TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); - - return TDM_ERROR_NONE; -} - -tdm_error -tdm_client_output_set_mode(tdm_client_output *output, const tdm_client_output_mode *mode) -{ - TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER); - - return TDM_ERROR_NONE; -} - void _tdm_client_voutput_send_available_modes(tdm_private_client_voutput *private_voutput) { diff --git a/client/tdm_client.h b/client/tdm_client.h index 8c10ebe..b52785a 100644 --- a/client/tdm_client.h +++ b/client/tdm_client.h @@ -462,7 +462,7 @@ tdm_error tdm_client_output_get_available_modes(tdm_client_output *output, tdm_client_output_mode **modes, int *count); tdm_error -tdm_client_output_set_mode(tdm_client_output *output, const tdm_client_output_mode *mode); +tdm_client_output_set_mode(tdm_client_output *output, int index); tdm_error tdm_client_output_connect(tdm_client_output *output); diff --git a/haltests/src/tc_tdm_client.cpp b/haltests/src/tc_tdm_client.cpp index 01668cb..883ac5c 100644 --- a/haltests/src/tc_tdm_client.cpp +++ b/haltests/src/tc_tdm_client.cpp @@ -802,6 +802,45 @@ TEST_P(TDMClient, ClientOutputGetDpmsNullOther) ASSERT_EQ(tdm_client_output_get_dpms(output, NULL), TDM_ERROR_INVALID_PARAMETER); } +TEST_P(TDMClient, ClientOutputGetAvailableModes) +{ + tdm_client_output_mode *modes; + int i, count = 0; + + ASSERT_EQ(PrepareClient(), true); + ASSERT_EQ(PrepareOutput(), true); + + ASSERT_EQ(tdm_client_output_get_available_modes(output, &modes, &count), TDM_ERROR_NONE); + ASSERT_GT(count, 0); + + for (i = 0; i < count; i++) { + tdm_client_output_mode *mode = (tdm_client_output_mode *)&modes[i]; + ASSERT_GT(mode->hdisplay, 0); + ASSERT_GT(mode->vdisplay, 0); + ASSERT_GT(mode->vrefresh, 0); + } +} + +TEST_P(TDMClient, ClientOutputGetAvailableModesNullObject) +{ + tdm_client_output_mode *modes; + int count = TDM_UT_INVALID_VALUE; + + ASSERT_EQ(PrepareClient(), true); + ASSERT_EQ(PrepareOutput(), true); + + ASSERT_EQ(tdm_client_output_get_available_modes(NULL, &modes, &count), TDM_ERROR_INVALID_PARAMETER); + ASSERT_EQ(count, TDM_UT_INVALID_VALUE); +} + +TEST_P(TDMClient, ClientOutputGetAvailableModesNullOther) +{ + ASSERT_EQ(PrepareClient(), true); + ASSERT_EQ(PrepareOutput(), true); + + ASSERT_EQ(tdm_client_output_get_available_modes(output, NULL, NULL), TDM_ERROR_INVALID_PARAMETER); +} + /* tdm_client_output_create_vblank */ TEST_P(TDMClient, ClientOutputCreateVblank) { diff --git a/protocol/tdm.xml b/protocol/tdm.xml index a152c95..8272eec 100644 --- a/protocol/tdm.xml +++ b/protocol/tdm.xml @@ -53,6 +53,11 @@ + + + + + @@ -69,6 +74,12 @@ + + + + + + diff --git a/src/tdm_server.c b/src/tdm_server.c index e51d868..a71eb0e 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -596,6 +596,53 @@ failed: wl_tdm_output_send_dpms(output_info->resource, TDM_OUTPUT_DPMS_OFF, ret); } +static void +_tdm_server_output_cb_get_available_modes(struct wl_client *client, struct wl_resource *resource) +{ + tdm_server_output_info *output_info = wl_resource_get_user_data(resource); + const tdm_output_mode *modes; + tdm_output_mode *mode; + struct wl_array array; + int i, size, count = 0; + tdm_error ret; + + ret = tdm_output_get_available_modes(output_info->output, &modes, &count); + + if ((ret != TDM_ERROR_NONE) || (count == 0)) { + wl_tdm_output_send_available_modes(output_info->resource, NULL, ret); + return; + } + + size = sizeof(tdm_output_mode); + wl_array_init(&array); + for (i = 0; i < count; i++) { + mode = wl_array_add(&array, size); + memcpy(mode, &modes[i], size); + } + + wl_tdm_output_send_available_modes(output_info->resource, &array, ret); + + wl_array_release(&array); +} + +static void +_tdm_server_output_cb_set_mode(struct wl_client *client, struct wl_resource *resource, unsigned int index) +{ + tdm_server_output_info *output_info = wl_resource_get_user_data(resource); + tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; + tdm_error ret; + + TDM_RETURN_IF_FAIL(output_info != NULL); + + ret = tdm_output_get_conn_status(output_info->output, &status); + TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); + TDM_RETURN_IF_FAIL(status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED); + + //To do + + return; +} + static const struct wl_tdm_output_interface tdm_output_implementation = { _tdm_server_output_cb_destroy, _tdm_server_output_cb_create_vblank, @@ -603,6 +650,8 @@ static const struct wl_tdm_output_interface tdm_output_implementation = { _tdm_server_output_cb_get_connection, _tdm_server_output_cb_get_mode, _tdm_server_output_cb_get_dpms, + _tdm_server_output_cb_get_available_modes, + _tdm_server_output_cb_set_mode, }; static void