summaryrefslogtreecommitdiffstats
path: root/keymap.c
diff options
context:
space:
mode:
Diffstat (limited to 'keymap.c')
-rw-r--r--keymap.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/keymap.c b/keymap.c
new file mode 100644
index 0000000..7da942b
--- /dev/null
+++ b/keymap.c
@@ -0,0 +1,261 @@
+// This file comes from the vncviewer source
+// Converted to C from C++ and used in -fromwin version of x2x
+// 2003 By Mark Hayter
+
+// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
+//
+// This file is part of the VNC system.
+//
+// The VNC system is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+//
+// If the source code for the VNC system is not available from the place
+// whence you received this file, check http://www.uk.research.att.com/vnc or contact
+// the authors on vnc@uk.research.att.com for information on obtaining it.
+
+// Thanks to Martin C. Mueller <mcm@itwm.uni-kl.de> for assistance with the
+// international keyboard mapping stuff.
+
+// KeyMap.cpp
+
+#ifdef WIN_2_X
+#include <stdio.h>
+#include <windows.h>
+#define XK_MISCELLANY
+#define XK_LATIN1
+#define XK_XKB_KEYS
+#include "keymap.h"
+
+// Define the keymap structure
+ typedef struct vncKeymapping_struct
+{
+ unsigned int wincode;
+ KeySym Xcode;
+ } vncKeymapping;
+ static const vncKeymapping keymap[] = {
+ {VK_BACK, XK_BackSpace},
+ {VK_TAB, XK_Tab},
+ {VK_CLEAR, XK_Clear},
+ {VK_RETURN, XK_Return},
+ {VK_LSHIFT, XK_Shift_L},
+ {VK_RSHIFT, XK_Shift_L}, /* XXX mdh - never gen SHIFT_R */
+{VK_SHIFT, XK_Shift_L}, {VK_LCONTROL, XK_Control_L}, {VK_RCONTROL, XK_Control_R}, {VK_CONTROL, XK_Control_L}, {VK_LMENU, XK_Alt_L}, {VK_RMENU, XK_Alt_R}, {VK_MENU, XK_Alt_L}, {VK_PAUSE, XK_Pause}, {VK_CAPITAL, XK_Caps_Lock}, {VK_ESCAPE, XK_Escape}, {VK_SPACE, XK_space}, {VK_PRIOR, XK_Page_Up}, {VK_NEXT, XK_Page_Down}, {VK_END, XK_End}, {VK_HOME, XK_Home}, {VK_LEFT, XK_Left}, {VK_UP, XK_Up}, {VK_RIGHT, XK_Right}, {VK_DOWN, XK_Down}, {VK_SELECT, XK_Select}, {VK_EXECUTE, XK_Execute}, {VK_SNAPSHOT, XK_Print}, {VK_INSERT, XK_Insert}, {VK_DELETE, XK_Delete}, {VK_HELP, XK_Help}, {VK_NUMPAD0, XK_KP_0}, {VK_NUMPAD1, XK_KP_1}, {VK_NUMPAD2, XK_KP_2}, {VK_NUMPAD3, XK_KP_3}, {VK_NUMPAD4, XK_KP_4}, {VK_NUMPAD5, XK_KP_5}, {VK_NUMPAD6, XK_KP_6}, {VK_NUMPAD7, XK_KP_7}, {VK_NUMPAD8, XK_KP_8}, {VK_NUMPAD9, XK_KP_9}, {VK_MULTIPLY, XK_KP_Multiply}, {VK_ADD, XK_KP_Add}, {VK_SEPARATOR, XK_KP_Separator}, // often comma
+{VK_SUBTRACT, XK_KP_Subtract},
+ {VK_DECIMAL, XK_KP_Decimal},
+ {VK_DIVIDE, XK_KP_Divide},
+ {VK_F1, XK_F1},
+ {VK_F2, XK_F2},
+ {VK_F3, XK_F3},
+ {VK_F4, XK_F4},
+ {VK_F5, XK_F5},
+ {VK_F6, XK_F6},
+ {VK_F7, XK_F7},
+ {VK_F8, XK_F8},
+ {VK_F9, XK_F9},
+ {VK_F10, XK_F10},
+ {VK_F11, XK_F11},
+ {VK_F12, XK_F12},
+ {VK_F13, XK_F13},
+ {VK_F14, XK_F14},
+ {VK_F15, XK_F15},
+ {VK_F16, XK_F16},
+ {VK_F17, XK_F17},
+ {VK_F18, XK_F18},
+ {VK_F19, XK_F19},
+ {VK_F20, XK_F20},
+ {VK_F21, XK_F21},
+ {VK_F22, XK_F22},
+ {VK_F23, XK_F23},
+ {VK_F24, XK_F24}, {VK_NUMLOCK, XK_Num_Lock}, {VK_SCROLL, XK_Scroll_Lock}
+};
+
+ static unsigned char buf[4];
+ static unsigned char keystate[256];
+ KeyActionSpec PCtoX (UINT virtkey, DWORD keyData)
+{
+ int numkeys = 0;
+ int mapsize, i;
+ int extended;
+ int ret;
+ KeyActionSpec kas;
+ kas.releaseModifiers = 0;
+ extended = ((keyData & 0x1000000) != 0);
+
+#ifdef DEBUG
+ printf (" keyData %04x ", (unsigned int) keyData);
+
+#endif /* */
+ if (extended)
+ {
+
+#ifdef DEBUG
+ printf (" (extended) ");
+
+#endif /* */
+ switch (virtkey)
+ {
+ case VK_MENU:
+ virtkey = VK_RMENU;
+ break;
+ case VK_CONTROL:
+ virtkey = VK_RCONTROL;
+ break;
+ }
+ }
+
+ // We try looking it up in our table
+ mapsize = sizeof (keymap) / sizeof (vncKeymapping);
+
+ // Look up the desired code in the table
+ for (i = 0; i < mapsize; i++)
+ {
+ if (keymap[i].wincode == virtkey)
+ {
+ kas.keycodes[numkeys++] = keymap[i].Xcode;
+ break;
+ }
+ }
+ if (numkeys != 0)
+ {
+
+#ifdef DEBUG
+ UINT key = kas.keycodes[numkeys - 1];
+ printf ("keymap gives %u (%x) ", key, key);
+
+#endif /* */
+ }
+ else
+ {
+
+ // not found in table
+#ifdef DEBUG
+ printf ("not in special keymap, ");
+
+#endif /* */
+ // we try a simple conversion to Ascii, using the current keyboard mapping
+ GetKeyboardState (keystate);
+ ret = ToAscii (virtkey, 0, keystate, (WORD *) buf, 0);
+
+ // If Left Ctrl & Alt both pressed and ToAscii gives a valid keysym
+ // This is for AltGr on international keyboards (= LCtrl-Alt).
+ // e.g. Ctrl-Alt-Q gives @ on German keyboards
+ if (((keystate[VK_MENU] & 0x80) != 0) &&
+ ((keystate[VK_CONTROL] & 0x80) != 0))
+ {
+
+ // If the key means anything in this keyboard layout
+ if ((ret >= 1) &&
+ (((*buf >= 32) && (*buf <= 126)) ||
+ ((*buf >= 160) && (*buf <= 255))) )
+ {
+
+ // Send the modifiers up, then the keystroke, then mods down
+ // We don't release the right control; this allows German users
+ // to use it for doing Ctl-@ etc. (though not under Win95 --
+ // see below)
+ if (GetKeyState (VK_LCONTROL) & 0x8000)
+ kas.releaseModifiers |= KEYMAP_LCONTROL;
+ if (GetKeyState (VK_LMENU) & 0x8000)
+ kas.releaseModifiers |= KEYMAP_LALT;
+ if (GetKeyState (VK_RMENU) & 0x8000)
+ kas.releaseModifiers |= KEYMAP_RALT;
+
+ // This is for windows 95, and possibly other systems.
+ // The above GetKeyState calls don't work in 95 - they always return 0.
+ // But if we're here at all we know that control and alt are pressed, so let's
+ // raise all Control and Alt keys if we haven't registered any yet.
+ if (kas.releaseModifiers == 0)
+ kas.releaseModifiers =
+ KEYMAP_LCONTROL | KEYMAP_LALT | KEYMAP_RALT;
+
+#ifdef DEBUG
+ printf
+ ("Ctrl-Alt pressed ToAscii(without modifiers)returns %d bytes: ",
+ ret);
+
+#endif /* */
+ for (i = 0; i < ret; i++)
+ {
+ kas.keycodes[numkeys++] = *(buf + i);
+
+#ifdef DEBUG
+ printf ("%02x (%c) ", *(buf + i), *(buf + i));
+
+#endif /* */
+ }
+
+#ifdef DEBUG
+ printf ("\n");
+
+#endif /* */
+ }
+ }
+
+ // If not a ctrl-alt key
+ if (numkeys == 0)
+ {
+
+ // There are no keysyms corresponding to control characters
+ // Eg Ctrl F. The server already knows whether the control
+ // key is pressed. So we are interested in the key that would be
+ // there if the Ctrl were not pressed.
+ keystate[VK_CONTROL] = keystate[VK_LCONTROL] =
+ keystate[VK_RCONTROL] = 0;
+ ret = ToAscii (virtkey, 0, keystate, (WORD *) buf, 0);
+ if (ret < 0)
+ {
+ switch (*buf)
+ {
+ case '`':
+ kas.keycodes[numkeys++] = XK_dead_grave;
+ break;
+ case '\'':
+ kas.keycodes[numkeys++] = XK_dead_acute;
+ break;
+ case '~':
+ kas.keycodes[numkeys++] = XK_dead_tilde;
+ break;
+ case '^':
+ kas.keycodes[numkeys++] = XK_dead_circumflex;
+ break;
+ }
+ }
+
+ // if this works, and it's a regular printable character, just send that
+ if (ret >= 1)
+ {
+
+#ifdef DEBUG
+ printf ("ToAscii (without ctrl) returns %d byte(s): ", ret);
+
+#endif /* */
+ for (i = 0; i < ret; i++)
+ {
+ kas.keycodes[numkeys++] = *(buf + i);
+
+#ifdef DEBUG
+ printf ("%02x (%c) ", *(buf + i), *(buf + i));
+
+#endif /* */
+ }
+ }
+ }
+ }
+ kas.keycodes[numkeys] = VoidKeyCode;
+ return kas;
+ }
+
+
+#endif /* */