chiark / gitweb /
terminal: allow user-context to be retrieved/stored
[elogind.git] / src / libsystemd-terminal / sysview.c
index fde87d11174b73bdc09a46114a812cb105e99064..208c6ce25c3661494bc59752354234ea35cfe40a 100644 (file)
@@ -104,6 +104,12 @@ sysview_device *sysview_device_free(sysview_device *device) {
         return NULL;
 }
 
+const char *sysview_device_get_name(sysview_device *device) {
+        assert_return(device, NULL);
+
+        return device->name;
+}
+
 unsigned int sysview_device_get_type(sysview_device *device) {
         assert_return(device, (unsigned)-1);
 
@@ -243,6 +249,18 @@ sysview_session *sysview_session_free(sysview_session *session) {
         return NULL;
 }
 
+void sysview_session_set_userdata(sysview_session *session, void *userdata) {
+        assert(session);
+
+        session->userdata = userdata;
+}
+
+void *sysview_session_get_userdata(sysview_session *session) {
+        assert_return(session, NULL);
+
+        return session->userdata;
+}
+
 const char *sysview_session_get_name(sysview_session *session) {
         assert_return(session, NULL);
 
@@ -517,6 +535,19 @@ static int context_raise_session_detach(sysview_context *c, sysview_session *ses
         return context_raise(c, &event, 0);
 }
 
+static int context_raise_session_refresh(sysview_context *c, sysview_session *session, sysview_device *device, struct udev_device *ud) {
+        sysview_event event = {
+                .type = SYSVIEW_EVENT_SESSION_REFRESH,
+                .session_refresh = {
+                        .session = session,
+                        .device = device,
+                        .ud = ud,
+                }
+        };
+
+        return context_raise(c, &event, 0);
+}
+
 static int context_add_device(sysview_context *c, sysview_device *device) {
         sysview_session *session;
         int r, error = 0;
@@ -569,6 +600,31 @@ static int context_remove_device(sysview_context *c, sysview_device *device) {
         return error;
 }
 
+static int context_change_device(sysview_context *c, sysview_device *device, struct udev_device *ud) {
+        sysview_session *session;
+        int r, error = 0;
+        Iterator i;
+
+        assert(c);
+        assert(device);
+
+        log_debug("sysview: change device '%s'", device->name);
+
+        HASHMAP_FOREACH(session, device->seat->session_map, i) {
+                if (!session->public)
+                        continue;
+
+                r = context_raise_session_refresh(c, session, device, ud);
+                if (r != 0)
+                        error = r;
+        }
+
+        if (error < 0)
+                log_debug("sysview: error while changing device '%s': %s",
+                          device->name, strerror(-r));
+        return error;
+}
+
 static int context_add_session(sysview_context *c, sysview_seat *seat, const char *id) {
         sysview_session *session;
         sysview_device *device;
@@ -872,7 +928,7 @@ static int context_ud_hotplug(sysview_context *c, struct udev_device *d) {
                 if (!device)
                         return 0;
 
-                /* TODO: send REFRESH event */
+                return context_change_device(c, device, d);
         } else if (!action || streq_ptr(action, "add")) {
                 struct udev_device *p;
                 unsigned int type, t;
@@ -883,7 +939,7 @@ static int context_ud_hotplug(sysview_context *c, struct udev_device *d) {
 
                 if (streq(subsystem, "input") && startswith(sysname, "event") && safe_atou(sysname + 5, &t) >= 0)
                         type = SYSVIEW_DEVICE_EVDEV;
-                else if (streq(subsystem, "drm") && startswith(sysname, "card") && safe_atou(sysname + 4, &t) >= 0)
+                else if (streq(subsystem, "drm") && startswith(sysname, "card"))
                         type = SYSVIEW_DEVICE_DRM;
                 else
                         type = (unsigned)-1;
@@ -893,11 +949,11 @@ static int context_ud_hotplug(sysview_context *c, struct udev_device *d) {
 
                 p = d;
                 seatname = NULL;
-                while ((p = udev_device_get_parent(p))) {
+                do {
                         seatname = udev_device_get_property_value(p, "ID_SEAT");
                         if (seatname)
                                 break;
-                }
+                } while ((p = udev_device_get_parent(p)));
 
                 seat = sysview_find_seat(c, seatname ? : "seat0");
                 if (!seat)