launcher: Handle tty setup and teardown in launcher
diff --git a/src/weston-launch.c b/src/weston-launch.c
index 87f4641..059010c 100644
--- a/src/weston-launch.c
+++ b/src/weston-launch.c
@@ -28,6 +28,7 @@
 #include <assert.h>
 #include <poll.h>
 #include <errno.h>
+#include <termios.h>
 
 #include <error.h>
 #include <getopt.h>
@@ -45,6 +46,7 @@
 #include <termios.h>
 #include <linux/vt.h>
 #include <linux/major.h>
+#include <linux/kd.h>
 
 #include <pwd.h>
 #include <grp.h>
@@ -69,6 +71,8 @@
 	int ttynr;
 	int sock[2];
 	int drm_fd;
+	struct termios terminal_attributes;
+	int kb_mode;
 	struct passwd *pw;
 
 	int signalfd;
@@ -369,6 +373,7 @@
 static void
 quit(struct weston_launch *wl, int status)
 {
+	struct vt_mode mode = { 0 };
 	int err;
 
 	close(wl->signalfd);
@@ -382,6 +387,20 @@
 		pam_end(wl->ph, err);
 	}
 
+	if (ioctl(wl->tty, KDSKBMODE, wl->kb_mode))
+		fprintf(stderr, "failed to restore keyboard mode: %m\n");
+
+	if (ioctl(wl->tty, KDSETMODE, KD_TEXT))
+		fprintf(stderr, "failed to set KD_TEXT mode on tty: %m\n");
+
+	if (tcsetattr(wl->tty, TCSANOW, &wl->terminal_attributes) < 0)
+		fprintf(stderr,
+			"could not restore terminal to canonical mode\n");
+
+	mode.mode = VT_AUTO;
+	if (ioctl(wl->tty, VT_SETMODE, &mode) < 0)
+		fprintf(stderr, "could not reset vt handling\n");
+
 	exit(status);
 }
 
@@ -441,9 +460,11 @@
 static int
 setup_tty(struct weston_launch *wl, const char *tty)
 {
+	struct termios raw_attributes;
 	struct stat buf;
 	struct vt_mode mode = { 0 };
 	char *t;
+	int ret;
 
 	if (!wl->new_user) {
 		wl->tty = STDIN_FILENO;
@@ -481,6 +502,30 @@
 		wl->ttynr = minor(buf.st_rdev);
 	}
 
+	if (tcgetattr(wl->tty, &wl->terminal_attributes) < 0)
+		error(1, errno, "could not get terminal attributes: %m\n");
+
+	/* Ignore control characters and disable echo */
+	raw_attributes = wl->terminal_attributes;
+	cfmakeraw(&raw_attributes);
+
+	/* Fix up line endings to be normal (cfmakeraw hoses them) */
+	raw_attributes.c_oflag |= OPOST | OCRNL;
+
+	if (tcsetattr(wl->tty, TCSANOW, &raw_attributes) < 0)
+		error(1, errno, "could not put terminal into raw mode: %m\n");
+
+	ioctl(wl->tty, KDGKBMODE, &wl->kb_mode);
+	ret = ioctl(wl->tty, KDSKBMODE, K_OFF);
+	if (ret)
+		ret = ioctl(wl->tty, KDSKBMODE, K_RAW);
+	if (ret)
+		error(1, errno, "failed to set keyboard mode on tty: %m\n");
+
+	ret = ioctl(wl->tty, KDSETMODE, KD_GRAPHICS);
+	if (ret)
+		error(1, errno, "failed to set KD_GRAPHICS mode on tty: %m\n");
+
 	mode.mode = VT_PROCESS;
 	mode.relsig = SIGUSR1;
 	mode.acqsig = SIGUSR2;