Converted win32 to new keyboard state tracking design. Also

changed locking to screen so that keys no longer count (only
mouse buttons and scroll lock toggled on).  This is to deal
with the unreliability of key event reporting which can leave
us locked to a screen with no key physically pressed.  The
result of this is that clients get key repeats and releases
without the corresponding key press.  CKeyState handles this
by discarding repeat/release events on keys it hasn't seen go
down.  Also made a few other minor fixes to win32 keyboard
handling.
This commit is contained in:
crs
2004-03-26 20:59:26 +00:00
parent ab11ebea01
commit e2a31e8b66
26 changed files with 1974 additions and 1761 deletions

View File

@@ -39,14 +39,7 @@ void
CKeyState::setKeyDown(KeyButton button, bool down)
{
button &= kButtonMask;
if (button != 0) {
if (down) {
m_keys[button] |= kDown;
}
else {
m_keys[button] &= ~kDown;
}
}
updateKeyState(button, button, down);
}
void
@@ -144,7 +137,8 @@ CKeyState::fakeKeyDown(KeyID id, KeyModifierMask mask, KeyButton button)
// get the sequence of keys to simulate key press and the final
// modifier state.
Keystrokes keys;
KeyButton localID = (mapKey(keys, id, mask, false) & kButtonMask);
KeyButton localID =
(KeyButton)(mapKey(keys, id, mask, false) & kButtonMask);
if (keys.empty()) {
// do nothing if there are no associated keys
LOG((CLOG_DEBUG2 "cannot map key 0x%08x", id));
@@ -155,7 +149,7 @@ CKeyState::fakeKeyDown(KeyID id, KeyModifierMask mask, KeyButton button)
fakeKeyEvents(keys, 1);
// note that key is down
updateKeyState(button & kButtonMask, localID, true);
updateKeyState((KeyButton)(button & kButtonMask), localID, true);
}
void
@@ -174,7 +168,7 @@ CKeyState::fakeKeyRepeat(
// get the sequence of keys to simulate key repeat and the final
// modifier state.
Keystrokes keys;
KeyButton localID = (mapKey(keys, id, mask, true) & kButtonMask);
KeyButton localID = (KeyButton)(mapKey(keys, id, mask, true) & kButtonMask);
if (localID == 0) {
LOG((CLOG_DEBUG2 "cannot map key 0x%08x", id));
return;
@@ -511,12 +505,16 @@ CKeyState::updateKeyState(KeyButton serverID, KeyButton localID, bool press)
KeyModifierMask mask = m_keyToMask[localID];
if (mask != 0) {
if (isToggle(mask)) {
m_keys[localID] ^= kToggled;
m_mask ^= mask;
// never report half-duplex keys as down
if (isHalfDuplex(mask)) {
m_keys[localID] &= ~kDown;
press = true;
}
// toggle on the press
if (press) {
m_keys[localID] ^= kToggled;
m_mask ^= mask;
}
}
else {

View File

@@ -33,9 +33,10 @@ public:
//! Mark key as being down
/*!
Sets the state of \p button to down or up.
Sets the state of \p button to down or up. If this is overridden
it must forward to the superclass.
*/
void setKeyDown(KeyButton button, bool down);
virtual void setKeyDown(KeyButton button, bool down);
//! Mark modifier as being toggled on
/*!
@@ -47,9 +48,10 @@ public:
//! Post a key event
/*!
Posts a key event. This may adjust the event or post additional
events in some circumstances.
events in some circumstances. If this is overridden it must forward
to the superclass.
*/
void sendKeyEvent(void* target,
virtual void sendKeyEvent(void* target,
bool press, bool isAutoRepeat,
KeyID key, KeyModifierMask mask,
SInt32 count, KeyButton button);
@@ -69,6 +71,7 @@ public:
SInt32 count, KeyButton button);
virtual void fakeKeyUp(KeyButton button);
virtual void fakeToggle(KeyModifierMask modifier);
virtual bool fakeCtrlAltDel() = 0;
virtual bool isKeyDown(KeyButton) const;
virtual KeyModifierMask
getActiveModifiers() const;

View File

@@ -63,6 +63,12 @@ CPlatformScreen::fakeToggle(KeyModifierMask modifier)
getKeyState()->fakeToggle(modifier);
}
bool
CPlatformScreen::fakeCtrlAltDel()
{
return getKeyState()->fakeCtrlAltDel();
}
bool
CPlatformScreen::isKeyDown(KeyButton button) const
{

View File

@@ -43,7 +43,6 @@ public:
virtual void getCursorCenter(SInt32& x, SInt32& y) const = 0;
// ISecondaryScreen overrides
virtual bool fakeCtrlAltDel() const = 0;
virtual void fakeMouseButton(ButtonID id, bool press) const = 0;
virtual void fakeMouseMove(SInt32 x, SInt32 y) const = 0;
virtual void fakeMouseWheel(SInt32 delta) const = 0;
@@ -57,6 +56,7 @@ public:
SInt32 count, KeyButton button);
virtual void fakeKeyUp(KeyButton button);
virtual void fakeToggle(KeyModifierMask modifier);
virtual bool fakeCtrlAltDel();
virtual bool isKeyDown(KeyButton) const;
virtual KeyModifierMask
getActiveModifiers() const;

View File

@@ -98,13 +98,13 @@ CScreen::enter(KeyModifierMask toggleMask)
// now on screen
m_entered = true;
m_screen->enter();
if (m_isPrimary) {
enterPrimary();
}
else {
enterSecondary(toggleMask);
}
m_screen->enter();
}
bool
@@ -315,6 +315,16 @@ CScreen::isLockedToScreen() const
return true;
}
// note -- we don't lock to the screen if a key is down. key
// reporting is simply not reliable enough to trust. the effect
// of switching screens with a key down is that the client will
// receive key repeats and key releases for keys that it hasn't
// see go down. that's okay because CKeyState will ignore those
// events. the user might be surprised that any modifier keys
// held while crossing to another screen don't apply on the
// target screen. if that ends up being a problem we can try
// to synthesize a key press for those modifiers on entry.
/*
// check for any pressed key
KeyButton key = isAnyKeyDown();
if (key != 0) {
@@ -332,6 +342,7 @@ CScreen::isLockedToScreen() const
LOG((CLOG_DEBUG "spuriously locked by %s", m_screen->getKeyName(key)));
}
}
*/
// not locked
return false;
@@ -431,9 +442,6 @@ CScreen::enterPrimary()
void
CScreen::enterSecondary(KeyModifierMask toggleMask)
{
// update our keyboard state to reflect the local state
m_screen->updateKeys();
// remember toggle key state. we'll restore this when we leave.
m_toggleKeys = getActiveModifiers();

View File

@@ -87,6 +87,13 @@ public:
*/
virtual void fakeToggle(KeyModifierMask modifier) = 0;
//! Fake ctrl+alt+del
/*!
Synthesize a press of ctrl+alt+del. Return true if processing is
complete and false if normal key processing should continue.
*/
virtual bool fakeCtrlAltDel() = 0;
//@}
//! @name accessors
//@{

View File

@@ -151,7 +151,6 @@ public:
virtual void getCursorCenter(SInt32& x, SInt32& y) const = 0;
// ISecondaryScreen overrides
virtual bool fakeCtrlAltDel() const = 0;
virtual void fakeMouseButton(ButtonID id, bool press) const = 0;
virtual void fakeMouseMove(SInt32 x, SInt32 y) const = 0;
virtual void fakeMouseWheel(SInt32 delta) const = 0;
@@ -165,6 +164,7 @@ public:
SInt32 count, KeyButton button) = 0;
virtual void fakeKeyUp(KeyButton button) = 0;
virtual void fakeToggle(KeyModifierMask modifier) = 0;
virtual bool fakeCtrlAltDel() = 0;
virtual bool isKeyDown(KeyButton) const = 0;
virtual KeyModifierMask
getActiveModifiers() const = 0;

View File

@@ -28,13 +28,6 @@ public:
//! @name accessors
//@{
//! Fake ctrl+alt+del
/*!
Synthesize a press of ctrl+alt+del. Return true if processing is
complete and false if normal key processing should continue.
*/
virtual bool fakeCtrlAltDel() const = 0;
//! Fake mouse press/release
/*!
Synthesize a press or release of mouse button \c id.

View File

@@ -91,10 +91,18 @@ SOURCE=.\CClipboard.cpp
# End Source File
# Begin Source File
SOURCE=.\CKeyState.cpp
# End Source File
# Begin Source File
SOURCE=.\CPacketStreamFilter.cpp
# End Source File
# Begin Source File
SOURCE=.\CPlatformScreen.cpp
# End Source File
# Begin Source File
SOURCE=.\CProtocolUtil.cpp
# End Source File
# Begin Source File
@@ -107,6 +115,10 @@ SOURCE=.\IClipboard.cpp
# End Source File
# Begin Source File
SOURCE=.\IKeyState.cpp
# End Source File
# Begin Source File
SOURCE=.\IPrimaryScreen.cpp
# End Source File
# Begin Source File
@@ -131,6 +143,10 @@ SOURCE=.\CClipboard.h
# End Source File
# Begin Source File
SOURCE=.\CKeyState.h
# End Source File
# Begin Source File
SOURCE=.\ClipboardTypes.h
# End Source File
# Begin Source File
@@ -139,6 +155,10 @@ SOURCE=.\CPacketStreamFilter.h
# End Source File
# Begin Source File
SOURCE=.\CPlatformScreen.h
# End Source File
# Begin Source File
SOURCE=.\CProtocolUtil.h
# End Source File
# Begin Source File