Apply async for dpms 24/209324/14 accepted/tizen/unified/20190709.113101 submit/tizen/20190709.075431
authorlokilee73 <changjoo.lee@samsung.com>
Fri, 5 Jul 2019 01:46:34 +0000 (10:46 +0900)
committerlokilee73 <changjoo.lee@samsung.com>
Tue, 9 Jul 2019 02:11:59 +0000 (11:11 +0900)
change communication method with dpms, from sync to async.

Change-Id: I50894dc5b2b3420d0fb9335e298601a400eb120a
Signed-off-by: lokilee73 <changjoo.lee@samsung.com>
plugins/iot/display/device-interface.c
plugins/mobile/display/device-interface.c
plugins/tv/display/device-interface.c
plugins/wearable/display/device-interface.c
src/display/display-dpms.c

index e92582e..01b98ac 100644 (file)
@@ -74,11 +74,6 @@ static struct display_device *display_dev;
 
 static int bl_onoff(int on)
 {
-       if (!dpms_is_available()) {
-               _E("Dpms is not available.");
-               return -EINVAL;
-       }
-
        dpms_set_state(on);
        return 0;
 }
index e92582e..01b98ac 100644 (file)
@@ -74,11 +74,6 @@ static struct display_device *display_dev;
 
 static int bl_onoff(int on)
 {
-       if (!dpms_is_available()) {
-               _E("Dpms is not available.");
-               return -EINVAL;
-       }
-
        dpms_set_state(on);
        return 0;
 }
index e92582e..01b98ac 100644 (file)
@@ -74,11 +74,6 @@ static struct display_device *display_dev;
 
 static int bl_onoff(int on)
 {
-       if (!dpms_is_available()) {
-               _E("Dpms is not available.");
-               return -EINVAL;
-       }
-
        dpms_set_state(on);
        return 0;
 }
index 44d5f90..f44c51a 100644 (file)
@@ -74,11 +74,6 @@ static struct display_device *display_dev;
 
 static int bl_onoff(int on)
 {
-       if (!dpms_is_available()) {
-               _E("Dpms is not available.");
-               return -EINVAL;
-       }
-
        dpms_set_state(on);
        return 0;
 }
index 5a0220e..b1a6221 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
-#include "core/log.h"
-#include "display/util.h"
+#include <glib.h>
 #include <wayland-client.h>
 #include <tizen-extension-client-protocol.h>
 #include <tizen-dpms-client-protocol.h>
+#include "core/log.h"
+#include "display/util.h"
+
+typedef struct {
+       GSource gsource;
+       GPollFD gfd;
+       gboolean prepared;
+
+       struct wl_display *wl_disp;
+       struct wl_registry *wl_registry;
+       struct wl_output *wl_output;
+       struct tizen_dpms_manager *tz_dpms_mng;
+
+       uint32_t dpms_mode;
+} wl_glib_info;
+
+wl_glib_info *info = NULL;
 
-struct wl_display *display;
-static struct wl_event_queue *queue;
-struct wl_output *wl_out;
-struct tizen_dpms_manager *tz_dpms_mng   = NULL;
-int lcd_state = -1;
 bool wm_is_ready;
 static bool dpms_connected;
-static int dpms_retry;
+static GSource *wl_glib_data = NULL;
 
-bool check_wm_ready(void)
+static void dpms_handle_state(void *data, struct tizen_dpms_manager *tz_dpms, uint32_t mode, uint32_t error)
 {
-       if (access("/run/.wm_ready", F_OK) == 0) {
-               _I("Window manager is ready.");
-               wm_is_ready = true;
-               return true;
-       }
-
-       _I("Window manager is not ready.");
-       return false;
+       _D("Dpms_state_cb - mode:%u, error:%u", mode, error);
+       info->dpms_mode = mode;
 }
 
 void disconnect_interface_with_dpms(void)
 {
-       if (tz_dpms_mng) {
-               tizen_dpms_manager_destroy(tz_dpms_mng);
-               tz_dpms_mng = NULL;
+       if (!info) {
+               _E("Info is NULL.");
+               return;
        }
 
-       if (wl_out) {
-               wl_output_destroy(wl_out);
-               wl_out = NULL;
+       if (info->tz_dpms_mng) {
+               tizen_dpms_manager_destroy(info->tz_dpms_mng);
+               info->tz_dpms_mng = NULL;
        }
 
-       if (display) {
-               wl_display_disconnect(display);
-               display = NULL;
+       if (info->wl_output) {
+               wl_output_destroy(info->wl_output);
+               info->wl_output = NULL;
        }
 
-       dpms_connected = false;
-}
+       if (info->wl_registry) {
+               wl_registry_destroy(info->wl_registry);
+               info->wl_registry= NULL;
+       }
 
-static void dpms_handle_state(void *data, struct tizen_dpms_manager *tz_dpms, uint32_t mode, uint32_t error)
-{
-       _D("dpms_state_cb - mode:%d, error:%d", mode, error);
-       lcd_state = mode;
-       dpms_retry = 0;
+       if (info->wl_disp) {
+               wl_display_disconnect(info->wl_disp);
+               info->wl_disp= NULL;
+       }
+
+       if (wl_glib_data) {
+               g_source_destroy(wl_glib_data);
+               wl_glib_data = NULL;
+       }
+
+       dpms_connected = false;
 }
 
 static const struct tizen_dpms_manager_listener dpms_listener = {
@@ -81,20 +94,26 @@ static const struct tizen_dpms_manager_listener dpms_listener = {
 static void handle_global(void *data, struct wl_registry *registry,
                                uint32_t name, const char *interface, uint32_t version)
 {
+       if (!data) {
+               _E("Data is NULL.");
+               return;
+       }
+       info = (wl_glib_info *)data;
+
        if (strcmp(interface, "wl_output") == 0) {
-               wl_out = wl_registry_bind(registry, name, &wl_output_interface, 2);
-               if (!wl_out) {
-                       _E("Handle wl_output bind failed.");
+               info->wl_output= wl_registry_bind(registry, name, &wl_output_interface, 2);
+               if (!info->wl_output) {
+                       _E("Failed to bind registry.");
                        disconnect_interface_with_dpms();
                }
                _D("Get wl_output.");
        } else if (strcmp(interface, "tizen_dpms_manager") == 0) {
-               tz_dpms_mng = wl_registry_bind(registry, name, &tizen_dpms_manager_interface, 1);
-               if (!tz_dpms_mng) {
-                       _E("Handle tizen_dpms_manager bind failed.");
+               info->tz_dpms_mng = wl_registry_bind(registry, name, &tizen_dpms_manager_interface, 1);
+               if (!info->tz_dpms_mng) {
+                       _E("Failed to bind registry.");
                        disconnect_interface_with_dpms();
-               }
-               tizen_dpms_manager_add_listener(tz_dpms_mng, &dpms_listener, NULL);
+               } else
+                       tizen_dpms_manager_add_listener(info->tz_dpms_mng, &dpms_listener, info);
 
                _D("Get dpms manager.");
        }
@@ -110,52 +129,240 @@ static const struct wl_registry_listener registry_listener = {
        handle_global_remove
 };
 
-bool connect_interface_with_dpms(void)
+static int
+wl_glib_wayland_init(wl_glib_info *info)
 {
-       struct wl_registry *registry = NULL;
+       int ret;
 
-       display = wl_display_connect(NULL);
-       if (display == NULL) {
-               _E("Display is NULL.");
-               goto error;
+       info->wl_disp = wl_display_connect(NULL);
+       if (info->wl_disp == NULL) {
+               _E("Failed to connect display.");
+               goto err;
        }
 
-       registry = wl_display_get_registry(display);
-       if (registry == NULL) {
-               _E("Registry is NULL.");
-               goto error;
+       info->wl_registry = wl_display_get_registry(info->wl_disp);
+       if (info->wl_registry == NULL) {
+               _E("Failed to get display registry.");
+               goto err;
        }
 
-       queue = wl_display_create_queue(display);
-       if (queue == NULL) {
-               printf(" failed wl_display_create_queue\n");
-               goto error;
+       ret = wl_registry_add_listener(info->wl_registry, &registry_listener, info);
+       if (ret) {
+               _E("Failed to add registry listener.");
+               goto err;
        }
 
-       wl_proxy_set_queue((struct wl_proxy *)display, queue);
-       wl_proxy_set_queue((struct wl_proxy *)registry, queue);
+       ret = wl_display_roundtrip(info->wl_disp);
+       if (ret < 0 || info->wl_output == NULL) {
+               _E("Failed to roundtrip display.");
+               goto err;
+       }
 
-       wl_registry_add_listener(registry, &registry_listener, NULL);
+       return 0;
 
-       wl_display_dispatch_queue(display, queue);
-       wl_display_roundtrip_queue(display, queue);
+err:
+       return -1;
+}
 
-       if (!wl_out || !tz_dpms_mng) {
-               _E("Roundtrip failed.");
-               goto error;
+static gboolean
+wl_glib_client_prepare(GSource *source, gint *time)
+{
+       if (!source) {
+               _E("Source is NULL.");
+               return FALSE;
        }
+       info = (wl_glib_info *)source;
 
-       wl_registry_destroy(registry);
-       _D("Setup with dpms is done.");
-       return true;
+       /* If info is already prepared, do nothing in this function. */
+       if (info->prepared == TRUE)
+               return FALSE;
+
+       while (wl_display_prepare_read(info->wl_disp) != 0) {
+               if (wl_display_dispatch_pending(info->wl_disp) == -1)
+                       _E("Failed to dispatch display pending.");
+       }
+
+       info->prepared = TRUE;
+
+       wl_display_flush(info->wl_disp);
+       *time = -1;
+
+       return FALSE;
+}
+
+static gboolean
+wl_glib_client_check(GSource *source)
+{
+       gboolean ret = FALSE;
+       int wl_ret = 0;
+
+       if (!source) {
+               _E("Source is NULL.");
+               return FALSE;
+       }
+       info = (wl_glib_info *)source;
+       if (g_source_is_destroyed(source)) {
+               if (info && info->wl_disp && info->prepared)
+                       wl_display_cancel_read(info->wl_disp);
+               _E("Display source(%p) already destroyed.", source);
+               return ret;
+       }
+
+       if (!info->prepared)
+               return ret;
+
+       if (info->gfd.revents & (G_IO_HUP|G_IO_ERR)) {
+               wl_display_cancel_read(info->wl_disp);
+               goto err;
+       }
+
+       if (info->gfd.revents & G_IO_IN) {
+               wl_ret = wl_display_read_events(info->wl_disp);
+               if (wl_ret < 0) {
+                       _E("Failed to read display events: %d", wl_ret);
+                       goto err;
+               }
+               ret = TRUE;
+       } else
+               wl_display_cancel_read(info->wl_disp);
+
+       info->prepared = FALSE;
+
+       return ret;
+
+err:
+       _E("Get ERROR in check: revent:0x%x, wl_err:%d", info->gfd.revents, wl_ret);
+
+       info->prepared = FALSE;
+       g_source_destroy(source);
+
+       return FALSE;
+}
+
+static gboolean
+wl_glib_client_dispatch(GSource *source, GSourceFunc cb, gpointer data)
+{
+       int ret = 0;
+
+       if (!source) {
+               _E("Source is NULL.");
+               return G_SOURCE_REMOVE;
+       }
+       info = (wl_glib_info *)source;
+
+       if (g_source_is_destroyed(source)) {
+               _E("Display source(%p) already destroyed.", source);
+               return G_SOURCE_REMOVE;
+       }
+
+       if (info->gfd.revents & (G_IO_HUP|G_IO_ERR))
+               goto err;
+
+       if (info->gfd.revents & G_IO_IN) {
+               ret = wl_display_dispatch_pending(info->wl_disp);
+               if (ret == -1) {
+                       _E("Failed to dispatch display pending: %d", ret);
+                       goto err;
+               }
+       }
+
+       ret = wl_display_flush(info->wl_disp);
+       if (ret == -1) {
+               _E("Failed to flush display: %d", ret);
+               goto err;
+       }
+
+       return G_SOURCE_CONTINUE;
+
+err:
+       _E("Err in dispatch: revent:0x%x, wl_err:%d", info->gfd.revents, ret);
+
+       return G_SOURCE_REMOVE;
+}
+
+static void
+wl_glib_client_finalize(GSource *source)
+{
+       if (!source) {
+               _E("Source is NULL.");
+               return;
+       }
+       info = (wl_glib_info *)source;
 
-error:
-       if (registry)
-               wl_registry_destroy(registry);
        disconnect_interface_with_dpms();
+       return;
+}
+
+static GSourceFuncs wl_glib_client_funcs = {
+       .prepare = wl_glib_client_prepare,
+       .check = wl_glib_client_check,
+       .dispatch = wl_glib_client_dispatch,
+       .finalize = wl_glib_client_finalize,
+};
+
+GSource* wl_glib_client_init(void)
+{
+       int ret;
+
+       info = (wl_glib_info *)g_source_new(&wl_glib_client_funcs, sizeof(wl_glib_info));
+       if (info == NULL) {
+               _E("Failed to make g_source_new.");
+               goto err;
+       }
+
+       ret = wl_glib_wayland_init(info);
+       if (ret < 0) {
+               _E("Failed to init wayland.");
+               goto err;
+       }
+
+       info->gfd.fd = wl_display_get_fd(info->wl_disp);
+       if (info->gfd.fd < 0) {
+               _E("Failed to get display fd");
+               goto err;
+       }
+
+       info->gfd.events = G_IO_IN | G_IO_ERR;
+       info->gfd.revents = 0;
+
+       g_source_add_poll(&info->gsource, &info->gfd);
+       g_source_attach(&info->gsource, NULL);
+       g_source_unref(&info->gsource);
+
+       return &info->gsource;
+
+err:
+       if (info) {
+               disconnect_interface_with_dpms();
+               g_source_unref(&info->gsource);
+       }
+
+       return NULL;
+}
+
+bool check_wm_ready(void)
+{
+       if (access("/run/.wm_ready", F_OK) == 0) {
+               _I("Window manager is ready.");
+               wm_is_ready = true;
+               return true;
+       }
+
+       _I("Window manager is not ready.");
        return false;
 }
 
+bool connect_interface_with_dpms(void)
+{
+       wl_glib_data = wl_glib_client_init();
+       if (!wl_glib_data) {
+               _E("Failed to init client.");
+               return false;
+       }
+
+       return true;
+}
+
 bool dpms_is_available(void)
 {
        /* Check window manager */
@@ -175,26 +382,27 @@ bool dpms_is_available(void)
 
 void dpms_set_state(int on)
 {
-       dpms_retry = 1;
+       uint32_t mode;
 
-       tizen_dpms_manager_set_dpms(tz_dpms_mng, wl_out, on);
-       wl_display_roundtrip(display);
-
-       while (dpms_retry) {
-               wl_display_dispatch_queue(display, queue);
+       if (!dpms_is_available()) {
+               _E("Dpms is not available.");
+               return;
        }
+
+       mode = (uint32_t)on;
+       tizen_dpms_manager_set_dpms(info->tz_dpms_mng, info->wl_output, mode);
+       wl_display_flush(info->wl_disp);
 }
 
 int dpms_get_state(void)
 {
-       dpms_retry = 1;
-
-       tizen_dpms_manager_get_dpms(tz_dpms_mng, wl_out);
-       wl_display_roundtrip(display);
-
-       while (dpms_retry) {
-               wl_display_dispatch_queue(display, queue);
+       if (!dpms_is_available()) {
+               _E("Dpms is not available.");
+               return -EINVAL;
        }
 
-       return lcd_state;
+       tizen_dpms_manager_get_dpms(info->tz_dpms_mng, info->wl_output);
+       wl_display_flush(info->wl_disp);
+
+       return (int)info->dpms_mode;
 }