Merge branch 'tizen' into sandbox/cyeon/devel
[platform/core/uifw/libtdm.git] / client / tdm_client.c
index 972ae00..0e50916 100644 (file)
@@ -225,6 +225,17 @@ _tdm_client_vblank_cb_stamp(void *data, struct wl_tdm_vblank *wl_tdm_vblank, uin
 }
 
 /* LCOV_EXCL_START */
+static int
+_tdm_client_vblank_wait_list_validation_check(tdm_private_client_vblank *private_vblank)
+{
+       if (private_vblank->wait_list.next == NULL || private_vblank->wait_list.prev == NULL) {
+               TDM_ERR("vblank(%p) wait_list broken. prev(%p), next(%p) pid(%d)",
+                       private_vblank, private_vblank->wait_list.prev, private_vblank->wait_list.next, getpid());
+       }
+
+       return 0;
+}
+
 static void
 _tdm_client_vblank_cb_done(void *data, struct wl_tdm_vblank *wl_tdm_vblank,
                                                   uint32_t req_id, uint32_t sequence, uint32_t tv_sec,
@@ -243,6 +254,8 @@ _tdm_client_vblank_cb_done(void *data, struct wl_tdm_vblank *wl_tdm_vblank,
        TDM_DBG("vblank(%p) req_id(%u) sequence(%u) time(%.6f)",
                        private_vblank, req_id, sequence, TDM_TIME(tv_sec, tv_usec));
 
+       _tdm_client_vblank_wait_list_validation_check(private_vblank);
+
        LIST_FOR_EACH_ENTRY(w, &private_vblank->wait_list, link) {
                if (w->req_id != req_id)
                        continue;
@@ -1061,6 +1074,51 @@ tdm_client_output_get_refresh_rate(tdm_client_output *output, unsigned int *refr
 }
 
 tdm_error
+tdm_client_output_get_mode(tdm_client_output *output, unsigned int *width, unsigned int *height)
+{
+       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(width != NULL, TDM_ERROR_INVALID_PARAMETER);
+       TDM_RETURN_VAL_IF_FAIL(height != NULL, 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->watch_output_changes) {
+               *width = private_output->width;
+               *height = private_output->height;
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_NONE;
+       }
+
+       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_mode(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;
+       }
+
+       *width = private_output->width;
+       *height = private_output->height;
+
+       pthread_mutex_unlock(&private_client->lock);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
 tdm_client_output_get_conn_status(tdm_client_output *output, tdm_output_conn_status *status)
 {
        tdm_private_client_output *private_output;
@@ -1957,7 +2015,7 @@ tdm_client_voutput *
 tdm_client_create_voutput(tdm_client *client, const char *name, tdm_error *error)
 {
        tdm_private_client *private_client;
-       tdm_private_client_output *private_output;
+       tdm_private_client_output *private_output = NULL;
        tdm_private_client_voutput *private_voutput;
        struct wl_proxy *wrapper;
 
@@ -2024,6 +2082,7 @@ tdm_client_create_voutput(tdm_client *client, const char *name, tdm_error *error
        private_voutput->bufmgr = tbm_bufmgr_init(-1);
        if (private_voutput->bufmgr == NULL) {
                /* LCOV_EXCL_START */
+               wl_proxy_wrapper_destroy(wrapper);
                TDM_ERR("fail tbm_bufmgr_init");
                free(private_voutput);
                if (error)
@@ -2037,7 +2096,8 @@ tdm_client_create_voutput(tdm_client *client, const char *name, tdm_error *error
        LIST_INITHEAD(&private_voutput->buffer_list);
 
        private_voutput->private_client = private_client;
-       strncpy(private_voutput->name, name, TDM_NAME_LEN);
+       strncpy(private_voutput->name, name, TDM_NAME_LEN - 1);
+       private_voutput->name[TDM_NAME_LEN - 1] = '\0';
 
        private_voutput->wl_voutput = wl_tdm_create_voutput((struct wl_tdm *)wrapper, name);
        wl_proxy_wrapper_destroy(wrapper);
@@ -2102,8 +2162,6 @@ tdm_client_voutput_destroy(tdm_client_voutput *voutput)
                LIST_FOR_EACH_ENTRY_SAFE(cb, cbb, &private_voutput->buffer_list, link) {
                        tbm_surface_h tbm_surface = NULL;
 
-                       if (!cb) continue;
-
                        LIST_DEL(&cb->link);
 
                        tbm_surface = (tbm_surface_h)wl_buffer_get_user_data(cb->wl_buffer);
@@ -2174,6 +2232,11 @@ tdm_client_voutput_set_available_modes(tdm_client_voutput *voutput, const tdm_cl
 
        if (count != 0) {
                private_voutput->available_modes.modes = calloc(count, sizeof(tdm_client_output_mode));
+               if (private_voutput->available_modes.modes == NULL) {
+                       private_voutput->available_modes.count = 0;
+                       pthread_mutex_unlock(&private_client->lock);
+                       return TDM_ERROR_OUT_OF_MEMORY;
+               }
                memcpy(private_voutput->available_modes.modes, modes, sizeof(tdm_client_output_mode) * count);
        }
 
@@ -2285,6 +2348,8 @@ tdm_client_voutput_remove_commit_handler(tdm_client_voutput *voutput,
                free(h);
 
                pthread_mutex_unlock(&private_client->lock);
+
+               return;
        }
 
        pthread_mutex_unlock(&private_client->lock);