371 lines
7.7 KiB
C
371 lines
7.7 KiB
C
/*
|
||
* tkWinKey.c --
|
||
*
|
||
* This file contains X emulation routines for keyboard related
|
||
* functions.
|
||
*
|
||
* Copyright (c) 1995 Sun Microsystems, Inc.
|
||
*
|
||
* See the file "license.terms" for information on usage and redistribution
|
||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||
*
|
||
* SCCS: @(#) tkWinKey.c 1.9 97/06/20 15:12:39
|
||
*/
|
||
|
||
#include "tkWinInt.h"
|
||
|
||
typedef struct {
|
||
unsigned int keycode;
|
||
KeySym keysym;
|
||
} Keys;
|
||
|
||
static Keys keymap[] = {
|
||
VK_CANCEL, XK_Cancel,
|
||
VK_BACK, XK_BackSpace,
|
||
VK_TAB, XK_Tab,
|
||
VK_CLEAR, XK_Clear,
|
||
VK_RETURN, XK_Return,
|
||
VK_SHIFT, XK_Shift_L,
|
||
VK_CONTROL, XK_Control_L,
|
||
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_Prior,
|
||
VK_NEXT, XK_Next,
|
||
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_PRINT, XK_Print,
|
||
VK_EXECUTE, XK_Execute,
|
||
VK_INSERT, XK_Insert,
|
||
VK_DELETE, XK_Delete,
|
||
VK_HELP, XK_Help,
|
||
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,
|
||
|
||
/*
|
||
* The following support the new keys in the Microsoft keyboard.
|
||
* Win_L and Win_R have the windows logo. App has the menu.
|
||
*/
|
||
|
||
VK_LWIN, XK_Win_L,
|
||
VK_RWIN, XK_Win_R,
|
||
VK_APPS, XK_App,
|
||
|
||
0, NoSymbol
|
||
};
|
||
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XLookupString --
|
||
*
|
||
* Retrieve the string equivalent for the given keyboard event.
|
||
*
|
||
* Results:
|
||
* Returns the number of characters stored in buffer_return.
|
||
*
|
||
* Side effects:
|
||
* Retrieves the characters stored in the event and inserts them
|
||
* into buffer_return.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
int
|
||
XLookupString(event_struct, buffer_return, bytes_buffer, keysym_return,
|
||
status_in_out)
|
||
XKeyEvent* event_struct;
|
||
char* buffer_return;
|
||
int bytes_buffer;
|
||
KeySym* keysym_return;
|
||
XComposeStatus* status_in_out;
|
||
{
|
||
int i, limit;
|
||
|
||
if (event_struct->send_event != -1) {
|
||
/*
|
||
* This is an event generated from generic code. It has no
|
||
* nchars or trans_chars members.
|
||
*/
|
||
|
||
int index;
|
||
KeySym keysym;
|
||
|
||
index = 0;
|
||
if (event_struct->state & ShiftMask) {
|
||
index |= 1;
|
||
}
|
||
if (event_struct->state & Mod1Mask) {
|
||
index |= 2;
|
||
}
|
||
keysym = XKeycodeToKeysym(event_struct->display,
|
||
event_struct->keycode, index);
|
||
if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256))
|
||
|| (keysym == XK_Return)
|
||
|| (keysym == XK_Tab)) {
|
||
buffer_return[0] = (char) keysym;
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
if ((event_struct->nchars <= 0) || (buffer_return == NULL)) {
|
||
return 0;
|
||
}
|
||
limit = (event_struct->nchars < bytes_buffer) ? event_struct->nchars :
|
||
bytes_buffer;
|
||
|
||
for (i = 0; i < limit; i++) {
|
||
buffer_return[i] = event_struct->trans_chars[i];
|
||
}
|
||
|
||
if (keysym_return != NULL) {
|
||
*keysym_return = NoSymbol;
|
||
}
|
||
return i;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XKeycodeToKeysym --
|
||
*
|
||
* Translate from a system-dependent keycode to a
|
||
* system-independent keysym.
|
||
*
|
||
* Results:
|
||
* Returns the translated keysym, or NoSymbol on failure.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
KeySym
|
||
XKeycodeToKeysym(display, keycode, index)
|
||
Display* display;
|
||
unsigned int keycode;
|
||
int index;
|
||
{
|
||
Keys* key;
|
||
BYTE keys[256];
|
||
int result;
|
||
char buf[4];
|
||
unsigned int scancode = MapVirtualKey(keycode, 0);
|
||
|
||
memset(keys, 0, 256);
|
||
if (index & 0x02) {
|
||
keys[VK_NUMLOCK] = 1;
|
||
}
|
||
if (index & 0x01) {
|
||
keys[VK_SHIFT] = 0x80;
|
||
}
|
||
result = ToAscii(keycode, scancode, keys, (LPWORD) buf, 0);
|
||
|
||
/*
|
||
* Keycode mapped to a valid Latin-1 character. Since the keysyms
|
||
* for alphanumeric characters map onto Latin-1, we just return it.
|
||
*/
|
||
|
||
if (result == 1 && buf[0] >= 0x20) {
|
||
return (KeySym) buf[0];
|
||
}
|
||
|
||
/*
|
||
* Keycode is a non-alphanumeric key, so we have to do the lookup.
|
||
*/
|
||
|
||
for (key = keymap; key->keycode != 0; key++) {
|
||
if (key->keycode == keycode) {
|
||
return key->keysym;
|
||
}
|
||
}
|
||
|
||
return NoSymbol;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XKeysymToKeycode --
|
||
*
|
||
* Translate a keysym back into a keycode.
|
||
*
|
||
* Results:
|
||
* Returns the keycode that would generate the specified keysym.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
KeyCode
|
||
XKeysymToKeycode(display, keysym)
|
||
Display* display;
|
||
KeySym keysym;
|
||
{
|
||
Keys* key;
|
||
SHORT result;
|
||
|
||
if (keysym >= 0x20) {
|
||
result = VkKeyScan((char) keysym);
|
||
if (result != -1) {
|
||
return (KeyCode) (result & 0xff);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Couldn't map the character to a virtual keycode, so do a
|
||
* table lookup.
|
||
*/
|
||
|
||
for (key = keymap; key->keycode != 0; key++) {
|
||
if (key->keysym == keysym) {
|
||
return key->keycode;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XGetModifierMapping --
|
||
*
|
||
* Fetch the current keycodes used as modifiers.
|
||
*
|
||
* Results:
|
||
* Returns a new modifier map.
|
||
*
|
||
* Side effects:
|
||
* Allocates a new modifier map data structure.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
XModifierKeymap *
|
||
XGetModifierMapping(display)
|
||
Display* display;
|
||
{
|
||
XModifierKeymap *map = (XModifierKeymap *)ckalloc(sizeof(XModifierKeymap));
|
||
|
||
map->max_keypermod = 1;
|
||
map->modifiermap = (KeyCode *) ckalloc(sizeof(KeyCode)*8);
|
||
map->modifiermap[ShiftMapIndex] = VK_SHIFT;
|
||
map->modifiermap[LockMapIndex] = VK_CAPITAL;
|
||
map->modifiermap[ControlMapIndex] = VK_CONTROL;
|
||
map->modifiermap[Mod1MapIndex] = VK_NUMLOCK;
|
||
map->modifiermap[Mod2MapIndex] = VK_MENU;
|
||
map->modifiermap[Mod3MapIndex] = VK_SCROLL;
|
||
map->modifiermap[Mod4MapIndex] = 0;
|
||
map->modifiermap[Mod5MapIndex] = 0;
|
||
return map;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XFreeModifiermap --
|
||
*
|
||
* Deallocate a modifier map that was created by
|
||
* XGetModifierMapping.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* Frees the datastructure referenced by modmap.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
XFreeModifiermap(modmap)
|
||
XModifierKeymap* modmap;
|
||
{
|
||
ckfree((char *) modmap->modifiermap);
|
||
ckfree((char *) modmap);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XStringToKeysym --
|
||
*
|
||
* Translate a keysym name to the matching keysym.
|
||
*
|
||
* Results:
|
||
* Returns the keysym. Since this is already handled by
|
||
* Tk's StringToKeysym function, we just return NoSymbol.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
KeySym
|
||
XStringToKeysym(string)
|
||
_Xconst char *string;
|
||
{
|
||
return NoSymbol;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XKeysymToString --
|
||
*
|
||
* Convert a keysym to character form.
|
||
*
|
||
* Results:
|
||
* Returns NULL, since Tk will have handled this already.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
char *
|
||
XKeysymToString(keysym)
|
||
KeySym keysym;
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
|