385 lines
8.4 KiB
C
385 lines
8.4 KiB
C
|
/*
|
|||
|
* tkMacKeyboard.c --
|
|||
|
*
|
|||
|
* Routines to support keyboard events on the Macintosh.
|
|||
|
*
|
|||
|
* Copyright (c) 1995-1996 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: @(#) tkMacKeyboard.c 1.14 96/08/15 15:34:00
|
|||
|
*/
|
|||
|
|
|||
|
#include "tkInt.h"
|
|||
|
#include "Xlib.h"
|
|||
|
#include "keysym.h"
|
|||
|
|
|||
|
#include <Events.h>
|
|||
|
#include <Script.h>
|
|||
|
|
|||
|
typedef struct {
|
|||
|
short keycode; /* Macintosh keycode */
|
|||
|
KeySym keysym; /* X windows Keysym */
|
|||
|
} KeyInfo;
|
|||
|
|
|||
|
static KeyInfo keyArray[] = {
|
|||
|
{0x4C, XK_Return},
|
|||
|
{0x24, XK_Return},
|
|||
|
{0x33, XK_BackSpace},
|
|||
|
{0x75, XK_Delete},
|
|||
|
{0x30, XK_Tab},
|
|||
|
{0x74, XK_Page_Up},
|
|||
|
{0x79, XK_Page_Down},
|
|||
|
{0x73, XK_Home},
|
|||
|
{0x77, XK_End},
|
|||
|
{0x7B, XK_Left},
|
|||
|
{0x7C, XK_Right},
|
|||
|
{0x7E, XK_Up},
|
|||
|
{0x7D, XK_Down},
|
|||
|
{0x72, XK_Help},
|
|||
|
{0x35, XK_Escape},
|
|||
|
{0x47, XK_Clear},
|
|||
|
{0, 0}
|
|||
|
};
|
|||
|
|
|||
|
static KeyInfo vituralkeyArray[] = {
|
|||
|
{122, XK_F1},
|
|||
|
{120, XK_F2},
|
|||
|
{99, XK_F3},
|
|||
|
{118, XK_F4},
|
|||
|
{96, XK_F5},
|
|||
|
{97, XK_F6},
|
|||
|
{98, XK_F7},
|
|||
|
{100, XK_F8},
|
|||
|
{101, XK_F9},
|
|||
|
{109, XK_F10},
|
|||
|
{103, XK_F11},
|
|||
|
{111, XK_F12},
|
|||
|
{105, XK_F13},
|
|||
|
{107, XK_F14},
|
|||
|
{113, XK_F15},
|
|||
|
{0, 0}
|
|||
|
};
|
|||
|
|
|||
|
static int initialized = 0;
|
|||
|
static Tcl_HashTable keycodeTable; /* keyArray hashed by keycode value. */
|
|||
|
static Tcl_HashTable vkeyTable; /* vituralkeyArray hashed by virtual
|
|||
|
keycode value. */
|
|||
|
static Ptr KCHRPtr; /* Pointer to 'KCHR' resource. */
|
|||
|
|
|||
|
/*
|
|||
|
* Prototypes for static functions used in this file.
|
|||
|
*/
|
|||
|
static void InitKeyMaps _ANSI_ARGS_((void));
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*
|
|||
|
* InitKeyMaps --
|
|||
|
*
|
|||
|
* Creates hash tables used by some of the functions in this file.
|
|||
|
*
|
|||
|
* Results:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Side effects:
|
|||
|
* Allocates memory & creates some hash tables.
|
|||
|
*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
static void
|
|||
|
InitKeyMaps()
|
|||
|
{
|
|||
|
register Tcl_HashEntry *hPtr;
|
|||
|
register KeyInfo *kPtr;
|
|||
|
int dummy;
|
|||
|
|
|||
|
Tcl_InitHashTable(&keycodeTable, TCL_ONE_WORD_KEYS);
|
|||
|
for (kPtr = keyArray; kPtr->keycode != 0; kPtr++) {
|
|||
|
hPtr = Tcl_CreateHashEntry(&keycodeTable, (char *) kPtr->keycode,
|
|||
|
&dummy);
|
|||
|
Tcl_SetHashValue(hPtr, kPtr->keysym);
|
|||
|
}
|
|||
|
Tcl_InitHashTable(&vkeyTable, TCL_ONE_WORD_KEYS);
|
|||
|
for (kPtr = vituralkeyArray; kPtr->keycode != 0; kPtr++) {
|
|||
|
hPtr = Tcl_CreateHashEntry(&vkeyTable, (char *) kPtr->keycode,
|
|||
|
&dummy);
|
|||
|
Tcl_SetHashValue(hPtr, kPtr->keysym);
|
|||
|
}
|
|||
|
KCHRPtr = (Ptr) GetScriptManagerVariable(smKCHRCache);
|
|||
|
initialized = 1;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*
|
|||
|
* 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* display,
|
|||
|
KeyCode keycode,
|
|||
|
int index)
|
|||
|
{
|
|||
|
register Tcl_HashEntry *hPtr;
|
|||
|
register char c;
|
|||
|
char virtualKey;
|
|||
|
int newKeycode;
|
|||
|
unsigned long dummy, newChar;
|
|||
|
|
|||
|
if (!initialized) {
|
|||
|
InitKeyMaps();
|
|||
|
}
|
|||
|
|
|||
|
c = keycode & charCodeMask;
|
|||
|
virtualKey = (keycode & keyCodeMask) >> 8;
|
|||
|
|
|||
|
/*
|
|||
|
* When determining what keysym to produce we firt check to see if
|
|||
|
* the key is a function key. We then check to see if the character
|
|||
|
* is another non-printing key. Finally, we return the key syms
|
|||
|
* for all ASCI chars.
|
|||
|
*/
|
|||
|
if (c == 0x10) {
|
|||
|
hPtr = Tcl_FindHashEntry(&vkeyTable, (char *) virtualKey);
|
|||
|
if (hPtr != NULL) {
|
|||
|
return (KeySym) Tcl_GetHashValue(hPtr);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
hPtr = Tcl_FindHashEntry(&keycodeTable, (char *) virtualKey);
|
|||
|
if (hPtr != NULL) {
|
|||
|
return (KeySym) Tcl_GetHashValue(hPtr);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Recompute the character based on the Shift key only.
|
|||
|
* TODO: The index may also specify the NUM_LOCK.
|
|||
|
*/
|
|||
|
newKeycode = virtualKey;
|
|||
|
if (index & 0x01) {
|
|||
|
newKeycode += 0x0200;
|
|||
|
}
|
|||
|
dummy = 0;
|
|||
|
newChar = KeyTranslate(KCHRPtr, (short) newKeycode, &dummy);
|
|||
|
c = newChar & charCodeMask;
|
|||
|
|
|||
|
if (c >= XK_space && c < XK_asciitilde) {
|
|||
|
return c;
|
|||
|
}
|
|||
|
|
|||
|
return 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(
|
|||
|
XKeyEvent* event_struct,
|
|||
|
char* buffer_return,
|
|||
|
int bytes_buffer,
|
|||
|
KeySym* keysym_return,
|
|||
|
XComposeStatus* status_in_out)
|
|||
|
{
|
|||
|
register Tcl_HashEntry *hPtr;
|
|||
|
char string[3];
|
|||
|
char virtualKey;
|
|||
|
char c;
|
|||
|
|
|||
|
if (!initialized) {
|
|||
|
InitKeyMaps();
|
|||
|
}
|
|||
|
|
|||
|
c = event_struct->keycode & charCodeMask;
|
|||
|
string[0] = c;
|
|||
|
string[1] = '\0';
|
|||
|
|
|||
|
/*
|
|||
|
* Just return NULL if the character is a function key or another
|
|||
|
* non-printing key.
|
|||
|
*/
|
|||
|
if (c == 0x10) {
|
|||
|
string[0] = '\0';
|
|||
|
} else {
|
|||
|
virtualKey = (event_struct->keycode & keyCodeMask) >> 8;
|
|||
|
hPtr = Tcl_FindHashEntry(&keycodeTable, (char *) virtualKey);
|
|||
|
if (hPtr != NULL) {
|
|||
|
string[0] = '\0';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (buffer_return != NULL) {
|
|||
|
strncpy(buffer_return, string, bytes_buffer);
|
|||
|
}
|
|||
|
|
|||
|
return strlen(string);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*
|
|||
|
* 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)
|
|||
|
{
|
|||
|
XModifierKeymap * modmap;
|
|||
|
|
|||
|
modmap = (XModifierKeymap *) ckalloc(sizeof(XModifierKeymap));
|
|||
|
modmap->max_keypermod = 0;
|
|||
|
modmap->modifiermap = NULL;
|
|||
|
return modmap;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*
|
|||
|
* XFreeModifiermap --
|
|||
|
*
|
|||
|
* Deallocate a modifier map that was created by
|
|||
|
* XGetModifierMapping.
|
|||
|
*
|
|||
|
* Results:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Side effects:
|
|||
|
* Frees the datastructure referenced by modmap.
|
|||
|
*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
void
|
|||
|
XFreeModifiermap(
|
|||
|
XModifierKeymap *modmap)
|
|||
|
{
|
|||
|
if (modmap->modifiermap != NULL) {
|
|||
|
ckfree((char *) modmap->modifiermap);
|
|||
|
}
|
|||
|
ckfree((char *) modmap);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*
|
|||
|
* XKeysymToString, XStringToKeysym --
|
|||
|
*
|
|||
|
* These X window functions map Keysyms to strings & strings to
|
|||
|
* keysyms. However, Tk already does this for the most common keysyms.
|
|||
|
* Therefor, these functions only need to support keysyms that will be
|
|||
|
* specific to the Macintosh. Currently, there are none.
|
|||
|
*
|
|||
|
* Results:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Side effects:
|
|||
|
* None.
|
|||
|
*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
char *
|
|||
|
XKeysymToString(
|
|||
|
KeySym keysym)
|
|||
|
{
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
KeySym
|
|||
|
XStringToKeysym(
|
|||
|
const char* string)
|
|||
|
{
|
|||
|
return NoSymbol;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*
|
|||
|
* XKeysymToKeycode --
|
|||
|
*
|
|||
|
* The function XKeysymToKeycode is only used by tkTest.c and
|
|||
|
* currently only implementes the support for keys used in the
|
|||
|
* Tk test suite.
|
|||
|
*
|
|||
|
* Results:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Side effects:
|
|||
|
* None.
|
|||
|
*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
KeyCode
|
|||
|
XKeysymToKeycode(
|
|||
|
Display* display,
|
|||
|
KeySym keysym)
|
|||
|
{
|
|||
|
KeyCode keycode = 0;
|
|||
|
char virtualKeyCode = 0;
|
|||
|
|
|||
|
if ((keysym >= XK_space) && (XK_asciitilde)) {
|
|||
|
if (keysym == 'a') {
|
|||
|
virtualKeyCode = 0x00;
|
|||
|
} else if (keysym == 'b' || keysym == 'B') {
|
|||
|
virtualKeyCode = 0x0B;
|
|||
|
} else if (keysym == 'c') {
|
|||
|
virtualKeyCode = 0x08;
|
|||
|
} else if (keysym == 'x' || keysym == 'X') {
|
|||
|
virtualKeyCode = 0x07;
|
|||
|
} else if (keysym == 'z') {
|
|||
|
virtualKeyCode = 0x06;
|
|||
|
} else if (keysym == ' ') {
|
|||
|
virtualKeyCode = 0x31;
|
|||
|
} else if (keysym == XK_Return) {
|
|||
|
virtualKeyCode = 0x24;
|
|||
|
keysym = '\r';
|
|||
|
}
|
|||
|
keycode = keysym + ((virtualKeyCode << 8) & keyCodeMask);
|
|||
|
}
|
|||
|
|
|||
|
return keycode;
|
|||
|
}
|