Keyboard fixes on win32.
This commit is contained in:
parent
b9193ae1bb
commit
28427a0e9b
|
@ -70,6 +70,19 @@
|
||||||
// CMSWindowsSecondaryScreen
|
// CMSWindowsSecondaryScreen
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// a list of modifier key info
|
||||||
|
const CMSWindowsSecondaryScreen::CModifierInfo
|
||||||
|
CMSWindowsSecondaryScreen::s_modifier[] = {
|
||||||
|
{ KeyModifierShift, VK_LSHIFT, VK_RSHIFT, false },
|
||||||
|
{ KeyModifierControl, VK_LCONTROL, VK_RCONTROL | 0x100,false },
|
||||||
|
{ KeyModifierAlt, VK_LMENU, VK_RMENU | 0x100, false },
|
||||||
|
// note -- no keys for KeyModifierMeta
|
||||||
|
{ KeyModifierSuper, VK_LWIN | 0x100, VK_RWIN | 0x100, false },
|
||||||
|
{ KeyModifierCapsLock, VK_CAPITAL, 0, true },
|
||||||
|
{ KeyModifierNumLock, VK_NUMLOCK | 0x100, 0, true },
|
||||||
|
{ KeyModifierScrollLock,VK_SCROLL, 0, true }
|
||||||
|
};
|
||||||
|
|
||||||
CMSWindowsSecondaryScreen::CMSWindowsSecondaryScreen(
|
CMSWindowsSecondaryScreen::CMSWindowsSecondaryScreen(
|
||||||
IScreenReceiver* receiver) :
|
IScreenReceiver* receiver) :
|
||||||
m_is95Family(CArchMiscWindows::isWindows95Family()),
|
m_is95Family(CArchMiscWindows::isWindows95Family()),
|
||||||
|
@ -90,9 +103,6 @@ void
|
||||||
CMSWindowsSecondaryScreen::keyDown(KeyID key,
|
CMSWindowsSecondaryScreen::keyDown(KeyID key,
|
||||||
KeyModifierMask mask, KeyButton button)
|
KeyModifierMask mask, KeyButton button)
|
||||||
{
|
{
|
||||||
Keystrokes keys;
|
|
||||||
UINT virtualKey;
|
|
||||||
|
|
||||||
CLock lock(&m_mutex);
|
CLock lock(&m_mutex);
|
||||||
m_screen->syncDesktop();
|
m_screen->syncDesktop();
|
||||||
|
|
||||||
|
@ -106,15 +116,21 @@ CMSWindowsSecondaryScreen::keyDown(KeyID key,
|
||||||
|
|
||||||
// get the sequence of keys to simulate key press and the final
|
// get the sequence of keys to simulate key press and the final
|
||||||
// modifier state.
|
// modifier state.
|
||||||
|
Keystrokes keys;
|
||||||
|
UINT virtualKey;
|
||||||
m_mask = mapKey(keys, virtualKey, key, mask, kPress);
|
m_mask = mapKey(keys, virtualKey, key, mask, kPress);
|
||||||
if (keys.empty()) {
|
if (keys.empty()) {
|
||||||
|
// do nothing if there are no associated keys (i.e. lookup failed)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate key events
|
// generate key events
|
||||||
doKeystrokes(keys, 1);
|
doKeystrokes(keys, 1);
|
||||||
|
|
||||||
|
// do not record button down if button is 0 (invalid)
|
||||||
|
if (button != 0) {
|
||||||
// note that key is now down
|
// note that key is now down
|
||||||
|
m_serverKeyMap[button] = virtualKey;
|
||||||
m_keys[virtualKey] |= 0x80;
|
m_keys[virtualKey] |= 0x80;
|
||||||
m_fakeKeys[virtualKey] |= 0x80;
|
m_fakeKeys[virtualKey] |= 0x80;
|
||||||
switch (virtualKey) {
|
switch (virtualKey) {
|
||||||
|
@ -136,18 +152,13 @@ CMSWindowsSecondaryScreen::keyDown(KeyID key,
|
||||||
m_fakeKeys[VK_MENU] |= 0x80;
|
m_fakeKeys[VK_MENU] |= 0x80;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// note which server key generated this key
|
|
||||||
m_serverKeyMap[button] = virtualKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CMSWindowsSecondaryScreen::keyRepeat(KeyID key,
|
CMSWindowsSecondaryScreen::keyRepeat(KeyID key,
|
||||||
KeyModifierMask mask, SInt32 count, KeyButton button)
|
KeyModifierMask mask, SInt32 count, KeyButton button)
|
||||||
{
|
{
|
||||||
Keystrokes keys;
|
|
||||||
UINT virtualKey;
|
|
||||||
|
|
||||||
CLock lock(&m_mutex);
|
CLock lock(&m_mutex);
|
||||||
m_screen->syncDesktop();
|
m_screen->syncDesktop();
|
||||||
|
|
||||||
|
@ -159,20 +170,26 @@ CMSWindowsSecondaryScreen::keyRepeat(KeyID key,
|
||||||
|
|
||||||
// get the sequence of keys to simulate key repeat and the final
|
// get the sequence of keys to simulate key repeat and the final
|
||||||
// modifier state.
|
// modifier state.
|
||||||
|
Keystrokes keys;
|
||||||
|
UINT virtualKey;
|
||||||
m_mask = mapKey(keys, virtualKey, key, mask, kRepeat);
|
m_mask = mapKey(keys, virtualKey, key, mask, kRepeat);
|
||||||
if (keys.empty()) {
|
if (keys.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we've seen this button (and we should have) then make sure
|
// if the keycode for the auto-repeat is not the same as for the
|
||||||
// we release the same key we pressed when we saw it.
|
// initial press then mark the initial key as released and the new
|
||||||
if (index != m_serverKeyMap.end() && virtualKey != index->second) {
|
// key as pressed. this can happen when we auto-repeat after a
|
||||||
|
// dead key. for example, a dead accent followed by 'a' will
|
||||||
|
// generate an 'a with accent' followed by a repeating 'a'. the
|
||||||
|
// keycodes for the two keysyms might be different.
|
||||||
|
if (virtualKey != index->second) {
|
||||||
// replace key up with previous keycode but leave key down
|
// replace key up with previous keycode but leave key down
|
||||||
// alone so it uses the new keycode and store that keycode
|
// alone so it uses the new keycode and store that keycode
|
||||||
// in the server key map.
|
// in the server key map.
|
||||||
for (Keystrokes::iterator index2 = keys.begin();
|
for (Keystrokes::iterator index2 = keys.begin();
|
||||||
index2 != keys.end(); ++index2) {
|
index2 != keys.end(); ++index2) {
|
||||||
if (index2->m_virtualKey == index->second) {
|
if (index2->m_virtualKey == virtualKey) {
|
||||||
index2->m_virtualKey = index->second;
|
index2->m_virtualKey = index->second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -195,12 +212,8 @@ CMSWindowsSecondaryScreen::keyRepeat(KeyID key,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CMSWindowsSecondaryScreen::keyUp(KeyID key,
|
CMSWindowsSecondaryScreen::keyUp(KeyID, KeyModifierMask, KeyButton button)
|
||||||
KeyModifierMask mask, KeyButton button)
|
|
||||||
{
|
{
|
||||||
Keystrokes keys;
|
|
||||||
UINT virtualKey;
|
|
||||||
|
|
||||||
CLock lock(&m_mutex);
|
CLock lock(&m_mutex);
|
||||||
m_screen->syncDesktop();
|
m_screen->syncDesktop();
|
||||||
|
|
||||||
|
@ -209,42 +222,18 @@ CMSWindowsSecondaryScreen::keyUp(KeyID key,
|
||||||
if (index == m_serverKeyMap.end()) {
|
if (index == m_serverKeyMap.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
UINT virtualKey = index->second;
|
||||||
|
|
||||||
// get the sequence of keys to simulate key release and the final
|
// get the sequence of keys to simulate key release and the final
|
||||||
// modifier state.
|
// modifier state.
|
||||||
m_mask = mapKey(keys, virtualKey, key, mask, kRelease);
|
Keystrokes keys;
|
||||||
|
m_mask = mapKeyRelease(keys, virtualKey);
|
||||||
// if there are no keys to generate then we should at least generate
|
|
||||||
// a key release for the key we pressed.
|
|
||||||
if (keys.empty()) {
|
|
||||||
Keystroke keystroke;
|
|
||||||
virtualKey = index->second;
|
|
||||||
keystroke.m_virtualKey = virtualKey;
|
|
||||||
keystroke.m_press = false;
|
|
||||||
keystroke.m_repeat = false;
|
|
||||||
keys.push_back(keystroke);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we've seen this button (and we should have) then make sure
|
|
||||||
// we release the same key we pressed when we saw it.
|
|
||||||
if (index != m_serverKeyMap.end() && virtualKey != index->second) {
|
|
||||||
// replace key up with previous virtual key
|
|
||||||
for (Keystrokes::iterator index2 = keys.begin();
|
|
||||||
index2 != keys.end(); ++index2) {
|
|
||||||
if (index2->m_virtualKey == virtualKey) {
|
|
||||||
index2->m_virtualKey = index->second;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// use old virtual key
|
|
||||||
virtualKey = index->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate key events
|
// generate key events
|
||||||
doKeystrokes(keys, 1);
|
doKeystrokes(keys, 1);
|
||||||
|
|
||||||
// note that key is now up
|
// note that key is now up
|
||||||
|
m_serverKeyMap.erase(index);
|
||||||
m_keys[virtualKey] &= ~0x80;
|
m_keys[virtualKey] &= ~0x80;
|
||||||
m_fakeKeys[virtualKey] &= ~0x80;
|
m_fakeKeys[virtualKey] &= ~0x80;
|
||||||
switch (virtualKey) {
|
switch (virtualKey) {
|
||||||
|
@ -290,11 +279,6 @@ CMSWindowsSecondaryScreen::keyUp(KeyID key,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove server key from map
|
|
||||||
if (index != m_serverKeyMap.end()) {
|
|
||||||
m_serverKeyMap.erase(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1003,6 +987,47 @@ CMSWindowsSecondaryScreen::mapKey(Keystrokes& keys, UINT& virtualKey,
|
||||||
return m_mask;
|
return m_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyModifierMask
|
||||||
|
CMSWindowsSecondaryScreen::mapKeyRelease(Keystrokes& keys,
|
||||||
|
UINT virtualKey) const
|
||||||
|
{
|
||||||
|
// add key release
|
||||||
|
Keystroke keystroke;
|
||||||
|
keystroke.m_virtualKey = virtualKey;
|
||||||
|
keystroke.m_press = false;
|
||||||
|
keystroke.m_repeat = false;
|
||||||
|
keys.push_back(keystroke);
|
||||||
|
|
||||||
|
// if this is a modifier keycode then update the current modifier mask
|
||||||
|
const CModifierInfo* modifier = getModifierInfo(virtualKey);
|
||||||
|
if (modifier != NULL) {
|
||||||
|
if (modifier->m_isToggle) {
|
||||||
|
// toggle keys modify the state on release
|
||||||
|
return (m_mask ^ modifier->m_mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// can't reset bit until all keys that set it are released.
|
||||||
|
// scan those keys to see if any (except virtualKey) are
|
||||||
|
// pressed.
|
||||||
|
bool down = false;
|
||||||
|
if (virtualKey != (modifier->m_virtualKey & 0xff) &&
|
||||||
|
(m_keys[modifier->m_virtualKey & 0xff] & 0x80) != 0) {
|
||||||
|
down = true;
|
||||||
|
}
|
||||||
|
if (modifier->m_virtualKey2 != 0 &&
|
||||||
|
virtualKey != (modifier->m_virtualKey2 & 0xff) &&
|
||||||
|
(m_keys[modifier->m_virtualKey2 & 0xff] & 0x80) != 0) {
|
||||||
|
down = true;
|
||||||
|
}
|
||||||
|
if (!down) {
|
||||||
|
return (m_mask & ~modifier->m_mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_mask;
|
||||||
|
}
|
||||||
|
|
||||||
UINT
|
UINT
|
||||||
CMSWindowsSecondaryScreen::mapCharacter(Keystrokes& keys,
|
CMSWindowsSecondaryScreen::mapCharacter(Keystrokes& keys,
|
||||||
char c, HKL hkl,
|
char c, HKL hkl,
|
||||||
|
@ -1102,73 +1127,7 @@ CMSWindowsSecondaryScreen::mapToKeystrokes(Keystrokes& keys,
|
||||||
KeyModifierMask currentMask,
|
KeyModifierMask currentMask,
|
||||||
KeyModifierMask desiredMask, EKeyAction action) const
|
KeyModifierMask desiredMask, EKeyAction action) const
|
||||||
{
|
{
|
||||||
// a list of modifier key info
|
const CModifierInfo* modifier = getModifierInfo(virtualKey);
|
||||||
class CModifierInfo {
|
|
||||||
public:
|
|
||||||
KeyModifierMask m_mask;
|
|
||||||
UINT m_virtualKey;
|
|
||||||
UINT m_virtualKey2;
|
|
||||||
bool m_isToggle;
|
|
||||||
};
|
|
||||||
static const CModifierInfo s_modifier[] = {
|
|
||||||
{ KeyModifierShift, VK_LSHIFT, VK_RSHIFT, false },
|
|
||||||
{ KeyModifierControl, VK_LCONTROL, VK_RCONTROL | 0x100,false },
|
|
||||||
{ KeyModifierAlt, VK_LMENU, VK_RMENU | 0x100, false },
|
|
||||||
// note -- no keys for KeyModifierMeta
|
|
||||||
{ KeyModifierSuper, VK_LWIN | 0x100, VK_RWIN | 0x100, false },
|
|
||||||
{ KeyModifierCapsLock, VK_CAPITAL, 0, true },
|
|
||||||
{ KeyModifierNumLock, VK_NUMLOCK | 0x100, 0, true },
|
|
||||||
{ KeyModifierScrollLock,VK_SCROLL, 0, true }
|
|
||||||
};
|
|
||||||
static const unsigned int s_numModifiers =
|
|
||||||
sizeof(s_modifier) / sizeof(s_modifier[0]);
|
|
||||||
|
|
||||||
// strip out extended key flag
|
|
||||||
UINT virtualKey2 = (virtualKey & ~0x100);
|
|
||||||
|
|
||||||
// note if the key is a modifier
|
|
||||||
unsigned int modifierIndex;
|
|
||||||
switch (virtualKey2) {
|
|
||||||
case VK_SHIFT:
|
|
||||||
case VK_LSHIFT:
|
|
||||||
case VK_RSHIFT:
|
|
||||||
modifierIndex = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_CONTROL:
|
|
||||||
case VK_LCONTROL:
|
|
||||||
case VK_RCONTROL:
|
|
||||||
modifierIndex = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_MENU:
|
|
||||||
case VK_LMENU:
|
|
||||||
case VK_RMENU:
|
|
||||||
modifierIndex = 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_LWIN:
|
|
||||||
case VK_RWIN:
|
|
||||||
modifierIndex = 3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_CAPITAL:
|
|
||||||
modifierIndex = 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_NUMLOCK:
|
|
||||||
modifierIndex = 5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_SCROLL:
|
|
||||||
modifierIndex = 6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
modifierIndex = s_numModifiers;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const bool isModifier = (modifierIndex != s_numModifiers);
|
|
||||||
|
|
||||||
// add the key events required to get to the desired modifier state.
|
// add the key events required to get to the desired modifier state.
|
||||||
// also save the key events required to restore the current state.
|
// also save the key events required to restore the current state.
|
||||||
|
@ -1176,7 +1135,9 @@ CMSWindowsSecondaryScreen::mapToKeystrokes(Keystrokes& keys,
|
||||||
// should not modify modifiers.
|
// should not modify modifiers.
|
||||||
Keystrokes undo;
|
Keystrokes undo;
|
||||||
Keystroke keystroke;
|
Keystroke keystroke;
|
||||||
if (desiredMask != currentMask && !isModifier) {
|
if (desiredMask != currentMask && modifier == NULL) {
|
||||||
|
const unsigned int s_numModifiers = sizeof(s_modifier) /
|
||||||
|
sizeof(s_modifier[0]);
|
||||||
for (unsigned int i = 0; i < s_numModifiers; ++i) {
|
for (unsigned int i = 0; i < s_numModifiers; ++i) {
|
||||||
KeyModifierMask bit = s_modifier[i].m_mask;
|
KeyModifierMask bit = s_modifier[i].m_mask;
|
||||||
if ((desiredMask & bit) != (currentMask & bit)) {
|
if ((desiredMask & bit) != (currentMask & bit)) {
|
||||||
|
@ -1274,35 +1235,12 @@ CMSWindowsSecondaryScreen::mapToKeystrokes(Keystrokes& keys,
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the key is a modifier key then compute the modifier mask after
|
// if the key is a modifier key then compute the modifier mask after
|
||||||
// this key is pressed.
|
// this key is pressed. toggle keys modify the state on release.
|
||||||
|
// other keys set the modifier bit on press.
|
||||||
KeyModifierMask mask = currentMask;
|
KeyModifierMask mask = currentMask;
|
||||||
if (isModifier && action != kRepeat) {
|
if (action == kPress) {
|
||||||
// toggle keys modify the state on release. other keys set
|
if (modifier != NULL && !modifier->m_isToggle) {
|
||||||
// the bit on press and clear the bit on release.
|
mask |= modifier->m_mask;
|
||||||
const CModifierInfo& modifier = s_modifier[modifierIndex];
|
|
||||||
if (modifier.m_isToggle) {
|
|
||||||
if (action == kRelease) {
|
|
||||||
mask ^= modifier.m_mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (action == kPress) {
|
|
||||||
mask |= modifier.m_mask;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// can't reset bit until all keys that set it are released.
|
|
||||||
// scan those keys to see if any are pressed.
|
|
||||||
bool down = false;
|
|
||||||
if (virtualKey2 != (modifier.m_virtualKey & 0xff) &&
|
|
||||||
(m_keys[modifier.m_virtualKey & 0xff] & 0x80) != 0) {
|
|
||||||
down = true;
|
|
||||||
}
|
|
||||||
if (modifier.m_virtualKey2 != 0 &&
|
|
||||||
virtualKey2 != (modifier.m_virtualKey2 & 0xff) &&
|
|
||||||
(m_keys[modifier.m_virtualKey2 & 0xff] & 0x80) != 0) {
|
|
||||||
down = true;
|
|
||||||
}
|
|
||||||
if (!down)
|
|
||||||
mask &= ~modifier.m_mask;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1344,6 +1282,45 @@ CMSWindowsSecondaryScreen::doKeystrokes(const Keystrokes& keys, SInt32 count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CMSWindowsSecondaryScreen::CModifierInfo*
|
||||||
|
CMSWindowsSecondaryScreen::getModifierInfo(UINT virtualKey) const
|
||||||
|
{
|
||||||
|
// note if the key is a modifier. strip out extended key flag from
|
||||||
|
// virtual key before lookup.
|
||||||
|
switch (virtualKey & ~0x100) {
|
||||||
|
case VK_SHIFT:
|
||||||
|
case VK_LSHIFT:
|
||||||
|
case VK_RSHIFT:
|
||||||
|
return s_modifier + 0;
|
||||||
|
|
||||||
|
case VK_CONTROL:
|
||||||
|
case VK_LCONTROL:
|
||||||
|
case VK_RCONTROL:
|
||||||
|
return s_modifier + 1;
|
||||||
|
|
||||||
|
case VK_MENU:
|
||||||
|
case VK_LMENU:
|
||||||
|
case VK_RMENU:
|
||||||
|
return s_modifier + 2;
|
||||||
|
|
||||||
|
case VK_LWIN:
|
||||||
|
case VK_RWIN:
|
||||||
|
return s_modifier + 3;
|
||||||
|
|
||||||
|
case VK_CAPITAL:
|
||||||
|
return s_modifier + 4;
|
||||||
|
|
||||||
|
case VK_NUMLOCK:
|
||||||
|
return s_modifier + 5;
|
||||||
|
|
||||||
|
case VK_SCROLL:
|
||||||
|
return s_modifier + 6;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CMSWindowsSecondaryScreen::releaseKeys()
|
CMSWindowsSecondaryScreen::releaseKeys()
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,6 +85,13 @@ private:
|
||||||
bool m_press;
|
bool m_press;
|
||||||
bool m_repeat;
|
bool m_repeat;
|
||||||
};
|
};
|
||||||
|
class CModifierInfo {
|
||||||
|
public:
|
||||||
|
KeyModifierMask m_mask;
|
||||||
|
UINT m_virtualKey;
|
||||||
|
UINT m_virtualKey2;
|
||||||
|
bool m_isToggle;
|
||||||
|
};
|
||||||
typedef std::vector<Keystroke> Keystrokes;
|
typedef std::vector<Keystroke> Keystrokes;
|
||||||
typedef std::map<KeyButton, UINT> ServerKeyMap;
|
typedef std::map<KeyButton, UINT> ServerKeyMap;
|
||||||
|
|
||||||
|
@ -103,6 +110,7 @@ private:
|
||||||
bool press, DWORD* data) const;
|
bool press, DWORD* data) const;
|
||||||
KeyModifierMask mapKey(Keystrokes&, UINT& virtualKey, KeyID,
|
KeyModifierMask mapKey(Keystrokes&, UINT& virtualKey, KeyID,
|
||||||
KeyModifierMask, EKeyAction) const;
|
KeyModifierMask, EKeyAction) const;
|
||||||
|
KeyModifierMask mapKeyRelease(Keystrokes& keys, UINT virtualKey) const;
|
||||||
UINT mapCharacter(Keystrokes& keys,
|
UINT mapCharacter(Keystrokes& keys,
|
||||||
char c, HKL hkl,
|
char c, HKL hkl,
|
||||||
KeyModifierMask currentMask,
|
KeyModifierMask currentMask,
|
||||||
|
@ -114,6 +122,7 @@ private:
|
||||||
KeyModifierMask desiredMask,
|
KeyModifierMask desiredMask,
|
||||||
EKeyAction action) const;
|
EKeyAction action) const;
|
||||||
void doKeystrokes(const Keystrokes&, SInt32 count);
|
void doKeystrokes(const Keystrokes&, SInt32 count);
|
||||||
|
const CModifierInfo* getModifierInfo(UINT virtualKey) const;
|
||||||
|
|
||||||
void toggleKey(UINT virtualKey, KeyModifierMask mask);
|
void toggleKey(UINT virtualKey, KeyModifierMask mask);
|
||||||
UINT virtualKeyToScanCode(UINT& virtualKey) const;
|
UINT virtualKeyToScanCode(UINT& virtualKey) const;
|
||||||
|
@ -149,6 +158,9 @@ private:
|
||||||
|
|
||||||
// map server key buttons to local virtual keys
|
// map server key buttons to local virtual keys
|
||||||
ServerKeyMap m_serverKeyMap;
|
ServerKeyMap m_serverKeyMap;
|
||||||
|
|
||||||
|
// modifier table
|
||||||
|
static const CModifierInfo s_modifier[];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue