From: Junkyeong Kim Date: Fri, 24 Aug 2018 09:36:59 +0000 (+0900) Subject: virtual: support tdm_client output_set_mode X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Flibtdm.git;a=commitdiff_plain;h=fed869744d5e1d1939c39a8fda793aa0caee6cc1 virtual: support tdm_client output_set_mode use mode index.(server and client know both full mode list) tdm server must set mode_change_request_handler if output mode change from client is possible. add tc for output_set_mode Change-Id: I1767e6a6a561cb396b708769b90cfeac16bdf47f Signed-off-by: Junkyeong Kim --- diff --git a/client/tdm_client.c b/client/tdm_client.c index f5c69db..136a08a 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -1228,11 +1228,15 @@ tdm_error tdm_client_output_set_mode(tdm_client_output *output, int index) { 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(index < 0, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(index >= 0, TDM_ERROR_INVALID_PARAMETER); private_output = (tdm_private_client_output*)output; + private_client = private_output->private_client; + + pthread_mutex_lock(&private_client->lock); if (private_output->available_modes.count - 1 < index) return TDM_ERROR_INVALID_PARAMETER; @@ -1243,6 +1247,8 @@ tdm_client_output_set_mode(tdm_client_output *output, int index) wl_tdm_output_set_mode(private_output->output, index); + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; } diff --git a/haltests/src/tc_tdm_client.cpp b/haltests/src/tc_tdm_client.cpp index 883ac5c..c2b2c20 100644 --- a/haltests/src/tc_tdm_client.cpp +++ b/haltests/src/tc_tdm_client.cpp @@ -841,6 +841,37 @@ TEST_P(TDMClient, ClientOutputGetAvailableModesNullOther) ASSERT_EQ(tdm_client_output_get_available_modes(output, NULL, NULL), TDM_ERROR_INVALID_PARAMETER); } +TEST_P(TDMClient, ClientOutputSetMode) +{ + tdm_client_output_mode *modes; + int count = 0; + + ASSERT_EQ(PrepareClient(), true); + ASSERT_EQ(PrepareOutput(), true); + + ASSERT_EQ(tdm_client_output_get_available_modes(output, &modes, &count), TDM_ERROR_NONE); + + printf("count:%d\n", count); + + ASSERT_EQ(tdm_client_output_set_mode(output, count - 1), TDM_ERROR_NONE); +} + +TEST_P(TDMClient, ClientOutputSetModeiNullObject) +{ + ASSERT_EQ(PrepareClient(), true); + ASSERT_EQ(PrepareOutput(), true); + + ASSERT_EQ(tdm_client_output_set_mode(NULL, 0), TDM_ERROR_INVALID_PARAMETER); +} + +TEST_P(TDMClient, ClientOutputSetModeInvalidIndex) +{ + ASSERT_EQ(PrepareClient(), true); + ASSERT_EQ(PrepareOutput(), true); + + ASSERT_EQ(tdm_client_output_set_mode(output, -1), TDM_ERROR_INVALID_PARAMETER); +} + /* tdm_client_output_create_vblank */ TEST_P(TDMClient, ClientOutputCreateVblank) { diff --git a/include/tdm.h b/include/tdm.h index 979c35e..6df3508 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -324,6 +324,16 @@ tdm_output_remove_change_handler(tdm_output *output, tdm_output_change_handler func, void *user_data); +tdm_error +tdm_output_add_mode_change_request_handler(tdm_output *output, + tdm_output_mode_change_request_handler func, + void *user_data); + +tdm_error +tdm_output_remove_mode_change_request_handler(tdm_output *output, + tdm_output_mode_change_request_handler func, + void *user_data); + /** * @brief Get the connection type of a output object. * @param[in] output A output object diff --git a/include/tdm_types.h b/include/tdm_types.h index 7c0f311..72edcb9 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -297,6 +297,12 @@ typedef void (*tdm_output_commit_handler)(tdm_output *output, unsigned int seque void *user_data); /** + * @brief The output mode change request handler + */ +typedef void (*tdm_output_mode_change_request_handler)(tdm_output *output, + unsigned int index, void *user_data); + +/** * @brief The layer commit handler */ typedef void (*tdm_layer_commit_handler)(tdm_layer *layer, unsigned int sequence, diff --git a/src/tdm.c b/src/tdm.c index 6999b9e..1761e9a 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -530,6 +530,7 @@ tdm_display_update_output(tdm_private_module *private_module, tdm_output *output LIST_INITHEAD(&private_output->pending_commit_handler_list); LIST_INITHEAD(&private_output->destroy_handler_list); LIST_INITHEAD(&private_output->change_handler_list); + LIST_INITHEAD(&private_output->mode_change_request_handler_list); if (func_output->output_set_status_handler) { func_output->output_set_status_handler(private_output->output_backend, diff --git a/src/tdm_output.c b/src/tdm_output.c index 902543e..7d73c1d 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -508,6 +508,85 @@ tdm_output_add_change_handler(tdm_output *output, return ret; } +EXTERN tdm_error +tdm_output_add_mode_change_request_handler(tdm_output *output, + tdm_output_mode_change_request_handler func, + void *user_data) +{ + tdm_private_display *private_display; + tdm_private_output *private_output; + tdm_private_output_mode_change_handler *mode_change_handler = NULL; + + TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); + + private_output = (tdm_private_output*)output; + private_display = private_output->private_display; + + _pthread_mutex_lock(&private_display->lock); + + LIST_FOR_EACH_ENTRY(mode_change_handler, &private_output->mode_change_request_handler_list, link) { + if (mode_change_handler->func == func && mode_change_handler->user_data == user_data) { + TDM_ERR("can't add twice"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_BAD_REQUEST; + } + } + + mode_change_handler = calloc(1, sizeof(tdm_private_output_change_handler)); + if (!mode_change_handler) { + /* LCOV_EXCL_START */ + TDM_ERR("failed: alloc memory"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OUT_OF_MEMORY; + /* LCOV_EXCL_STOP */ + } + + mode_change_handler->private_output = private_output; + mode_change_handler->func = func; + mode_change_handler->user_data = user_data; + + LIST_ADDTAIL(&mode_change_handler->link, &private_output->mode_change_request_handler_list); + + _pthread_mutex_unlock(&private_display->lock); + + return TDM_ERROR_NONE; +} + +EXTERN tdm_error +tdm_output_remove_mode_change_request_handler(tdm_output *output, + tdm_output_mode_change_request_handler func, + void *user_data) +{ + tdm_private_display *private_display; + tdm_private_output *private_output; + tdm_private_output_mode_change_handler *mode_change_handler = NULL, *hh = NULL; + + TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); + + private_output = (tdm_private_output*)output; + private_display = private_output->private_display; + + _pthread_mutex_lock(&private_display->lock); + + LIST_FOR_EACH_ENTRY_SAFE(mode_change_handler, hh, &private_output->mode_change_request_handler_list, link) { + if (mode_change_handler->func != func || mode_change_handler->user_data != user_data) + continue; + + LIST_DEL(&mode_change_handler->link); + free(mode_change_handler); + + _pthread_mutex_unlock(&private_display->lock); + + return TDM_ERROR_NONE; + } + + _pthread_mutex_unlock(&private_display->lock); + + return TDM_ERROR_INVALID_PARAMETER; +} + EXTERN void tdm_output_remove_change_handler(tdm_output *output, tdm_output_change_handler func, @@ -579,7 +658,7 @@ tdm_output_get_layer_count(tdm_output *output, int *count) *count = 0; LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) - (*count)++; + (*count)++; if (*count == 0) { _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; @@ -1214,6 +1293,23 @@ tdm_output_remove_commit_handler(tdm_output *output, tdm_output_commit_handler f return ret; } +INTERN void +tdm_output_call_mode_set_request(tdm_output *output, unsigned int index) +{ + tdm_private_output *private_output = (tdm_private_output*)output; + tdm_private_output_mode_change_handler *mode_change_handler = NULL; + + TDM_RETURN_IF_FAIL(private_output != NULL); + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + + if (LIST_IS_EMPTY(&private_output->mode_change_request_handler_list)) + return; + + LIST_FOR_EACH_ENTRY(mode_change_handler, &private_output->mode_change_request_handler_list, link) { + mode_change_handler->func(mode_change_handler->private_output, index, mode_change_handler->user_data); + } +} + tdm_error _tdm_output_commit_virtual(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data) { diff --git a/src/tdm_private.h b/src/tdm_private.h index a5c59e3..2acf467 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -138,6 +138,10 @@ void tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_handler func, void *user_data); void tdm_output_remove_commit_handler_internal(tdm_output *output, tdm_output_commit_handler func, void *user_data); + +void +tdm_output_call_mode_set_request(tdm_output *output, unsigned int index); + void tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data); diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 743367b..0ef71bd 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -112,6 +112,7 @@ typedef struct _tdm_private_output_destroy_handler tdm_private_output_destroy_ha typedef struct _tdm_private_output_change_handler tdm_private_output_change_handler; typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler; typedef struct _tdm_private_output_vblank_handler tdm_private_output_vblank_handler; +typedef struct _tdm_private_output_mode_change_handler tdm_private_output_mode_change_handler; typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler; typedef struct _tdm_private_hwc_commit_handler tdm_private_hwc_commit_handler; @@ -236,6 +237,7 @@ struct _tdm_private_output { /* virtual */ char name[TDM_NAME_LEN]; + struct list_head mode_change_request_handler_list; }; struct _tdm_private_layer { @@ -437,6 +439,14 @@ struct _tdm_private_output_commit_handler { pid_t owner_tid; }; +struct _tdm_private_output_mode_change_handler { + struct list_head link; + + tdm_private_output *private_output; + tdm_output_mode_change_request_handler func; + void *user_data; +}; + struct _tdm_private_hwc_commit_handler { struct list_head link; diff --git a/src/tdm_server.c b/src/tdm_server.c index a71eb0e..453e10e 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -607,7 +607,6 @@ _tdm_server_output_cb_get_available_modes(struct wl_client *client, struct wl_re 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; @@ -630,6 +629,8 @@ _tdm_server_output_cb_set_mode(struct wl_client *client, struct wl_resource *res { tdm_server_output_info *output_info = wl_resource_get_user_data(resource); tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; + const tdm_output_mode *modes; + int count = 0; tdm_error ret; TDM_RETURN_IF_FAIL(output_info != NULL); @@ -638,7 +639,10 @@ _tdm_server_output_cb_set_mode(struct wl_client *client, struct wl_resource *res TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); TDM_RETURN_IF_FAIL(status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED); - //To do + ret = tdm_output_get_available_modes(output_info->output, &modes, &count); + TDM_RETURN_IF_FAIL(index < count); + + tdm_output_call_mode_set_request(output_info->output, index); return; }