#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 = {
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.");
}
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, ®istry_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, ®istry_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 */
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;
}