From: Boram Park Date: Fri, 8 Sep 2017 02:07:43 +0000 (+0900) Subject: add get_dpms, get_connection, get_mode request X-Git-Tag: accepted/tizen/4.0/unified/20170911.154640~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d2014e64bf637ccf6399aed6abc1f91ed30d820b;p=platform%2Fcore%2Fuifw%2Flibtdm.git add get_dpms, get_connection, get_mode request If a client adds the change_handler, we might be able to guess that the client will watch the tdm client's fd and handle tdm events in event loop. Otherwise, we CAN'T make sure if a client has event loop which handles tdm events. Change-Id: I49685d7eb3b88cda59b167f5ae66a7e9501a2315 --- diff --git a/client/tdm_client.c b/client/tdm_client.c index 858e4f5..04c9d2f 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -76,6 +76,7 @@ typedef struct _tdm_private_client_output { struct list_head change_handler_list; unsigned int req_id; + unsigned int watch_output_changes; struct list_head link; } tdm_private_client_output; @@ -508,9 +509,18 @@ tdm_client_output_add_change_handler(tdm_client_output *output, h = calloc(1, sizeof *h); TDM_RETURN_VAL_IF_FAIL(h != NULL, TDM_ERROR_OUT_OF_MEMORY); - if (LIST_IS_EMPTY(&private_output->change_handler_list)) + if (LIST_IS_EMPTY(&private_output->change_handler_list)) { wl_tdm_output_watch_output_changes(private_output->output, 1); + /* TODO: this is very tricky. + * If a client adds the change_handler, we might be able to guess that + * the client will watch the tdm client's fd and handle tdm events in + * event loop. Otherwise, we CAN'T make sure if a client has event loop + * which handles tdm events. + */ + private_output->watch_output_changes = 1; + } + h->private_output = private_output; h->func = func; h->user_data = user_data; @@ -550,12 +560,24 @@ tdm_error tdm_client_output_get_refresh_rate(tdm_client_output *output, unsigned int *refresh) { 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(refresh != NULL, TDM_ERROR_INVALID_PARAMETER); private_output = (tdm_private_client_output*)output; + if (private_output->watch_output_changes) { + *refresh = private_output->refresh; + return TDM_ERROR_NONE; + } + + private_client = private_output->private_client; + TDM_RETURN_VAL_IF_FAIL(private_client != NULL, TDM_ERROR_INVALID_PARAMETER); + + wl_tdm_output_get_mode(private_output->output); + wl_display_roundtrip(private_client->display); + *refresh = private_output->refresh; return TDM_ERROR_NONE; @@ -565,12 +587,24 @@ tdm_error tdm_client_output_get_conn_status(tdm_client_output *output, tdm_output_conn_status *status) { 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(status != NULL, TDM_ERROR_INVALID_PARAMETER); private_output = (tdm_private_client_output*)output; + if (private_output->watch_output_changes) { + *status = private_output->connection; + return TDM_ERROR_NONE; + } + + private_client = private_output->private_client; + TDM_RETURN_VAL_IF_FAIL(private_client != NULL, TDM_ERROR_INVALID_PARAMETER); + + wl_tdm_output_get_connection(private_output->output); + wl_display_roundtrip(private_client->display); + *status = private_output->connection; return TDM_ERROR_NONE; @@ -580,12 +614,24 @@ tdm_error tdm_client_output_get_dpms(tdm_client_output *output, tdm_output_dpms *dpms) { 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(dpms != NULL, TDM_ERROR_INVALID_PARAMETER); private_output = (tdm_private_client_output*)output; + if (private_output->watch_output_changes) { + *dpms = private_output->dpms; + return TDM_ERROR_NONE; + } + + private_client = private_output->private_client; + TDM_RETURN_VAL_IF_FAIL(private_client != NULL, TDM_ERROR_INVALID_PARAMETER); + + wl_tdm_output_get_dpms(private_output->output); + wl_display_roundtrip(private_client->display); + *dpms = private_output->dpms; return TDM_ERROR_NONE; @@ -778,10 +824,11 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli if (!private_vblank->started) private_vblank->started = 1; - if (private_output->dpms != TDM_OUTPUT_DPMS_ON && !private_vblank->enable_fake) { - TDM_INFO("dpms off"); - return TDM_ERROR_DPMS_OFF; - } + if (private_output->watch_output_changes) + if (private_output->dpms != TDM_OUTPUT_DPMS_ON && !private_vblank->enable_fake) { + TDM_INFO("dpms off"); + return TDM_ERROR_DPMS_OFF; + } w = calloc(1, sizeof *w); if (!w) { @@ -854,10 +901,11 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, if (!private_vblank->started) private_vblank->started = 1; - if (private_output->dpms != TDM_OUTPUT_DPMS_ON && !private_vblank->enable_fake) { - TDM_INFO("dpms off"); - return TDM_ERROR_DPMS_OFF; - } + if (private_output->watch_output_changes) + if (private_output->dpms != TDM_OUTPUT_DPMS_ON && !private_vblank->enable_fake) { + TDM_INFO("dpms off"); + return TDM_ERROR_DPMS_OFF; + } w = calloc(1, sizeof *w); if (!w) { diff --git a/protocol/tdm.xml b/protocol/tdm.xml index 47e6536..dcd99ed 100644 --- a/protocol/tdm.xml +++ b/protocol/tdm.xml @@ -61,6 +61,12 @@ + + + + + + diff --git a/src/tdm_server.c b/src/tdm_server.c index b69926b..c49e9db 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -451,10 +451,94 @@ _tdm_server_output_cb_watch_output_changes(struct wl_client *client, struct wl_r output_info->watch_output_changes = enable; } +static void +_tdm_server_output_cb_get_connection(struct wl_client *client, struct wl_resource *resource) +{ + 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_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + + wl_tdm_output_send_connection(output_info->resource, status); + + return; + +failed: + wl_tdm_output_send_connection(output_info->resource, TDM_OUTPUT_CONN_STATUS_DISCONNECTED); +} + +static void +_tdm_server_output_cb_get_mode(struct wl_client *client, struct wl_resource *resource) +{ + 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_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + + if (status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { + const tdm_output_mode *mode = NULL; + unsigned int hdisplay, vdisplay, vrefresh; + + ret = tdm_output_get_mode(output_info->output, &mode); + TDM_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + + hdisplay = (mode) ? mode->hdisplay : 0; + vdisplay = (mode) ? mode->vdisplay : 0; + vrefresh = (mode) ? mode->vrefresh : 0; + + wl_tdm_output_send_mode(output_info->resource, hdisplay, vdisplay, vrefresh); + } else { + wl_tdm_output_send_mode(output_info->resource, 0, 0, 0); + } + + return; +failed: + wl_tdm_output_send_mode(output_info->resource, 0, 0, 0); +} + +static void +_tdm_server_output_cb_get_dpms(struct wl_client *client, struct wl_resource *resource) +{ + 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_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + + if (status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { + tdm_output_dpms dpms_value = TDM_OUTPUT_DPMS_OFF; + + ret = tdm_output_get_dpms(output_info->output, &dpms_value); + TDM_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + + wl_tdm_output_send_dpms(output_info->resource, dpms_value); + } else { + wl_tdm_output_send_dpms(output_info->resource, TDM_OUTPUT_DPMS_OFF); + } + + return; +failed: + wl_tdm_output_send_dpms(output_info->resource, TDM_OUTPUT_DPMS_OFF); +} + static const struct wl_tdm_output_interface tdm_output_implementation = { _tdm_server_output_cb_destroy, _tdm_server_output_cb_create_vblank, _tdm_server_output_cb_watch_output_changes, + _tdm_server_output_cb_get_connection, + _tdm_server_output_cb_get_mode, + _tdm_server_output_cb_get_dpms, }; static void @@ -484,9 +568,7 @@ _tdm_server_cb_create_output(struct wl_client *client, struct wl_resource *resou tdm_server_output_info *output_info; struct wl_resource *output_resource = NULL; tdm_output *output; - const tdm_output_mode *mode = NULL; - tdm_output_dpms dpms_value; - tdm_output_conn_status status; + tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; output = _tdm_server_find_output(private_server, name); if (!output) { @@ -496,17 +578,6 @@ _tdm_server_cb_create_output(struct wl_client *client, struct wl_resource *resou return; } - tdm_output_get_mode(output, &mode); - if (!mode) { - TDM_ERR("no mode for '%s' output", name); - wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "no mode for '%s' output", name); - return; - } - - tdm_output_get_dpms(output, &dpms_value); - tdm_output_get_conn_status(output, &status); - output_resource = wl_resource_create(client, &wl_tdm_output_interface, wl_resource_get_version(resource), id); @@ -535,9 +606,26 @@ _tdm_server_cb_create_output(struct wl_client *client, struct wl_resource *resou wl_resource_set_implementation(output_resource, &tdm_output_implementation, output_info, destroy_output_callback); - wl_tdm_output_send_mode(output_resource, mode->hdisplay, mode->vdisplay, mode->vrefresh); - wl_tdm_output_send_dpms(output_resource, dpms_value); + tdm_output_get_conn_status(output, &status); wl_tdm_output_send_connection(output_resource, status); + + if (status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { + tdm_output_dpms dpms_value = TDM_OUTPUT_DPMS_OFF; + const tdm_output_mode *mode = NULL; + unsigned int hdisplay, vdisplay, vrefresh; + + tdm_output_get_mode(output, &mode); + hdisplay = (mode) ? mode->hdisplay : 0; + vdisplay = (mode) ? mode->vdisplay : 0; + vrefresh = (mode) ? mode->vrefresh : 0; + wl_tdm_output_send_mode(output_resource, hdisplay, vdisplay, vrefresh); + + tdm_output_get_dpms(output, &dpms_value); + wl_tdm_output_send_dpms(output_resource, dpms_value); + } else { + wl_tdm_output_send_mode(output_resource, 0, 0, 0); + wl_tdm_output_send_dpms(output_resource, TDM_OUTPUT_DPMS_OFF); + } } static void