uvtd: add VT subsystem
authorDavid Herrmann <dh.herrmann@gmail.com>
Tue, 5 Mar 2013 17:03:18 +0000 (18:03 +0100)
committerDavid Herrmann <dh.herrmann@gmail.com>
Tue, 5 Mar 2013 17:03:18 +0000 (18:03 +0100)
The VT subsystem manages the virtual VTs and registers them with the
seat/session-scheduler. They manage control and legacy nodes as they are
mostly the same.

The different contexts create these VTs and assign them to cdev clients.
This allows us to split the VT and cdev logic apart so they can be
assigned freely to different clients.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Makefile.am
src/uvtd_vt.c [new file with mode: 0644]
src/uvtd_vt.h [new file with mode: 0644]

index 03e62c8..44787f9 100644 (file)
@@ -700,6 +700,8 @@ uvtd_SOURCES = \
        src/uvtd_main.c \
        src/uvtd_ctx.h \
        src/uvtd_ctx.c \
+       src/uvtd_vt.h \
+       src/uvtd_vt.c \
        src/uvtd_seat.h \
        src/uvtd_seat.c
 uvtd_CPPFLAGS = \
diff --git a/src/uvtd_vt.c b/src/uvtd_vt.c
new file mode 100644 (file)
index 0000000..78ba70e
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * uvtd - User-space VT daemon
+ *
+ * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Virtual Terminals
+ * Every virtual terminal forms a session inside of uvtd. Sessions are scheduled
+ * by the seat/session-scheduler and notified whenever they get active/inactive.
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include "shl_hook.h"
+#include "shl_log.h"
+#include "uvt.h"
+#include "uvtd_seat.h"
+#include "uvtd_vt.h"
+
+#define LOG_SUBSYSTEM "vt"
+
+struct uvtd_vt {
+       unsigned long ref;
+       struct uvt_ctx *uctx;
+       struct shl_hook *hook;
+       struct uvtd_session *session;
+       bool is_legacy;
+};
+
+static void vt_hup(struct uvtd_vt *vt)
+{
+       struct uvt_vt_event ev;
+
+       memset(&ev, 0, sizeof(ev));
+       ev.type = UVT_VT_HUP;
+
+       shl_hook_call(vt->hook, vt, &ev);
+}
+
+static int vt_session_event(struct uvtd_session *session, unsigned int event,
+                           void *data)
+{
+       struct uvtd_vt *vt = data;
+
+       switch (event) {
+       case UVTD_SESSION_UNREGISTER:
+               vt->session = NULL;
+               vt_hup(vt);
+               break;
+       case UVTD_SESSION_ACTIVATE:
+               log_debug("activate %p", vt);
+               break;
+       case UVTD_SESSION_DEACTIVATE:
+               log_debug("deactivate %p", vt);
+               break;
+       }
+
+       return 0;
+}
+
+int uvtd_vt_new(struct uvtd_vt **out, struct uvt_ctx *uctx, unsigned int id,
+               struct uvtd_seat *seat, bool is_legacy)
+{
+       struct uvtd_vt *vt;
+       int ret;
+
+       if (!out || !uctx)
+               return -EINVAL;
+
+       vt = malloc(sizeof(*vt));
+       if (!vt)
+               return -ENOMEM;
+
+       memset(vt, 0, sizeof(*vt));
+       vt->ref = 1;
+       vt->uctx = uctx;
+       vt->is_legacy = is_legacy;
+
+       ret = shl_hook_new(&vt->hook);
+       if (ret)
+               goto err_free;
+
+       ret = uvtd_seat_register_session(seat, &vt->session, id,
+                                        vt_session_event, vt);
+       if (ret)
+               goto err_hook;
+
+       uvt_ctx_ref(vt->uctx);
+       *out = vt;
+       return 0;
+
+err_hook:
+       shl_hook_free(vt->hook);
+err_free:
+       free(vt);
+       return ret;
+}
+
+void uvtd_vt_ref(struct uvtd_vt *vt)
+{
+       if (!vt || !vt->ref)
+               return;
+
+       ++vt->ref;
+}
+
+void uvtd_vt_unref(struct uvtd_vt *vt)
+{
+       if (!vt || !vt->ref || --vt->ref)
+               return;
+
+       uvtd_session_unregister(vt->session);
+       shl_hook_free(vt->hook);
+       uvt_ctx_unref(vt->uctx);
+       free(vt);
+}
+
+int uvtd_vt_register_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data)
+{
+       if (!vt)
+               return -EINVAL;
+
+       return shl_hook_add_cast(vt->hook, cb, data, false);
+}
+
+void uvtd_vt_unregister_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data)
+{
+       if (!vt)
+               return;
+
+       shl_hook_rm_cast(vt->hook, cb, data);
+}
+
+int uvtd_vt_read(struct uvtd_vt *vt, uint8_t *mem, size_t len)
+{
+       return -EAGAIN;
+}
+
+int uvtd_vt_write(struct uvtd_vt *vt, const uint8_t *mem, size_t len)
+{
+       return len;
+}
+
+unsigned int uvtd_vt_poll(struct uvtd_vt *vt)
+{
+       return UVT_TTY_WRITE;
+}
+
+/* compatibility to UVT-VT ops */
+
+static void vt_ref(void *vt)
+{
+       uvtd_vt_ref(vt);
+}
+
+static void vt_unref(void *vt)
+{
+       uvtd_vt_unref(vt);
+}
+
+static int vt_register_cb(void *vt, uvt_vt_cb cb, void *data)
+{
+       return uvtd_vt_register_cb(vt, cb, data);
+}
+
+static void vt_unregister_cb(void *vt, uvt_vt_cb cb, void *data)
+{
+       uvtd_vt_register_cb(vt, cb, data);
+}
+
+static int vt_read(void *vt, uint8_t *mem, size_t len)
+{
+       return uvtd_vt_read(vt, mem, len);
+}
+
+static int vt_write(void *vt, const uint8_t *mem, size_t len)
+{
+       return uvtd_vt_write(vt, mem, len);
+}
+
+static unsigned int vt_poll(void *vt)
+{
+       return uvtd_vt_poll(vt);
+}
+
+struct uvt_vt_ops uvtd_vt_ops = {
+       .ref = vt_ref,
+       .unref = vt_unref,
+       .register_cb = vt_register_cb,
+       .unregister_cb = vt_unregister_cb,
+       .read = vt_read,
+       .write = vt_write,
+       .poll = vt_poll,
+};
diff --git a/src/uvtd_vt.h b/src/uvtd_vt.h
new file mode 100644 (file)
index 0000000..fe83671
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * uvtd - User-space VT daemon
+ *
+ * Copyright (c) 2013 David Herrmann <dh.herrmann@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Virtual Terminals
+ * Every virtual terminal forms a session inside of uvtd. Sessions are scheduled
+ * by the seat/session-scheduler and notified whenever they get active/inactive.
+ */
+
+#ifndef UVTD_VT_H
+#define UVTD_VT_H
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include "uvt.h"
+
+struct uvtd_vt;
+extern struct uvt_vt_ops uvtd_vt_ops;
+
+int uvtd_vt_new(struct uvtd_vt **out, struct uvt_ctx *uctx, unsigned int id,
+               struct uvtd_seat *seat, bool is_legacy);
+void uvtd_vt_ref(struct uvtd_vt *vt);
+void uvtd_vt_unref(struct uvtd_vt *vt);
+
+int uvtd_vt_register_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data);
+void uvtd_vt_unregister_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data);
+
+int uvtd_vt_read(struct uvtd_vt *vt, uint8_t *mem, size_t len);
+int uvtd_vt_write(struct uvtd_vt *vt, const uint8_t *mem, size_t len);
+unsigned int uvtd_vt_poll(struct uvtd_vt *vt);
+
+#endif /* UVTD_VT_H */