* Access to raw keycodes in xen domU
@ 2008-08-14 13:58 Maxim Gorbachyov
2008-08-14 14:07 ` Keir Fraser
2008-08-14 14:10 ` Samuel Thibault
0 siblings, 2 replies; 7+ messages in thread
From: Maxim Gorbachyov @ 2008-08-14 13:58 UTC (permalink / raw)
To: xen-devel
Hi.
There is a need to have access to raw keycodes in xen domU (like
showkey (1)). Using xen-hypervisor-3.2 and linux-2.6.18-xen-3.2.0 with
these parameters:
kernel = "/my/vmlinuz"
memory = 128
name = "dn1"
vif = [ '' ]
disk = [ 'tap:aio:/my/img,hda1,w' ]
root = "/dev/hda1 ro"
extra = "2 xencons=tty"
I run "# strace showkey" inside domU and get this:
...
open("/dev/tty", O_RDWR) = 3
ioctl(3, KDGKBTYPE, 0x7fff91e9da17) = -1 EINVAL (Invalid argument)
...
Indeed there is no ioctl() implementation assigned to
xencons_ops.ioctl in
linux-2.6.18-xen-3.2.0/drivers/xen/console/console.c
I've tried assigning xencons_ops.ioctl to something like that:
static int xencons_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg)
{
unsigned char ucval;
long val;
switch (cmd) {
case KDGKBTYPE:
ucval = KB_101;
return put_user(ucval, (char __user *)arg);
case KDGKBMODE:
val = K_UNICODE;
return put_user(val, (long __user *)arg);
case KDSKBMODE:
return 0;
}
return -ENOIOCTLCMD;
}
It's enough to make showkey run, but it does not report correct
keycodes. I think I have to do something like
HYPERVISOR_console_io(CONSOLEIO_ioctl, ... )
but there is no CONSOLEIO_ioctl.
Could you please suggest what can I do to access raw keycodes?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Access to raw keycodes in xen domU
2008-08-14 13:58 Access to raw keycodes in xen domU Maxim Gorbachyov
@ 2008-08-14 14:07 ` Keir Fraser
2008-08-14 14:39 ` Ian Jackson
2008-08-14 14:10 ` Samuel Thibault
1 sibling, 1 reply; 7+ messages in thread
From: Keir Fraser @ 2008-08-14 14:07 UTC (permalink / raw)
To: Maxim Gorbachyov, xen-devel
Keyboard is owned by dom0. There's not really an easy way to propagate the
raw keycodes to a pv domU. For an hvm domU we reverse-map to the raw
keycodes in qemu-dm and send those via the emulated pckeyboard.
-- Keir
On 14/8/08 14:58, "Maxim Gorbachyov" <maxim.gorbachyov@gmail.com> wrote:
> Hi.
>
> There is a need to have access to raw keycodes in xen domU (like
> showkey (1)). Using xen-hypervisor-3.2 and linux-2.6.18-xen-3.2.0 with
> these parameters:
>
> kernel = "/my/vmlinuz"
> memory = 128
> name = "dn1"
> vif = [ '' ]
> disk = [ 'tap:aio:/my/img,hda1,w' ]
> root = "/dev/hda1 ro"
> extra = "2 xencons=tty"
>
> I run "# strace showkey" inside domU and get this:
> ...
> open("/dev/tty", O_RDWR) = 3
> ioctl(3, KDGKBTYPE, 0x7fff91e9da17) = -1 EINVAL (Invalid argument)
> ...
>
> Indeed there is no ioctl() implementation assigned to
> xencons_ops.ioctl in
> linux-2.6.18-xen-3.2.0/drivers/xen/console/console.c
>
> I've tried assigning xencons_ops.ioctl to something like that:
>
> static int xencons_ioctl(struct tty_struct *tty, struct file * file,
> unsigned int cmd, unsigned long arg)
> {
> unsigned char ucval;
> long val;
>
> switch (cmd) {
> case KDGKBTYPE:
> ucval = KB_101;
> return put_user(ucval, (char __user *)arg);
>
> case KDGKBMODE:
> val = K_UNICODE;
> return put_user(val, (long __user *)arg);
>
> case KDSKBMODE:
> return 0;
> }
> return -ENOIOCTLCMD;
> }
>
> It's enough to make showkey run, but it does not report correct
> keycodes. I think I have to do something like
>
> HYPERVISOR_console_io(CONSOLEIO_ioctl, ... )
>
> but there is no CONSOLEIO_ioctl.
>
> Could you please suggest what can I do to access raw keycodes?
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Access to raw keycodes in xen domU
2008-08-14 13:58 Access to raw keycodes in xen domU Maxim Gorbachyov
2008-08-14 14:07 ` Keir Fraser
@ 2008-08-14 14:10 ` Samuel Thibault
1 sibling, 0 replies; 7+ messages in thread
From: Samuel Thibault @ 2008-08-14 14:10 UTC (permalink / raw)
To: Maxim Gorbachyov; +Cc: xen-devel
Maxim Gorbachyov, le Thu 14 Aug 2008 17:58:44 +0400, a écrit :
> Could you please suggest what can I do to access raw keycodes?
You could use a pvfb instead. That one should have raw keycodes.
Samuel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Access to raw keycodes in xen domU
2008-08-14 14:07 ` Keir Fraser
@ 2008-08-14 14:39 ` Ian Jackson
2008-08-14 15:09 ` Maxim Gorbachyov
0 siblings, 1 reply; 7+ messages in thread
From: Ian Jackson @ 2008-08-14 14:39 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel, Maxim Gorbachyov
Keir Fraser writes ("Re: [Xen-devel] Access to raw keycodes in xen domU"):
> Keyboard is owned by dom0. There's not really an easy way to propagate the
> raw keycodes to a pv domU. For an hvm domU we reverse-map to the raw
> keycodes in qemu-dm and send those via the emulated pckeyboard.
There was a discussion of some of this area on qemu-devel recently.
Sadly it's a bit of a mess (in part, inevitably), and it may be
difficult to do exactly what you want.
If you tell us why you want the raw keycodes - what overall result
you're trying to achieve etc. - then we may be able to suggest some
kind of answer.
Ian.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Access to raw keycodes in xen domU
2008-08-14 14:39 ` Ian Jackson
@ 2008-08-14 15:09 ` Maxim Gorbachyov
2008-08-14 15:21 ` Samuel Thibault
0 siblings, 1 reply; 7+ messages in thread
From: Maxim Gorbachyov @ 2008-08-14 15:09 UTC (permalink / raw)
To: Ian Jackson; +Cc: xen-devel
On Thu, Aug 14, 2008 at 6:39 PM, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote:
> There was a discussion of some of this area on qemu-devel recently.
> Sadly it's a bit of a mess (in part, inevitably), and it may be
> difficult to do exactly what you want.
>
> If you tell us why you want the raw keycodes - what overall result
> you're trying to achieve etc. - then we may be able to suggest some
> kind of answer.
There is a binary which sets K_RAW and expects certain codes from
keyboard to work. It's kind of dinosaur, but we have to use it..
Thanx you all who answered.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Access to raw keycodes in xen domU
2008-08-14 15:09 ` Maxim Gorbachyov
@ 2008-08-14 15:21 ` Samuel Thibault
2008-08-25 9:26 ` Maxim Gorbachyov
0 siblings, 1 reply; 7+ messages in thread
From: Samuel Thibault @ 2008-08-14 15:21 UTC (permalink / raw)
To: Maxim Gorbachyov; +Cc: xen-devel, Ian Jackson
Maxim Gorbachyov, le Thu 14 Aug 2008 19:09:55 +0400, a écrit :
> On Thu, Aug 14, 2008 at 6:39 PM, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote:
> > There was a discussion of some of this area on qemu-devel recently.
> > Sadly it's a bit of a mess (in part, inevitably), and it may be
> > difficult to do exactly what you want.
> >
> > If you tell us why you want the raw keycodes - what overall result
> > you're trying to achieve etc. - then we may be able to suggest some
> > kind of answer.
>
> There is a binary which sets K_RAW and expects certain codes from
> keyboard to work. It's kind of dinosaur, but we have to use it..
Well, the problem is that since the xen console can be accessed e.g.
through ssh, there is really no way to properly return keycodes. If you
can not use pvfb, The only half-sane way I see is that you hardcode the
translation that your dinosaur binary expects according to the keyboard
layout you are using and use that patched version. I really don't see
how that could ever fit generically in xen console.
Samuel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Access to raw keycodes in xen domU
2008-08-14 15:21 ` Samuel Thibault
@ 2008-08-25 9:26 ` Maxim Gorbachyov
0 siblings, 0 replies; 7+ messages in thread
From: Maxim Gorbachyov @ 2008-08-25 9:26 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: Type: text/plain, Size: 698 bytes --]
Hello.
On Thu, Aug 14, 2008 at 7:21 PM, Samuel Thibault
<samuel.thibault@eu.citrix.com> wrote:
> Well, the problem is that since the xen console can be accessed e.g.
> through ssh, there is really no way to properly return keycodes. If you
> can not use pvfb, The only half-sane way I see is that you hardcode the
> translation that your dinosaur binary expects according to the keyboard
> layout you are using and use that patched version. I really don't see
> how that could ever fit generically in xen console.
There were doubts if anyone beside me needs it. Well, just
informational, this is the way I did it (see diff attached). Note,
some used esc-sequences are not in the default keymap.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: domU-raw-keycodes.patch --]
[-- Type: text/x-diff; name=domU-raw-keycodes.patch, Size: 15898 bytes --]
Index: linux-2.6.18-xen-3.2.0/drivers/xen/console/console.c
===================================================================
--- linux-2.6.18-xen-3.2.0/drivers/xen/console/console.c (revision 2)
+++ linux-2.6.18-xen-3.2.0/drivers/xen/console/console.c (working copy)
@@ -50,6 +50,10 @@
#include <linux/sysrq.h>
#include <linux/screen_info.h>
#include <linux/vt.h>
+#include <linux/vt_kern.h>
+#include <linux/kd.h>
+#include <linux/kbd_kern.h>
+#include <linux/workqueue.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
@@ -344,18 +348,388 @@
static struct tty_struct *xencons_tty;
static int xencons_priv_irq;
static char x_char;
+static unsigned char xencons_mode;
+static void match(void *unused);
+DECLARE_WORK(match_work, match, NULL);
+static DEFINE_SPINLOCK(translate_lock);
+static char raw_in[1024], pending;
+static unsigned current_in;
+
+typedef struct {
+ char *in;
+ char *out;
+ unsigned char in_len;
+ unsigned char out_len;
+} reverse_entry_t;
+
+#define ESC_CODE_IN 0x1b
+
+static reverse_entry_t reverse_escaped[] = {
+ { "\x1b\x5b\x44", "\xe0\x4b\xe0\xcb", 0, 0 }, // arrow left
+ { "\x1b\x5b\x41", "\xe0\x48\xe0\xc8", 0, 0 }, // arrow up
+ { "\x1b\x5b\x43", "\xe0\x4d\xe0\xcd", 0, 0 }, // arrow right
+ { "\x1b\x5b\x42", "\xe0\x50\xe0\xd0", 0, 0 }, // arrow down
+ { "\x1b\x5b\x5b\x41", "\x3b\xbb", 0, 0 }, // f1
+ { "\x1b\x5b\x5b\x42", "\x3c\xbc", 0, 0 }, // f2
+ { "\x1b\x5b\x5b\x43", "\x3d\xbd", 0, 0 }, // f3
+ { "\x1b\x5b\x5b\x44", "\x3e\xbe", 0, 0 }, // f4
+ { "\x1b\x5b\x5b\x45", "\x3f\xbf", 0, 0 }, // f5
+ { "\x1b\x5b\x31\x37\x7e", "\x40\xc0", 0, 0 }, // f6
+ { "\x1b\x5b\x31\x38\x7e", "\x41\xc1", 0, 0 }, // f7
+ { "\x1b\x5b\x31\x39\x7e", "\x42\xc2", 0, 0 }, // f8
+ { "\x1b\x5b\x32\x30\x7e", "\x43\xc3", 0, 0 }, // f9
+ { "\x1b\x5b\x32\x31\x7e", "\x44\xc4", 0, 0 }, // f10
+ { "\x1b\x5b\x32\x33\x7e", "\x57\xd7", 0, 0 }, // f11
+ { "\x1b\x5b\x32\x34\x7e", "\x58\xd8", 0, 0 }, // f12
+ { "\x1b\x5b\x50", "\x77\xf7", 0, 0 }, // pause
+ { "\x1b\x5b\x32\x7e", "\x6e\xee", 0, 0 }, // ins
+ { "\x1b\x5b\x31\x7e", "\x66\xe6", 0, 0 }, // home
+ { "\x1b\x5b\x35\x7e", "\x68\xe8", 0, 0 }, // pg up
+ { "\x1b\x5b\x33\x7e", "\x6f\xef", 0, 0 }, // del
+ { "\x1b\x5b\x34\x7e", "\x6b\xeb", 0, 0 }, // end
+ { "\x1b\x5b\x36\x7e", "\x6d\xed", 0, 0 }, // pg down
+ { "\x1b\x5b\x31\x7e", "\x47\xc7", 0, 0 }, // num - home
+ { "\x1b\x5b\x41", "\x48\xc8", 0, 0 }, // num - up
+ { "\x1b\x5b\x35\x7e", "\x49\xc9", 0, 0 }, // num - pg up
+ { "\x1b\x5b\x44", "\x4b\xcb", 0, 0 }, // num - arrow left
+ { "\x1b\x5b\x47", "\x4c\xcc", 0, 0 }, // num - center
+ { "\x1b\x5b\x43", "\x4d\xcd", 0, 0 }, // num - arrow right
+ { "\x1b\x5b\x34\x7e", "\x4f\xcf", 0, 0 }, // num - end
+ { "\x1b\x5b\x42", "\x50\xd0", 0, 0 }, // num - arrow down
+ { "\x1b\x5b\x36\x7e", "\x51\xd1", 0, 0 }, // num - pg down
+ { "\x1b\x5b\x32\x7e", "\x52\xd2", 0, 0 }, // num - ins
+ { "\x1b\x5b\x33\x7e", "\x53\xd3", 0, 0 }, // num - del
+ /* ctrl + f[1-12] */
+ { "\033[35~", "\x1d\x3b\xbb\x9d", 0, 0 },
+ { "\033[36~", "\x1d\x3c\xbc\x9d", 0, 0 },
+ { "\033[37~", "\x1d\x3d\xbd\x9d", 0, 0 },
+ { "\033[38~", "\x1d\x3e\xbe\x9d", 0, 0 },
+ { "\033[39~", "\x1d\x3f\xbf\x9d", 0, 0 },
+ { "\033[40~", "\x1d\x40\xc0\x9d", 0, 0 },
+ { "\033[41~", "\x1d\x41\xc1\x9d", 0, 0 },
+ { "\033[42~", "\x1d\x42\xc2\x9d", 0, 0 },
+ { "\033[43~", "\x1d\x43\xc3\x9d", 0, 0 },
+ { "\033[44~", "\x1d\x44\xc4\x9d", 0, 0 },
+ { "\033[45~", "\x1d\x57\xd7\x9d", 0, 0 },
+ { "\033[46~", "\x1d\x58\xd8\x9d", 0, 0 },
+ /* alt + f[1-12] */
+ { "\033[55~", "\x38\x3b\xbb\xb8", 0, 0 },
+ { "\033[56~", "\x38\x3c\xbc\xb8", 0, 0 },
+ { "\033[57~", "\x38\x3d\xbd\xb8", 0, 0 },
+ { "\033[58~", "\x38\x3e\xbe\xb8", 0, 0 },
+ { "\033[59~", "\x38\x3f\xbf\xb8", 0, 0 },
+ { "\033[60~", "\x38\x40\xc0\xb8", 0, 0 },
+ { "\033[61~", "\x38\x41\xc1\xb8", 0, 0 },
+ { "\033[62~", "\x38\x42\xc2\xb8", 0, 0 },
+ { "\033[63~", "\x38\x43\xc3\xb8", 0, 0 },
+ { "\033[64~", "\x38\x44\xc4\xb8", 0, 0 },
+ { "\033[65~", "\x38\x57\xd7\xb8", 0, 0 },
+ { "\033[66~", "\x38\x58\xd8\xb8", 0, 0 },
+ /* shift + F[1-12] */
+ { "\033[75~", "\x2a\x3b\xbb\xaa", 0, 0 },
+ { "\033[76~", "\x2a\x3c\xbc\xaa", 0, 0 },
+ { "\033[77~", "\x2a\x3d\xbd\xaa", 0, 0 },
+ { "\033[78~", "\x2a\x3e\xbe\xaa", 0, 0 },
+ { "\033[79~", "\x2a\x3f\xbf\xaa", 0, 0 },
+ { "\033[80~", "\x2a\x40\xc0\xaa", 0, 0 },
+ { "\033[81~", "\x2a\x41\xc1\xaa", 0, 0 },
+ { "\033[82~", "\x2a\x42\xc2\xaa", 0, 0 },
+ { "\033[83~", "\x2a\x43\xc3\xaa", 0, 0 },
+ { "\033[84~", "\x2a\x44\xc4\xaa", 0, 0 },
+ { "\033[85~", "\x2a\x57\xd7\xaa", 0, 0 },
+ { "\033[86~", "\x2a\x58\xd8\xaa", 0, 0 },
+ /* alt + [:alpha:] */
+ { "\033[altq~", "\x38\x10\x90\xb8", 0, 0 },
+ { "\033[altw~", "\x38\x11\x91\xb8", 0, 0 },
+ { "\033[alte~", "\x38\x12\x92\xb8", 0, 0 },
+ { "\033[altr~", "\x38\x13\x93\xb8", 0, 0 },
+ { "\033[altt~", "\x38\x14\x94\xb8", 0, 0 },
+ { "\033[alty~", "\x38\x15\x95\xb8", 0, 0 },
+ { "\033[altu~", "\x38\x16\x96\xb8", 0, 0 },
+ { "\033[alti~", "\x38\x17\x97\xb8", 0, 0 },
+ { "\033[alto~", "\x38\x18\x98\xb8", 0, 0 },
+ { "\033[altp~", "\x38\x19\x99\xb8", 0, 0 },
+ { "\033[alta~", "\x38\x1e\x9e\xb8", 0, 0 },
+ { "\033[alts~", "\x38\x1f\x9f\xb8", 0, 0 },
+ { "\033[altd~", "\x38\x20\xa0\xb8", 0, 0 },
+ { "\033[altf~", "\x38\x21\xa1\xb8", 0, 0 },
+ { "\033[altg~", "\x38\x22\xa2\xb8", 0, 0 },
+ { "\033[alth~", "\x38\x23\xa3\xb8", 0, 0 },
+ { "\033[altj~", "\x38\x24\xa4\xb8", 0, 0 },
+ { "\033[altk~", "\x38\x25\xa5\xb8", 0, 0 },
+ { "\033[altl~", "\x38\x26\xa6\xb8", 0, 0 },
+ { "\033[altz~", "\x38\x2c\xac\xb8", 0, 0 },
+ { "\033[altx~", "\x38\x2d\xad\xb8", 0, 0 },
+ { "\033[altc~", "\x38\x2e\xae\xb8", 0, 0 },
+ { "\033[altv~", "\x38\x2f\xaf\xb8", 0, 0 },
+ { "\033[altb~", "\x38\x30\xb0\xb8", 0, 0 },
+ { "\033[altn~", "\x38\x31\xb1\xb8", 0, 0 },
+ { "\033[altm~", "\x38\x32\xb2\xb8", 0, 0 },
+ /* alt + [:num:] */
+ { "\033[altone~", "\x38\x02\x82\xb8", 0, 0 },
+ { "\033[alttwo~", "\x38\x03\x83\xb8", 0, 0 },
+ { "\033[altthree~", "\x38\x04\x84\xb8", 0, 0 },
+ { "\033[altfour~", "\x38\x05\x85\xb8", 0, 0 },
+ { "\033[altfive~", "\x38\x06\x86\xb8", 0, 0 },
+ { "\033[altsix~", "\x38\x07\x87\xb8", 0, 0 },
+ { "\033[altseven~", "\x38\x08\x88\xb8", 0, 0 },
+ { "\033[alteight~", "\x38\x09\x89\xb8", 0, 0 },
+ { "\033[altnine~", "\x38\x0a\x8a\xb8", 0, 0 },
+ { "\033[altzero~", "\x38\x0b\x8b\xb8", 0, 0 },
+
+ { 0, 0, 0, 0 }
+};
+
+static reverse_entry_t reverse_short[] = {
+ { "\x1b", "\x01\x81", 0, 0 }, // esc
+ { "\x60", "\x29\xa9", 0, 0 }, // `
+ { "\x31", "\x02\x82", 0, 0 }, // 1
+ { "\x32", "\x03\x83", 0, 0 }, // 2
+ { "\x33", "\x04\x84", 0, 0 }, // 3
+ { "\x34", "\x05\x85", 0, 0 }, // 4
+ { "\x35", "\x06\x86", 0, 0 }, // 5
+ { "\x36", "\x07\x87", 0, 0 }, // 6
+ { "\x37", "\x08\x88", 0, 0 }, // 7
+ { "\x38", "\x09\x89", 0, 0 }, // 8
+ { "\x39", "\x0a\x8a", 0, 0 }, // 9
+ { "\x30", "\x0b\x8b", 0, 0 }, // 0
+ { "\x2d", "\x0c\x8c", 0, 0 }, // -
+ { "\x3d", "\x0d\x8d", 0, 0 }, // =
+ { "\x7f", "\x0e\x8e", 0, 0 }, // backspace
+ { "\x09", "\x0f\x8f", 0, 0 }, // tab
+ /* Well, that's true only for dionis inteface.
+ * In the real world [:alpha:] keys below
+ * must produce 0x2a 0xaa with Shift pressed */
+ { "\x71", "\x2a\x10\x90\xaa", 0, 0 }, // q
+ { "\x77", "\x2a\x11\x91\xaa", 0, 0 }, // w
+ { "\x65", "\x2a\x12\x92\xaa", 0, 0 }, // e
+ { "\x72", "\x2a\x13\x93\xaa", 0, 0 }, // r
+ { "\x74", "\x2a\x14\x94\xaa", 0, 0 }, // t
+ { "\x79", "\x2a\x15\x95\xaa", 0, 0 }, // y
+ { "\x75", "\x2a\x16\x96\xaa", 0, 0 }, // u
+ { "\x69", "\x2a\x17\x97\xaa", 0, 0 }, // i
+ { "\x6f", "\x2a\x18\x98\xaa", 0, 0 }, // o
+ { "\x70", "\x2a\x19\x99\xaa", 0, 0 }, // p
+ { "\x5b", "\x1a\x9a", 0, 0 }, // [
+ { "\x5d", "\x1b\x9b", 0, 0 }, // ]
+ { "\x5c", "\x2b\xab", 0, 0 }, /* \ */
+ { "\x61", "\x2a\x1e\x9e\xaa", 0, 0 }, // a
+ { "\x73", "\x2a\x1f\x9f\xaa", 0, 0 }, // s
+ { "\x64", "\x2a\x20\xa0\xaa", 0, 0 }, // d
+ { "\x66", "\x2a\x21\xa1\xaa", 0, 0 }, // f
+ { "\x67", "\x2a\x22\xa2\xaa", 0, 0 }, // g
+ { "\x68", "\x2a\x23\xa3\xaa", 0, 0 }, // h
+ { "\x6a", "\x2a\x24\xa4\xaa", 0, 0 }, // j
+ { "\x6b", "\x2a\x25\xa5\xaa", 0, 0 }, // k
+ { "\x6c", "\x2a\x26\xa6\xaa", 0, 0 }, // l
+ { "\x3b", "\x27\xa7", 0, 0 }, // ;
+ { "\x27", "\x28\xa8", 0, 0 }, // '
+ { "\x0d", "\x1c\x9c", 0, 0 }, // enter
+ { "\x7a", "\x2a\x2c\xac\xaa", 0, 0 }, // z
+ { "\x78", "\x2a\x2d\xad\xaa", 0, 0 }, // x
+ { "\x63", "\x2a\x2e\xae\xaa", 0, 0 }, // c
+ { "\x76", "\x2a\x2f\xaf\xaa", 0, 0 }, // v
+ { "\x62", "\x2a\x30\xb0\xaa", 0, 0 }, // b
+ { "\x6e", "\x2a\x31\xb1\xaa", 0, 0 }, // n
+ { "\x6d", "\x2a\x32\xb2\xaa", 0, 0 }, // m
+ { "\x2c", "\x33\xb3", 0, 0 }, // ,
+ { "\x2e", "\x34\xb4", 0, 0 }, // .
+ { "\x2f", "\x35\xb5", 0, 0 }, // /
+ { "\x20", "\x39\xb9", 0, 0 }, // space
+ { "\x1c", "\x63\xe3", 0, 0 }, // prt scr
+ { "\x2a", "\x37\xb7", 0, 0 }, // num *
+ { "\x2b", "\x4e\xce", 0, 0 }, // num +
+ /* with 'shift' pressed: */
+ { "\x7e", "\x2a\x29\xa9\xaa", 0, 0 }, // ~
+ { "\x21", "\x2a\x02\x82\xaa", 0, 0 }, // !
+ { "\x40", "\x2a\x03\x83\xaa", 0, 0 }, // @
+ { "\x23", "\x2a\x04\x84\xaa", 0, 0 }, // #
+ { "\x24", "\x2a\x05\x85\xaa", 0, 0 }, // $
+ { "\x25", "\x2a\x06\x86\xaa", 0, 0 }, // %
+ { "\x5e", "\x2a\x07\x87\xaa", 0, 0 }, // ^
+ { "\x26", "\x2a\x08\x88\xaa", 0, 0 }, // &
+ { "\x28", "\x2a\x0a\x8a\xaa", 0, 0 }, // (
+ { "\x29", "\x2a\x0b\x8b\xaa", 0, 0 }, // )
+ { "\x5f", "\x2a\x0c\x8c\xaa", 0, 0 }, // _
+ /* Again, use inversed behavior for [:alpha:] with Shift: */
+ { "\x51", "\x10\x90", 0, 0 }, // Q
+ { "\x57", "\x11\x91", 0, 0 }, // W
+ { "\x45", "\x12\x92", 0, 0 }, // E
+ { "\x52", "\x13\x93", 0, 0 }, // R
+ { "\x54", "\x14\x94", 0, 0 }, // T
+ { "\x59", "\x15\x95", 0, 0 }, // Y
+ { "\x55", "\x16\x96", 0, 0 }, // U
+ { "\x49", "\x17\x97", 0, 0 }, // I
+ { "\x4f", "\x18\x98", 0, 0 }, // O
+ { "\x50", "\x19\x99", 0, 0 }, // P
+ { "\x7b", "\x2a\x1a\x9a\xaa", 0, 0 }, // {
+ { "\x7d", "\x2a\x1b\x9b\xaa", 0, 0 }, // }
+ { "\x7c", "\x2a\x2b\xab\xaa", 0, 0 }, // |
+ { "\x41", "\x1e\x9e", 0, 0 }, // A
+ { "\x53", "\x1f\x9f", 0, 0 }, // S
+ { "\x44", "\x20\xa0", 0, 0 }, // D
+ { "\x46", "\x21\xa1", 0, 0 }, // F
+ { "\x47", "\x22\xa2", 0, 0 }, // G
+ { "\x48", "\x23\xa3", 0, 0 }, // H
+ { "\x4a", "\x24\xa4", 0, 0 }, // J
+ { "\x4b", "\x25\xa5", 0, 0 }, // K
+ { "\x4c", "\x26\xa6", 0, 0 }, // L
+ { "\x3a", "\x2a\x27\xa7\xaa", 0, 0 }, // :
+ { "\x22", "\x2a\x28\xa8\xaa", 0, 0 }, // "
+ { "\x5a", "\x2c\xac", 0, 0 }, // Z
+ { "\x58", "\x2d\xad", 0, 0 }, // X
+ { "\x43", "\x2e\xae", 0, 0 }, // C
+ { "\x56", "\x2f\xaf", 0, 0 }, // V
+ { "\x42", "\x30\xb0", 0, 0 }, // B
+ { "\x4e", "\x31\xb1", 0, 0 }, // N
+ { "\x4d", "\x32\xb2", 0, 0 }, // M
+ { "\x3c", "\x2a\x33\xb3\xaa", 0, 0 }, // <
+ { "\x3e", "\x2a\x34\xb4\xaa", 0, 0 }, // >
+ { "\x3f", "\x2a\x35\xb5\xaa", 0, 0 }, // ?
+ { 0, 0, 0, 0 }
+};
+
+static void xencons_tty_in(char *buf, unsigned len)
+{
+ unsigned i;
+
+ for (i = 0; i < len; ++i)
+ tty_insert_flip_char(xencons_tty, buf[i], 0);
+ tty_flip_buffer_push(xencons_tty);
+}
+
+/**
+ * return -1 if match is not possible
+ * return 0 if in_len bytes are equal
+ * return 1 if match is possible with more raw data provided
+ */
+static int trans_cmp(char *raw, unsigned raw_len, char *in, unsigned in_len)
+{
+ unsigned i, limit;
+ int success_means;
+
+ if (raw_len < in_len) {
+ limit = raw_len;
+ success_means = 1;
+ } else {
+ limit = in_len;
+ success_means = 0;
+ }
+
+ for (i = 0; i < limit; ++i)
+ if (raw[i] != in[i])
+ return -1;
+
+ return success_means;
+}
+
+static void match(void *unused)
+{
+ reverse_entry_t *re, *found;
+ int cmp_res;
+
+ spin_lock(&translate_lock);
+
+try_match:
+ if (!current_in)
+ goto out;
+
+ found = NULL;
+ pending = 0;
+
+ re = reverse_escaped;
+ while (re->in) {
+ cmp_res = trans_cmp(raw_in, current_in, re->in, re->in_len);
+ if (0 == cmp_res) {
+ found = re;
+ goto fnd;
+ } else if (1 == cmp_res) {
+ pending = 1;
+ }
+ ++re;
+ }
+
+ re = reverse_short;
+ while (re->in) {
+ cmp_res = trans_cmp(raw_in, current_in, re->in, re->in_len);
+ if (0 == cmp_res) {
+ found = re;
+ goto fnd;
+ }
+ ++re;
+ }
+fnd:
+ if (found) {
+ xencons_tty_in(found->out, found->out_len);
+ current_in -= found->in_len;
+ if (current_in) {
+ memmove(raw_in, raw_in + found->in_len, current_in);
+ goto try_match;
+ }
+ } else if (!pending) {
+ /* there is no match possible with more data provided,
+ * so remove heading garbage and try again
+ */
+ --current_in;
+ if (current_in) {
+ memmove(raw_in, raw_in + 1, current_in);
+ goto try_match;
+ }
+ }
+out:
+ spin_unlock(&translate_lock);
+}
+
+/**
+ * Idea is to wait for more data if ESC code was found.
+ * It prevents from matching start of escaped sequence to bare esc code.
+ */
+static void translate(char *in, unsigned in_len)
+{
+ unsigned i;
+
+ /* TODO: what? clear raw_in? */
+ if (in_len > sizeof(raw_in) - current_in)
+ return;
+
+ spin_lock(&translate_lock);
+ memcpy(raw_in + current_in, in, in_len);
+ current_in += in_len;
+ spin_unlock(&translate_lock);
+
+ for (i = 0; i < in_len; ++i)
+ if (ESC_CODE_IN == in[i]) {
+ schedule_delayed_work(&match_work, HZ/10);
+ return;
+ }
+
+ if (!match_work.pending)
+ match(NULL);
+}
+
+static void reset_trans(void)
+{
+ spin_lock(&translate_lock);
+ cancel_delayed_work(&match_work);
+ pending = 0;
+ current_in = 0;
+ spin_unlock(&translate_lock);
+}
+
void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
{
- int i;
+#ifdef CONFIG_MAGIC_SYSRQ
+ unsigned i;
+#endif
unsigned long flags;
spin_lock_irqsave(&xencons_lock, flags);
if (xencons_tty == NULL)
goto out;
+#ifdef CONFIG_MAGIC_SYSRQ
for (i = 0; i < len; i++) {
-#ifdef CONFIG_MAGIC_SYSRQ
if (sysrq_enabled) {
if (buf[i] == '\x0f') { /* ^O */
if (!sysrq_requested) {
@@ -378,11 +752,12 @@
}
}
}
+ }
#endif
- tty_insert_flip_char(xencons_tty, buf[i], 0);
- }
- tty_flip_buffer_push(xencons_tty);
-
+ if (K_RAW == xencons_mode)
+ translate(buf, len);
+ else
+ xencons_tty_in(buf, len);
out:
spin_unlock_irqrestore(&xencons_lock, flags);
}
@@ -593,8 +968,10 @@
spin_lock_irqsave(&xencons_lock, flags);
tty->driver_data = NULL;
- if (xencons_tty == NULL)
+ if (xencons_tty == NULL) {
xencons_tty = tty;
+ xencons_mode = K_XLATE;
+ }
__xencons_tx_flush();
spin_unlock_irqrestore(&xencons_lock, flags);
@@ -628,9 +1005,46 @@
tty->closing = 0;
spin_lock_irqsave(&xencons_lock, flags);
xencons_tty = NULL;
+ xencons_mode = K_XLATE;
spin_unlock_irqrestore(&xencons_lock, flags);
+ reset_trans();
}
+static int xencons_ioctl(struct tty_struct *tty, struct file * file,
+ unsigned int cmd, unsigned long arg)
+{
+ unsigned char ucval, perm;
+ long val;
+
+ perm = 0;
+ if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
+ perm = 1;
+
+ switch (cmd) {
+ case KDGKBTYPE:
+ ucval = KB_101;
+ return put_user(ucval, (char __user *)arg);
+
+ case KDGKBMODE:
+ val = xencons_mode;
+ return put_user(val, (long __user *)arg);
+
+ case KDSKBMODE:
+ if (!perm)
+ return -EPERM;
+ if (K_RAW != arg
+ && K_XLATE != arg
+ && K_MEDIUMRAW != arg
+ && K_UNICODE != arg)
+ return -EINVAL;
+ xencons_mode = arg;
+ reset_trans();
+ tty_ldisc_flush(tty);
+ return 0;
+ }
+ return -ENOIOCTLCMD;
+}
+
static struct tty_operations xencons_ops = {
.open = xencons_open,
.close = xencons_close,
@@ -644,12 +1058,29 @@
.throttle = xencons_throttle,
.unthrottle = xencons_unthrottle,
.wait_until_sent = xencons_wait_until_sent,
+ .ioctl = xencons_ioctl,
};
static int __init xencons_init(void)
{
int rc;
+ reverse_entry_t *re;
+ /* initialize reverse tables */
+ re = reverse_escaped;
+ while (re->in) {
+ re->in_len = strlen(re->in);
+ re->out_len = strlen(re->out);
+ ++re;
+ }
+
+ re = reverse_short;
+ while (re->in) {
+ re->in_len = strlen(re->in);
+ re->out_len = strlen(re->out);
+ ++re;
+ }
+
if (!is_running_on_xen())
return -ENODEV;
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-08-25 9:26 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-14 13:58 Access to raw keycodes in xen domU Maxim Gorbachyov
2008-08-14 14:07 ` Keir Fraser
2008-08-14 14:39 ` Ian Jackson
2008-08-14 15:09 ` Maxim Gorbachyov
2008-08-14 15:21 ` Samuel Thibault
2008-08-25 9:26 ` Maxim Gorbachyov
2008-08-14 14:10 ` Samuel Thibault
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.