--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "ecore_drm_private.h"
+#include <sys/eventfd.h>
+
+static DBusConnection *conn;
+static DBusPendingCall *dpending;
+static Ecore_Fd_Handler *_dbus_hdlr;
+static Ecore_Fd_Handler *_watch_hdlr;
+static char *dpath;
+static const char *sid;
+
+static void
+_dbus_session_removed(DBusMessage *msg)
+{
+ const char *n, *o;
+ dbus_bool_t ret;
+
+ ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &n,
+ DBUS_TYPE_OBJECT_PATH, &o, DBUS_TYPE_INVALID);
+ if (!ret) return;
+
+ if (!strcmp(n, sid))
+ {
+ ERR("DBus Session Closed");
+// ecore_main_loop_quit();
+ }
+}
+
+static void
+_dbus_cb_notify(DBusPendingCall *pending, void *data EINA_UNUSED)
+{
+ DBusMessage *msg;
+ DBusMessageIter iter, s;
+ dbus_bool_t ret;
+ int type = 0;
+
+ dbus_pending_call_unref(dpending);
+ dpending = NULL;
+
+ msg = dbus_pending_call_steal_reply(pending);
+ if (!msg) return;
+
+ type = dbus_message_get_type(msg);
+ if (type != DBUS_MESSAGE_TYPE_METHOD_RETURN) goto err;
+
+ if ((!dbus_message_iter_init(msg, &iter)) ||
+ (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT))
+ goto err;
+
+ dbus_message_iter_recurse(&iter, &s);
+
+ if (dbus_message_iter_get_arg_type(&s) != DBUS_TYPE_BOOLEAN)
+ goto err;
+
+ dbus_message_iter_get_basic(&s, &ret);
+ if (!ret)
+ {
+ /* TODO: emit active signal to compositor ? */
+ }
+
+err:
+ dbus_message_unref(msg);
+}
+
+static void
+_dbus_active_get(void)
+{
+ DBusPendingCall *pend;
+ DBusMessage *msg;
+ dbus_bool_t ret;
+ const char *iface, *n;
+
+ msg =
+ dbus_message_new_method_call("org.freedesktop.login1", dpath,
+ "org.freedesktop.DBus.Properties", "Get");
+ if (!msg) return;
+
+ iface = "org.freedesktop.login1.Session";
+ n = "Active";
+
+ ret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &iface,
+ DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID);
+ if (!ret) goto err;
+
+ ret = dbus_connection_send_with_reply(conn, msg, &pend, -1);
+ if (!ret) goto err;
+
+ ret = dbus_pending_call_set_notify(pend, _dbus_cb_notify, NULL, NULL);
+ if (!ret)
+ {
+ dbus_pending_call_cancel(pend);
+ dbus_pending_call_unref(pend);
+ goto err;
+ }
+
+ if (dpending)
+ {
+ dbus_pending_call_cancel(dpending);
+ dbus_pending_call_unref(dpending);
+ }
+
+ dpending = pend;
+
+ return;
+
+err:
+ dbus_message_unref(msg);
+}
+
+static void
+_dbus_property_changed(DBusMessage *msg)
+{
+ DBusMessageIter iter, s, ent;
+ const char *iface, *n;
+ dbus_bool_t ret;
+
+ if ((!dbus_message_iter_init(msg, &iter)) ||
+ (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING))
+ return;
+
+ dbus_message_iter_get_basic(&iter, &iface);
+
+ if ((!dbus_message_iter_next(&iter)) ||
+ (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY))
+ return;
+
+ dbus_message_iter_recurse(&iter, &s);
+ while (dbus_message_iter_get_arg_type(&s) == DBUS_TYPE_DICT_ENTRY)
+ {
+ dbus_message_iter_recurse(&s, &ent);
+ if (dbus_message_iter_get_arg_type(&ent) != DBUS_TYPE_STRING)
+ return;
+
+ dbus_message_iter_get_basic(&ent, &n);
+ if (!dbus_message_iter_next(&ent)) return;
+
+ if (!strcmp(n, "Active"))
+ {
+ if (dbus_message_iter_get_arg_type(&ent) == DBUS_TYPE_BOOLEAN)
+ {
+ dbus_message_iter_get_basic(&ent, &ret);
+ if (!ret)
+ {
+ /* TODO: emit active signal to compositor ? */
+ }
+ return;
+ }
+ }
+
+ dbus_message_iter_next(&s);
+ }
+
+ if ((!dbus_message_iter_next(&iter)) ||
+ (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY))
+ return;
+
+ dbus_message_iter_recurse(&iter, &s);
+ while (dbus_message_iter_get_arg_type(&s) == DBUS_TYPE_STRING)
+ {
+ dbus_message_iter_get_basic(&s, &n);
+ if (!strcmp(n, "Active"))
+ {
+ _dbus_active_get();
+ return;
+ }
+
+ dbus_message_iter_next(&s);
+ }
+}
+
+static void
+_dbus_device_pause_done(uint32_t major, uint32_t minor)
+{
+ DBusMessage *msg;
+ dbus_bool_t ret;
+
+ msg = dbus_message_new_method_call("org.freedesktop.login1", dpath,
+ "org.freedesktop.login1.Session",
+ "PauseDeviceComplete");
+ if (msg)
+ {
+ ret = dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,
+ DBUS_TYPE_UINT32, &minor,
+ DBUS_TYPE_INVALID);
+ if (ret)
+ dbus_connection_send(conn, msg, NULL);
+
+ dbus_message_unref(msg);
+ }
+}
+
+static void
+_dbus_device_paused(DBusMessage *msg)
+{
+ dbus_bool_t ret;
+ const char *type;
+ uint32_t maj, min;
+
+ ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &maj,
+ DBUS_TYPE_UINT32, &min,
+ DBUS_TYPE_STRING, &type, DBUS_TYPE_INVALID);
+ if (!ret) return;
+
+ if (!strcmp(type, "pause"))
+ _dbus_device_pause_done(maj, min);
+
+ if (maj == DRM_MAJOR)
+ {
+ /* TODO: emit active signal to compositor ? */
+ }
+}
+
+static void
+_dbus_device_resumed(DBusMessage *msg)
+{
+ dbus_bool_t ret;
+ uint32_t maj;
+
+ ret = dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_UINT32, &maj, DBUS_TYPE_INVALID);
+ if (!ret) return;
+
+ if (maj == DRM_MAJOR)
+ {
+ /* TODO: emit active signal to compositor ? */
+ }
+}
+
+static void
+_dbus_device_release(uint32_t major, uint32_t minor)
+{
+ DBusMessage *msg;
+
+ msg = dbus_message_new_method_call("org.freedesktop.login1", dpath,
+ "org.freedesktop.login1.Session",
+ "ReleaseDevice");
+ if (msg)
+ {
+ dbus_bool_t ret;
+
+ ret = dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,
+ DBUS_TYPE_UINT32, &minor,
+ DBUS_TYPE_INVALID);
+ if (ret) dbus_connection_send(conn, msg, NULL);
+ dbus_message_unref(msg);
+ }
+}
+
+static int
+_dbus_device_take(uint32_t major, uint32_t minor)
+{
+ DBusMessage *msg, *rep;
+ DBusError err;
+ dbus_bool_t p, ret;
+ int fd = -1;
+
+ msg = dbus_message_new_method_call("org.freedesktop.login1", dpath,
+ "org.freedesktop.login1.Session",
+ "TakeDevice");
+ if (!msg) return -1;
+
+ ret = dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,
+ DBUS_TYPE_UINT32, &minor, DBUS_TYPE_INVALID);
+ if (!ret) goto err;
+
+ dbus_error_init(&err);
+
+ rep =
+ dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+ if (!rep)
+ {
+ if (dbus_error_has_name(&err, DBUS_ERROR_UNKNOWN_METHOD))
+ ERR("Old Systemd Version detected");
+ else if (dbus_error_is_set(&err))
+ ERR("DBusError: %s %s", err.name, err.message);
+ dbus_error_free(&err);
+ goto err;
+ }
+
+ ret = dbus_message_get_args(rep, &err, DBUS_TYPE_UNIX_FD, &fd,
+ DBUS_TYPE_BOOLEAN, &p, DBUS_TYPE_INVALID);
+ if (!ret)
+ {
+ if (dbus_error_is_set(&err))
+ ERR("DBusError: %s %s", err.name, err.message);
+
+ dbus_error_free(&err);
+ goto err_rep;
+ }
+
+ return fd;
+
+err_rep:
+ dbus_message_unref(rep);
+err:
+ dbus_message_unref(msg);
+ return -1;
+}
+
+static int
+_dbus_device_open(const char *path)
+{
+ struct stat st;
+ int ret, fl, fd = -1;
+ /* char name[256] = "unknown"; */
+
+ if ((ret = stat(path, &st)) < 0) return -1;
+ if (!S_ISCHR(st.st_mode)) return -1;
+
+ fd = _dbus_device_take(major(st.st_rdev), minor(st.st_rdev));
+ if (fd < 0)
+ {
+ ERR("Failed to take device: %s", path);
+ return -1;
+ }
+
+ if ((fl = fcntl(fd, F_GETFL)) < 0)
+ {
+ ERR("Failed to get file flags: %m");
+ goto flag_err;
+ }
+
+ fl = (O_RDWR | O_NONBLOCK);
+
+ if ((ret = fcntl(fd, F_SETFL, fl)) < 0)
+ {
+ ERR("Failed to set file flags: %m");
+ goto flag_err;
+ }
+
+ if ((fl = fcntl(fd, F_GETFD)) < 0)
+ {
+ ERR("Failed to get file fd: %m");
+ goto flag_err;
+ }
+
+ fl &= ~FD_CLOEXEC;
+
+ if ((ret = fcntl(fd, F_SETFD, fl)) < 0)
+ {
+ ERR("Failed to set file fds: %m");
+ goto flag_err;
+ }
+
+ /* if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) */
+ /* { */
+ /* ERR("Could not get device name: %m"); */
+ /* goto flag_err; */
+ /* } */
+ /* else */
+ /* { */
+ /* name[sizeof(name) - 1] = '\0'; */
+ /* DBG("%s Opened", name); */
+ /* } */
+
+ return fd;
+
+flag_err:
+ _dbus_device_release(major(st.st_rdev), minor(st.st_rdev));
+ return -1;
+}
+
+static DBusHandlerResult
+_dbus_cb_filter(DBusConnection *conn EINA_UNUSED, DBusMessage *msg, void *data EINA_UNUSED)
+{
+ if (dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected"))
+ {
+ ERR("DBus Disconnected");
+ }
+ else if (dbus_message_is_signal(msg, "org.freedesktop.login1.Manager",
+ "SessionRemoved"))
+ _dbus_session_removed(msg);
+ else if (dbus_message_is_signal(msg, "org.freedesktop.DBus.Properties",
+ "PropertiesChanged"))
+ _dbus_property_changed(msg);
+ else if (dbus_message_is_signal(msg, "org.freedesktop.login1.Session",
+ "PauseDevice"))
+ _dbus_device_paused(msg);
+ else if (dbus_message_is_signal(msg, "org.freedesktop.login1.Sesion",
+ "ResumeDevice"))
+ _dbus_device_resumed(msg);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static Eina_Bool
+_dbus_cb_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
+{
+ DBusConnection *conn;
+ int ret = 0;
+
+ if (!(conn = data)) return ECORE_CALLBACK_CANCEL;
+
+ do
+ {
+ ret = dbus_connection_dispatch(conn);
+ switch (ret)
+ {
+ case DBUS_DISPATCH_COMPLETE:
+ ret = 0;
+ break;
+ case DBUS_DISPATCH_DATA_REMAINS:
+ ret = -EAGAIN;
+ break;
+ case DBUS_DISPATCH_NEED_MEMORY:
+ ret = -ENOMEM;
+ break;
+ default:
+ ret = -EIO;
+ break;
+ }
+ } while (ret == -EAGAIN);
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_dbus_cb_watch(void *data, Ecore_Fd_Handler *hdlr)
+{
+ DBusWatch *watch;
+ uint32_t flags = 0;
+
+ if (!(watch = data)) return ECORE_CALLBACK_RENEW;
+
+ if (dbus_watch_get_enabled(watch))
+ {
+ if (ecore_main_fd_handler_active_get(hdlr, ECORE_FD_READ))
+ flags |= DBUS_WATCH_READABLE;
+ if (ecore_main_fd_handler_active_get(hdlr, ECORE_FD_WRITE))
+ flags |= DBUS_WATCH_WRITABLE;
+ if (ecore_main_fd_handler_active_get(hdlr, ECORE_FD_ERROR))
+ flags |= DBUS_WATCH_ERROR;
+
+ dbus_watch_handle(watch, flags);
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static dbus_bool_t
+_dbus_watch_add(DBusWatch *watch, void *data EINA_UNUSED)
+{
+ uint32_t msk = 0, flags = 0;
+ int fd = -1;
+
+ msk |= ECORE_FD_ERROR;
+ if (dbus_watch_get_enabled(watch))
+ {
+ flags = dbus_watch_get_flags(watch);
+ if (flags & DBUS_WATCH_READABLE)
+ msk |= ECORE_FD_READ;
+ if (flags & DBUS_WATCH_WRITABLE)
+ msk |= ECORE_FD_WRITE;
+ }
+
+ fd = dbus_watch_get_unix_fd(watch);
+
+ _watch_hdlr =
+ ecore_main_fd_handler_add(fd, msk, _dbus_cb_watch, watch, NULL, NULL);
+
+ dbus_watch_set_data(watch, _watch_hdlr, NULL);
+
+ return TRUE;
+}
+
+static void
+_dbus_watch_del(DBusWatch *watch, void *data EINA_UNUSED)
+{
+ Ecore_Fd_Handler *hdlr;
+
+ if (!(hdlr = dbus_watch_get_data(watch))) return;
+ ecore_main_fd_handler_del(hdlr);
+ _watch_hdlr = NULL;
+}
+
+static void
+_dbus_watch_toggle(DBusWatch *watch, void *data EINA_UNUSED)
+{
+ uint32_t flags = 0, mask = 0;
+ Ecore_Fd_Handler *hdlr;
+
+ if (!(hdlr = dbus_watch_get_data(watch))) return;
+
+ if (dbus_watch_get_enabled(watch))
+ {
+ flags = dbus_watch_get_flags(watch);
+ if (flags & DBUS_WATCH_READABLE)
+ mask |= ECORE_FD_READ;
+ if (flags & DBUS_WATCH_WRITABLE)
+ mask |= ECORE_FD_WRITE;
+ }
+
+ ecore_main_fd_handler_active_set(hdlr, mask);
+}
+
+static Eina_Bool
+_dbus_cb_timeout(void *data)
+{
+ DBusTimeout *timeout;
+
+ if (!(timeout = data)) return ECORE_CALLBACK_RENEW;
+
+ if (dbus_timeout_get_enabled(timeout))
+ dbus_timeout_handle(timeout);
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static dbus_bool_t
+_dbus_timeout_add(DBusTimeout *timeout, void *data EINA_UNUSED)
+{
+ if (dbus_timeout_get_enabled(timeout))
+ {
+ Ecore_Timer *tmr = NULL;
+ int tme;
+
+ tme = dbus_timeout_get_interval(timeout);
+ if (!(tmr = ecore_timer_loop_add(tme, _dbus_cb_timeout, timeout)))
+ return EINA_FALSE;
+
+ dbus_timeout_set_data(timeout, tmr, NULL);
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_dbus_timeout_del(DBusTimeout *timeout, void *data EINA_UNUSED)
+{
+ Ecore_Timer *tmr = NULL;
+
+ if (!(tmr = dbus_timeout_get_data(timeout))) return;
+ ecore_timer_del(tmr);
+}
+
+static void
+_dbus_timeout_toggle(DBusTimeout *timeout, void *data EINA_UNUSED)
+{
+ Ecore_Timer *tmr = NULL;
+
+ if (!(tmr = dbus_timeout_get_data(timeout))) return;
+
+ if (dbus_timeout_get_enabled(timeout))
+ ecore_timer_thaw(tmr);
+ else
+ ecore_timer_freeze(tmr);
+}
+
+static Eina_Bool
+_dbus_match_add(DBusConnection *conn, const char *format, ...)
+{
+ DBusError err;
+ va_list lst;
+ char *tmp;
+ int ret;
+
+ va_start(lst, format);
+ ret = vasprintf(&tmp, format, lst);
+ va_end(lst);
+
+ if (ret < 0) return EINA_FALSE;
+
+ dbus_error_init(&err);
+ dbus_bus_add_match(conn, tmp, &err);
+ free(tmp);
+
+ if (dbus_error_is_set(&err))
+ {
+ dbus_error_free(&err);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_dbus_signal_add(DBusConnection *conn, const char *sender, const char *iface, const char *mem, const char *path)
+{
+ return _dbus_match_add(conn, "type='signal',sender='%s',"
+ "interface='%s',member='%s',path='%s'",
+ sender, iface, mem, path);
+}
+
+static Eina_Bool
+_dbus_setup(void)
+{
+ int ret = 0;
+ dbus_bool_t res;
+
+ ret = asprintf(&dpath, "/org/freedesktop/login1/session/%s", sid);
+ if (ret < 0) return EINA_FALSE;
+
+ res = dbus_connection_add_filter(conn, _dbus_cb_filter, NULL, NULL);
+ if (!res)
+ {
+ ERR("Could not setup dbus filter: %m\n");
+ goto err;
+ }
+
+ res = _dbus_signal_add(conn, "org.freedesktop.login1",
+ "org.freedesktop.login1.Manager",
+ "SessionRemoved", "/org/freedesktop/login1");
+ if (!res) goto err;
+
+ res = _dbus_signal_add(conn, "org.freedesktop.login1",
+ "org.freedesktop.login1.Session",
+ "PauseDevice", dpath);
+ if (!res) goto err;
+
+ res = _dbus_signal_add(conn, "org.freedesktop.login1",
+ "org.freedesktop.login1.Session",
+ "ResumeDevice", dpath);
+ if (!res) goto err;
+
+ res = _dbus_signal_add(conn, "org.freedesktop.login1",
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged", dpath);
+ if (!res) goto err;
+
+ return EINA_TRUE;
+
+err:
+ free(dpath);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_dbus_control_take(void)
+{
+ DBusError err;
+ DBusMessage *msg, *rep;
+ dbus_bool_t f = EINA_FALSE;
+
+ dbus_error_init(&err);
+
+ msg =
+ dbus_message_new_method_call("org.freedesktop.login1", dpath,
+ "org.freedesktop.login1.Session",
+ "TakeControl");
+ if (!msg) goto err;
+
+ if (!dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &f, DBUS_TYPE_INVALID))
+ goto msg_err;
+
+ rep = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+ if (!rep)
+ {
+ if (dbus_error_has_name(&err, DBUS_ERROR_UNKNOWN_METHOD))
+ ERR("Old Systemd Version detected\n");
+ goto msg_err;
+ }
+
+ dbus_message_unref(rep);
+ dbus_message_unref(msg);
+ dbus_error_free(&err);
+
+ return EINA_TRUE;
+
+msg_err:
+ dbus_message_unref(msg);
+err:
+ if (dbus_error_is_set(&err))
+ ERR("DBusError: %s %s", err.name, err.message);
+ dbus_error_free(&err);
+ return EINA_FALSE;
+}
+
+static void
+_dbus_control_release(void)
+{
+ DBusMessage *msg;
+
+ msg =
+ dbus_message_new_method_call("org.freedesktop.login1", dpath,
+ "org.freedesktop.login1.Session",
+ "ReleaseControl");
+ if (msg)
+ {
+ dbus_connection_send(conn, msg, NULL);
+ dbus_message_unref(msg);
+ }
+}
+
+static Eina_Bool
+_dbus_bind(DBusConnection *conn)
+{
+ int fd = -1;
+
+ if ((fd = eventfd(0, EFD_CLOEXEC)) < 0)
+ {
+ ERR("Could not create eventfd: %m");
+ return EINA_FALSE;
+ }
+
+ _dbus_hdlr =
+ ecore_main_fd_handler_add(fd, (ECORE_FD_READ | ECORE_FD_WRITE),
+ _dbus_cb_dispatch, conn, NULL, NULL);
+ if (!_dbus_hdlr)
+ {
+ ERR("Failed to create ecore fd handler");
+ goto hdlr_err;
+ }
+
+ if (!dbus_connection_set_watch_functions(conn, _dbus_watch_add,
+ _dbus_watch_del,
+ _dbus_watch_toggle, NULL, NULL))
+ {
+ ERR("Failed to set dbus watch functions: %m");
+ goto watch_err;
+ }
+
+ if (!dbus_connection_set_timeout_functions(conn, _dbus_timeout_add,
+ _dbus_timeout_del,
+ _dbus_timeout_toggle,
+ NULL, NULL))
+ {
+ ERR("Failed to set dbus timeout functions: %m");
+ goto timeout_err;
+ }
+
+ dbus_connection_ref(conn);
+
+ return EINA_TRUE;
+
+timeout_err:
+ dbus_connection_set_watch_functions(conn, NULL, NULL, NULL, NULL, NULL);
+watch_err:
+ ecore_main_fd_handler_del(_dbus_hdlr);
+ _dbus_hdlr = NULL;
+hdlr_err:
+ close(fd);
+ return EINA_FALSE;
+}
+
+static DBusConnection *
+_dbus_open(void)
+{
+ DBusConnection *conn;
+
+ dbus_connection_set_change_sigpipe(EINA_FALSE);
+
+ conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);
+ if (!conn)
+ {
+ ERR("Failed to get dbus connection: %m");
+ goto conn_err;
+ }
+
+ dbus_connection_set_exit_on_disconnect(conn, EINA_FALSE);
+
+ if (!_dbus_bind(conn))
+ {
+ ERR("Failed to bind dbus: %m");
+ goto bind_err;
+ }
+
+ return conn;
+
+bind_err:
+ dbus_connection_close(conn);
+ dbus_connection_unref(conn);
+conn_err:
+ return NULL;
+}
+
+static void
+_dbus_close(void)
+{
+ dbus_connection_set_timeout_functions(conn, NULL, NULL, NULL, NULL, NULL);
+ dbus_connection_set_watch_functions(conn, NULL, NULL, NULL, NULL, NULL);
+
+ if (_dbus_hdlr) ecore_main_fd_handler_del(_dbus_hdlr);
+ _dbus_hdlr = NULL;
+
+ dbus_connection_close(conn);
+ dbus_connection_unref(conn);
+}
+
+Eina_Bool
+_ecore_drm_dbus_init(const char *session)
+{
+ if (conn) return EINA_TRUE;
+
+ /* try to init dbus */
+ if (!(conn = _dbus_open())) return EINA_FALSE;
+
+ sid = eina_stringshare_add(session);
+
+ /* try to setup signal handlers */
+ if (!_dbus_setup()) goto setup_err;
+
+ /* try to take control of the session */
+ if (!_dbus_control_take()) goto setup_err;
+
+ return EINA_TRUE;
+
+setup_err:
+ _dbus_close();
+ eina_stringshare_del(sid);
+ return EINA_FALSE;
+}
+
+void
+_ecore_drm_dbus_shutdown(void)
+{
+ _dbus_control_release();
+ _dbus_close();
+ eina_stringshare_del(sid);
+ free(dpath);
+}
+
+int
+_ecore_drm_dbus_device_open(const char *device)
+{
+ return _dbus_device_open(device);
+}