summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2012-08-12 09:11:35 +0200
committerDavid Herrmann <dh.herrmann@googlemail.com>2012-08-12 09:11:35 +0200
commit1101a6b5c3989d39260032c4792c9caf45088a7a (patch)
tree6061aa5bd6ef1c0870eb295da09bbbce79cd1287
parent891400ad9140f31ff69bbe2bb85023271281bf16 (diff)
uterm: vt: move all vt.h/c code into uterm_vt.c
This merges both files so we can reduce the code overhead here. This is still some very old code that was never correctly merged into new uterm_vt.c subsystem. This should help doing it now. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
-rw-r--r--Makefile.am6
-rw-r--r--src/main.c1
-rw-r--r--src/uterm_vt.c390
-rw-r--r--src/vt.c439
-rw-r--r--src/vt.h69
5 files changed, 391 insertions, 514 deletions
diff --git a/Makefile.am b/Makefile.am
index 5be4414..7859b02 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -176,13 +176,11 @@ libuterm_la_SOURCES = \
src/uterm_internal.h \
src/uterm_video.c \
src/uterm_monitor.c \
+ src/uterm_vt.c \
src/uterm_input.c \
src/uterm_input_plain.c \
external/imKStoUCS.h \
- external/imKStoUCS.c \
- src/uterm_vt.c \
- src/vt.h \
- src/vt.c
+ external/imKStoUCS.c
libuterm_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
diff --git a/src/main.c b/src/main.c
index 76fb2b8..ad1e04e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -39,7 +39,6 @@
#include "text.h"
#include "ui.h"
#include "uterm.h"
-#include "vt.h"
struct kmscon_app {
struct ev_eloop *eloop;
diff --git a/src/uterm_vt.c b/src/uterm_vt.c
index 9f62f42..8c6d319 100644
--- a/src/uterm_vt.c
+++ b/src/uterm_vt.c
@@ -28,19 +28,407 @@
*/
#include <errno.h>
+#include <fcntl.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include <signal.h>
#include <stdbool.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/signalfd.h>
+#include <termios.h>
#include <unistd.h>
#include "eloop.h"
#include "log.h"
#include "static_misc.h"
#include "uterm.h"
#include "uterm_internal.h"
-#include "vt.h"
#define LOG_SUBSYSTEM "vt"
+struct kmscon_vt;
+
+enum kmscon_vt_action {
+ KMSCON_VT_ENTER,
+ KMSCON_VT_LEAVE,
+};
+
+enum kmscon_vt_id {
+ KMSCON_VT_CUR = 0,
+ KMSCON_VT_NEW = -1,
+};
+
+typedef bool (*kmscon_vt_cb) (struct kmscon_vt *vt,
+ enum kmscon_vt_action action,
+ void *data);
+
+void kmscon_vt_close(struct kmscon_vt *vt);
+
+struct kmscon_vt {
+ unsigned long ref;
+
+ int fd;
+ int num;
+ int saved_num;
+ struct termios saved_attribs;
+ kmscon_vt_cb cb;
+ void *data;
+
+ struct ev_eloop *eloop;
+ struct ev_fd *efd;
+};
+
+int kmscon_vt_new(struct kmscon_vt **out, kmscon_vt_cb cb, void *data)
+{
+ struct kmscon_vt *vt;
+
+ if (!out)
+ return -EINVAL;
+
+ vt = malloc(sizeof(*vt));
+ if (!vt)
+ return -ENOMEM;
+
+ memset(vt, 0, sizeof(*vt));
+ vt->ref = 1;
+ vt->fd = -1;
+ vt->num = -1;
+ vt->saved_num = -1;
+ vt->cb = cb;
+ vt->data = data;
+
+ log_debug("new vt object %p", vt);
+ *out = vt;
+ return 0;
+}
+
+void kmscon_vt_ref(struct kmscon_vt *vt)
+{
+ if (!vt)
+ return;
+
+ ++vt->ref;
+}
+
+void kmscon_vt_unref(struct kmscon_vt *vt)
+{
+ if (!vt || !vt->ref || --vt->ref)
+ return;
+
+ log_debug("free vt object %p", vt);
+ kmscon_vt_close(vt);
+ free(vt);
+}
+
+static void vt_enter(struct ev_eloop *eloop, struct signalfd_siginfo *info,
+ void *data)
+{
+ struct kmscon_vt *vt = data;
+ struct vt_stat vts;
+ int ret;
+
+ if (!vt || vt->fd < 0)
+ return;
+
+ ret = ioctl(vt->fd, VT_GETSTATE, &vts);
+ if (ret || vts.v_active != vt->num)
+ return;
+
+ log_debug("enter VT %d %p", vt->num, vt);
+
+ ioctl(vt->fd, VT_RELDISP, VT_ACKACQ);
+
+ if (ioctl(vt->fd, KDSETMODE, KD_GRAPHICS))
+ log_warn("cannot set graphics mode on vt %p", vt);
+
+ if (vt->cb)
+ vt->cb(vt, KMSCON_VT_ENTER, vt->data);
+}
+
+static void vt_leave(struct ev_eloop *eloop, struct signalfd_siginfo *info,
+ void *data)
+{
+ struct kmscon_vt *vt = data;
+ struct vt_stat vts;
+ int ret;
+
+ if (!vt || vt->fd < 0)
+ return;
+
+ ret = ioctl(vt->fd, VT_GETSTATE, &vts);
+ if (ret || vts.v_active != vt->num)
+ return;
+
+ if (vt->cb && !vt->cb(vt, KMSCON_VT_LEAVE, vt->data)) {
+ log_debug("leaving VT %d %p denied", vt->num, vt);
+ ioctl(vt->fd, VT_RELDISP, 0);
+ } else {
+ log_debug("leaving VT %d %p", vt->num, vt);
+ ioctl(vt->fd, VT_RELDISP, 1);
+ if (ioctl(vt->fd, KDSETMODE, KD_TEXT))
+ log_warn("cannot set text mode on vt %p", vt);
+ }
+}
+
+static void vt_input(struct ev_fd *fd, int mask, void *data)
+{
+ struct kmscon_vt *vt = data;
+
+ if (!vt || vt->fd < 0)
+ return;
+
+ /* we ignore input from the VT because we get it from evdev */
+ tcflush(vt->fd, TCIFLUSH);
+}
+
+static int connect_eloop(struct kmscon_vt *vt, struct ev_eloop *eloop)
+{
+ int ret;
+
+ if (!vt || !eloop || vt->fd < 0)
+ return -EINVAL;
+
+ ret = ev_eloop_register_signal_cb(eloop, SIGUSR1, vt_leave, vt);
+ if (ret)
+ return ret;
+
+ ret = ev_eloop_register_signal_cb(eloop, SIGUSR2, vt_enter, vt);
+ if (ret)
+ goto err_sig1;
+
+ ret = ev_eloop_new_fd(eloop, &vt->efd, vt->fd, EV_READABLE,
+ vt_input, vt);
+ if (ret)
+ goto err_sig2;
+
+ vt->eloop = eloop;
+ ev_eloop_ref(vt->eloop);
+ return 0;
+
+err_sig2:
+ ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR2, vt_enter, vt);
+err_sig1:
+ ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR1, vt_leave, vt);
+ return ret;
+}
+
+static void disconnect_eloop(struct kmscon_vt *vt)
+{
+ if (!vt)
+ return;
+
+ ev_eloop_rm_fd(vt->efd);
+ ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR2, vt_enter, vt);
+ ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR1, vt_leave, vt);
+ ev_eloop_unref(vt->eloop);
+ vt->efd = NULL;
+ vt->eloop = NULL;
+}
+
+static int open_tty(int id, int *tty_fd, int *tty_num)
+{
+ int fd;
+ char filename[16];
+
+ if (!tty_fd || !tty_num)
+ return -EINVAL;
+
+ if (id == KMSCON_VT_NEW) {
+ fd = open("/dev/tty0", O_NONBLOCK | O_NOCTTY | O_CLOEXEC);
+ if (fd < 0) {
+ fd = open("/dev/tty1",
+ O_NONBLOCK | O_NOCTTY | O_CLOEXEC);
+ if (fd < 0) {
+ log_err("cannot find parent tty");
+ return -errno;
+ }
+ }
+
+ if (ioctl(fd, VT_OPENQRY, &id) || id <= 0) {
+ close(fd);
+ log_err("cannot get unused tty");
+ return -EINVAL;
+ }
+ close(fd);
+ }
+
+ snprintf(filename, sizeof(filename), "/dev/tty%d", id);
+ filename[sizeof(filename) - 1] = 0;
+ log_notice("using tty %s", filename);
+
+ fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC);
+ if (fd < 0) {
+ log_err("cannot open tty %s", filename);
+ return -errno;
+ }
+
+ *tty_fd = fd;
+ *tty_num = id;
+ return 0;
+}
+
+int kmscon_vt_open(struct kmscon_vt *vt, int id, struct ev_eloop *eloop)
+{
+ struct termios raw_attribs;
+ struct vt_mode mode;
+ struct vt_stat vts;
+ int ret;
+ sigset_t mask;
+
+ if (vt->fd >= 0)
+ return -EALREADY;
+
+ log_debug("open vt %p", vt);
+
+ ret = open_tty(id, &vt->fd, &vt->num);
+ if (ret)
+ return ret;
+
+ ret = connect_eloop(vt, eloop);
+ if (ret)
+ goto err_fd;
+
+ /*
+ * Get the number of the VT which is active now, so we have something
+ * to switch back to in kmscon_vt_switch_leave.
+ */
+ ret = ioctl(vt->fd, VT_GETSTATE, &vts);
+ if (ret) {
+ log_warn("cannot find the currently active VT");
+ vt->saved_num = -1;
+ } else {
+ vt->saved_num = vts.v_active;
+ }
+
+ if (tcgetattr(vt->fd, &vt->saved_attribs) < 0) {
+ log_err("cannot get terminal attributes");
+ ret = -EFAULT;
+ goto err_eloop;
+ }
+
+ /* Ignore control characters and disable echo */
+ raw_attribs = vt->saved_attribs;
+ cfmakeraw(&raw_attribs);
+
+ /* Fix up line endings to be normal (cfmakeraw hoses them) */
+ raw_attribs.c_oflag |= OPOST | OCRNL;
+
+ if (tcsetattr(vt->fd, TCSANOW, &raw_attribs) < 0)
+ log_warn("cannot put terminal into raw mode");
+
+ if (ioctl(vt->fd, KDSETMODE, KD_GRAPHICS)) {
+ log_err("vt: cannot set graphics mode\n");
+ ret = -errno;
+ goto err_reset;
+ }
+
+ memset(&mode, 0, sizeof(mode));
+ mode.mode = VT_PROCESS;
+ mode.relsig = SIGUSR1;
+ mode.acqsig = SIGUSR2;
+
+ if (ioctl(vt->fd, VT_SETMODE, &mode)) {
+ log_err("cannot take control of vt handling");
+ ret = -errno;
+ goto err_text;
+ }
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGUSR1);
+ sigaddset(&mask, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+
+ return 0;
+
+err_text:
+ ioctl(vt->fd, KDSETMODE, KD_TEXT);
+err_reset:
+ tcsetattr(vt->fd, TCSANOW, &vt->saved_attribs);
+err_eloop:
+ disconnect_eloop(vt);
+err_fd:
+ close(vt->fd);
+ vt->fd = -1;
+ return ret;
+}
+
+void kmscon_vt_close(struct kmscon_vt *vt)
+{
+ if (!vt || vt->fd < 0)
+ return;
+
+ log_debug("closing vt %p", vt);
+ ioctl(vt->fd, KDSETMODE, KD_TEXT);
+ tcsetattr(vt->fd, TCSANOW, &vt->saved_attribs);
+ disconnect_eloop(vt);
+ close(vt->fd);
+
+ vt->fd = -1;
+ vt->num = -1;
+ vt->saved_num = -1;
+}
+
+/* Switch to this VT and make it the active VT. */
+int kmscon_vt_enter(struct kmscon_vt *vt)
+{
+ int ret;
+
+ if (!vt || vt->fd < 0 || vt->num < 0)
+ return -EINVAL;
+
+ ret = ioctl(vt->fd, VT_ACTIVATE, vt->num);
+ if (ret) {
+ log_warn("cannot enter VT %p", vt);
+ return -EFAULT;
+ }
+
+ log_debug("entering VT %p on demand", vt);
+ return 0;
+}
+
+/*
+ * Switch back to the VT from which we started.
+ * Note: The VT switch needs to be acknowledged by us so we need to react on
+ * SIGUSR. This function returns -EINPROGRESS if we started the VT switch but
+ * still needs to react on SIGUSR. Make sure you call the eloop dispatcher again
+ * if you get -EINPROGRESS here.
+ *
+ * Returns 0 if we don't know the previous VT or if the previous VT is already
+ * active. Returns -EINPROGRESS if we started the VT switch. Returns <0 on
+ * failure.
+ */
+int kmscon_vt_leave(struct kmscon_vt *vt)
+{
+ int ret;
+ struct vt_stat vts;
+
+ if (!vt || vt->fd < 0)
+ return -EINVAL;
+
+ if (vt->saved_num < 0)
+ return 0;
+
+ ret = ioctl(vt->fd, VT_GETSTATE, &vts);
+ if (ret) {
+ log_warn("cannot find current VT");
+ return -EFAULT;
+ }
+
+ if (vts.v_active != vt->num)
+ return 0;
+
+ ret = ioctl(vt->fd, VT_ACTIVATE, vt->saved_num);
+ if (ret) {
+ log_warn("cannot leave VT %p", vt);
+ return -EFAULT;
+ }
+
+ log_debug("leaving VT %p on demand", vt);
+ return -EINPROGRESS;
+}
+
struct uterm_vt {
unsigned long ref;
struct kmscon_dlist list;
diff --git a/src/vt.c b/src/vt.c
deleted file mode 100644
index a6e1ed8..0000000
--- a/src/vt.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * kmscon - VT compatibility layer
- *
- * Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
- * Copyright (c) 2011 University of Tuebingen
- *
- * 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.
- */
-
-/*
- * This kmscon-VT API is based on the wayland-compositor demo:
- *
- * Copyright © 2010 Intel Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. The copyright holders make
- * no representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * VT compatibility
- * Although we do not use the VT for drawing or anything, we set it to graphical
- * mode to avoid side effects.
- * This behavior is copied from wayland. If someone has more insight in VT
- * handling, they may adjust this code.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/kd.h>
-#include <linux/vt.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/signalfd.h>
-#include <termios.h>
-#include <unistd.h>
-#include "eloop.h"
-#include "log.h"
-#include "vt.h"
-
-#define LOG_SUBSYSTEM "vt"
-
-struct kmscon_vt {
- unsigned long ref;
-
- int fd;
- int num;
- int saved_num;
- struct termios saved_attribs;
- kmscon_vt_cb cb;
- void *data;
-
- struct ev_eloop *eloop;
- struct ev_fd *efd;
-};
-
-int kmscon_vt_new(struct kmscon_vt **out, kmscon_vt_cb cb, void *data)
-{
- struct kmscon_vt *vt;
-
- if (!out)
- return -EINVAL;
-
- vt = malloc(sizeof(*vt));
- if (!vt)
- return -ENOMEM;
-
- memset(vt, 0, sizeof(*vt));
- vt->ref = 1;
- vt->fd = -1;
- vt->num = -1;
- vt->saved_num = -1;
- vt->cb = cb;
- vt->data = data;
-
- log_debug("new vt object %p", vt);
- *out = vt;
- return 0;
-}
-
-void kmscon_vt_ref(struct kmscon_vt *vt)
-{
- if (!vt)
- return;
-
- ++vt->ref;
-}
-
-void kmscon_vt_unref(struct kmscon_vt *vt)
-{
- if (!vt || !vt->ref || --vt->ref)
- return;
-
- log_debug("free vt object %p", vt);
- kmscon_vt_close(vt);
- free(vt);
-}
-
-static void vt_enter(struct ev_eloop *eloop, struct signalfd_siginfo *info,
- void *data)
-{
- struct kmscon_vt *vt = data;
- struct vt_stat vts;
- int ret;
-
- if (!vt || vt->fd < 0)
- return;
-
- ret = ioctl(vt->fd, VT_GETSTATE, &vts);
- if (ret || vts.v_active != vt->num)
- return;
-
- log_debug("enter VT %d %p", vt->num, vt);
-
- ioctl(vt->fd, VT_RELDISP, VT_ACKACQ);
-
- if (ioctl(vt->fd, KDSETMODE, KD_GRAPHICS))
- log_warn("cannot set graphics mode on vt %p", vt);
-
- if (vt->cb)
- vt->cb(vt, KMSCON_VT_ENTER, vt->data);
-}
-
-static void vt_leave(struct ev_eloop *eloop, struct signalfd_siginfo *info,
- void *data)
-{
- struct kmscon_vt *vt = data;
- struct vt_stat vts;
- int ret;
-
- if (!vt || vt->fd < 0)
- return;
-
- ret = ioctl(vt->fd, VT_GETSTATE, &vts);
- if (ret || vts.v_active != vt->num)
- return;
-
- if (vt->cb && !vt->cb(vt, KMSCON_VT_LEAVE, vt->data)) {
- log_debug("leaving VT %d %p denied", vt->num, vt);
- ioctl(vt->fd, VT_RELDISP, 0);
- } else {
- log_debug("leaving VT %d %p", vt->num, vt);
- ioctl(vt->fd, VT_RELDISP, 1);
- if (ioctl(vt->fd, KDSETMODE, KD_TEXT))
- log_warn("cannot set text mode on vt %p", vt);
- }
-}
-
-static void vt_input(struct ev_fd *fd, int mask, void *data)
-{
- struct kmscon_vt *vt = data;
-
- if (!vt || vt->fd < 0)
- return;
-
- /* we ignore input from the VT because we get it from evdev */
- tcflush(vt->fd, TCIFLUSH);
-}
-
-static int connect_eloop(struct kmscon_vt *vt, struct ev_eloop *eloop)
-{
- int ret;
-
- if (!vt || !eloop || vt->fd < 0)
- return -EINVAL;
-
- ret = ev_eloop_register_signal_cb(eloop, SIGUSR1, vt_leave, vt);
- if (ret)
- return ret;
-
- ret = ev_eloop_register_signal_cb(eloop, SIGUSR2, vt_enter, vt);
- if (ret)
- goto err_sig1;
-
- ret = ev_eloop_new_fd(eloop, &vt->efd, vt->fd, EV_READABLE,
- vt_input, vt);
- if (ret)
- goto err_sig2;
-
- vt->eloop = eloop;
- ev_eloop_ref(vt->eloop);
- return 0;
-
-err_sig2:
- ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR2, vt_enter, vt);
-err_sig1:
- ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR1, vt_leave, vt);
- return ret;
-}
-
-static void disconnect_eloop(struct kmscon_vt *vt)
-{
- if (!vt)
- return;
-
- ev_eloop_rm_fd(vt->efd);
- ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR2, vt_enter, vt);
- ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR1, vt_leave, vt);
- ev_eloop_unref(vt->eloop);
- vt->efd = NULL;
- vt->eloop = NULL;
-}
-
-static int open_tty(int id, int *tty_fd, int *tty_num)
-{
- int fd;
- char filename[16];
-
- if (!tty_fd || !tty_num)
- return -EINVAL;
-
- if (id == KMSCON_VT_NEW) {
- fd = open("/dev/tty0", O_NONBLOCK | O_NOCTTY | O_CLOEXEC);
- if (fd < 0) {
- fd = open("/dev/tty1",
- O_NONBLOCK | O_NOCTTY | O_CLOEXEC);
- if (fd < 0) {
- log_err("cannot find parent tty");
- return -errno;
- }
- }
-
- if (ioctl(fd, VT_OPENQRY, &id) || id <= 0) {
- close(fd);
- log_err("cannot get unused tty");
- return -EINVAL;
- }
- close(fd);
- }
-
- snprintf(filename, sizeof(filename), "/dev/tty%d", id);
- filename[sizeof(filename) - 1] = 0;
- log_notice("using tty %s", filename);
-
- fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC);
- if (fd < 0) {
- log_err("cannot open tty %s", filename);
- return -errno;
- }
-
- *tty_fd = fd;
- *tty_num = id;
- return 0;
-}
-
-int kmscon_vt_open(struct kmscon_vt *vt, int id, struct ev_eloop *eloop)
-{
- struct termios raw_attribs;
- struct vt_mode mode;
- struct vt_stat vts;
- int ret;
- sigset_t mask;
-
- if (vt->fd >= 0)
- return -EALREADY;
-
- log_debug("open vt %p", vt);
-
- ret = open_tty(id, &vt->fd, &vt->num);
- if (ret)
- return ret;
-
- ret = connect_eloop(vt, eloop);
- if (ret)
- goto err_fd;
-
- /*
- * Get the number of the VT which is active now, so we have something
- * to switch back to in kmscon_vt_switch_leave.
- */
- ret = ioctl(vt->fd, VT_GETSTATE, &vts);
- if (ret) {
- log_warn("cannot find the currently active VT");
- vt->saved_num = -1;
- } else {
- vt->saved_num = vts.v_active;
- }
-
- if (tcgetattr(vt->fd, &vt->saved_attribs) < 0) {
- log_err("cannot get terminal attributes");
- ret = -EFAULT;
- goto err_eloop;
- }
-
- /* Ignore control characters and disable echo */
- raw_attribs = vt->saved_attribs;
- cfmakeraw(&raw_attribs);
-
- /* Fix up line endings to be normal (cfmakeraw hoses them) */
- raw_attribs.c_oflag |= OPOST | OCRNL;
-
- if (tcsetattr(vt->fd, TCSANOW, &raw_attribs) < 0)
- log_warn("cannot put terminal into raw mode");
-
- if (ioctl(vt->fd, KDSETMODE, KD_GRAPHICS)) {
- log_err("vt: cannot set graphics mode\n");
- ret = -errno;
- goto err_reset;
- }
-
- memset(&mode, 0, sizeof(mode));
- mode.mode = VT_PROCESS;
- mode.relsig = SIGUSR1;
- mode.acqsig = SIGUSR2;
-
- if (ioctl(vt->fd, VT_SETMODE, &mode)) {
- log_err("cannot take control of vt handling");
- ret = -errno;
- goto err_text;
- }
-
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- sigaddset(&mask, SIGUSR2);
- sigprocmask(SIG_BLOCK, &mask, NULL);
-
- return 0;
-
-err_text:
- ioctl(vt->fd, KDSETMODE, KD_TEXT);
-err_reset:
- tcsetattr(vt->fd, TCSANOW, &vt->saved_attribs);
-err_eloop:
- disconnect_eloop(vt);
-err_fd:
- close(vt->fd);
- vt->fd = -1;
- return ret;
-}
-
-void kmscon_vt_close(struct kmscon_vt *vt)
-{
- if (!vt || vt->fd < 0)
- return;
-
- log_debug("closing vt %p", vt);
- ioctl(vt->fd, KDSETMODE, KD_TEXT);
- tcsetattr(vt->fd, TCSANOW, &vt->saved_attribs);
- disconnect_eloop(vt);
- close(vt->fd);
-
- vt->fd = -1;
- vt->num = -1;
- vt->saved_num = -1;
-}
-
-/* Switch to this VT and make it the active VT. */
-int kmscon_vt_enter(struct kmscon_vt *vt)
-{
- int ret;
-
- if (!vt || vt->fd < 0 || vt->num < 0)
- return -EINVAL;
-
- ret = ioctl(vt->fd, VT_ACTIVATE, vt->num);
- if (ret) {
- log_warn("cannot enter VT %p", vt);
- return -EFAULT;
- }
-
- log_debug("entering VT %p on demand", vt);
- return 0;
-}
-
-/*
- * Switch back to the VT from which we started.
- * Note: The VT switch needs to be acknowledged by us so we need to react on
- * SIGUSR. This function returns -EINPROGRESS if we started the VT switch but
- * still needs to react on SIGUSR. Make sure you call the eloop dispatcher again
- * if you get -EINPROGRESS here.
- *
- * Returns 0 if we don't know the previous VT or if the previous VT is already
- * active. Returns -EINPROGRESS if we started the VT switch. Returns <0 on
- * failure.
- */
-int kmscon_vt_leave(struct kmscon_vt *vt)
-{
- int ret;
- struct vt_stat vts;
-
- if (!vt || vt->fd < 0)
- return -EINVAL;
-
- if (vt->saved_num < 0)
- return 0;
-
- ret = ioctl(vt->fd, VT_GETSTATE, &vts);
- if (ret) {
- log_warn("cannot find current VT");
- return -EFAULT;
- }
-
- if (vts.v_active != vt->num)
- return 0;
-
- ret = ioctl(vt->fd, VT_ACTIVATE, vt->saved_num);
- if (ret) {
- log_warn("cannot leave VT %p", vt);
- return -EFAULT;
- }
-
- log_debug("leaving VT %p on demand", vt);
- return -EINPROGRESS;
-}
diff --git a/src/vt.h b/src/vt.h
deleted file mode 100644
index f83fefc..0000000
--- a/src/vt.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * kmscon - VT compatibility layer
- *
- * Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
- * Copyright (c) 2011 University of Tuebingen
- *
- * 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.
- */
-
-/*
- * VT compatibility
- * If the kmscon application runs in a VT we need to react on VT switch events
- * to allow other applications to access the DRM. This is only needed as long as
- * we run in a VT. In the future we will be able to disable all VTs and run as
- * service daemon. We then need another way to switch between graphical
- * applications, though.
- */
-
-#ifndef KMSCON_VT_H
-#define KMSCON_VT_H
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include "eloop.h"
-
-struct kmscon_vt;
-
-enum kmscon_vt_action {
- KMSCON_VT_ENTER,
- KMSCON_VT_LEAVE,
-};
-
-enum kmscon_vt_id {
- KMSCON_VT_CUR = 0,
- KMSCON_VT_NEW = -1,
-};
-
-typedef bool (*kmscon_vt_cb) (struct kmscon_vt *vt,
- enum kmscon_vt_action action,
- void *data);
-
-int kmscon_vt_new(struct kmscon_vt **out, kmscon_vt_cb cb, void *data);
-void kmscon_vt_ref(struct kmscon_vt *vt);
-void kmscon_vt_unref(struct kmscon_vt *vt);
-
-int kmscon_vt_open(struct kmscon_vt *vt, int id, struct ev_eloop *eloop);
-void kmscon_vt_close(struct kmscon_vt *vt);
-
-int kmscon_vt_enter(struct kmscon_vt *vt);
-int kmscon_vt_leave(struct kmscon_vt *vt);
-
-#endif /* KMSCON_VT_H */