checkpoint. converting KeyID to use UTF-32 encoding instead of

X11 keysyms.
This commit is contained in:
crs 2002-07-23 17:04:41 +00:00
parent 57b64f1fe7
commit 8271c8accc
3 changed files with 225 additions and 35 deletions

View File

@ -371,8 +371,8 @@ CXWindowsSecondaryScreen::mapKey(Keystrokes& keys, KeyCode& keycode,
// that cannot be accomodated. // that cannot be accomodated.
// note if the key is the caps lock and it's "half-duplex" // note if the key is the caps lock and it's "half-duplex"
const bool isHalfDuplex = ((id == XK_Caps_Lock && m_capsLockHalfDuplex) || const bool isHalfDuplex = ((id == kKeyCapsLock && m_capsLockHalfDuplex) ||
(id == XK_Num_Lock && m_numLockHalfDuplex)); (id == kKeyNumLock && m_numLockHalfDuplex));
// ignore releases and repeats for half-duplex keys // ignore releases and repeats for half-duplex keys
if (isHalfDuplex && action != kPress) { if (isHalfDuplex && action != kPress) {
@ -385,10 +385,10 @@ CXWindowsSecondaryScreen::mapKey(Keystrokes& keys, KeyCode& keycode,
if (!findKeyCode(keycode, outMask, id, maskToX(mask))) { if (!findKeyCode(keycode, outMask, id, maskToX(mask))) {
// we cannot generate the desired keysym because no key // we cannot generate the desired keysym because no key
// maps to that keysym. just return the current mask. // maps to that keysym. just return the current mask.
log((CLOG_DEBUG2 "no keycode for keysym %d modifiers 0x%04x", id, mask)); log((CLOG_DEBUG2 "no keycode for KeyID %d modifiers 0x%04x", id, mask));
return m_mask; return m_mask;
} }
log((CLOG_DEBUG2 "keysym %d -> keycode %d modifiers 0x%04x", id, keycode, outMask)); log((CLOG_DEBUG2 "keysym %d -> KeyID %d modifiers 0x%04x", id, keycode, outMask));
// if we cannot match the modifier mask then don't return any // if we cannot match the modifier mask then don't return any
// keys and just return the current mask. // keys and just return the current mask.
@ -580,67 +580,93 @@ bool
CXWindowsSecondaryScreen::findKeyCode(KeyCode& keycode, CXWindowsSecondaryScreen::findKeyCode(KeyCode& keycode,
unsigned int& maskOut, KeyID id, unsigned int maskIn) const unsigned int& maskOut, KeyID id, unsigned int maskIn) const
{ {
// if XK_Tab is requested with shift active then try XK_ISO_Left_Tab // convert id to keysym
KeySym keysym = 0;
switch (id & 0xffffff00) {
case 0x0000:
// Latin-1
keysym = static_cast<KeySym>(id);
break;
case 0xee00:
// ISO 9995 Function and Modifier Keys
if (id == kKeyLeftTab) {
keysym = XK_ISO_Left_Tab;
}
break;
case 0xef00:
// MISCELLANY
keysym = static_cast<KeySym>(id - 0xef00 + 0xff00);
break;
}
// fail if unknown key
if (keysym == 0) {
return false;
}
// if kKeyTab is requested with shift active then try XK_ISO_Left_Tab
// instead. if that doesn't work, we'll fall back to XK_Tab with // instead. if that doesn't work, we'll fall back to XK_Tab with
// shift active. this is to handle primary screens that don't map // shift active. this is to handle primary screens that don't map
// XK_ISO_Left_Tab sending events to secondary screens that do. // XK_ISO_Left_Tab sending events to secondary screens that do.
if (id == XK_Tab && (maskIn & ShiftMask) != 0) { if (keysym == XK_Tab && (maskIn & ShiftMask) != 0) {
id = XK_ISO_Left_Tab; keysym = XK_ISO_Left_Tab;
maskIn &= ~ShiftMask; maskIn &= ~ShiftMask;
} }
// find a keycode to generate id. XKeysymToKeycode() almost does // find a keycode to generate id. XKeysymToKeycode() almost does
// what we need but won't tell us which index to use with the // what we need but won't tell us which index to use with the
// keycode. return false if there's no keycode to generate id. // keycode. return false if there's no keycode to generate id.
KeyCodeMap::const_iterator index = m_keycodeMap.find(id); KeyCodeMap::const_iterator index = m_keycodeMap.find(keysym);
if (index == m_keycodeMap.end()) { if (index == m_keycodeMap.end()) {
// try backup keysym for certain keys (particularly the numpad // try backup keysym for certain keys (particularly the numpad
// keys since most laptops don't have a separate numpad and the // keys since most laptops don't have a separate numpad and the
// numpad overlaying the main keyboard may not have movement // numpad overlaying the main keyboard may not have movement
// key bindings). // key bindings).
switch (id) { switch (keysym) {
case XK_KP_Home: case XK_KP_Home:
id = XK_Home; keysym = XK_Home;
break; break;
case XK_KP_Left: case XK_KP_Left:
id = XK_Left; keysym = XK_Left;
break; break;
case XK_KP_Up: case XK_KP_Up:
id = XK_Up; keysym = XK_Up;
break; break;
case XK_KP_Right: case XK_KP_Right:
id = XK_Right; keysym = XK_Right;
break; break;
case XK_KP_Down: case XK_KP_Down:
id = XK_Down; keysym = XK_Down;
break; break;
case XK_KP_Prior: case XK_KP_Prior:
id = XK_Prior; keysym = XK_Prior;
break; break;
case XK_KP_Next: case XK_KP_Next:
id = XK_Next; keysym = XK_Next;
break; break;
case XK_KP_End: case XK_KP_End:
id = XK_End; keysym = XK_End;
break; break;
case XK_KP_Insert: case XK_KP_Insert:
id = XK_Insert; keysym = XK_Insert;
break; break;
case XK_KP_Delete: case XK_KP_Delete:
id = XK_Delete; keysym = XK_Delete;
break; break;
case XK_ISO_Left_Tab: case XK_ISO_Left_Tab:
id = XK_Tab; keysym = XK_Tab;
maskIn |= ShiftMask; maskIn |= ShiftMask;
break; break;
@ -648,7 +674,7 @@ CXWindowsSecondaryScreen::findKeyCode(KeyCode& keycode,
return false; return false;
} }
index = m_keycodeMap.find(id); index = m_keycodeMap.find(keysym);
if (index == m_keycodeMap.end()) { if (index == m_keycodeMap.end()) {
return false; return false;
} }
@ -659,14 +685,14 @@ CXWindowsSecondaryScreen::findKeyCode(KeyCode& keycode,
// compute output mask. that's the set of modifiers that need to // compute output mask. that's the set of modifiers that need to
// be enabled when the keycode event is encountered in order to // be enabled when the keycode event is encountered in order to
// generate the id keysym and match maskIn. it's possible that // generate the keysym and match maskIn. it's possible that
// maskIn wants, say, a shift key to be down but that would make // maskIn wants, say, a shift key to be down but that would make
// it impossible to generate the keysym. in that case we must // it impossible to generate the keysym. in that case we must
// override maskIn. this is complicated by caps/shift-lock and // override maskIn. this is complicated by caps/shift-lock and
// num-lock. // num-lock.
maskOut = (maskIn & ~index->second.m_keyMaskMask); maskOut = (maskIn & ~index->second.m_keyMaskMask);
log((CLOG_DEBUG2 "maskIn(0x%04x) & ~maskMask(0x%04x) -> 0x%04x", maskIn, index->second.m_keyMaskMask, maskOut)); log((CLOG_DEBUG2 "maskIn(0x%04x) & ~maskMask(0x%04x) -> 0x%04x", maskIn, index->second.m_keyMaskMask, maskOut));
if (IsKeypadKey(id) || IsPrivateKeypadKey(id)) { if (IsKeypadKey(keysym) || IsPrivateKeypadKey(keysym)) {
if ((m_mask & m_numLockMask) != 0) { if ((m_mask & m_numLockMask) != 0) {
maskOut &= ~index->second.m_keyMask; maskOut &= ~index->second.m_keyMask;
maskOut |= m_numLockMask; maskOut |= m_numLockMask;
@ -687,7 +713,7 @@ CXWindowsSecondaryScreen::findKeyCode(KeyCode& keycode,
// characters that are not case conversions. see if // characters that are not case conversions. see if
// case conversion is necessary. // case conversion is necessary.
KeySym lKey, uKey; KeySym lKey, uKey;
XConvertCase(id, &lKey, &uKey); XConvertCase(keysym, &lKey, &uKey);
if (lKey != uKey) { if (lKey != uKey) {
log((CLOG_DEBUG2 "case convertable, shift && capsLock -> caps lock")); log((CLOG_DEBUG2 "case convertable, shift && capsLock -> caps lock"));
maskShift = m_capsLockMask; maskShift = m_capsLockMask;

View File

@ -12,6 +12,7 @@
# include <X11/X.h> # include <X11/X.h>
# include <X11/Xutil.h> # include <X11/Xutil.h>
# define XK_MISCELLANY # define XK_MISCELLANY
# define XK_XKB_KEYS
# include <X11/keysymdef.h> # include <X11/keysymdef.h>
#endif #endif
@ -172,10 +173,10 @@ CXWindowsPrimaryScreen::onEvent(CEvent* event)
const KeyID key = mapKey(&xevent.xkey); const KeyID key = mapKey(&xevent.xkey);
if (key != kKeyNone) { if (key != kKeyNone) {
m_receiver->onKeyDown(key, mask); m_receiver->onKeyDown(key, mask);
if (key == XK_Caps_Lock && m_capsLockHalfDuplex) { if (key == kKeyCapsLock && m_capsLockHalfDuplex) {
m_receiver->onKeyUp(key, mask | KeyModifierCapsLock); m_receiver->onKeyUp(key, mask | KeyModifierCapsLock);
} }
else if (key == XK_Num_Lock && m_numLockHalfDuplex) { else if (key == kKeyNumLock && m_numLockHalfDuplex) {
m_receiver->onKeyUp(key, mask | KeyModifierNumLock); m_receiver->onKeyUp(key, mask | KeyModifierNumLock);
} }
} }
@ -209,10 +210,10 @@ CXWindowsPrimaryScreen::onEvent(CEvent* event)
if (!hasPress) { if (!hasPress) {
// no press event follows so it's a plain release // no press event follows so it's a plain release
log((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state)); log((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
if (key == XK_Caps_Lock && m_capsLockHalfDuplex) { if (key == kKeyCapsLock && m_capsLockHalfDuplex) {
m_receiver->onKeyDown(key, mask); m_receiver->onKeyDown(key, mask);
} }
else if (key == XK_Num_Lock && m_numLockHalfDuplex) { else if (key == kKeyNumLock && m_numLockHalfDuplex) {
m_receiver->onKeyDown(key, mask); m_receiver->onKeyDown(key, mask);
} }
m_receiver->onKeyUp(key, mask); m_receiver->onKeyUp(key, mask);
@ -621,12 +622,35 @@ CXWindowsPrimaryScreen::mapModifier(unsigned int state) const
KeyID KeyID
CXWindowsPrimaryScreen::mapKey(XKeyEvent* event) const CXWindowsPrimaryScreen::mapKey(XKeyEvent* event) const
{ {
CDisplayLock display(m_screen);
// convert to a keysym
// FIXME -- we're not properly handling unicode
KeySym keysym; KeySym keysym;
char dummy[1]; char dummy[1];
CDisplayLock display(m_screen);
XLookupString(event, dummy, 0, &keysym, NULL); XLookupString(event, dummy, 0, &keysym, NULL);
return static_cast<KeyID>(keysym);
// convert key
switch (keysym & 0xffffff00) {
case 0x0000:
// Latin-1
return static_cast<KeyID>(keysym);
case 0xfe00:
// ISO 9995 Function and Modifier Keys
if (keysym == XK_ISO_Left_Tab) {
return kKeyLeftTab;
}
return kKeyNone;
case 0xff00:
// MISCELLANY
return static_cast<KeyID>(keysym - 0xff00 + 0xef00);
default:
// FIXME -- support unicode characters
return kKeyNone;
}
} }
ButtonID ButtonID

View File

@ -3,15 +3,14 @@
#include "BasicTypes.h" #include "BasicTypes.h"
// type to hold a key identifier // type to hold a key identifier. the encoding is UTF-32, using
// U+E000 through U+EFFF for the various control keys (e.g. arrow
// keys, function keys, modifier keys, etc).
typedef UInt32 KeyID; typedef UInt32 KeyID;
// type to hold bitmask of key modifiers (e.g. shift keys) // type to hold bitmask of key modifiers (e.g. shift keys)
typedef UInt32 KeyModifierMask; typedef UInt32 KeyModifierMask;
// key codes
static const KeyID kKeyNone = 0;
// modifier key bitmasks // modifier key bitmasks
static const KeyModifierMask KeyModifierShift = 0x0001; static const KeyModifierMask KeyModifierShift = 0x0001;
static const KeyModifierMask KeyModifierControl = 0x0002; static const KeyModifierMask KeyModifierControl = 0x0002;
@ -21,4 +20,145 @@ static const KeyModifierMask KeyModifierCapsLock = 0x1000;
static const KeyModifierMask KeyModifierNumLock = 0x2000; static const KeyModifierMask KeyModifierNumLock = 0x2000;
static const KeyModifierMask KeyModifierScrollLock = 0x4000; static const KeyModifierMask KeyModifierScrollLock = 0x4000;
//
// key codes. all codes except kKeyNone are equal to the corresponding
// X11 keysym - 0x1000.
//
// no key
static const KeyID kKeyNone = 0x0000;
// TTY functions
static const KeyID kKeyBackSpace = 0xEF08; /* back space, back char */
static const KeyID kKeyTab = 0xEF09;
static const KeyID kKeyLinefeed = 0xEF0A; /* Linefeed, LF */
static const KeyID kKeyClear = 0xEF0B;
static const KeyID kKeyReturn = 0xEF0D; /* Return, enter */
static const KeyID kKeyPause = 0xEF13; /* Pause, hold */
static const KeyID kKeyScrollLock = 0xEF14;
static const KeyID kKeySysReq = 0xEF15;
static const KeyID kKeyEscape = 0xEF1B;
static const KeyID kKeyDelete = 0xEFFF; /* Delete, rubout */
// cursor control
static const KeyID kKeyHome = 0xEF50;
static const KeyID kKeyLeft = 0xEF51; /* Move left, left arrow */
static const KeyID kKeyUp = 0xEF52; /* Move up, up arrow */
static const KeyID kKeyRight = 0xEF53; /* Move right, right arrow */
static const KeyID kKeyDown = 0xEF54; /* Move down, down arrow */
static const KeyID kKeyPageUp = 0xEF55;
static const KeyID kKeyPageDown = 0xEF56;
static const KeyID kKeyEnd = 0xEF57; /* EOL */
static const KeyID kKeyBegin = 0xEF58; /* BOL */
// misc functions
static const KeyID kKeySelect = 0xEF60; /* Select, mark */
static const KeyID kKeyPrint = 0xEF61;
static const KeyID kKeyExecute = 0xEF62; /* Execute, run, do */
static const KeyID kKeyInsert = 0xEF63; /* Insert, insert here */
static const KeyID kKeyUndo = 0xEF65; /* Undo, oops */
static const KeyID kKeyRedo = 0xEF66; /* redo, again */
static const KeyID kKeyMenu = 0xEF67;
static const KeyID kKeyFind = 0xEF68; /* Find, search */
static const KeyID kKeyCancel = 0xEF69; /* Cancel, stop, abort, exit */
static const KeyID kKeyHelp = 0xEF6A; /* Help */
static const KeyID kKeyBreak = 0xEF6B;
static const KeyID kKeyModeSwitch = 0xEF7E; /* Character set switch */
static const KeyID kKeyNumLock = 0xEF7F;
// keypad
static const KeyID kKeyKP_Space = 0xEF80; /* space */
static const KeyID kKeyKP_Tab = 0xEF89;
static const KeyID kKeyKP_Enter = 0xEF8D; /* enter */
static const KeyID kKeyKP_F1 = 0xEF91; /* PF1, KP_A, ... */
static const KeyID kKeyKP_F2 = 0xEF92;
static const KeyID kKeyKP_F3 = 0xEF93;
static const KeyID kKeyKP_F4 = 0xEF94;
static const KeyID kKeyKP_Home = 0xEF95;
static const KeyID kKeyKP_Left = 0xEF96;
static const KeyID kKeyKP_Up = 0xEF97;
static const KeyID kKeyKP_Right = 0xEF98;
static const KeyID kKeyKP_Down = 0xEF99;
static const KeyID kKeyKP_Prior = 0xEF9A;
static const KeyID kKeyKP_PageUp = 0xEF9A;
static const KeyID kKeyKP_Next = 0xEF9B;
static const KeyID kKeyKP_PageDown = 0xEF9B;
static const KeyID kKeyKP_End = 0xEF9C;
static const KeyID kKeyKP_Begin = 0xEF9D;
static const KeyID kKeyKP_Insert = 0xEF9E;
static const KeyID kKeyKP_Delete = 0xEF9F;
static const KeyID kKeyKP_Equal = 0xEFBD; /* equals */
static const KeyID kKeyKP_Multiply = 0xEFAA;
static const KeyID kKeyKP_Add = 0xEFAB;
static const KeyID kKeyKP_Separator= 0xEFAC; /* separator, often comma */
static const KeyID kKeyKP_Subtract = 0xEFAD;
static const KeyID kKeyKP_Decimal = 0xEFAE;
static const KeyID kKeyKP_Divide = 0xEFAF;
static const KeyID kKeyKP_0 = 0xEFB0;
static const KeyID kKeyKP_1 = 0xEFB1;
static const KeyID kKeyKP_2 = 0xEFB2;
static const KeyID kKeyKP_3 = 0xEFB3;
static const KeyID kKeyKP_4 = 0xEFB4;
static const KeyID kKeyKP_5 = 0xEFB5;
static const KeyID kKeyKP_6 = 0xEFB6;
static const KeyID kKeyKP_7 = 0xEFB7;
static const KeyID kKeyKP_8 = 0xEFB8;
static const KeyID kKeyKP_9 = 0xEFB9;
// function keys
static const KeyID kKeyF1 = 0xEFBE;
static const KeyID kKeyF2 = 0xEFBF;
static const KeyID kKeyF3 = 0xEFC0;
static const KeyID kKeyF4 = 0xEFC1;
static const KeyID kKeyF5 = 0xEFC2;
static const KeyID kKeyF6 = 0xEFC3;
static const KeyID kKeyF7 = 0xEFC4;
static const KeyID kKeyF8 = 0xEFC5;
static const KeyID kKeyF9 = 0xEFC6;
static const KeyID kKeyF10 = 0xEFC7;
static const KeyID kKeyF11 = 0xEFC8;
static const KeyID kKeyF12 = 0xEFC9;
static const KeyID kKeyF13 = 0xEFCA;
static const KeyID kKeyF14 = 0xEFCB;
static const KeyID kKeyF15 = 0xEFCC;
static const KeyID kKeyF16 = 0xEFCD;
static const KeyID kKeyF17 = 0xEFCE;
static const KeyID kKeyF18 = 0xEFCF;
static const KeyID kKeyF19 = 0xEFD0;
static const KeyID kKeyF20 = 0xEFD1;
static const KeyID kKeyF21 = 0xEFD2;
static const KeyID kKeyF22 = 0xEFD3;
static const KeyID kKeyF23 = 0xEFD4;
static const KeyID kKeyF24 = 0xEFD5;
static const KeyID kKeyF25 = 0xEFD6;
static const KeyID kKeyF26 = 0xEFD7;
static const KeyID kKeyF27 = 0xEFD8;
static const KeyID kKeyF28 = 0xEFD9;
static const KeyID kKeyF29 = 0xEFDA;
static const KeyID kKeyF30 = 0xEFDB;
static const KeyID kKeyF31 = 0xEFDC;
static const KeyID kKeyF32 = 0xEFDD;
static const KeyID kKeyF33 = 0xEFDE;
static const KeyID kKeyF34 = 0xEFDF;
static const KeyID kKeyF35 = 0xEFE0;
// modifiers
static const KeyID kKeyShift_L = 0xEFE1; /* Left shift */
static const KeyID kKeyShift_R = 0xEFE2; /* Right shift */
static const KeyID kKeyControl_L = 0xEFE3; /* Left control */
static const KeyID kKeyControl_R = 0xEFE4; /* Right control */
static const KeyID kKeyCapsLock = 0xEFE5; /* Caps lock */
static const KeyID kKeyShiftLock = 0xEFE6; /* Shift lock */
static const KeyID kKeyMeta_L = 0xEFE7; /* Left meta */
static const KeyID kKeyMeta_R = 0xEFE8; /* Right meta */
static const KeyID kKeyAlt_L = 0xEFE9; /* Left alt */
static const KeyID kKeyAlt_R = 0xEFEA; /* Right alt */
static const KeyID kKeySuper_L = 0xEFEB; /* Left super */
static const KeyID kKeySuper_R = 0xEFEC; /* Right super */
static const KeyID kKeyHyper_L = 0xEFED; /* Left hyper */
static const KeyID kKeyHyper_R = 0xEFEE; /* Right hyper */
// more function and modifier keys
static const KeyID kKeyLeftTab = 0xEE20;
#endif #endif