9d98434
From 934dab76d01afb3a77439b94631eae37bf05c954 Mon Sep 17 00:00:00 2001
9d98434
From: Peter Hutterer <peter.hutterer@redhat.com>
9d98434
Date: Sun, 12 Oct 2008 21:58:30 +1030
9d98434
Subject: [PATCH] xfree86: if AllowEmptyInput is true, enable RAW mode on the console.
9d98434
9d98434
Usually, the console is set to RAW in the kbd driver. If we hotplug all input
9d98434
devices (i.e. the evdev driver for keyboards) and the console is left as-is.
9d98434
As a result, the evdev driver must put an EVIOCGRAB on the device to avoid
9d98434
characters leaking onto the console. This again breaks many things, amongst
9d98434
them lirc, in-kernel mouse button emulation and HAL.
9d98434
9d98434
This patch sets the console to RAW if AllowEmptyInput is on.
9d98434
9d98434
Use-cases:
9d98434
1. AEI is off
9d98434
  1.1. Only kbd driver is used - behaviour as-is.
9d98434
  1.2. kbd and evdev driver is used: if evdev does not grab the device,
9d98434
       duplicate events are generated.
9d98434
2. AEI is on
9d98434
  2.1. Only evdev driver is used - behaviour as-is, but evdev does not need
9d98434
       to grab the device anymore.
9d98434
  2.2. evdev and kbd are used: duplicate key events are generated if evdev
9d98434
       does not grab the device.
9d98434
9d98434
1.2 is a marginal use-case that can be fixed by adding a "grab" option to the
9d98434
evdev driver (update of xorg.conf is needed).
9d98434
9d98434
2.2 is an issue. If we have no ServerLayout section, AEI is on, but devices
9d98434
specified in the xorg.conf are still added [1], resulting in duplicate events.
9d98434
This is a common configuration and needs sorting out.
9d98434
9d98434
[1] 2eaed4a10fe5bf727579bca4ab8d4a47c8763a7d
9d98434
9d98434
Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
9d98434
Signed-off-by: Adam Jackson <ajax@redhat.com>
9d98434
9d98434
---
9d98434
 hw/xfree86/os-support/linux/lnx_init.c |   35 +++++++++++++++++++++++++++++++-
9d98434
 1 files changed, 34 insertions(+), 1 deletions(-)
9d98434
9d98434
diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
9d98434
index 4c36b7c..6f68ba5 100644
9d98434
--- a/hw/xfree86/os-support/linux/lnx_init.c
9d98434
+++ b/hw/xfree86/os-support/linux/lnx_init.c
9d98434
@@ -53,6 +53,8 @@ static int activeVT = -1;
9d98434
 
9d98434
 static int vtPermSave[4];
9d98434
 static char vtname[11];
9d98434
+static struct termios tty_attr; /* tty state to restore */
9d98434
+static int tty_mode; /* kbd mode to restore */
9d98434
 
9d98434
 static int
9d98434
 saveVtPerms(void)
9d98434
@@ -272,6 +274,34 @@ xf86OpenConsole(void)
9d98434
 	        FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
9d98434
 		           strerror(errno));
9d98434
 
9d98434
+	    /* Set the keyboard to RAW mode. If we're using the keyboard
9d98434
+	     * driver, the driver does it for us. If we have AEI on, then
9d98434
+	     * we're expecting the devices to be added (i.e. evdev) and we
9d98434
+	     * have to set it manually.
9d98434
+	     */
9d98434
+	    if (xf86Info.allowEmptyInput)
9d98434
+	    {
9d98434
+		struct termios nTty;
9d98434
+
9d98434
+		tcgetattr(xf86Info.consoleFd, &tty_attr);
9d98434
+		ioctl(xf86Info.consoleFd, KDGKBMODE, &tty_mode);
9d98434
+
9d98434
+		if (ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW) < 0)
9d98434
+		    FatalError("xf86OpenConsole: KDSKBMODE K_RAW failed %s\n",
9d98434
+			    strerror(errno));
9d98434
+
9d98434
+		nTty = tty_attr;
9d98434
+		nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
9d98434
+		nTty.c_oflag = 0;
9d98434
+		nTty.c_cflag = CREAD | CS8;
9d98434
+		nTty.c_lflag = 0;
9d98434
+		nTty.c_cc[VTIME]=0;
9d98434
+		nTty.c_cc[VMIN]=1;
9d98434
+		cfsetispeed(&nTty, 9600);
9d98434
+		cfsetospeed(&nTty, 9600);
9d98434
+		tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
9d98434
+	    }
9d98434
+
9d98434
 	    /* we really should have a InitOSInputDevices() function instead
9d98434
 	     * of Init?$#*&Device(). So I just place it here */
9d98434
 	
9d98434
@@ -328,7 +358,10 @@ xf86CloseConsole()
9d98434
     if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT) < 0)
9d98434
 	xf86Msg(X_WARNING, "xf86CloseConsole: KDSETMODE failed: %s\n",
9d98434
 		strerror(errno));
9d98434
-	
9d98434
+
9d98434
+    ioctl(xf86Info.consoleFd, KDSKBMODE, tty_mode);
9d98434
+    tcsetattr(xf86Info.consoleFd, TCSANOW, &tty_attr);
9d98434
+
9d98434
     if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0) 
9d98434
 	xf86Msg(X_WARNING, "xf86CloseConsole: VT_GETMODE failed: %s\n",
9d98434
 		strerror(errno));
9d98434
-- 
9d98434
1.6.0.1
9d98434