diff --git a/man/org.freedesktop.login1.xml b/man/org.freedesktop.login1.xml index 108a47a38da..4cc9f278919 100644 --- a/man/org.freedesktop.login1.xml +++ b/man/org.freedesktop.login1.xml @@ -1075,6 +1075,7 @@ node /org/freedesktop/login1/session/1 { TakeControl(in b force); ReleaseControl(); SetType(in s type); + SetDisplay(in s display); TakeDevice(in u major, in u minor, out h fd, @@ -1172,6 +1173,8 @@ node /org/freedesktop/login1/session/1 { + + @@ -1268,6 +1271,11 @@ node /org/freedesktop/login1/session/1 { connection. This should help prevent a session from entering an inconsistent state, for example if the controller crashes. The only argument type is the new session type. + SetDisplay() allows the display name of the graphical session to be changed. This is + useful if the display server is started as part of the session. It can only be called by session's current + controller. If TakeControl() has not been called, this method will fail. The only argument + display is the new display name. + TakeDevice() allows a session controller to get a file descriptor for a specific device. Pass in the major and minor numbers of the character device and systemd-logind will return a file descriptor for the device. Only a limited set of diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 7d46759822b..539109c5e88 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -413,6 +413,30 @@ static int method_set_type(sd_bus_message *message, void *userdata, sd_bus_error return sd_bus_reply_method_return(message, NULL); } +static int method_set_display(sd_bus_message *message, void *userdata, sd_bus_error *error) { + Session *s = ASSERT_PTR(userdata); + const char *display; + int r; + + assert(message); + + r = sd_bus_message_read(message, "s", &display); + if (r < 0) + return r; + + if (!session_is_controller(s, sd_bus_message_get_sender(message))) + return sd_bus_error_set(error, BUS_ERROR_NOT_IN_CONTROL, "You must be in control of this session to set display"); + + if (!SESSION_TYPE_IS_GRAPHICAL(s->type)) + return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Setting display is only supported for graphical sessions"); + + r = session_set_display(s, display); + if (r < 0) + return r; + + return sd_bus_reply_method_return(message, NULL); +} + static int method_take_device(sd_bus_message *message, void *userdata, sd_bus_error *error) { Session *s = userdata; uint32_t major, minor; @@ -901,6 +925,11 @@ static const sd_bus_vtable session_vtable[] = { SD_BUS_NO_RESULT, method_set_type, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_ARGS("SetDisplay", + SD_BUS_ARGS("s", display), + SD_BUS_NO_RESULT, + method_set_display, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_ARGS("TakeDevice", SD_BUS_ARGS("u", major, "u", minor), SD_BUS_RESULT("h", fd, "b", inactive), diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 4995e5885aa..ac3904352e9 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -1044,6 +1044,26 @@ void session_set_type(Session *s, SessionType t) { session_send_changed(s, "Type", NULL); } +int session_set_display(Session *s, const char *display) { + int r; + + assert(s); + assert(display); + + if (streq(s->display, display)) + return 0; + + r = free_and_strdup(&s->display, display); + if (r < 0) + return r; + + session_save(s); + + session_send_changed(s, "Display", NULL); + + return 1; +} + static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) { Session *s = userdata; diff --git a/src/login/logind-session.h b/src/login/logind-session.h index 5c35071dc52..6b6ac2d573f 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -137,6 +137,7 @@ int session_set_idle_hint(Session *s, bool b); int session_get_locked_hint(Session *s); void session_set_locked_hint(Session *s, bool b); void session_set_type(Session *s, SessionType t); +int session_set_display(Session *s, const char *display); int session_create_fifo(Session *s); int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error); int session_stop(Session *s, bool force); diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf index 95d2ef0f063..6113b64aa7e 100644 --- a/src/login/org.freedesktop.login1.conf +++ b/src/login/org.freedesktop.login1.conf @@ -346,6 +346,10 @@ send_interface="org.freedesktop.login1.User" send_member="Kill"/> + +