common: fix syntax error
[platform/core/uifw/libtdm.git] / client / tdm_client.c
index 41a5fe2..4023208 100644 (file)
@@ -9,7 +9,7 @@
  *          Taeheon Kim <th908.kim@samsung.com>,
  *          YoungJun Cho <yj44.cho@samsung.com>,
  *          SooChan Lim <sc1.lim@samsung.com>,
- *          Boram Park <sc1.lim@samsung.com>
+ *          Boram Park <boram1288.park@samsung.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -42,6 +42,7 @@
 #include <stdlib.h>
 #include <time.h>
 #include <strings.h>
+#include <poll.h>
 
 #include <tdm-client-protocol.h>
 
@@ -570,6 +571,116 @@ tdm_client_handle_events(tdm_client *client)
        /* LCOV_EXCL_STOP */
 }
 
+static int
+_tdm_client_poll(struct wl_display *display, short int events, int timeout)
+{
+       int ret;
+       struct pollfd pfd[1];
+
+       pfd[0].fd = wl_display_get_fd(display);
+       pfd[0].events = events;
+       do {
+               ret = poll(pfd, 1, timeout);
+       } while (ret == -1 && errno == EINTR);
+
+       return ret;
+}
+
+static tdm_error
+_tdm_client_dispatch_timeout(tdm_private_client *private_client, int timeout)
+{
+       int ret;
+       struct wl_display *display = private_client->display;
+
+       if (wl_display_prepare_read(display) == -1) {
+               if (wl_display_dispatch_pending(display) > 0)
+                       return TDM_ERROR_NONE;
+               else
+                       return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       while (true) {
+               ret = wl_display_flush(display);
+
+               if (ret != -1 || errno != EAGAIN)
+                       break;
+
+               if (_tdm_client_poll(display, POLLOUT, -1) == -1) {
+                       wl_display_cancel_read(display);
+                       TDM_ERR("_tdm_client_poll failed");
+                       return TDM_ERROR_OPERATION_FAILED;
+               }
+       }
+
+       /* Don't stop if flushing hits an EPIPE; continue so we can read any
+        * protocol error that may have triggered it. */
+       if (ret < 0 && errno != EPIPE) {
+               TDM_ERR("ret(%d) errno(%d)", ret, errno);
+               wl_display_cancel_read(display);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       ret = _tdm_client_poll(display, POLLIN, timeout);
+       if (ret <= 0) {
+               wl_display_cancel_read(display);
+               if (ret == 0) {
+                       TDM_ERR("_tdm_client_poll timeout.");
+                       return TDM_ERROR_TIMEOUT;
+               } else {
+                       TDM_ERR("_tdm_client_poll failed. (ret:%d)", ret);
+                       return TDM_ERROR_OPERATION_FAILED;
+               }
+       }
+
+       if (wl_display_read_events(display) == -1) {
+               TDM_ERR("wl_display_read_events failed");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       ret = wl_display_dispatch_pending(display);
+
+       if (ret < 0) {
+               TDM_ERR("_tdm_client_dispatch_timeout failed");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+tdm_client_handle_events_timeout(tdm_client *client, int ms_timeout)
+{
+       tdm_private_client *private_client;
+       tdm_error ret;
+       TDM_RETURN_VAL_IF_FAIL(client != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       private_client = (tdm_private_client*)client;
+
+       pthread_mutex_lock(&private_client->lock);
+
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
+       if (private_client->enable_ttrace)
+               TDM_TRACE_ASYNC_BEGIN((int)private_client->stamp, "TDM_Client_Events_Timeout:%u", (unsigned int)private_client->stamp);
+
+       ret = _tdm_client_dispatch_timeout(private_client, ms_timeout);
+
+       if (private_client->enable_ttrace)
+               TDM_TRACE_ASYNC_END((int)private_client->stamp, "TDM_Client_Events_Timeout:%u", (unsigned int)private_client->stamp);
+
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
+       pthread_mutex_unlock(&private_client->lock);
+
+       return ret;
+}
+
 typedef struct _tdm_client_vblank_temp {
        tdm_client_vblank_handler2 func;
        void *user_data;
@@ -659,8 +770,14 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error)
                return NULL;
        }
 
-       if (!name)
+       if (!name) {
                name = "primary";
+       } else if (strncmp(name, "primary", 7) && strncmp(name, "default", 7)) {
+               if (error)
+                       *error = TDM_ERROR_INVALID_PARAMETER;
+               pthread_mutex_unlock(&private_client->lock);
+               return NULL;
+       }
 
        LIST_FOR_EACH_ENTRY(private_output, &private_client->output_list, link) {
                if (!strncmp(private_output->name, name, TDM_NAME_LEN)) {
@@ -743,7 +860,7 @@ tdm_client_output_add_change_handler(tdm_client_output *output,
 {
        tdm_private_client_output *private_output;
        tdm_private_client *private_client;
-       tdm_client_output_handler_info *h;
+       tdm_client_output_handler_info *h = NULL;
 
        TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
        TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
@@ -751,6 +868,13 @@ tdm_client_output_add_change_handler(tdm_client_output *output,
        private_output = (tdm_private_client_output*)output;
        private_client = private_output->private_client;
 
+       LIST_FOR_EACH_ENTRY(h, &private_output->change_handler_list, link) {
+               if (h->func == func && h->user_data == user_data) {
+                       TDM_ERR("can't add twice");
+                       return TDM_ERROR_BAD_REQUEST;
+               }
+       }
+
        h = calloc(1, sizeof *h);
        TDM_RETURN_VAL_IF_FAIL(h != NULL, TDM_ERROR_OUT_OF_MEMORY);
 
@@ -764,6 +888,7 @@ tdm_client_output_add_change_handler(tdm_client_output *output,
 
        if (LIST_IS_EMPTY(&private_output->change_handler_list)) {
                wl_tdm_output_watch_output_changes(private_output->output, 1);
+               wl_display_roundtrip_queue(private_client->display, private_client->queue);
 
                /* TODO: this is very tricky.
                 * If a client adds the change_handler, we might be able to guess that
@@ -810,8 +935,11 @@ tdm_client_output_remove_change_handler(tdm_client_output *output,
                free(h);
 
                if (LIST_IS_EMPTY(&private_output->change_handler_list)) {
-                       if (!CHECK_WL_PROTOCOL_ERROR(private_client))
+                       private_output->watch_output_changes = 0;
+                       if (!CHECK_WL_PROTOCOL_ERROR(private_client)) {
                                wl_tdm_output_watch_output_changes(private_output->output, 0);
+                               wl_display_roundtrip_queue(private_client->display, private_client->queue);
+                       }
                }
 
                pthread_mutex_unlock(&private_client->lock);
@@ -1257,7 +1385,7 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli
        if (!private_vblank->started)
                private_vblank->started = 1;
 
-       if (private_output->watch_output_changes && !private_vblank->enable_fake) {
+       if (!private_vblank->enable_fake) {
                if (private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
                        TDM_ERR("output disconnected");
                        pthread_mutex_unlock(&private_client->lock);
@@ -1369,7 +1497,7 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence,
        if (!private_vblank->started)
                private_vblank->started = 1;
 
-       if (private_output->watch_output_changes && !private_vblank->enable_fake) {
+       if (!private_vblank->enable_fake) {
                if (private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
                        TDM_ERR("output disconnected");
                        pthread_mutex_unlock(&private_client->lock);
@@ -1451,3 +1579,15 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence,
 
        /* LCOV_EXCL_STOP */
 }
+
+unsigned int
+tdm_client_vblank_is_waiting(tdm_client_vblank *vblank)
+{
+       tdm_private_client_vblank *private_vblank;
+
+       TDM_RETURN_VAL_IF_FAIL(vblank != NULL, 0);
+
+       private_vblank = vblank;
+
+       return (LIST_LENGTH(&private_vblank->wait_list) > 0) ? 1 : 0;
+}