1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include "bus-errors.h"
30 #include "logind-seat.h"
32 static int property_get_active_session(
35 const char *interface
,
37 sd_bus_message
*reply
,
39 sd_bus_error
*error
) {
41 _cleanup_free_
char *p
= NULL
;
48 p
= s
->active
? session_bus_path(s
->active
) : strdup("/");
52 return sd_bus_message_append(reply
, "(so)", s
->active
? s
->active
->id
: "", p
);
55 static int property_get_can_multi_session(
58 const char *interface
,
60 sd_bus_message
*reply
,
62 sd_bus_error
*error
) {
70 return sd_bus_message_append(reply
, "b", seat_can_multi_session(s
));
73 static int property_get_can_tty(
76 const char *interface
,
78 sd_bus_message
*reply
,
80 sd_bus_error
*error
) {
88 return sd_bus_message_append(reply
, "b", seat_can_tty(s
));
91 static int property_get_can_graphical(
94 const char *interface
,
96 sd_bus_message
*reply
,
98 sd_bus_error
*error
) {
106 return sd_bus_message_append(reply
, "b", seat_can_tty(s
));
109 static int property_get_sessions(
112 const char *interface
,
113 const char *property
,
114 sd_bus_message
*reply
,
116 sd_bus_error
*error
) {
126 r
= sd_bus_message_open_container(reply
, 'a', "(so)");
130 LIST_FOREACH(sessions_by_seat
, session
, s
->sessions
) {
131 _cleanup_free_
char *p
= NULL
;
133 p
= session_bus_path(session
);
137 r
= sd_bus_message_append(reply
, "(so)", session
->id
, p
);
143 r
= sd_bus_message_close_container(reply
);
150 static int property_get_idle_hint(
153 const char *interface
,
154 const char *property
,
155 sd_bus_message
*reply
,
157 sd_bus_error
*error
) {
165 return sd_bus_message_append(reply
, "b", seat_get_idle_hint(s
, NULL
) > 0);
168 static int property_get_idle_since_hint(
171 const char *interface
,
172 const char *property
,
173 sd_bus_message
*reply
,
175 sd_bus_error
*error
) {
186 r
= seat_get_idle_hint(s
, &t
);
190 u
= streq(property
, "IdleSinceHint") ? t
.realtime
: t
.monotonic
;
192 return sd_bus_message_append(reply
, "t", u
);
195 static int method_terminate(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
203 r
= seat_stop_sessions(s
);
207 return sd_bus_reply_method_return(message
, NULL
);
210 static int method_activate_session(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
220 r
= sd_bus_message_read(message
, "s", &name
);
224 session
= hashmap_get(s
->manager
->sessions
, name
);
226 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SESSION
, "No session '%s' known", name
);
228 if (session
->seat
!= s
)
229 return sd_bus_error_setf(error
, BUS_ERROR_SESSION_NOT_ON_SEAT
, "Session %s not on seat %s", name
, s
->id
);
231 r
= session_activate(session
);
235 return sd_bus_reply_method_return(message
, NULL
);
238 const sd_bus_vtable seat_vtable
[] = {
239 SD_BUS_VTABLE_START(0),
241 SD_BUS_PROPERTY("Id", "s", NULL
, offsetof(Seat
, id
), 0),
242 SD_BUS_PROPERTY("ActiveSession", "(so)", property_get_active_session
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
243 SD_BUS_PROPERTY("CanMultiSession", "b", property_get_can_multi_session
, 0, 0),
244 SD_BUS_PROPERTY("CanTTY", "b", property_get_can_tty
, 0, 0),
245 SD_BUS_PROPERTY("CanGraphical", "b", property_get_can_graphical
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
246 SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
247 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
248 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
249 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
251 SD_BUS_METHOD("Terminate", NULL
, NULL
, method_terminate
, 0),
252 SD_BUS_METHOD("ActivateSession", "s", NULL
, method_activate_session
, 0),
257 int seat_object_find(sd_bus
*bus
, const char *path
, const char *interface
, void **found
, void *userdata
) {
258 Manager
*m
= userdata
;
268 if (streq(path
, "/org/freedesktop/login1/seat/self")) {
269 sd_bus_message
*message
;
273 message
= sd_bus_get_current(bus
);
277 r
= sd_bus_get_owner_pid(bus
, sd_bus_message_get_sender(message
), &pid
);
281 r
= manager_get_session_by_pid(m
, pid
, &session
);
288 seat
= session
->seat
;
290 _cleanup_free_
char *e
= NULL
;
293 p
= startswith(path
, "/org/freedesktop/login1/seat/");
297 e
= sd_bus_label_unescape(p
);
301 seat
= hashmap_get(m
->seats
, e
);
310 char *seat_bus_path(Seat
*s
) {
311 _cleanup_free_
char *t
= NULL
;
315 t
= sd_bus_label_escape(s
->id
);
319 return strappend("/org/freedesktop/login1/seat/", t
);
322 int seat_node_enumerator(sd_bus
*bus
, const char *path
, char ***nodes
, void *userdata
) {
323 _cleanup_strv_free_
char **l
= NULL
;
324 Manager
*m
= userdata
;
333 HASHMAP_FOREACH(seat
, m
->seats
, i
) {
336 p
= seat_bus_path(seat
);
340 r
= strv_push(&l
, p
);
353 int seat_send_signal(Seat
*s
, bool new_seat
) {
354 _cleanup_free_
char *p
= NULL
;
358 p
= seat_bus_path(s
);
362 return sd_bus_emit_signal(
364 "/org/freedesktop/login1",
365 "org.freedesktop.login1.Manager",
366 new_seat
? "SeatNew" : "SeatRemoved",
370 int seat_send_changed(Seat
*s
, const char *properties
, ...) {
371 _cleanup_free_
char *p
= NULL
;
379 p
= seat_bus_path(s
);
383 l
= strv_from_stdarg_alloca(properties
);
385 return sd_bus_emit_properties_changed_strv(s
->manager
->bus
, p
, "org.freedesktop.login1.Seat", l
);