X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogind-seat-dbus.c;h=669e83e82d5e035ee32fbd2e805ec87387e92acb;hp=4937d65f745adc60f78c6e30baf7f9e248b1d12c;hb=e6a6b406791a76ca979ff5e615fd4d9a986a14b8;hpb=f401e48c2db22ff9d1a05885b5599bebf19c2707 diff --git a/src/logind-seat-dbus.c b/src/logind-seat-dbus.c index 4937d65f7..669e83e82 100644 --- a/src/logind-seat-dbus.c +++ b/src/logind-seat-dbus.c @@ -20,6 +20,7 @@ ***/ #include +#include #include "logind.h" #include "logind-seat.h" @@ -36,6 +37,9 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ #define INTROSPECTION \ @@ -98,7 +102,7 @@ static int bus_seat_append_sessions(DBusMessageIter *i, const char *property, vo assert(property); assert(s); - if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "so", &sub)) + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(so)", &sub)) return -ENOMEM; LIST_FOREACH(sessions_by_seat, session, s->sessions) { @@ -129,7 +133,6 @@ static int bus_seat_append_sessions(DBusMessageIter *i, const char *property, vo return 0; } - static int bus_seat_append_can_activate(DBusMessageIter *i, const char *property, void *data) { Seat *s = data; dbus_bool_t b; @@ -138,7 +141,7 @@ static int bus_seat_append_can_activate(DBusMessageIter *i, const char *property assert(property); assert(s); - b = s->manager->vtconsole == s; + b = seat_is_vtconsole(s); if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) return -ENOMEM; @@ -146,6 +149,39 @@ static int bus_seat_append_can_activate(DBusMessageIter *i, const char *property return 0; } +static int bus_seat_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(s); + + b = seat_get_idle_hint(s, NULL) > 0; + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dual_timestamp t; + uint64_t k; + + assert(i); + assert(property); + assert(s); + + seat_get_idle_hint(s, &t); + k = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &k)) + return -ENOMEM; + + return 0; +} + static int get_seat_for_path(Manager *m, const char *path, Seat **_s) { Seat *s; char *id; @@ -181,14 +217,73 @@ static DBusHandlerResult seat_message_dispatch( { "org.freedesktop.login1.Seat", "ActiveSession", bus_seat_append_active, "(so)", s }, { "org.freedesktop.login1.Seat", "CanActivateSessions", bus_seat_append_can_activate, "b", s }, { "org.freedesktop.login1.Seat", "Sessions", bus_seat_append_sessions, "a(so)", s }, + { "org.freedesktop.login1.Seat", "IdleHint", bus_seat_append_idle_hint, "b", s }, + { "org.freedesktop.login1.Seat", "IdleSinceHint", bus_seat_append_idle_hint_since, "t", s }, + { "org.freedesktop.login1.Seat", "IdleSinceHintMonotonic", bus_seat_append_idle_hint_since, "t", s }, { NULL, NULL, NULL, NULL, NULL } }; + DBusError error; + DBusMessage *reply = NULL; + int r; + assert(s); assert(connection); assert(message); - return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties); + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Seat", "Terminate")) { + + r = seat_stop_sessions(s); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Seat", "ActivateSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(s->manager->sessions, name); + if (!session || session->seat != s) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = session_activate(session); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties); + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; } static DBusHandlerResult seat_message_handler( @@ -238,3 +333,71 @@ char *seat_bus_path(Seat *s) { return r; } + +int seat_send_signal(Seat *s, bool new_seat) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + m = dbus_message_new_signal("/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + new_seat ? "SeatNew" : "SeatRemoved"); + + if (!m) + return -ENOMEM; + + p = seat_bus_path(s); + if (!p) + goto finish; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &s->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + dbus_message_unref(m); + free(p); + + return r; +} + +int seat_send_changed(Seat *s, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + if (!s->started) + return 0; + + p = seat_bus_path(s); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.Seat", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +}