checkpoint. converting KeyID to use UTF-32 encoding instead of
X11 keysyms.
This commit is contained in:
parent
57b64f1fe7
commit
8271c8accc
|
@ -371,8 +371,8 @@ CXWindowsSecondaryScreen::mapKey(Keystrokes& keys, KeyCode& keycode,
|
|||
// that cannot be accomodated.
|
||||
|
||||
// note if the key is the caps lock and it's "half-duplex"
|
||||
const bool isHalfDuplex = ((id == XK_Caps_Lock && m_capsLockHalfDuplex) ||
|
||||
(id == XK_Num_Lock && m_numLockHalfDuplex));
|
||||
const bool isHalfDuplex = ((id == kKeyCapsLock && m_capsLockHalfDuplex) ||
|
||||
(id == kKeyNumLock && m_numLockHalfDuplex));
|
||||
|
||||
// ignore releases and repeats for half-duplex keys
|
||||
if (isHalfDuplex && action != kPress) {
|
||||
|
@ -385,10 +385,10 @@ CXWindowsSecondaryScreen::mapKey(Keystrokes& keys, KeyCode& keycode,
|
|||
if (!findKeyCode(keycode, outMask, id, maskToX(mask))) {
|
||||
// we cannot generate the desired keysym because no key
|
||||
// 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;
|
||||
}
|
||||
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
|
||||
// keys and just return the current mask.
|
||||
|
@ -580,67 +580,93 @@ bool
|
|||
CXWindowsSecondaryScreen::findKeyCode(KeyCode& keycode,
|
||||
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
|
||||
// shift active. this is to handle primary screens that don't map
|
||||
// XK_ISO_Left_Tab sending events to secondary screens that do.
|
||||
if (id == XK_Tab && (maskIn & ShiftMask) != 0) {
|
||||
id = XK_ISO_Left_Tab;
|
||||
if (keysym == XK_Tab && (maskIn & ShiftMask) != 0) {
|
||||
keysym = XK_ISO_Left_Tab;
|
||||
maskIn &= ~ShiftMask;
|
||||
}
|
||||
|
||||
// find a keycode to generate id. XKeysymToKeycode() almost does
|
||||
// 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.
|
||||
KeyCodeMap::const_iterator index = m_keycodeMap.find(id);
|
||||
KeyCodeMap::const_iterator index = m_keycodeMap.find(keysym);
|
||||
if (index == m_keycodeMap.end()) {
|
||||
// try backup keysym for certain keys (particularly the numpad
|
||||
// keys since most laptops don't have a separate numpad and the
|
||||
// numpad overlaying the main keyboard may not have movement
|
||||
// key bindings).
|
||||
switch (id) {
|
||||
switch (keysym) {
|
||||
case XK_KP_Home:
|
||||
id = XK_Home;
|
||||
keysym = XK_Home;
|
||||
break;
|
||||
|
||||
case XK_KP_Left:
|
||||
id = XK_Left;
|
||||
keysym = XK_Left;
|
||||
break;
|
||||
|
||||
case XK_KP_Up:
|
||||
id = XK_Up;
|
||||
keysym = XK_Up;
|
||||
break;
|
||||
|
||||
case XK_KP_Right:
|
||||
id = XK_Right;
|
||||
keysym = XK_Right;
|
||||
break;
|
||||
|
||||
case XK_KP_Down:
|
||||
id = XK_Down;
|
||||
keysym = XK_Down;
|
||||
break;
|
||||
|
||||
case XK_KP_Prior:
|
||||
id = XK_Prior;
|
||||
keysym = XK_Prior;
|
||||
break;
|
||||
|
||||
case XK_KP_Next:
|
||||
id = XK_Next;
|
||||
keysym = XK_Next;
|
||||
break;
|
||||
|
||||
case XK_KP_End:
|
||||
id = XK_End;
|
||||
keysym = XK_End;
|
||||
break;
|
||||
|
||||
case XK_KP_Insert:
|
||||
id = XK_Insert;
|
||||
keysym = XK_Insert;
|
||||
break;
|
||||
|
||||
case XK_KP_Delete:
|
||||
id = XK_Delete;
|
||||
keysym = XK_Delete;
|
||||
break;
|
||||
|
||||
case XK_ISO_Left_Tab:
|
||||
id = XK_Tab;
|
||||
keysym = XK_Tab;
|
||||
maskIn |= ShiftMask;
|
||||
break;
|
||||
|
||||
|
@ -648,7 +674,7 @@ CXWindowsSecondaryScreen::findKeyCode(KeyCode& keycode,
|
|||
return false;
|
||||
}
|
||||
|
||||
index = m_keycodeMap.find(id);
|
||||
index = m_keycodeMap.find(keysym);
|
||||
if (index == m_keycodeMap.end()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -659,14 +685,14 @@ CXWindowsSecondaryScreen::findKeyCode(KeyCode& keycode,
|
|||
|
||||
// compute output mask. that's the set of modifiers that need 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
|
||||
// it impossible to generate the keysym. in that case we must
|
||||
// override maskIn. this is complicated by caps/shift-lock and
|
||||
// num-lock.
|
||||
maskOut = (maskIn & ~index->second.m_keyMaskMask);
|
||||
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) {
|
||||
maskOut &= ~index->second.m_keyMask;
|
||||
maskOut |= m_numLockMask;
|
||||
|
@ -687,7 +713,7 @@ CXWindowsSecondaryScreen::findKeyCode(KeyCode& keycode,
|
|||
// characters that are not case conversions. see if
|
||||
// case conversion is necessary.
|
||||
KeySym lKey, uKey;
|
||||
XConvertCase(id, &lKey, &uKey);
|
||||
XConvertCase(keysym, &lKey, &uKey);
|
||||
if (lKey != uKey) {
|
||||
log((CLOG_DEBUG2 "case convertable, shift && capsLock -> caps lock"));
|
||||
maskShift = m_capsLockMask;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# include <X11/X.h>
|
||||
# include <X11/Xutil.h>
|
||||
# define XK_MISCELLANY
|
||||
# define XK_XKB_KEYS
|
||||
# include <X11/keysymdef.h>
|
||||
#endif
|
||||
|
||||
|
@ -172,10 +173,10 @@ CXWindowsPrimaryScreen::onEvent(CEvent* event)
|
|||
const KeyID key = mapKey(&xevent.xkey);
|
||||
if (key != kKeyNone) {
|
||||
m_receiver->onKeyDown(key, mask);
|
||||
if (key == XK_Caps_Lock && m_capsLockHalfDuplex) {
|
||||
if (key == kKeyCapsLock && m_capsLockHalfDuplex) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -209,10 +210,10 @@ CXWindowsPrimaryScreen::onEvent(CEvent* event)
|
|||
if (!hasPress) {
|
||||
// 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));
|
||||
if (key == XK_Caps_Lock && m_capsLockHalfDuplex) {
|
||||
if (key == kKeyCapsLock && m_capsLockHalfDuplex) {
|
||||
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->onKeyUp(key, mask);
|
||||
|
@ -621,12 +622,35 @@ CXWindowsPrimaryScreen::mapModifier(unsigned int state) const
|
|||
KeyID
|
||||
CXWindowsPrimaryScreen::mapKey(XKeyEvent* event) const
|
||||
{
|
||||
CDisplayLock display(m_screen);
|
||||
|
||||
// convert to a keysym
|
||||
// FIXME -- we're not properly handling unicode
|
||||
KeySym keysym;
|
||||
char dummy[1];
|
||||
|
||||
CDisplayLock display(m_screen);
|
||||
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
|
||||
|
|
|
@ -3,15 +3,14 @@
|
|||
|
||||
#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;
|
||||
|
||||
// type to hold bitmask of key modifiers (e.g. shift keys)
|
||||
typedef UInt32 KeyModifierMask;
|
||||
|
||||
// key codes
|
||||
static const KeyID kKeyNone = 0;
|
||||
|
||||
// modifier key bitmasks
|
||||
static const KeyModifierMask KeyModifierShift = 0x0001;
|
||||
static const KeyModifierMask KeyModifierControl = 0x0002;
|
||||
|
@ -21,4 +20,145 @@ static const KeyModifierMask KeyModifierCapsLock = 0x1000;
|
|||
static const KeyModifierMask KeyModifierNumLock = 0x2000;
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue