package version up to 1.6.17
[platform/core/uifw/libtdm.git] / client / tdm_client.c
index f03ae63..4d8ba30 100644 (file)
@@ -47,6 +47,8 @@
 #include "tdm_log.h"
 #include "tdm_macro.h"
 #include "tdm_list.h"
+#include "tdm.h"
+#include "tdm_private.h"
 #include "tdm-client-protocol.h"
 
 typedef struct _tdm_private_client_vblank tdm_private_client_vblank;
@@ -84,6 +86,7 @@ struct _tdm_private_client_vblank {
        struct wl_tdm_vblank *vblank;
        struct list_head wait_list;
 
+       char name[TDM_NAME_LEN];
        unsigned int sync;
        unsigned int fps;
        int offset;
@@ -127,6 +130,8 @@ _tdm_client_vblank_cb_done(void *data, struct wl_tdm_vblank *wl_tdm_vblank,
 
        TDM_RETURN_IF_FAIL(private_vblank != NULL);
 
+       TDM_TRACE_COUNT(ClientDoneVBlank, req_id);
+
        LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->wait_list, link) {
                if (w->req_id != req_id)
                        continue;
@@ -253,7 +258,7 @@ _tdm_client_cb_global(void *data, struct wl_registry *registry,
 {
        tdm_private_client *private_client = data;
 
-       if (strcmp(interface, "wl_tdm") == 0) {
+       if (strncmp(interface, "wl_tdm", 6) == 0) {
                private_client->tdm =
                        wl_registry_bind(registry, name, &wl_tdm_interface, version);
                TDM_RETURN_IF_FAIL(private_client->tdm != NULL);
@@ -494,6 +499,9 @@ 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))
+               wl_tdm_output_watch_output_changes(private_output->output, 1);
+
        h->private_output = private_output;
        h->func = func;
        h->user_data = user_data;
@@ -521,6 +529,10 @@ tdm_client_output_remove_change_handler(tdm_client_output *output,
 
                LIST_DEL(&h->link);
                free(h);
+
+               if (LIST_IS_EMPTY(&private_output->change_handler_list))
+                       wl_tdm_output_watch_output_changes(private_output->output, 0);
+
                return;
        }
 }
@@ -643,6 +655,26 @@ tdm_client_vblank_destroy(tdm_client_vblank *vblank)
 }
 
 tdm_error
+tdm_client_vblank_set_name(tdm_client_vblank *vblank, const char *name)
+{
+       tdm_private_client_vblank *private_vblank;
+
+       TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       private_vblank = vblank;
+
+       if (!name)
+               name = TDM_VBLANK_DEFAULT_NAME;
+
+       strncpy(private_vblank->name, name, TDM_NAME_LEN - 1);
+       private_vblank->name[TDM_NAME_LEN - 1] = '\0';
+
+       wl_tdm_vblank_set_name(private_vblank->vblank, private_vblank->name);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
 tdm_client_vblank_set_sync(tdm_client_vblank *vblank, unsigned int sync)
 {
        tdm_private_client_vblank *private_vblank;
@@ -664,7 +696,6 @@ tdm_client_vblank_set_fps(tdm_client_vblank *vblank, unsigned int fps)
        TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER);
 
        private_vblank = vblank;
-       TDM_RETURN_VAL_IF_FAIL(private_vblank->started == 0, TDM_ERROR_BAD_REQUEST);
 
        if (private_vblank->fps == fps)
                return TDM_ERROR_NONE;
@@ -762,6 +793,75 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli
 
        wl_tdm_vblank_wait_vblank(private_vblank->vblank, interval, w->req_id, w->req_sec, w->req_usec);
 
+       TDM_TRACE_COUNT(ClientWaitVBlank, w->req_id);
+
+       if (!private_vblank->sync) {
+               wl_display_flush(private_client->display);
+               return TDM_ERROR_NONE;
+       }
+
+       while (ret != -1 && !w->need_free)
+               ret = wl_display_dispatch(private_client->display);
+
+       clock_gettime(CLOCK_MONOTONIC, &tp);
+       TDM_DBG("block during %d us",
+                       ((unsigned int)(tp.tv_sec * 1000000) + (unsigned int)(tp.tv_nsec / 1000))
+                       - (w->req_sec * 1000000 + w->req_usec));
+
+       LIST_DEL(&w->link);
+       free(w);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence,
+                                                  tdm_client_vblank_handler func, void *user_data)
+{
+       tdm_private_client *private_client;
+       tdm_private_client_output *private_output;
+       tdm_private_client_vblank *private_vblank;
+       tdm_client_wait_info *w;
+       struct timespec tp;
+       int ret = 0;
+
+       TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER);
+       TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       private_vblank = vblank;
+       private_output = private_vblank->private_output;
+       private_client = private_output->private_client;
+
+       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;
+       }
+
+       w = calloc(1, sizeof *w);
+       if (!w) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       w->private_vblank = private_vblank;
+       w->func = func;
+       w->user_data = user_data;
+
+       LIST_ADDTAIL(&w->link, &private_vblank->wait_list);
+
+       clock_gettime(CLOCK_MONOTONIC, &tp);
+       w->req_id = ++private_output->req_id;
+       w->req_sec = (unsigned int)tp.tv_sec;
+       w->req_usec = (unsigned int)(tp.tv_nsec / 1000);
+       w->need_free = (private_vblank->sync) ? 0 : 1;
+
+       wl_tdm_vblank_wait_vblank_seq(private_vblank->vblank, sequence, w->req_id, w->req_sec, w->req_usec);
+
+       TDM_TRACE_COUNT(ClientWaitVBlank, w->req_id);
+
        if (!private_vblank->sync) {
                wl_display_flush(private_client->display);
                return TDM_ERROR_NONE;