summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-09-10 17:15:48 +0200
committerGerd Hoffmann <kraxel@redhat.com>2010-09-10 17:15:48 +0200
commitff7a8c7dceecc449cce0513c6d936ca8d0723f56 (patch)
treed6fdd1ef75c9f7913fa78bf2f1497fa9f0ca1416
parentec8d5d0cd37c243b56e26f686df4cfc8691894e9 (diff)
starting keyboard support.
copyed keymaps bits from gtk-vnc.
-rw-r--r--gtk/.gitignore2
-rw-r--r--gtk/Makefile.am39
-rw-r--r--gtk/channel-inputs.c30
-rwxr-xr-xgtk/keymap-gen.pl202
-rw-r--r--gtk/keymaps.csv461
-rw-r--r--gtk/spice-channel.h2
-rw-r--r--gtk/spice-widget.c31
-rw-r--r--gtk/spicy.c3
-rw-r--r--gtk/vncdisplaykeymap.c245
-rw-r--r--gtk/vncdisplaykeymap.h35
10 files changed, 1042 insertions, 8 deletions
diff --git a/gtk/.gitignore b/gtk/.gitignore
index c78b11a..e60ccfe 100644
--- a/gtk/.gitignore
+++ b/gtk/.gitignore
@@ -6,6 +6,6 @@
generated_*marshallers*.c
spice-marshal.c
spice-marshal.h
+vncdisplaykeymap_*.c
snappy
spicy
-
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 32c742c..8b82dd6 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -3,11 +3,21 @@ NULL =
COMMON_DIR=$(SPICE_COMMON_SRCDIR)
CLIENT_DIR=$(top_srcdir)/client
-EXTRA_DIST = spice-marshall.txt
+EXTRA_DIST = spice-marshall.txt keymap-gen.pl keymaps.csv
bin_PROGRAMS = spicy snappy
lib_LTLIBRARIES = libspice-client-gtk.la libspice-client-glib.la
+KEYMAP_GEN = $(srcdir)/keymap-gen.pl
+
+KEYMAPS = \
+ vncdisplaykeymap_xorgevdev2rfb.c \
+ vncdisplaykeymap_xorgkbd2rfb.c \
+ vncdisplaykeymap_xorgxquartz2rfb.c \
+ vncdisplaykeymap_xorgxwin2rfb.c \
+ vncdisplaykeymap_osx2rfb.c \
+ vncdisplaykeymap_win322rfb.c
+
WARN = -Wall -Wno-sign-compare -Wmissing-prototypes -Wpointer-arith -Wunused
INCLUDES = \
@@ -40,6 +50,8 @@ libspice_client_gtk_la_LIBADD = \
libspice_client_gtk_la_SOURCES = \
spice-widget.c \
spice-widget.h \
+ vncdisplaykeymap.c \
+ vncdisplaykeymap.h \
$(NULL)
@@ -155,8 +167,31 @@ generated_marshallers.c: $(top_srcdir)/spice.proto
generated_marshallers1.c: $(top_srcdir)/spice1.proto
$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include messages.h --include marshallers.h --client --prefix 1 --ptrsize 8 $< $@
+vncdisplaykeymap.c: $(KEYMAPS)
+
+$(KEYMAPS): $(KEYMAP_GEN) keymaps.csv
+
+vncdisplaykeymap_xorgevdev2rfb.c:
+ $(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgevdev rfb > $@ || rm $@
+
+vncdisplaykeymap_xorgkbd2rfb.c:
+ $(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgkbd rfb > $@ || rm $@
+
+vncdisplaykeymap_xorgxquartz2rfb.c:
+ $(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgxquartz rfb > $@ || rm $@
+
+vncdisplaykeymap_xorgxwin2rfb.c:
+ $(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgxwin rfb > $@ || rm $@
+
+vncdisplaykeymap_osx2rfb.c:
+ $(KEYMAP_GEN) $(srcdir)/keymaps.csv osx rfb > $@ || rm $@
+
+vncdisplaykeymap_win322rfb.c:
+ $(KEYMAP_GEN) $(srcdir)/keymaps.csv win32 rfb > $@ || rm $@
+
BUILT_SOURCES = spice-marshal.c spice-marshal.h \
generated_demarshallers.c generated_demarshallers1.c \
- generated_marshallers.c generated_marshallers1.c
+ generated_marshallers.c generated_marshallers1.c \
+ $(KEYMAPS)
CLEANFILES = $(BUILT_SOURCES)
diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c
index 88eef06..83d1154 100644
--- a/gtk/channel-inputs.c
+++ b/gtk/channel-inputs.c
@@ -149,3 +149,33 @@ void spice_inputs_button_release(SpiceChannel *channel, gint button, gint button
spice_msg_out_send(msg);
spice_msg_out_put(msg);
}
+
+void spice_inputs_key_press(SpiceChannel *channel, guint scancode)
+{
+ spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
+ SpiceMsgcKeyDown down = {
+ .code = scancode,
+ };
+ spice_msg_out *msg;
+
+ fprintf(stderr, "%s: scancode %d\n", __FUNCTION__, scancode);
+ msg = spice_msg_out_new(channel, SPICE_MSGC_INPUTS_KEY_DOWN);
+ c->marshallers->msgc_inputs_key_down(msg->marshaller, &down);
+ spice_msg_out_send(msg);
+ spice_msg_out_put(msg);
+}
+
+void spice_inputs_key_release(SpiceChannel *channel, guint scancode)
+{
+ spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
+ SpiceMsgcKeyUp up = {
+ .code = scancode | 0x80,
+ };
+ spice_msg_out *msg;
+
+ fprintf(stderr, "%s: scancode %d\n", __FUNCTION__, scancode);
+ msg = spice_msg_out_new(channel, SPICE_MSGC_INPUTS_KEY_UP);
+ c->marshallers->msgc_inputs_key_up(msg->marshaller, &up);
+ spice_msg_out_send(msg);
+ spice_msg_out_put(msg);
+}
diff --git a/gtk/keymap-gen.pl b/gtk/keymap-gen.pl
new file mode 100755
index 0000000..fd96bdf
--- /dev/null
+++ b/gtk/keymap-gen.pl
@@ -0,0 +1,202 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Text::CSV;
+
+my %names = (
+ linux => [],
+ osx => []
+);
+
+my %namecolumns = (
+ linux => 0,
+ osx => 2,
+ win32 => 10,
+ );
+
+# Base data sources:
+#
+# linux: Linux: linux/input.h (master set)
+# osx: OS-X: Carbon/HIToolbox/Events.h (manually mapped)
+# atset1: AT Set 1: linux/drivers/input/keyboard/atkbd.c (atkbd_set2_keycode + atkbd_unxlate_table)
+# atset2: AT Set 2: linux/drivers/input/keyboard/atkbd.c (atkbd_set2_keycode)
+# atset3: AT Set 3: linux/drivers/input/keyboard/atkbd.c (atkbd_set3_keycode)
+# xt: XT: linux/drivers/input/keyboard/xt.c (xtkbd_keycode)
+# xtkbd: Linux RAW: linux/drivers/char/keyboard.c (x86_keycodes)
+# usb: USB HID: linux/drivers/hid/usbhid/usbkbd.c (usb_kbd_keycode)
+# win32: Win32: mingw32/winuser.h (manually mapped)
+# xwinxt: XWin XT: xorg-server/hw/xwin/{winkeybd.c,winkeynames.h} (xt + manually transcribed)
+# xkbdxt: XKBD XT: xf86-input-keyboard/src/at_scancode.c (xt + manually transcribed)
+#
+# Derived data sources
+#
+# xorgevdev: Xorg + evdev: linux + an offset
+# xorgkbd: Xorg + kbd: xkbdxt + an offset
+# xorgxquartz: Xorg + OS-X: osx + an offset
+# xorgxwin: Xorg + Cygwin: xwinxt + an offset
+# rfb: XT over RFB: xtkbd + special re-encoding of high bit
+
+my @basemaps = qw(linux osx atset1 atset2 atset3 xt xtkbd usb win32 xwinxt xkbdxt);
+my @derivedmaps = qw(xorgevdev xorgkbd xorgxquartz xorgxwin rfb);
+my @maps = (@basemaps, @derivedmaps);
+
+my %maps;
+
+foreach my $map (@maps) {
+ $maps{$map} = [ [], [] ];
+}
+my %mapcolumns = (
+ osx => 3,
+ atset1 => 4,
+ atset2 => 5,
+ atset3 => 6,
+ xt => 7,
+ xtkbd => 8,
+ usb => 9,
+ win32 => 11,
+ xwinxt => 12,
+ xkbdxt => 13,
+ );
+
+sub help {
+ my $msg = shift;
+ print $msg;
+ print "\n";
+ print "Valid keymaps are:\n";
+ print "\n";
+ foreach my $name (sort { $a cmp $b } keys %maps) {
+ print " $name\n";
+ }
+ print "\n";
+ exit (1);
+}
+
+if ($#ARGV != 2) {
+ help("syntax: $0 KEYMAPS SRCMAP DSTMAP\n");
+}
+
+my $keymaps = shift @ARGV;
+my $src = shift @ARGV;
+my $dst = shift @ARGV;
+
+help("$src is not a known keymap\n") unless exists $maps{$src};
+help("$dst is not a known keymap\n") unless exists $maps{$dst};
+
+
+open CSV, $keymaps
+ or die "cannot read $keymaps: $!";
+
+my $csv = Text::CSV->new();
+# Discard column headings
+$csv->getline(\*CSV);
+
+my $row;
+while ($row = $csv->getline(\*CSV)) {
+ my $linux = $row->[1];
+
+ $linux = hex($linux) if $linux =~ /0x/;
+
+ my $to = $maps{linux}->[0];
+ my $from = $maps{linux}->[1];
+ $to->[$linux] = $linux;
+ $from->[$linux] = $linux;
+
+ foreach my $name (keys %namecolumns) {
+ my $col = $namecolumns{$name};
+ my $val = $row->[$col];
+
+ $val = "" unless defined $val;
+
+ $names{$name}->[$linux] = $val;
+ }
+
+ foreach my $name (keys %mapcolumns) {
+ my $col = $mapcolumns{$name};
+ my $val = $row->[$col];
+
+ $val = 0 unless $val;
+ $val = hex($val) if $val =~ /0x/;
+
+ $to = $maps{$name}->[0];
+ $from = $maps{$name}->[1];
+ $to->[$linux] = $val;
+ $from->[$val] = $linux;
+ }
+
+ # XXX there are some special cases in kbd to handle
+ # Xorg KBD driver is the Xorg KBD XT codes offset by +8
+ # The XKBD XT codes are the same as normal XT codes
+ # for values <= 83, and completely made up for extended
+ # scancodes :-(
+ ($to, $from) = @{$maps{xorgkbd}};
+ $to->[$linux] = $maps{xkbdxt}->[0]->[$linux] + 8;
+ $from->[$to->[$linux]] = $linux;
+
+ # Xorg evdev is simply Linux keycodes offset by +8
+ ($to, $from) = @{$maps{xorgevdev}};
+ $to->[$linux] = $linux + 8;
+ $from->[$to->[$linux]] = $linux;
+
+ # Xorg XQuartz is simply OS-X keycodes offset by +8
+ ($to, $from) = @{$maps{xorgxquartz}};
+ $to->[$linux] = $maps{osx}->[0]->[$linux] + 8;
+ $from->[$to->[$linux]] = $linux;
+
+ # RFB keycodes are XT kbd keycodes with a slightly
+ # different encoding of 0xe0 scan codes. RFB uses
+ # the high bit of the first byte, instead of the low
+ # bit of the second byte.
+ ($to, $from) = @{$maps{rfb}};
+ my $xtkbd = $maps{xtkbd}->[0]->[$linux];
+ $to->[$linux] = $xtkbd ? (($xtkbd & 0x100)>>1) | ($xtkbd & 0x7f) : 0;
+ $from->[$to->[$linux]] = $linux;
+
+ # Xorg Cygwin is the Xorg Cygwin XT codes offset by +8
+ # The Cygwin XT codes are the same as normal XT codes
+ # for values <= 83, and completely made up for extended
+ # scancodes :-(
+ ($to, $from) = @{$maps{xorgxwin}};
+ $to->[$linux] = $maps{xwinxt}->[0]->[$linux] + 8;
+ $from->[$to->[$linux]] = $linux;
+
+# print $linux, "\n";
+}
+
+close CSV;
+
+my $srcmap = $maps{$src}->[1];
+my $dstmap = $maps{$dst}->[0];
+
+printf "static const guint16 keymap_%s2%s[] = {\n", $src, $dst;
+
+for (my $i = 0 ; $i <= $#{$srcmap} ; $i++) {
+ my $linux = $srcmap->[$i] || 0;
+ my $j = $dstmap->[$linux];
+ next unless $linux && $j;
+
+ my $srcname = $names{$src}->[$linux] if exists $names{$src};
+ my $dstname = $names{$dst}->[$linux] if exists $names{$dst};
+ my $vianame = $names{linux}->[$linux] unless $src eq "linux" || $dst eq "linux";
+
+ $srcname = "" unless $srcname;
+ $dstname = "" unless $dstname;
+ $vianame = "" unless $vianame;
+ $srcname = " ($srcname)" if $srcname;
+ $dstname = " ($dstname)" if $dstname;
+ $vianame = " ($vianame)" if $vianame;
+
+ my $comment;
+ if ($src ne "linux" && $dst ne "linux") {
+ $comment = sprintf "%d%s => %d%s via %d%s", $i, $srcname, $j, $dstname, $linux, $vianame;
+ } else {
+ $comment = sprintf "%d%s => %d%s", $i, $srcname, $j, $dstname;
+ }
+
+ my $data = sprintf "[0x%x] = 0x%x,", $i, $j;
+
+ printf " %-20s /* %s */\n", $data, $comment;
+}
+
+print "};\n";
diff --git a/gtk/keymaps.csv b/gtk/keymaps.csv
new file mode 100644
index 0000000..275dc17
--- /dev/null
+++ b/gtk/keymaps.csv
@@ -0,0 +1,461 @@
+"Linux Name","Linux Keycode","OS-X Name","OS-X Keycode","AT set1 keycode","AT set2 keycode","AT set3 keycode",XT,"XT KBD","USB Keycodes","Win32 Name","Win32 Keycode","Xwin XT","Xfree86 KBD XT"
+KEY_RESERVED,0,,0x0,,,,,,,,,,
+KEY_ESC,1,Escape,0x35,1,118,8,1,1,41,VK_ESCAPE,0x1b,1,1
+KEY_1,2,ANSI_1,0x12,2,22,22,2,2,30,VK_1,0x31,2,2
+KEY_2,3,ANSI_2,0x13,3,30,30,3,3,31,VK_2,0x32,3,3
+KEY_3,4,ANSI_3,0x14,4,38,38,4,4,32,VK_3,0x33,4,4
+KEY_4,5,ANSI_4,0x15,5,37,37,5,5,33,VK_4,0x34,5,5
+KEY_5,6,ANSI_5,0x17,6,46,46,6,6,34,VK_5,0x35,6,6
+KEY_6,7,ANSI_6,0x16,7,54,54,7,7,35,VK_6,0x36,7,7
+KEY_7,8,ANSI_7,0x1a,8,61,61,8,8,36,VK_7,0x37,8,8
+KEY_8,9,ANSI_8,0x1c,9,62,62,9,9,37,VK_8,0x38,9,9
+KEY_9,10,ANSI_9,0x19,10,70,70,10,10,38,VK_9,0x39,10,10
+KEY_0,11,ANSI_0,0x1d,11,69,69,11,11,39,VK_0,0x30,11,11
+KEY_MINUS,12,ANSI_Minus,0x1b,12,78,78,12,12,45,VK_OEM_MINUS,0xbd,12,12
+KEY_EQUAL,13,ANSI_Equal,0x18,13,85,85,13,13,46,VK_OEM_PLUS,0xbb,13,13
+KEY_BACKSPACE,14,Delete,0x33,14,102,102,14,14,42,VK_BACK,0x08,14,14
+KEY_TAB,15,Tab,0x30,15,13,13,15,15,43,VK_TAB,0x09,15,15
+KEY_Q,16,ANSI_Q,0xc,16,21,21,16,16,20,VK_Q,0x51,16,16
+KEY_W,17,ANSI_W,0xd,17,29,29,17,17,26,VK_W,0x57,17,17
+KEY_E,18,ANSI_E,0xe,18,36,36,18,18,8,VK_E,0x45,18,18
+KEY_R,19,ANSI_R,0xf,19,45,45,19,19,21,VK_R,0x52,19,19
+KEY_T,20,ANSI_T,0x11,20,44,44,20,20,23,VK_T,0x54,20,20
+KEY_Y,21,ANSI_Y,0x10,21,53,53,21,21,28,VK_Y,0x59,21,21
+KEY_U,22,ANSI_U,0x20,22,60,60,22,22,24,VK_U,0x55,22,22
+KEY_I,23,ANSI_I,0x22,23,67,67,23,23,12,VK_I,0x49,23,23
+KEY_O,24,ANSI_O,0x1f,24,68,68,24,24,18,VK_O,0x4f,24,24
+KEY_P,25,ANSI_P,0x23,25,77,77,25,25,19,VK_P,0x50,25,25
+KEY_LEFTBRACE,26,ANSI_LeftBracket,0x21,26,84,84,26,26,47,VK_OEM_4,0xdb,26,26
+KEY_RIGHTBRACE,27,ANSI_RightBracket,0x1e,27,91,91,27,27,48,VK_OEM_6,0xdd,27,27
+KEY_ENTER,28,Return,0x24,28,90,90,28,28,40,VK_RETURN,0x0d,28,28
+KEY_LEFTCTRL,29,Control,0x3b,29,20,17,29,29,224,VK_LCONTROL,0xa2,29,29
+KEY_A,30,ANSI_A,0x0,30,28,28,30,30,4,VK_A,0x41,30,30
+KEY_S,31,ANSI_S,0x1,31,27,27,31,31,22,VK_S,0x53,31,31
+KEY_D,32,ANSI_D,0x2,32,35,35,32,32,7,VK_D,0x44,32,32
+KEY_F,33,ANSI_F,0x3,33,43,43,33,33,9,VK_F,0x46,33,33
+KEY_G,34,ANSI_G,0x5,34,52,52,34,34,10,VK_G,0x47,34,34
+KEY_H,35,ANSI_H,0x4,35,51,51,35,35,11,VK_H,0x48,35,35
+KEY_J,36,ANSI_J,0x26,36,59,59,36,36,13,VK_J,0x4a,36,36
+KEY_K,37,ANSI_K,0x28,37,66,66,37,37,14,VK_K,0x4b,37,37
+KEY_L,38,ANSI_L,0x25,38,75,75,38,38,15,VK_L,0x4c,38,38
+KEY_SEMICOLON,39,ANSI_Semicolon,0x29,39,76,76,39,39,51,VK_OEM_1,0xba,39,39
+KEY_APOSTROPHE,40,ANSI_Quote,0x27,40,82,82,40,40,52,VK_OEM_2,0xbf,40,40
+KEY_GRAVE,41,ANSI_Grave,0x32,41,14,14,41,41,53,VK_OEM_3,0xc0,41,41
+KEY_LEFTSHIFT,42,Shift,0x38,42,18,18,42,42,225,VK_LSHIFT,0xa0,42,42
+KEY_BACKSLASH,43,ANSI_Backslash,0x2a,43,93,93,43,43,50,VK_OEM_5,0xdc,43,43
+KEY_Z,44,ANSI_Z,0x6,44,26,26,44,44,29,VK_Z,0x5a,44,44
+KEY_X,45,ANSI_X,0x7,45,34,34,45,45,27,VK_X,0x58,45,45
+KEY_C,46,ANSI_C,0x8,46,33,33,46,46,6,VK_C,0x43,46,46
+KEY_V,47,ANSI_V,0x9,47,42,42,47,47,25,VK_V,0x56,47,47
+KEY_B,48,ANSI_B,0xb,48,50,50,48,48,5,VK_B,0x42,48,48
+KEY_N,49,ANSI_N,0x2d,49,49,49,49,49,17,VK_N,0x4e,49,49
+KEY_M,50,ANSI_M,0x2e,50,58,58,50,50,16,VK_M,0x4d,50,50
+KEY_COMMA,51,ANSI_Comma,0x2b,51,65,65,51,51,54,VK_OEM_COMMA,0xbc,51,51
+KEY_DOT,52,ANSI_Period,0x2f,52,73,73,52,52,55,VK_OEM_PERIOD,0xbe,52,52
+KEY_SLASH,53,ANSI_Slash,0x2c,53,74,74,53,53,56,VK_OEM_2,0xbf,53,53
+KEY_RIGHTSHIFT,54,RightShift,0x3c,54,89,89,54,54,229,VK_RSHIFT,0xa1,54,54
+KEY_KPASTERISK,55,ANSI_KeypadMultiply,0x43,55,124,126,55,55,85,VK_MULTIPLY,0x6a,55,55
+KEY_LEFTALT,56,Option,0x3a,56,17,25,56,56,226,VK_LMENU,0xa4,56,56
+KEY_SPACE,57,Space,0x31,57,41,41,57,57,44,VK_SPACE,0x20,57,57
+KEY_CAPSLOCK,58,CapsLock,0x39,58,88,20,58,58,57,VK_CAPITAL,0x14,58,58
+KEY_F1,59,F1,0x7a,59,5,7,59,59,58,VK_F1,0x70,59,59
+KEY_F2,60,F2,0x78,60,6,15,60,60,59,VK_F2,0x71,60,60
+KEY_F3,61,F3,0x63,61,4,23,61,61,60,VK_F3,0x72,61,61
+KEY_F4,62,F4,0x76,62,12,31,62,62,61,VK_F4,0x73,62,62
+KEY_F5,63,F5,0x60,63,3,39,63,63,62,VK_F5,0x74,63,63
+KEY_F6,64,F6,0x61,64,11,47,64,64,63,VK_F6,0x75,64,64
+KEY_F7,65,F7,0x62,65,259,55,65,65,64,VK_F7,0x76,65,65
+KEY_F8,66,F8,0x64,66,10,63,66,66,65,VK_F8,0x77,66,66
+KEY_F9,67,F9,0x65,67,1,71,67,67,66,VK_F9,0x78,67,67
+KEY_F10,68,F10,0x6d,68,9,79,68,68,67,VK_F10,0x79,68,68
+KEY_NUMLOCK,69,,,69,119,118,69,69,83,VK_NUMLOCK,0x90,69,69
+KEY_SCROLLLOCK,70,,,70,126,95,70,70,71,VK_SCROLL,0x91,70,70
+KEY_KP7,71,ANSI_Keypad7,0x59,71,108,108,71,71,95,VK_NUMPAD7,0x67,71,71
+KEY_KP8,72,ANSI_Keypad8,0x5b,72,117,117,72,72,96,VK_NUMPAD8,0x68,72,72
+KEY_KP9,73,ANSI_Keypad9,0x5c,73,125,125,73,73,97,VK_NUMPAD9,0x69,73,73
+KEY_KPMINUS,74,ANSI_KeypadMinus,0x4e,74,123,132,74,74,86,VK_SUBTRACT,0x6d,74,74
+KEY_KP4,75,ANSI_Keypad4,0x56,75,107,107,75,75,92,VK_NUMPAD4,0x64,75,75
+KEY_KP5,76,ANSI_Keypad5,0x57,76,115,115,76,76,93,VK_NUMPAD5,0x65,76,76
+KEY_KP6,77,ANSI_Keypad6,0x58,77,116,116,77,77,94,VK_NUMPAD6,0x66,77,77
+KEY_KPPLUS,78,ANSI_KeypadPlus,0x45,78,121,124,78,78,87,VK_ADD,0x6b,78,78
+KEY_KP1,79,ANSI_Keypad1,0x53,79,105,105,79,79,89,VK_NUMPAD1,0x61,79,79
+KEY_KP2,80,ANSI_Keypad2,0x54,80,114,114,80,80,90,VK_NUMPAD2,0x62,80,80
+KEY_KP3,81,ANSI_Keypad3,0x55,81,122,122,81,81,91,VK_NUMPAD3,0x63,81,81
+KEY_KP0,82,ANSI_Keypad0,0x52,82,112,112,82,82,98,VK_NUMPAD0,0x60,82,82
+KEY_KPDOT,83,ANSI_KeypadDecimal,0x41,83,113,113,83,83,99,VK_DECIMAL,0x6e,83,83
+,84,,,,,,,84,,,,,
+KEY_ZENKAKUHANKAKU,85,,,118,95,,,118,148,,,,
+KEY_102ND,86,,,86,97,19,,86,100,VK_OEM_102,0xe1,,
+KEY_F11,87,F11,0x67,87,120,86,101,87,68,VK_F11,0x7a,,
+KEY_F12,88,F12,0x6f,88,7,94,102,88,69,VK_F12,0x7b,,
+KEY_RO,89,,,115,81,,,115,135,,,,
+KEY_KATAKANA,90,JIS_Kana????,0x68,120,99,,,120,146,VK_KANA,0x15,,
+KEY_HIRAGANA,91,,,119,98,,,119,147,,,,
+KEY_HENKAN,92,,,121,100,134,,121,138,,,,
+KEY_KATAKANAHIRAGANA,93,,,112,19,135,,,136,,,0xc8,0xc8
+KEY_MUHENKAN,94,,,123,103,133,,123,139,,,,
+KEY_KPJPCOMMA,95,JIS_KeypadComma,0x5f,92,39,,,92,140,,,,
+KEY_KPENTER,96,ANSI_KeypadEnter,0x4c,,158,121,,284,88,,,0x64,0x64
+KEY_RIGHTCTRL,97,RightControl,0x3e,,,88,,285,228,VK_RCONTROL,0xa3,0x65,0x65
+KEY_KPSLASH,98,ANSI_KeypadDivide,0x4b,,181,119,,309,84,VK_DIVIDE,0x6f,0x68,0x68
+KEY_SYSRQ,99,,,84,260,87,,84,70,"VK_SNAPSHOT ???",0x2c,0x67,0x67
+KEY_RIGHTALT,100,RightOption,0x3d,,,57,,312,230,VK_RMENU,0xa5,0x69,0x69
+KEY_LINEFEED,101,,,,,,,91,,,,,
+KEY_HOME,102,Home,0x73,,224,110,,327,74,VK_HOME,0x24,0x59,0x59
+KEY_UP,103,UpArrow,0x7e,,236,99,109,328,82,VK_UP,0x26,0x5a,0x5a
+KEY_PAGEUP,104,PageUp,0x74,,201,111,,329,75,VK_PRIOR,0x21,0x5b,0x5b
+KEY_LEFT,105,LeftArrow,0x7b,,203,97,111,331,80,VK_LEFT,0x25,0x5c,0x5c
+KEY_RIGHT,106,RightArrow,0x7c,,205,106,112,333,79,VK_RIGHT,0x27,0x5e,0x5e
+KEY_END,107,End,0x77,,225,101,,335,77,VK_END,0x23,0x5f,0x5f
+KEY_DOWN,108,DownArrow,0x7d,,254,96,110,336,81,VK_DOWN,0x28,0x60,0x60
+KEY_PAGEDOWN,109,PageDown,0x79,,243,109,,337,78,VK_NEXT,0x22,0x61,0x61
+KEY_INSERT,110,,,,210,103,107,338,73,VK_INSERT,0x2d,0x62,0x62
+KEY_DELETE,111,ForwardDelete,0x75,,244,100,108,339,76,VK_DELETE,0x2e,0x63,0x63
+KEY_MACRO,112,,,,239,142,,367,,,,,
+KEY_MUTE,113,Mute,0x4a,,251,156,,288,239,VK_VOLUME_MUTE,0xad,,
+KEY_VOLUMEDOWN,114,VolumeDown,0x49,,,157,,302,238,VK_VOLUME_DOWN,0xae,,
+KEY_VOLUMEUP,115,VolumeUp,0x48,,233,149,,304,237,VK_VOLUME_UP,0xaf,,
+KEY_POWER,116,,,,,,,350,102,,,,
+KEY_KPEQUAL,117,ANSI_KeypadEquals,0x51,89,15,,,89,103,,,0x76,0x76
+KEY_KPPLUSMINUS,118,,,,206,,,334,,,,,
+KEY_PAUSE,119,,,,198,98,,326,72,VK_PAUSE,0x013,0x66,0x66
+KEY_SCALE,120,,,,,,,267,,,,,
+KEY_KPCOMMA,121,ANSI_KeypadClear????,0x47,126,109,,,126,133,VK_SEPARATOR??,0x6c,,
+KEY_HANGEUL,122,,,,,,,,144,VK_HANGEUL,0x15,,
+KEY_HANJA,123,,,,,,,269,145,VK_HANJA,0x19,,
+KEY_YEN,124,JIS_Yen,0x5d,125,106,,,125,137,,,0x7d,0x7d
+KEY_LEFTMETA,125,Command,0x37,,,139,,347,227,VK_LWIN,0x5b,0x6b,0x6b
+KEY_RIGHTMETA,126,,,,,140,,348,231,VK_RWIN,0x5c,0x6c,0x6c
+KEY_COMPOSE,127,Function,0x3f,,,141,,349,101,VK_APPS,0x5d,0x6d,0x6d
+KEY_STOP,128,,,,,10,,360,243,VK_BROWSER_STOP,0xa9,,
+KEY_AGAIN,129,,,,,11,,261,121,,,,
+KEY_PROPS,130,,,,,12,,262,118,,,,
+KEY_UNDO,131,,,,,16,,263,122,,,,
+KEY_FRONT,132,,,,,,,268,119,,,,
+KEY_COPY,133,,,,,24,,376,124,,,,
+KEY_OPEN,134,,,,,32,,100,116,,,,
+KEY_PASTE,135,,,,,40,,101,125,,,,
+KEY_FIND,136,,,,,48,,321,244,,,,
+KEY_CUT,137,,,,,56,,316,123,,,,
+KEY_HELP,138,,,,,9,,373,117,VK_HELP,0x2f,,
+KEY_MENU,139,,,,,145,,286,,,,,
+KEY_CALC,140,,,,174,163,,289,251,,,,
+KEY_SETUP,141,,,,,,,102,,,,,
+KEY_SLEEP,142,,,,,,,351,248,VK_SLEEP,0x5f,,
+KEY_WAKEUP,143,,,,,,,355,,,,,
+KEY_FILE,144,,,,,,,103,,,,,
+KEY_SENDFILE,145,,,,,,,104,,,,,
+KEY_DELETEFILE,146,,,,,,,105,,,,,
+KEY_XFER,147,,,,,162,,275,,,,,
+KEY_PROG1,148,,,,,160,,287,,,,,
+KEY_PROG2,149,,,,,161,,279,,,,,
+KEY_WWW,150,,,,,,,258,240,,,,
+KEY_MSDOS,151,,,,,,,106,,,,,
+KEY_SCREENLOCK,152,,,,,150,,274,249,,,,
+KEY_DIRECTION,153,,,,,,,107,,,,,
+KEY_CYCLEWINDOWS,154,,,,,155,,294,,,,,
+KEY_MAIL,155,,,,,,,364,,,,,
+KEY_BOOKMARKS,156,,,,,,,358,,,,,
+KEY_COMPUTER,157,,,,,,,363,,,,,
+KEY_BACK,158,,,,,,,362,241,VK_BROWSER_BACK,0xa6,,
+KEY_FORWARD,159,,,,,,,361,242,VK_BROWSER_FORWARD,0xa7,,
+KEY_CLOSECD,160,,,,,154,,291,,,,,
+KEY_EJECTCD,161,,,,,,,108,236,,,,
+KEY_EJECTCLOSECD,162,,,,,,,381,,,,,
+KEY_NEXTSONG,163,,,,241,147,,281,235,VK_MEDIA_NEXT_TRACK,0xb0,,
+KEY_PLAYPAUSE,164,,,,173,,,290,232,VK_MEDIA_PLAY_PAUSE,0xb3,,
+KEY_PREVIOUSSONG,165,,,,250,148,,272,234,VK_MEDIA_PREV_TRACK,0xb1,,
+KEY_STOPCD,166,,,,164,152,,292,233,VK_MEDIA_STOP,0xb2,,
+KEY_RECORD,167,,,,,158,,305,,,,,
+KEY_REWIND,168,,,,,159,,280,,,,,
+KEY_PHONE,169,,,,,,,99,,,,,
+KEY_ISO,170,ISO_Section,0xa,,,,,112,,,,,
+KEY_CONFIG,171,,,,,,,257,,,,,
+KEY_HOMEPAGE,172,,,,178,151,,306,,VK_BROWSER_HOME,0xac,,
+KEY_REFRESH,173,,,,,,,359,250,VK_BROWSER_REFRESH,0xa8,,
+KEY_EXIT,174,,,,,,,113,,,,,
+KEY_MOVE,175,,,,,,,114,,,,,
+KEY_EDIT,176,,,,,,,264,247,,,,
+KEY_SCROLLUP,177,,,,,,,117,245,,,,
+KEY_SCROLLDOWN,178,,,,,,,271,246,,,,
+KEY_KPLEFTPAREN,179,,,,,,,374,182,,,,
+KEY_KPRIGHTPAREN,180,,,,,,,379,183,,,,
+KEY_NEW,181,,,,,,,265,,,,,
+KEY_REDO,182,,,,,,,266,,,,,
+KEY_F13,183,F13,0x69,93,47,127,,93,104,VK_F13,0x7c,0x6e,0x6e
+KEY_F14,184,F14,0x6b,94,55,128,,94,105,VK_F14,0x7d,0x6f,0x6f
+KEY_F15,185,F15,0x71,95,63,129,,95,106,VK_F15,0x7e,0x70,0x70
+KEY_F16,186,F16,0x6a,,,130,,85,107,VK_F16,0x7f,0x71,0x71
+KEY_F17,187,F17,0x40,,,131,,259,108,VK_F17,0x80,0x72,0x72
+KEY_F18,188,F18,0x4f,,,,,375,109,VK_F18,0x81,,
+KEY_F19,189,F19,0x50,,,,,260,110,VK_F19,0x82,,
+KEY_F20,190,F20,0x5a,,,,,90,111,VK_F20,0x83,,
+KEY_F21,191,,,,,,,116,112,VK_F21,0x84,,
+KEY_F22,192,,,,,,,377,113,VK_F22,0x85,,
+KEY_F23,193,,,,,,,109,114,VK_F23,0x86,,
+KEY_F24,194,,,,,,,111,115,VK_F24,0x87,,
+,195,,,,,,,277,,,,,
+,196,,,,,,,278,,,,,
+,197,,,,,,,282,,,,,
+,198,,,,,,,283,,,,,
+,199,,,,,,,295,,,,,
+KEY_PLAYCD,200,,,,,,,296,,,,,
+KEY_PAUSECD,201,,,,,,,297,,,,,
+KEY_PROG3,202,,,,,,,299,,,,,
+KEY_PROG4,203,,,,,,,300,,,,,
+KEY_DASHBOARD,204,,,,,,,301,,,,,
+KEY_SUSPEND,205,,,,,,,293,,,,,
+KEY_CLOSE,206,,,,,,,303,,,,,
+KEY_PLAY,207,,,,,,,307,,VK_PLAY,0xfa,,
+KEY_FASTFORWARD,208,,,,,,,308,,,,,
+KEY_BASSBOOST,209,,,,,,,310,,,,,
+KEY_PRINT,210,,,,,,,313,,VK_PRINT,0x2a,,
+KEY_HP,211,,,,,,,314,,,,,
+KEY_CAMERA,212,,,,,,,315,,,,,
+KEY_SOUND,213,,,,,,,317,,,,,
+KEY_QUESTION,214,,,,,,,318,,,,,
+KEY_EMAIL,215,,,,,,,319,,VK_LAUNCH_MAIL,0xb4,,
+KEY_CHAT,216,,,,,,,320,,,,,
+KEY_SEARCH,217,,,,,,,357,,VK_BROWSER_SEARCH,0xaa,,
+KEY_CONNECT,218,,,,,,,322,,,,,
+KEY_FINANCE,219,,,,,,,323,,,,,
+KEY_SPORT,220,,,,,,,324,,,,,
+KEY_SHOP,221,,,,,,,325,,,,,
+KEY_ALTERASE,222,,,,,,,276,,,,,
+KEY_CANCEL,223,,,,,,,330,,,,,
+KEY_BRIGHTNESSDOWN,224,,,,,,,332,,,,,
+KEY_BRIGHTNESSUP,225,,,,,,,340,,,,,
+KEY_MEDIA,226,,,,,,,365,,,,,
+KEY_SWITCHVIDEOMODE,227,,,,,,,342,,,,,
+KEY_KBDILLUMTOGGLE,228,,,,,,,343,,,,,
+KEY_KBDILLUMDOWN,229,,,,,,,344,,,,,
+KEY_KBDILLUMUP,230,,,,,,,345,,,,,
+KEY_SEND,231,,,,,,,346,,,,,
+KEY_REPLY,232,,,,,,,356,,,,,
+KEY_FORWARDMAIL,233,,,,,,,270,,,,,
+KEY_SAVE,234,,,,,,,341,,,,,
+KEY_DOCUMENTS,235,,,,,,,368,,,,,
+KEY_BATTERY,236,,,,,,,369,,,,,
+KEY_BLUETOOTH,237,,,,,,,370,,,,,
+KEY_WLAN,238,,,,,,,371,,,,,
+KEY_UWB,239,,,,,,,372,,,,,
+KEY_UNKNOWN,240,,,,,,,,,,,,
+KEY_VIDEO_NEXT,241,,,,,,,,,,,,
+KEY_VIDEO_PREV,242,,,,,,,,,,,,
+KEY_BRIGHTNESS_CYCLE,243,,,,,,,,,,,,
+KEY_BRIGHTNESS_ZERO,244,,,,,,,,,,,,
+KEY_DISPLAY_OFF,245,,,,,,,,,,,,
+KEY_WIMAX,246,,,,,,,,,,,,
+,247,,,,,,,,,,,,
+,248,,,,,,,,,,,,
+,249,,,,,,,,,,,,
+,250,,,,,,,,,,,,
+,251,,,,,,,,,,,,
+,252,,,,,,,,,,,,
+,253,,,,,,,,,,,,
+,254,,,,,,,,,,,,
+,255,,,,182,,,,,,,,
+BTN_MISC,0x100,,,,,,,,,,,,
+BTN_0,0x100,,,,,,,,,VK_LBUTTON,0x01,,
+BTN_1,0x101,,,,,,,,,VK_RBUTTON,0x02,,
+BTN_2,0x102,,,,,,,,,VK_MBUTTON,0x04,,
+BTN_3,0x103,,,,,,,,,VK_XBUTTON1,0x05,,
+BTN_4,0x104,,,,,,,,,VK_XBUTTON2,0x06,,
+BTN_5,0x105,,,,,,,,,,,,
+BTN_6,0x106,,,,,,,,,,,,
+BTN_7,0x107,,,,,,,,,,,,
+BTN_8,0x108,,,,,,,,,,,,
+BTN_9,0x109,,,,,,,,,,,,
+BTN_MOUSE,0x110,,,,,,,,,,,,
+BTN_LEFT,0x110,,,,,,,,,,,,
+BTN_RIGHT,0x111,,,,,,,,,,,,
+BTN_MIDDLE,0x112,,,,,,,,,,,,
+BTN_SIDE,0x113,,,,,,,,,,,,
+BTN_EXTRA,0x114,,,,,,,,,,,,
+BTN_FORWARD,0x115,,,,,,,,,,,,
+BTN_BACK,0x116,,,,,,,,,,,,
+BTN_TASK,0x117,,,,,,,,,,,,
+BTN_JOYSTICK,0x120,,,,,,,,,,,,
+BTN_TRIGGER,0x120,,,,,,,,,,,,
+BTN_THUMB,0x121,,,,,,,,,,,,
+BTN_THUMB2,0x122,,,,,,,,,,,,
+BTN_TOP,0x123,,,,,,,,,,,,
+BTN_TOP2,0x124,,,,,,,,,,,,
+BTN_PINKIE,0x125,,,,,,,,,,,,
+BTN_BASE,0x126,,,,,,,,,,,,
+BTN_BASE2,0x127,,,,,,,,,,,,
+BTN_BASE3,0x128,,,,,,,,,,,,
+BTN_BASE4,0x129,,,,,,,,,,,,
+BTN_BASE5,0x12a,,,,,,,,,,,,
+BTN_BASE6,0x12b,,,,,,,,,,,,
+BTN_DEAD,0x12f,,,,,,,,,,,,
+BTN_GAMEPAD,0x130,,,,,,,,,,,,
+BTN_A,0x130,,,,,,,,,,,,
+BTN_B,0x131,,,,,,,,,,,,
+BTN_C,0x132,,,,,,,,,,,,
+BTN_X,0x133,,,,,,,,,,,,
+BTN_Y,0x134,,,,,,,,,,,,
+BTN_Z,0x135,,,,,,,,,,,,
+BTN_TL,0x136,,,,,,,,,,,,
+BTN_TR,0x137,,,,,,,,,,,,
+BTN_TL2,0x138,,,,,,,,,,,,
+BTN_TR2,0x139,,,,,,,,,,,,
+BTN_SELECT,0x13a,,,,,,,,,,,,
+BTN_START,0x13b,,,,,,,,,,,,
+BTN_MODE,0x13c,,,,,,,,,,,,
+BTN_THUMBL,0x13d,,,,,,,,,,,,
+BTN_THUMBR,0x13e,,,,,,,,,,,,
+BTN_DIGI,0x140,,,,,,,,,,,,
+BTN_TOOL_PEN,0x140,,,,,,,,,,,,
+BTN_TOOL_RUBBER,0x141,,,,,,,,,,,,
+BTN_TOOL_BRUSH,0x142,,,,,,,,,,,,
+BTN_TOOL_PENCIL,0x143,,,,,,,,,,,,
+BTN_TOOL_AIRBRUSH,0x144,,,,,,,,,,,,
+BTN_TOOL_FINGER,0x145,,,,,,,,,,,,
+BTN_TOOL_MOUSE,0x146,,,,,,,,,,,,
+BTN_TOOL_LENS,0x147,,,,,,,,,,,,
+BTN_TOUCH,0x14a,,,,,,,,,,,,
+BTN_STYLUS,0x14b,,,,,,,,,,,,
+BTN_STYLUS2,0x14c,,,,,,,,,,,,
+BTN_TOOL_DOUBLETAP,0x14d,,,,,,,,,,,,
+BTN_TOOL_TRIPLETAP,0x14e,,,,,,,,,,,,
+BTN_TOOL_QUADTAP,0x14f,,,,,,,,,,,,
+BTN_WHEEL,0x150,,,,,,,,,,,,
+BTN_GEAR_DOWN,0x150,,,,,,,,,,,,
+BTN_GEAR_UP,0x151,,,,,,,,,,,,
+KEY_OK,0x160,,,,,,,,,,,,
+KEY_SELECT,0x161,,,,,,,,,VK_SELECT,0x29,,
+KEY_GOTO,0x162,,,,,,,,,,,,
+KEY_CLEAR,0x163,,,,,,,,,,,,
+KEY_POWER2,0x164,,,,,,,,,,,,
+KEY_OPTION,0x165,,,,,,,,,,,,
+KEY_INFO,0x166,,,,,,,,,,,,
+KEY_TIME,0x167,,,,,,,,,,,,
+KEY_VENDOR,0x168,,,,,,,,,,,,
+KEY_ARCHIVE,0x169,,,,,,,,,,,,
+KEY_PROGRAM,0x16a,,,,,,,,,,,,
+KEY_CHANNEL,0x16b,,,,,,,,,,,,
+KEY_FAVORITES,0x16c,,,,,,,,,VK_BROWSER_FAVOURITES,0xab,,
+KEY_EPG,0x16d,,,,,,,,,,,,
+KEY_PVR,0x16e,,,,,,,,,,,,
+KEY_MHP,0x16f,,,,,,,,,,,,
+KEY_LANGUAGE,0x170,,,,,,,,,,,,
+KEY_TITLE,0x171,,,,,,,,,,,,
+KEY_SUBTITLE,0x172,,,,,,,,,,,,
+KEY_ANGLE,0x173,,,,,,,,,,,,
+KEY_ZOOM,0x174,,,,,,,,,VK_ZOOM,0xfb,,
+KEY_MODE,0x175,,,,,,,,,,,,
+KEY_KEYBOARD,0x176,,,,,,,,,,,,
+KEY_SCREEN,0x177,,,,,,,,,,,,
+KEY_PC,0x178,,,,,,,,,,,,
+KEY_TV,0x179,,,,,,,,,,,,
+KEY_TV2,0x17a,,,,,,,,,,,,
+KEY_VCR,0x17b,,,,,,,,,,,,
+KEY_VCR2,0x17c,,,,,,,,,,,,
+KEY_SAT,0x17d,,,,,,,,,,,,
+KEY_SAT2,0x17e,,,,,,,,,,,,
+KEY_CD,0x17f,,,,,,,,,,,,
+KEY_TAPE,0x180,,,,,,,,,,,,
+KEY_RADIO,0x181,,,,,,,,,,,,
+KEY_TUNER,0x182,,,,,,,,,,,,
+KEY_PLAYER,0x183,,,,,,,,,,,,
+KEY_TEXT,0x184,,,,,,,,,,,,
+KEY_DVD,0x185,,,,,,,,,,,,
+KEY_AUX,0x186,,,,,,,,,,,,
+KEY_MP3,0x187,,,,,,,,,,,,
+KEY_AUDIO,0x188,,,,,,,,,,,,
+KEY_VIDEO,0x189,,,,,,,,,,,,
+KEY_DIRECTORY,0x18a,,,,,,,,,,,,
+KEY_LIST,0x18b,,,,,,,,,,,,
+KEY_MEMO,0x18c,,,,,,,,,,,,
+KEY_CALENDAR,0x18d,,,,,,,,,,,,
+KEY_RED,0x18e,,,,,,,,,,,,
+KEY_GREEN,0x18f,,,,,,,,,,,,
+KEY_YELLOW,0x190,,,,,,,,,,,,
+KEY_BLUE,0x191,,,,,,,,,,,,
+KEY_CHANNELUP,0x192,,,,,,,,,,,,
+KEY_CHANNELDOWN,0x193,,,,,,,,,,,,
+KEY_FIRST,0x194,,,,,,,,,,,,
+KEY_LAST,0x195,,,,,,,,,,,,
+KEY_AB,0x196,,,,,,,,,,,,
+KEY_NEXT,0x197,,,,,,,,,,,,
+KEY_RESTART,0x198,,,,,,,,,,,,
+KEY_SLOW,0x199,,,,,,,,,,,,
+KEY_SHUFFLE,0x19a,,,,,,,,,,,,
+KEY_BREAK,0x19b,,,,,,,,,,,,
+KEY_PREVIOUS,0x19c,,,,,,,,,,,,
+KEY_DIGITS,0x19d,,,,,,,,,,,,
+KEY_TEEN,0x19e,,,,,,,,,,,,
+KEY_TWEN,0x19f,,,,,,,,,,,,
+KEY_VIDEOPHONE,0x1a0,,,,,,,,,,,,
+KEY_GAMES,0x1a1,,,,,,,,,,,,
+KEY_ZOOMIN,0x1a2,,,,,,,,,,,,
+KEY_ZOOMOUT,0x1a3,,,,,,,,,,,,
+KEY_ZOOMRESET,0x1a4,,,,,,,,,,,,
+KEY_WORDPROCESSOR,0x1a5,,,,,,,,,,,,
+KEY_EDITOR,0x1a6,,,,,,,,,,,,
+KEY_SPREADSHEET,0x1a7,,,,,,,,,,,,
+KEY_GRAPHICSEDITOR,0x1a8,,,,,,,,,,,,
+KEY_PRESENTATION,0x1a9,,,,,,,,,,,,
+KEY_DATABASE,0x1aa,,,,,,,,,,,,
+KEY_NEWS,0x1ab,,,,,,,,,,,,
+KEY_VOICEMAIL,0x1ac,,,,,,,,,,,,
+KEY_ADDRESSBOOK,0x1ad,,,,,,,,,,,,
+KEY_MESSENGER,0x1ae,,,,,,,,,,,,
+KEY_DISPLAYTOGGLE,0x1af,,,,,,,,,,,,
+KEY_SPELLCHECK,0x1b0,,,,,,,,,,,,
+KEY_LOGOFF,0x1b1,,,,,,,,,,,,
+KEY_DOLLAR,0x1b2,,,,,,,,,,,,
+KEY_EURO,0x1b3,,,,,,,,,,,,
+KEY_FRAMEBACK,0x1b4,,,,,,,,,,,,
+KEY_FRAMEFORWARD,0x1b5,,,,,,,,,,,,
+KEY_CONTEXT_MENU,0x1b6,,,,,,,,,,,,
+KEY_MEDIA_REPEAT,0x1b7,,,,,,,,,,,,
+KEY_DEL_EOL,0x1c0,,,,,,,,,,,,
+KEY_DEL_EOS,0x1c1,,,,,,,,,,,,
+KEY_INS_LINE,0x1c2,,,,,,,,,,,,
+KEY_DEL_LINE,0x1c3,,,,,,,,,,,,
+KEY_FN,0x1d0,,,,,,,,,,,,
+KEY_FN_ESC,0x1d1,,,,,,,,,,,,
+KEY_FN_F1,0x1d2,,,,,,,,,,,,
+KEY_FN_F2,0x1d3,,,,,,,,,,,,
+KEY_FN_F3,0x1d4,,,,,,,,,,,,
+KEY_FN_F4,0x1d5,,,,,,,,,,,,
+KEY_FN_F5,0x1d6,,,,,,,,,,,,
+KEY_FN_F6,0x1d7,,,,,,,,,,,,
+KEY_FN_F7,0x1d8,,,,,,,,,,,,
+KEY_FN_F8,0x1d9,,,,,,,,,,,,
+KEY_FN_F9,0x1da,,,,,,,,,,,,
+KEY_FN_F10,0x1db,,,,,,,,,,,,
+KEY_FN_F11,0x1dc,,,,,,,,,,,,
+KEY_FN_F12,0x1dd,,,,,,,,,,,,
+KEY_FN_1,0x1de,,,,,,,,,,,,
+KEY_FN_2,0x1df,,,,,,,,,,,,
+KEY_FN_D,0x1e0,,,,,,,,,,,,
+KEY_FN_E,0x1e1,,,,,,,,,,,,
+KEY_FN_F,0x1e2,,,,,,,,,,,,
+KEY_FN_S,0x1e3,,,,,,,,,,,,
+KEY_FN_B,0x1e4,,,,,,,,,,,,
+KEY_BRL_DOT1,0x1f1,,,,,,,,,,,,
+KEY_BRL_DOT2,0x1f2,,,,,,,,,,,,
+KEY_BRL_DOT3,0x1f3,,,,,,,,,,,,
+KEY_BRL_DOT4,0x1f4,,,,,,,,,,,,
+KEY_BRL_DOT5,0x1f5,,,,,,,,,,,,
+KEY_BRL_DOT6,0x1f6,,,,,,,,,,,,
+KEY_BRL_DOT7,0x1f7,,,,,,,,,,,,
+KEY_BRL_DOT8,0x1f8,,,,,,,,,,,,
+KEY_BRL_DOT9,0x1f9,,,,,,,,,,,,
+KEY_BRL_DOT10,0x1fa,,,,,,,,,,,,
+KEY_NUMERIC_0,0x200,,,,,,,,,,,,
+KEY_NUMERIC_1,0x201,,,,,,,,,,,,
+KEY_NUMERIC_2,0x202,,,,,,,,,,,,
+KEY_NUMERIC_3,0x203,,,,,,,,,,,,
+KEY_NUMERIC_4,0x204,,,,,,,,,,,,
+KEY_NUMERIC_5,0x205,,,,,,,,,,,,
+KEY_NUMERIC_6,0x206,,,,,,,,,,,,
+KEY_NUMERIC_7,0x207,,,,,,,,,,,,
+KEY_NUMERIC_8,0x208,,,,,,,,,,,,
+KEY_NUMERIC_9,0x209,,,,,,,,,,,,
+KEY_NUMERIC_STAR,0x20a,,,,,,,,,,,,
+KEY_NUMERIC_POUND,0x20b,,,,,,,,,,,,
+KEY_RFKILL,0x20c,,,,,,,,,,,,
diff --git a/gtk/spice-channel.h b/gtk/spice-channel.h
index cafa8a8..86183a2 100644
--- a/gtk/spice-channel.h
+++ b/gtk/spice-channel.h
@@ -73,6 +73,8 @@ void spice_inputs_position(SpiceChannel *channel, gint x, gint y,
gint display, gint button_state);
void spice_inputs_button_press(SpiceChannel *channel, gint button, gint button_state);
void spice_inputs_button_release(SpiceChannel *channel, gint button, gint button_state);
+void spice_inputs_key_press(SpiceChannel *channel, guint keyval);
+void spice_inputs_key_release(SpiceChannel *channel, guint keyval);
spice_msg_in *spice_msg_in_new(SpiceChannel *channel);
void spice_msg_in_get(spice_msg_in *in);
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index bba74fb..acca016 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -1,4 +1,5 @@
#include "spice-widget.h"
+#include "vncdisplaykeymap.h"
#include <gdk/gdkx.h>
@@ -28,6 +29,9 @@ struct spice_display {
SpiceChannel *inputs;
enum SpiceMouseMode mouse_mode;
+
+ const guint16 const *keycode_map;
+ size_t keycode_maplen;
};
G_DEFINE_TYPE(SpiceDisplay, spice_display, GTK_TYPE_DRAWING_AREA)
@@ -104,6 +108,9 @@ static void spice_display_init(SpiceDisplay *display)
GDK_LEAVE_NOTIFY_MASK |
GDK_KEY_PRESS_MASK);
gtk_widget_set_double_buffered(widget, false);
+ gtk_widget_set_can_focus(widget, true);
+
+ d->keycode_map = vnc_display_keymap_gdk2rfb_table(&d->keycode_maplen);
}
static void recalc_geometry(GtkWidget *widget)
@@ -247,14 +254,29 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose)
static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
{
-#if 0
SpiceDisplay *display = SPICE_DISPLAY(widget);
spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
-#endif
+ int scancode;
- fprintf(stderr, "%s %s: keycode: %d state: %d group %d, keyval: %d",
+ fprintf(stderr, "%s %s: keycode: %d state: %d group %d\n",
__FUNCTION__, key->type == GDK_KEY_PRESS ? "press" : "release",
- key->hardware_keycode, key->state, key->group, key->keyval);
+ key->hardware_keycode, key->state, key->group);
+
+ if (!d->inputs)
+ return true;
+
+ scancode = vnc_display_keymap_gdk2rfb(d->keycode_map, d->keycode_maplen,
+ key->hardware_keycode);
+ switch (key->type) {
+ case GDK_KEY_PRESS:
+ spice_inputs_key_press(d->inputs, scancode);
+ break;
+ case GDK_KEY_RELEASE:
+ spice_inputs_key_release(d->inputs, scancode);
+ break;
+ default:
+ break;
+ }
return true;
}
@@ -347,6 +369,7 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
button->type == GDK_BUTTON_PRESS ? "press" : "release",
button->button);
#endif
+ gtk_widget_grab_focus (widget);
if (!d->inputs)
return true;
diff --git a/gtk/spicy.c b/gtk/spicy.c
index 07c639d..6be2298 100644
--- a/gtk/spicy.c
+++ b/gtk/spicy.c
@@ -41,7 +41,8 @@ static void menu_cb_fullscreen(GtkAction *action, void *data)
static void menu_cb_about(GtkAction *action, void *data)
{
- static char *comments = "spice client";
+ static char *comments = "gtk client app for the\n"
+ "spice remote desktop protocol";
static char *copyright = "(c) 2010 Red Hat";
static char *website = "http://www.spice-space.org";
static char *authors[] = { "Gerd Hoffmann <kraxel@redhat.com>", NULL };
diff --git a/gtk/vncdisplaykeymap.c b/gtk/vncdisplaykeymap.c
new file mode 100644
index 0000000..7dae592
--- /dev/null
+++ b/gtk/vncdisplaykeymap.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2008 Anthony Liguori <anthony@codemonkey.ws>
+ * Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include "vncdisplaykeymap.h"
+
+#define VNC_DEBUG(message) fprintf(stderr, "%s\n", message);
+
+/*
+ * This table is taken from QEMU x_keymap.c, under the terms:
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.
+ */
+
+/* keycode translation for sending ISO_Left_Send
+ * to vncserver
+ */
+static struct {
+ GdkKeymapKey *keys;
+ gint n_keys;
+ guint keyval;
+} untranslated_keys[] = {{NULL, 0, GDK_Tab}};
+
+static unsigned int ref_count_for_untranslated_keys = 0;
+
+#if defined(GDK_WINDOWING_X11)
+#include <gdk/gdkx.h>
+#include <X11/XKBlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+/* Xorg Linux + kbd (offset + mangled XT keycodes) */
+#include "vncdisplaykeymap_xorgkbd2rfb.c"
+/* Xorg Linux + evdev (offset evdev keycodes) */
+#include "vncdisplaykeymap_xorgevdev2rfb.c"
+/* Xorg OS-X aka XQuartz (offset OS-X keycodes) */
+#include "vncdisplaykeymap_xorgxquartz2rfb.c"
+/* Xorg Cygwin aka XWin (offset + mangled XT keycodes) */
+#include "vncdisplaykeymap_xorgxwin2rfb.c"
+
+#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
+
+static gboolean check_for_xwin(void)
+{
+ char *vendor = ServerVendor(GDK_DISPLAY());
+
+ if (strstr(vendor, "Cygwin/X"))
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean check_for_xquartz(void)
+{
+ int nextensions;
+ int i;
+ gboolean match = FALSE;
+ char **extensions = XListExtensions(GDK_DISPLAY(), &nextensions);
+ for (i = 0 ; extensions != NULL && i < nextensions ; i++) {
+ if (strcmp(extensions[i], "Apple-WM") == 0 ||
+ strcmp(extensions[i], "Apple-DRI") == 0)
+ match = TRUE;
+ }
+ if (extensions)
+ XFreeExtensionList(extensions);
+
+ return match;
+}
+
+const guint16 const *vnc_display_keymap_gdk2rfb_table(size_t *maplen)
+{
+ XkbDescPtr desc;
+ const gchar *keycodes = NULL;
+
+ /* There is no easy way to determine what X11 server
+ * and platform & keyboard driver is in use. Thus we
+ * do best guess heuristics.
+ *
+ * This will need more work for people with other
+ * X servers..... patches welcomed.
+ */
+
+ desc = XkbGetKeyboard(GDK_DISPLAY(), XkbGBN_AllComponentsMask,
+ XkbUseCoreKbd);
+ if (desc) {
+ if (desc->names) {
+ keycodes = gdk_x11_get_xatom_name(desc->names->keycodes);
+ if (!keycodes)
+ g_warning("could not lookup keycode name");
+ }
+ XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True);
+ }
+
+ if (check_for_xwin()) {
+ VNC_DEBUG("Using xwin keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_xorgxwin2rfb);
+ return keymap_xorgxwin2rfb;
+ } else if (check_for_xquartz()) {
+ VNC_DEBUG("Using xquartz keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_xorgxquartz2rfb);
+ return keymap_xorgxquartz2rfb;
+ } else if (keycodes && STRPREFIX(keycodes, "evdev_")) {
+ VNC_DEBUG("Using evdev keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_xorgevdev2rfb);
+ return keymap_xorgevdev2rfb;
+ } else if (keycodes && STRPREFIX(keycodes, "xfree86_")) {
+ VNC_DEBUG("Using xfree86 keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_xorgkbd2rfb);
+ return keymap_xorgkbd2rfb;
+ } else {
+ g_warning("Unknown keycode mapping '%s'.\n"
+ "Please report to gtk-vnc-list@gnome.org\n"
+ "including the following information:\n"
+ "\n"
+ " - Operating system\n"
+ " - GTK build\n"
+ " - X11 Server\n"
+ " - xprop -root\n"
+ " - xdpyinfo\n",
+ keycodes);
+ return NULL;
+ }
+}
+
+#elif defined(GDK_WINDOWING_WIN32)
+/* Win32 native virtual keycodes */
+#include "vncdisplaykeymap_win322rfb.c"
+
+const guint16 const *vnc_display_keymap_gdk2rfb_table(size_t *maplen)
+{
+ VNC_DEBUG("Using Win32 virtual keycode mapping");
+ *maplen = sizeof(keymap_win322rfb);
+ return keymap_win322rfb;
+}
+
+#elif defined(GDK_WINDOWING_QUARTZ)
+/* OS-X native keycodes */
+#include "vncdisplaykeymap_osx2rfb.c"
+
+const guint16 const *vnc_display_keymap_gdk2rfb_table(size_t *maplen)
+{
+ VNC_DEBUG("Using OS-X virtual keycode mapping");
+ *maplen = sizeof(keymap_osx2rfb);
+ return keymap_osx2rfb;
+}
+
+
+#else
+
+const guint16 const *vnc_display_keymap_gdk2rfb_table(size_t *maplen)
+{
+ g_warning("Unsupported GDK Windowing platform.\n"
+ "Please report to gtk-vnc-list@gnome.org\n"
+ "including the following information:\n"
+ "\n"
+ " - Operating system\n"
+ " - GTK Windowing system build\n");
+ return NULL;
+}
+#endif
+
+guint16 vnc_display_keymap_gdk2rfb(const guint16 const *keycode_map,
+ size_t keycode_maplen,
+ guint16 keycode)
+{
+ if (!keycode_map)
+ return 0;
+ if (keycode >= keycode_maplen)
+ return 0;
+ return keycode_map[keycode];
+}
+
+/* Set the keymap entries */
+void vnc_display_keyval_set_entries(void)
+{
+ size_t i;
+ if (ref_count_for_untranslated_keys == 0)
+ for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++)
+ gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(),
+ untranslated_keys[i].keyval,
+ &untranslated_keys[i].keys,
+ &untranslated_keys[i].n_keys);
+ ref_count_for_untranslated_keys++;
+}
+
+/* Free the keymap entries */
+void vnc_display_keyval_free_entries(void)
+{
+ size_t i;
+
+ if (ref_count_for_untranslated_keys == 0)
+ return;
+
+ ref_count_for_untranslated_keys--;
+ if (ref_count_for_untranslated_keys == 0)
+ for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++)
+ g_free(untranslated_keys[i].keys);
+
+}
+
+/* Get the keyval from the keycode without the level. */
+guint vnc_display_keyval_from_keycode(guint keycode, guint keyval)
+{
+ size_t i;
+ for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++) {
+ if (keycode == untranslated_keys[i].keys[0].keycode) {
+ return untranslated_keys[i].keyval;
+ }
+ }
+
+ return keyval;
+}
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/gtk/vncdisplaykeymap.h b/gtk/vncdisplaykeymap.h
new file mode 100644
index 0000000..7cb9946
--- /dev/null
+++ b/gtk/vncdisplaykeymap.h
@@ -0,0 +1,35 @@
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ * Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef VNC_DISPLAY_KEYMAP_H
+#define VNC_DISPLAY_KEYMAP_H
+
+#include <glib.h>
+
+const guint16 const *vnc_display_keymap_gdk2rfb_table(size_t *maplen);
+guint16 vnc_display_keymap_gdk2rfb(const guint16 *keycode_map,
+ size_t keycode_maplen,
+ guint16 keycode);
+void vnc_display_keyval_set_entries(void);
+void vnc_display_keyval_free_entries(void);
+guint vnc_display_keyval_from_keycode(guint keycode, guint keyval);
+
+#endif /* VNC_DISPLAY_KEYMAP_H */