const DBusObjectPathVTable bus_manager_vtable = {
.message_function = manager_message_handler
};
+
+int manager_send_changed(Manager *manager, const char *properties) {
+ DBusMessage *m;
+ int r = -ENOMEM;
+
+ assert(manager);
+
+ m = bus_properties_changed_new("/org/freedesktop/login1", "org.freedesktop.login1.Manager", properties);
+ if (!m)
+ goto finish;
+
+ if (!dbus_connection_send(manager->bus, m, NULL))
+ goto finish;
+
+ r = 0;
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ return r;
+}
return r;
}
+
+int seat_send_changed(Seat *s, const char *properties) {
+ DBusMessage *m;
+ int r = -ENOMEM;
+ char *p = NULL;
+
+ assert(s);
+
+ 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;
+}
return r;
}
+int seat_set_active(Seat *s, Session *session) {
+ Session *old_active;
+
+ assert(s);
+ assert(session);
+ assert(session->seat == s);
+
+ if (session == s->active)
+ return 0;
+
+ old_active = s->active;
+ s->active = session;
+
+ seat_apply_acls(s, old_active);
+
+ if (session && session->started)
+ session_send_changed(session, "Active\0");
+
+ if (!session || session->started)
+ seat_send_changed(s, "ActiveSession\0");
+
+ return 0;
+}
+
int seat_active_vt_changed(Seat *s, int vtnr) {
- Session *i, *new_active = NULL, *old_active;
+ Session *i, *new_active = NULL;
+ int r;
assert(s);
assert(vtnr >= 1);
break;
}
- if (new_active == s->active)
- return 0;
-
- old_active = s->active;
- s->active = new_active;
-
- seat_apply_acls(s, old_active);
+ r = seat_set_active(s, new_active);
manager_spawn_autovt(s->manager, vtnr);
- return 0;
+ return r;
}
int seat_read_active_vt(Seat *s) {
assert(session);
assert(!session->seat);
- if (!seat_is_vtconsole(s)) {
- if (s->sessions)
- return -EEXIST;
-
- assert(!s->active);
- s->active = session;
- }
+ if (!seat_is_vtconsole(s) && s->sessions)
+ return -EEXIST;
session->seat = s;
LIST_PREPEND(Session, sessions_by_seat, s->sessions, session);
+ seat_send_changed(s, "Sessions\0");
+
+ if (!seat_is_vtconsole(s)) {
+ assert(!s->active);
+ seat_set_active(s, session);
+ }
+
return 0;
}
int seat_load(Seat *s);
int seat_apply_acls(Seat *s, Session *old_active);
+int seat_set_active(Seat *s, Session *session);
int seat_active_vt_changed(Seat *s, int vtnr);
int seat_read_active_vt(Seat *s);
extern const DBusObjectPathVTable bus_seat_vtable;
int seat_send_signal(Seat *s, bool new_seat);
+int seat_send_changed(Seat *s, const char *properties);
#endif
return r;
}
+
+int session_send_changed(Session *s, const char *properties) {
+ DBusMessage *m;
+ int r = -ENOMEM;
+ char *p = NULL;
+
+ assert(s);
+
+ p = session_bus_path(s);
+ if (!p)
+ return -ENOMEM;
+
+ m = bus_properties_changed_new(p, "org.freedesktop.login1.Session", 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;
+}
s->user->display = NULL;
}
- if (s->seat)
+ if (s->seat) {
+ if (s->seat->active == s)
+ s->seat->active = NULL;
+
LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s);
+ }
free(s->cgroup_path);
strv_free(s->controllers);
s->kill_processes = k;
}
- if (seat) {
+ if (seat && !s->seat) {
Seat *o;
o = hashmap_get(s->manager->seats, seat);
assert(s);
assert(s->user);
+ if (s->started)
+ return 0;
+
/* Create cgroup */
r = session_create_cgroup(s);
if (r < 0)
dual_timestamp_get(&s->timestamp);
+ s->started = true;
+
session_send_signal(s, true);
+ if (s->seat) {
+ if (s->seat->active == s)
+ seat_send_changed(s->seat, "Sessions\0ActiveSession\0");
+ else
+ seat_send_changed(s->seat, "Sessions\0");
+ }
+
+ user_send_changed(s->user, "Sessions\0");
+
return 0;
}
assert(s);
- session_send_signal(s, false);
+ if (!s->started)
+ return 0;
/* Kill cgroup */
k = session_kill_cgroup(s);
unlink(s->state_file);
session_add_to_gc_queue(s);
+ session_send_signal(s, false);
+
+ if (s->seat) {
+ if (s->seat->active == s)
+ seat_set_active(s->seat, NULL);
+
+ seat_send_changed(s->seat, "Sessions\0");
+ }
+
+ user_send_changed(s->user, "Sessions\0");
+
+ s->started = false;
+
return r;
}
s->idle_hint = b;
dual_timestamp_get(&s->idle_hint_timestamp);
+
+ session_send_changed(s,
+ "IdleHint\0"
+ "IdleSinceHint\0"
+ "IdleSinceHintMonotonic\0");
+
+ if (s->seat)
+ seat_send_changed(s->seat,
+ "IdleHint\0"
+ "IdleSinceHint\0"
+ "IdleSinceHintMonotonic\0");
+
+ user_send_changed(s->user,
+ "IdleHint\0"
+ "IdleSinceHint\0"
+ "IdleSinceHintMonotonic\0");
+
+ manager_send_changed(s->manager,
+ "IdleHint\0"
+ "IdleSinceHint\0"
+ "IdleSinceHintMonotonic\0");
}
int session_check_gc(Session *s) {
bool kill_processes;
bool in_gc_queue:1;
+ bool started:1;
LIST_FIELDS(Session, sessions_by_user);
LIST_FIELDS(Session, sessions_by_seat);
extern const DBusObjectPathVTable bus_session_vtable;
int session_send_signal(Session *s, bool new_session);
+int session_send_changed(Session *s, const char *properties);
const char* session_type_to_string(SessionType t);
SessionType session_type_from_string(const char *s);
return r;
}
+
+int user_send_changed(User *u, const char *properties) {
+ DBusMessage *m;
+ int r = -ENOMEM;
+ char *p = NULL;
+
+ assert(u);
+
+ p = user_bus_path(u);
+ if (!p)
+ return -ENOMEM;
+
+ m = bus_properties_changed_new(p, "org.freedesktop.login1.User", properties);
+ if (!m)
+ goto finish;
+
+ if (!dbus_connection_send(u->manager->bus, m, NULL))
+ goto finish;
+
+ r = 0;
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+ free(p);
+
+ return r;
+}
assert(u);
+ if (u->started)
+ return 0;
+
/* Make XDG_RUNTIME_DIR */
r = user_mkdir_runtime_path(u);
if (r < 0)
dual_timestamp_get(&u->timestamp);
+ u->started = true;
+
user_send_signal(u, true);
return 0;
int r = 0, k;
assert(u);
+ if (!u->started)
+ return 0;
+
LIST_FOREACH(sessions_by_user, s, u->sessions) {
k = session_stop(s);
if (k < 0)
unlink(u->state_file);
user_add_to_gc_queue(u);
+ u->started = false;
+
return r;
}
dual_timestamp timestamp;
bool in_gc_queue:1;
+ bool started:1;
LIST_HEAD(Session, sessions);
LIST_FIELDS(User, gc_queue);
extern const DBusObjectPathVTable bus_user_vtable;
int user_send_signal(User *u, bool new_user);
+int user_send_changed(User *u, const char *properties);
const char* user_state_to_string(UserState s);
UserState user_state_from_string(const char *s);
return idle_hint;
}
-
int manager_startup(Manager *m) {
int r;
Seat *seat;
extern const DBusObjectPathVTable bus_manager_vtable;
+int manager_send_changed(Manager *manager, const char *properties);
+
#endif