forked from enlightenment/efl
403 lines
10 KiB
C
403 lines
10 KiB
C
#include "ecore_drm_private.h"
|
|
|
|
static int _dbus_init_count = 0;
|
|
|
|
static Eldbus_Connection *dconn;
|
|
static Eldbus_Object *dobj;
|
|
|
|
static void
|
|
_ecore_drm_dbus_device_pause_done(uint32_t major, uint32_t minor)
|
|
{
|
|
Eldbus_Proxy *proxy;
|
|
Eldbus_Message *msg;
|
|
|
|
/* try to get the Session proxy */
|
|
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Session")))
|
|
{
|
|
ERR("Could not get eldbus session proxy");
|
|
return;
|
|
}
|
|
|
|
if (!(msg = eldbus_proxy_method_call_new(proxy, "PauseDeviceComplete")))
|
|
{
|
|
ERR("Could not create method call for proxy");
|
|
return;
|
|
}
|
|
|
|
eldbus_message_arguments_append(msg, "uu", major, minor);
|
|
eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
|
|
}
|
|
|
|
static void
|
|
_cb_session_removed(void *data, const Eldbus_Message *msg)
|
|
{
|
|
Ecore_Drm_Device *dev;
|
|
const char *errname, *errmsg;
|
|
const char *sid;
|
|
|
|
if (!(dev = data)) return;
|
|
|
|
if (eldbus_message_error_get(msg, &errname, &errmsg))
|
|
{
|
|
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
|
return;
|
|
}
|
|
|
|
if (eldbus_message_arguments_get(msg, "s", &sid))
|
|
{
|
|
if (!strcmp(sid, dev->session))
|
|
{
|
|
WRN("\tCurrent Session Removed!!");
|
|
_ecore_drm_logind_restore(dev);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
_cb_device_paused(void *ctxt EINA_UNUSED, const Eldbus_Message *msg)
|
|
{
|
|
const char *errname, *errmsg;
|
|
const char *type;
|
|
uint32_t maj, min;
|
|
|
|
if (eldbus_message_error_get(msg, &errname, &errmsg))
|
|
{
|
|
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
|
return;
|
|
}
|
|
|
|
if (eldbus_message_arguments_get(msg, "uus", &maj, &min, &type))
|
|
{
|
|
if (!strcmp(type, "pause"))
|
|
_ecore_drm_dbus_device_pause_done(maj, min);
|
|
|
|
if (maj == DRM_MAJOR)
|
|
_ecore_drm_event_activate_send(EINA_FALSE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_cb_device_resumed(void *ctxt EINA_UNUSED, const Eldbus_Message *msg)
|
|
{
|
|
const char *errname, *errmsg;
|
|
uint32_t maj, min;
|
|
int fd;
|
|
|
|
if (eldbus_message_error_get(msg, &errname, &errmsg))
|
|
{
|
|
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
|
return;
|
|
}
|
|
|
|
if (eldbus_message_arguments_get(msg, "uuh", &maj, &min, &fd))
|
|
{
|
|
if (maj == DRM_MAJOR)
|
|
_ecore_drm_event_activate_send(EINA_TRUE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_property_response_set(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
|
|
{
|
|
const char *errname, *errmsg;
|
|
|
|
if (eldbus_message_error_get(msg, &errname, &errmsg))
|
|
ERR("Eldbus Message error %s - %s\n\n", errname, errmsg);
|
|
}
|
|
|
|
static void
|
|
_cb_properties_changed(void *data EINA_UNUSED, Eldbus_Proxy *proxy EINA_UNUSED, void *event)
|
|
{
|
|
Eldbus_Proxy_Event_Property_Changed *ev;
|
|
|
|
ev = event;
|
|
|
|
if (!strcmp(ev->name, "Active"))
|
|
{
|
|
eldbus_proxy_property_set(proxy, "Active", "b", (void *)EINA_TRUE,
|
|
_property_response_set, NULL);
|
|
eldbus_proxy_property_set(proxy, "State", "s", &"active",
|
|
_property_response_set, NULL);
|
|
}
|
|
}
|
|
|
|
Eina_Bool
|
|
_ecore_drm_dbus_session_take(void)
|
|
{
|
|
Eldbus_Proxy *proxy;
|
|
Eldbus_Message *msg, *reply;
|
|
const char *errname, *errmsg;
|
|
|
|
/* try to get the Session proxy */
|
|
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Session")))
|
|
{
|
|
ERR("Could not get eldbus session proxy");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/* send call to take control */
|
|
if (!(msg = eldbus_proxy_method_call_new(proxy, "TakeControl")))
|
|
{
|
|
ERR("Could not create method call for proxy");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
eldbus_message_arguments_append(msg, "b", EINA_FALSE);
|
|
|
|
reply = eldbus_proxy_send_and_block(proxy, msg, -1);
|
|
if (eldbus_message_error_get(reply, &errname, &errmsg))
|
|
{
|
|
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_ecore_drm_dbus_session_release(void)
|
|
{
|
|
Eldbus_Proxy *proxy;
|
|
Eldbus_Message *msg, *reply;
|
|
const char *errname, *errmsg;
|
|
|
|
/* try to get the Session proxy */
|
|
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Session")))
|
|
{
|
|
ERR("Could not get eldbus session proxy");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/* send call to release control */
|
|
if (!(msg = eldbus_proxy_method_call_new(proxy, "ReleaseControl")))
|
|
{
|
|
ERR("Could not create method call for proxy");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
reply = eldbus_proxy_send_and_block(proxy, msg, -1);
|
|
if (eldbus_message_error_get(reply, &errname, &errmsg))
|
|
{
|
|
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
void
|
|
_ecore_drm_dbus_device_release(uint32_t major, uint32_t minor)
|
|
{
|
|
Eldbus_Proxy *proxy;
|
|
Eldbus_Message *msg;
|
|
|
|
/* try to get the Session proxy */
|
|
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Session")))
|
|
{
|
|
ERR("Could not get eldbus session proxy");
|
|
return;
|
|
}
|
|
|
|
if (!(msg = eldbus_proxy_method_call_new(proxy, "ReleaseDevice")))
|
|
{
|
|
ERR("Could not create method call for proxy");
|
|
return;
|
|
}
|
|
|
|
eldbus_message_arguments_append(msg, "uu", major, minor);
|
|
|
|
eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
|
|
}
|
|
|
|
static void
|
|
_cb_device_taken(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
|
|
{
|
|
const char *errname, *errmsg;
|
|
Ecore_Drm_Open_Cb callback = NULL;
|
|
Eina_Bool b = EINA_FALSE;
|
|
int fd = -1;
|
|
|
|
if (eldbus_message_error_get(msg, &errname, &errmsg))
|
|
{
|
|
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
|
goto eldbus_err;
|
|
}
|
|
|
|
/* DBUS_TYPE_UNIX_FD == 'h' */
|
|
if (!eldbus_message_arguments_get(msg, "hb", &fd, &b))
|
|
ERR("\tCould not get UNIX_FD from eldbus message: %d %d", fd, b);
|
|
|
|
eldbus_err:
|
|
callback = (Ecore_Drm_Open_Cb)eldbus_pending_data_del(pending, "callback");
|
|
if (callback) callback(data, fd, b);
|
|
}
|
|
|
|
int
|
|
_ecore_drm_dbus_device_take(uint32_t major, uint32_t minor, Ecore_Drm_Open_Cb callback, void *data)
|
|
{
|
|
Eldbus_Proxy *proxy;
|
|
Eldbus_Message *msg;
|
|
Eldbus_Pending *pending;
|
|
|
|
/* try to get the Session proxy */
|
|
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Session")))
|
|
{
|
|
ERR("Could not get eldbus session proxy");
|
|
return -1;
|
|
}
|
|
|
|
if (!(msg = eldbus_proxy_method_call_new(proxy, "TakeDevice")))
|
|
{
|
|
ERR("Could not create method call for proxy");
|
|
return -1;
|
|
}
|
|
|
|
eldbus_message_arguments_append(msg, "uu", major, minor);
|
|
pending = eldbus_proxy_send(proxy, msg, _cb_device_taken, data, -1);
|
|
if (callback) eldbus_pending_data_set(pending, "callback", callback);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
_ecore_drm_dbus_device_take_no_pending(uint32_t major, uint32_t minor, Eina_Bool *paused_out, double timeout)
|
|
{
|
|
Eldbus_Proxy *proxy;
|
|
Eldbus_Message *msg, *reply;
|
|
Eina_Bool b;
|
|
const char *errname, *errmsg;
|
|
int fd;
|
|
|
|
/* try to get the Session proxy */
|
|
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Session")))
|
|
{
|
|
ERR("Could not get eldbus session proxy");
|
|
return -1;
|
|
}
|
|
|
|
if (!(msg = eldbus_proxy_method_call_new(proxy, "TakeDevice")))
|
|
{
|
|
ERR("Could not create method call for proxy");
|
|
return -1;
|
|
}
|
|
|
|
if (!eldbus_message_arguments_append(msg, "uu", major, minor))
|
|
return -1;
|
|
|
|
reply = eldbus_proxy_send_and_block(proxy, msg, timeout);
|
|
if (eldbus_message_error_get(reply, &errname, &errmsg))
|
|
{
|
|
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
|
return -1;
|
|
}
|
|
|
|
if (!eldbus_message_arguments_get(reply, "hb", &fd, &b))
|
|
return -1;
|
|
|
|
if (paused_out) *paused_out = b;
|
|
return fd;
|
|
}
|
|
|
|
int
|
|
_ecore_drm_dbus_init(Ecore_Drm_Device *dev)
|
|
{
|
|
Eldbus_Proxy *proxy;
|
|
int ret = 0;
|
|
char *dpath;
|
|
|
|
if (++_dbus_init_count != 1) return _dbus_init_count;
|
|
|
|
if (!dev->session) return --_dbus_init_count;
|
|
|
|
/* try to init eldbus */
|
|
if (!eldbus_init())
|
|
{
|
|
ERR("Could not init eldbus library");
|
|
return --_dbus_init_count;
|
|
}
|
|
|
|
/* try to get the dbus connection */
|
|
if (!(dconn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM)))
|
|
{
|
|
ERR("Failed to get eldbus system connection");
|
|
goto conn_err;
|
|
}
|
|
|
|
/* assemble dbus path */
|
|
ret = asprintf(&dpath, "/org/freedesktop/login1/session/%s", dev->session);
|
|
if (ret < 0)
|
|
{
|
|
ERR("Could not assemble dbus path");
|
|
goto path_err;
|
|
}
|
|
|
|
/* try to get the eldbus object */
|
|
if (!(dobj = eldbus_object_get(dconn, "org.freedesktop.login1", dpath)))
|
|
{
|
|
ERR("Could not get eldbus object: %s", dpath);
|
|
goto obj_err;
|
|
}
|
|
|
|
/* try to get the Manager proxy */
|
|
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Manager")))
|
|
{
|
|
ERR("Could not get eldbus proxy");
|
|
goto proxy_err;
|
|
}
|
|
|
|
eldbus_proxy_signal_handler_add(proxy, "SessionRemoved",
|
|
_cb_session_removed, dev);
|
|
|
|
/* try to get the Session proxy */
|
|
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Session")))
|
|
{
|
|
ERR("Could not get eldbus proxy");
|
|
goto proxy_err;
|
|
}
|
|
|
|
eldbus_proxy_signal_handler_add(proxy, "PauseDevice",
|
|
_cb_device_paused, NULL);
|
|
eldbus_proxy_signal_handler_add(proxy, "ResumeDevice",
|
|
_cb_device_resumed, NULL);
|
|
|
|
/* try to get the Properties proxy */
|
|
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.DBus.Properties")))
|
|
{
|
|
ERR("Could not get eldbus proxy");
|
|
goto proxy_err;
|
|
}
|
|
|
|
eldbus_proxy_properties_monitor(proxy, EINA_TRUE);
|
|
eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
|
|
_cb_properties_changed, NULL);
|
|
|
|
return _dbus_init_count;
|
|
|
|
proxy_err:
|
|
eldbus_object_unref(dobj);
|
|
obj_err:
|
|
free(dpath);
|
|
path_err:
|
|
eldbus_connection_unref(dconn);
|
|
conn_err:
|
|
eldbus_shutdown();
|
|
return --_dbus_init_count;
|
|
}
|
|
|
|
int
|
|
_ecore_drm_dbus_shutdown(void)
|
|
{
|
|
if (--_dbus_init_count != 0) return _dbus_init_count;
|
|
|
|
/* release dbus object */
|
|
if (dobj) eldbus_object_unref(dobj);
|
|
|
|
/* release the dbus connection */
|
|
if (dconn) eldbus_connection_unref(dconn);
|
|
|
|
/* shutdown eldbus library */
|
|
eldbus_shutdown();
|
|
|
|
return _dbus_init_count;
|
|
}
|