added other mouse and key event handling to CXScreen. key repeat

isn't implemented and modifier masks are ignored.  modifier masks
are new;  they indicate the modifier key (shift, ctrl, etc) state
at the time of the key event.
This commit is contained in:
crs 2001-05-14 21:14:25 +00:00
parent fe79ac593c
commit 8beea84a8d
9 changed files with 170 additions and 100 deletions

View File

@ -154,8 +154,13 @@ void CClient::onRead()
(static_cast<UInt32>(buf[2]) << 16) + (static_cast<UInt32>(buf[2]) << 16) +
(static_cast<UInt32>(buf[3]) << 8) + (static_cast<UInt32>(buf[3]) << 8) +
(static_cast<UInt32>(buf[4]) )); (static_cast<UInt32>(buf[4]) ));
TRACE((" key down: %d", k)); const KeyModifierMask m = static_cast<KeyModifierMask>(
m_screen->onKeyDown(k); (static_cast<UInt32>(buf[5]) << 24) +
(static_cast<UInt32>(buf[6]) << 16) +
(static_cast<UInt32>(buf[7]) << 8) +
(static_cast<UInt32>(buf[8]) ));
TRACE((" key down: %d 0x%08x", k, m));
m_screen->onKeyDown(k, m);
break; break;
} }
@ -165,13 +170,18 @@ void CClient::onRead()
(static_cast<UInt32>(buf[2]) << 16) + (static_cast<UInt32>(buf[2]) << 16) +
(static_cast<UInt32>(buf[3]) << 8) + (static_cast<UInt32>(buf[3]) << 8) +
(static_cast<UInt32>(buf[4]) )); (static_cast<UInt32>(buf[4]) ));
const SInt32 n = static_cast<SInt32>( const KeyModifierMask m = static_cast<KeyModifierMask>(
(static_cast<UInt32>(buf[5]) << 24) + (static_cast<UInt32>(buf[5]) << 24) +
(static_cast<UInt32>(buf[6]) << 16) + (static_cast<UInt32>(buf[6]) << 16) +
(static_cast<UInt32>(buf[7]) << 8) + (static_cast<UInt32>(buf[7]) << 8) +
(static_cast<UInt32>(buf[8]) )); (static_cast<UInt32>(buf[8]) ));
TRACE((" key repeat: %d x%d", k, n)); const SInt32 n = static_cast<SInt32>(
m_screen->onKeyRepeat(k, n); (static_cast<UInt32>(buf[9]) << 24) +
(static_cast<UInt32>(buf[10]) << 16) +
(static_cast<UInt32>(buf[11]) << 8) +
(static_cast<UInt32>(buf[12]) ));
TRACE((" key repeat: %d 0x%08x x%d", k, m, n));
m_screen->onKeyRepeat(k, m, n);
break; break;
} }
@ -181,17 +191,13 @@ void CClient::onRead()
(static_cast<UInt32>(buf[2]) << 16) + (static_cast<UInt32>(buf[2]) << 16) +
(static_cast<UInt32>(buf[3]) << 8) + (static_cast<UInt32>(buf[3]) << 8) +
(static_cast<UInt32>(buf[4]) )); (static_cast<UInt32>(buf[4]) ));
TRACE((" key up: %d", k)); const KeyModifierMask m = static_cast<KeyModifierMask>(
m_screen->onKeyUp(k); (static_cast<UInt32>(buf[5]) << 24) +
break; (static_cast<UInt32>(buf[6]) << 16) +
} (static_cast<UInt32>(buf[7]) << 8) +
(static_cast<UInt32>(buf[8]) ));
case '\012': { TRACE((" key up: %d 0x%08x", k, m));
const KeyToggleMask m = static_cast<KeyToggleMask>( m_screen->onKeyUp(k, m);
(static_cast<UInt32>(buf[1]) << 8) +
(static_cast<UInt32>(buf[2]) ));
TRACE((" key toggle: 0x%04x", m));
m_screen->onKeyToggle(m);
break; break;
} }

View File

@ -27,6 +27,7 @@ class CEventBase {
class CEventKey : public CEventBase { class CEventKey : public CEventBase {
public: public:
KeyID m_key; KeyID m_key;
KeyModifierMask m_mask;
SInt32 m_count; SInt32 m_count;
}; };

View File

@ -82,49 +82,53 @@ void CScreenProxy::setClipboard(const IClipboard*)
// FIXME // FIXME
} }
void CScreenProxy::onKeyDown(KeyID k) void CScreenProxy::onKeyDown(KeyID k, KeyModifierMask m)
{ {
char buf[5]; char buf[9];
memcpy(buf, "\007", 1); memcpy(buf, "\007", 1);
buf[1] = static_cast<char>((k >> 24) & 0xff); buf[1] = static_cast<char>((k >> 24) & 0xff);
buf[2] = static_cast<char>((k >> 16) & 0xff); buf[2] = static_cast<char>((k >> 16) & 0xff);
buf[3] = static_cast<char>((k >> 8) & 0xff); buf[3] = static_cast<char>((k >> 8) & 0xff);
buf[4] = static_cast<char>(k & 0xff); buf[4] = static_cast<char>(k & 0xff);
buf[5] = static_cast<char>((m >> 24) & 0xff);
buf[6] = static_cast<char>((m >> 16) & 0xff);
buf[7] = static_cast<char>((m >> 8) & 0xff);
buf[8] = static_cast<char>(m & 0xff);
m_socket->write(buf, sizeof(buf)); m_socket->write(buf, sizeof(buf));
} }
void CScreenProxy::onKeyRepeat(KeyID k, SInt32 n) void CScreenProxy::onKeyRepeat(
KeyID k, KeyModifierMask m, SInt32 n)
{ {
char buf[9]; char buf[13];
memcpy(buf, "\010", 1); memcpy(buf, "\010", 1);
buf[1] = static_cast<char>((k >> 24) & 0xff); buf[1] = static_cast<char>((k >> 24) & 0xff);
buf[2] = static_cast<char>((k >> 16) & 0xff); buf[2] = static_cast<char>((k >> 16) & 0xff);
buf[3] = static_cast<char>((k >> 8) & 0xff); buf[3] = static_cast<char>((k >> 8) & 0xff);
buf[4] = static_cast<char>(k & 0xff); buf[4] = static_cast<char>(k & 0xff);
buf[5] = static_cast<char>((n >> 24) & 0xff); buf[5] = static_cast<char>((m >> 24) & 0xff);
buf[6] = static_cast<char>((n >> 16) & 0xff); buf[6] = static_cast<char>((m >> 16) & 0xff);
buf[7] = static_cast<char>((n >> 8) & 0xff); buf[7] = static_cast<char>((m >> 8) & 0xff);
buf[8] = static_cast<char>(n & 0xff); buf[8] = static_cast<char>(m & 0xff);
buf[9] = static_cast<char>((n >> 24) & 0xff);
buf[10] = static_cast<char>((n >> 16) & 0xff);
buf[11] = static_cast<char>((n >> 8) & 0xff);
buf[12] = static_cast<char>(n & 0xff);
m_socket->write(buf, sizeof(buf)); m_socket->write(buf, sizeof(buf));
} }
void CScreenProxy::onKeyUp(KeyID k) void CScreenProxy::onKeyUp(KeyID k, KeyModifierMask m)
{ {
char buf[5]; char buf[9];
memcpy(buf, "\011", 1); memcpy(buf, "\011", 1);
buf[1] = static_cast<char>((k >> 24) & 0xff); buf[1] = static_cast<char>((k >> 24) & 0xff);
buf[2] = static_cast<char>((k >> 16) & 0xff); buf[2] = static_cast<char>((k >> 16) & 0xff);
buf[3] = static_cast<char>((k >> 8) & 0xff); buf[3] = static_cast<char>((k >> 8) & 0xff);
buf[4] = static_cast<char>(k & 0xff); buf[4] = static_cast<char>(k & 0xff);
m_socket->write(buf, sizeof(buf)); buf[5] = static_cast<char>((m >> 24) & 0xff);
} buf[6] = static_cast<char>((m >> 16) & 0xff);
buf[7] = static_cast<char>((m >> 8) & 0xff);
void CScreenProxy::onKeyToggle(KeyToggleMask m) buf[8] = static_cast<char>(m & 0xff);
{
char buf[3];
memcpy(buf, "\012", 1);
buf[1] = static_cast<char>((m >> 8) & 0xff);
buf[2] = static_cast<char>(m & 0xff);
m_socket->write(buf, sizeof(buf)); m_socket->write(buf, sizeof(buf));
} }

View File

@ -18,10 +18,9 @@ class CScreenProxy : public IScreen {
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute); virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute);
virtual void setClipboard(const IClipboard*); virtual void setClipboard(const IClipboard*);
virtual void onScreenSaver(bool show); virtual void onScreenSaver(bool show);
virtual void onKeyDown(KeyID); virtual void onKeyDown(KeyID, KeyModifierMask);
virtual void onKeyRepeat(KeyID, SInt32 count); virtual void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count);
virtual void onKeyUp(KeyID); virtual void onKeyUp(KeyID, KeyModifierMask);
virtual void onKeyToggle(KeyToggleMask);
virtual void onMouseDown(ButtonID); virtual void onMouseDown(ButtonID);
virtual void onMouseUp(ButtonID); virtual void onMouseUp(ButtonID);
virtual void onMouseMove(SInt32 xAbsolute, SInt32 yAbsolute); virtual void onMouseMove(SInt32 xAbsolute, SInt32 yAbsolute);

View File

@ -350,15 +350,16 @@ void CServer::relayEvent(const CEvent* event)
break; break;
case CEventBase::kKeyDown: case CEventBase::kKeyDown:
m_activeScreen->onKeyDown(event->m_key.m_key); m_activeScreen->onKeyDown(event->m_key.m_key, event->m_key.m_mask);
break; break;
case CEventBase::kKeyRepeat: case CEventBase::kKeyRepeat:
m_activeScreen->onKeyRepeat(event->m_key.m_key, event->m_key.m_count); m_activeScreen->onKeyRepeat(event->m_key.m_key,
event->m_key.m_mask, event->m_key.m_count);
break; break;
case CEventBase::kKeyUp: case CEventBase::kKeyUp:
m_activeScreen->onKeyUp(event->m_key.m_key); m_activeScreen->onKeyUp(event->m_key.m_key, event->m_key.m_mask);
break; break;
case CEventBase::kMouseDown: case CEventBase::kMouseDown:

View File

@ -146,7 +146,17 @@ void CXScreen::onScreenSaver(bool show)
onScreenSaverSecondary(show); onScreenSaverSecondary(show);
} }
void CXScreen::onKeyDown(KeyID) void CXScreen::onKeyDown(KeyID key, KeyModifierMask)
{
assert(m_display != NULL);
assert(m_primary == false);
// FIXME -- use mask
::XTestFakeKeyEvent(m_display, mapKeyToX(key), True, CurrentTime);
::XSync(m_display, False);
}
void CXScreen::onKeyRepeat(KeyID, KeyModifierMask, SInt32)
{ {
assert(m_display != NULL); assert(m_display != NULL);
assert(m_primary == false); assert(m_primary == false);
@ -154,44 +164,32 @@ void CXScreen::onKeyDown(KeyID)
// FIXME // FIXME
} }
void CXScreen::onKeyRepeat(KeyID, SInt32) void CXScreen::onKeyUp(KeyID key, KeyModifierMask)
{ {
assert(m_display != NULL); assert(m_display != NULL);
assert(m_primary == false); assert(m_primary == false);
// FIXME // FIXME -- use mask
::XTestFakeKeyEvent(m_display, mapKeyToX(key), False, CurrentTime);
::XSync(m_display, False);
} }
void CXScreen::onKeyUp(KeyID) void CXScreen::onMouseDown(ButtonID button)
{ {
assert(m_display != NULL); assert(m_display != NULL);
assert(m_primary == false); assert(m_primary == false);
// FIXME ::XTestFakeButtonEvent(m_display, mapButtonToX(button), True, CurrentTime);
::XSync(m_display, False);
} }
void CXScreen::onKeyToggle(KeyToggleMask) void CXScreen::onMouseUp(ButtonID button)
{ {
assert(m_display != NULL); assert(m_display != NULL);
assert(m_primary == false); assert(m_primary == false);
// FIXME ::XTestFakeButtonEvent(m_display, mapButtonToX(button), False, CurrentTime);
} ::XSync(m_display, False);
void CXScreen::onMouseDown(ButtonID)
{
assert(m_display != NULL);
assert(m_primary == false);
// FIXME
}
void CXScreen::onMouseUp(ButtonID)
{
assert(m_display != NULL);
assert(m_primary == false);
// FIXME
} }
void CXScreen::onMouseMove(SInt32 x, SInt32 y) void CXScreen::onMouseMove(SInt32 x, SInt32 y)
@ -430,27 +428,79 @@ void CXScreen::selectEvents(Window w) const
} }
} }
KeyID CXScreen::mapKey(unsigned int keycode) const KeyModifierMask CXScreen::mapModifierFromX(unsigned int state) const
{ {
return keycode; // FIXME -- should be configurable
KeyModifierMask mask = 0;
if (state & 1)
mask |= KeyModifierShift;
if (state & 2)
mask |= KeyModifierCapsLock;
if (state & 4)
mask |= KeyModifierControl;
if (state & 8)
mask |= KeyModifierAlt;
if (state & 16)
mask |= KeyModifierNumLock;
if (state & 32)
mask |= KeyModifierMeta;
if (state & 128)
mask |= KeyModifierScrollLock;
return mask;
} }
ButtonID CXScreen::mapButton(unsigned int button) const unsigned int CXScreen::mapModifierToX(KeyModifierMask mask) const
{ {
switch (button) { // FIXME -- should be configurable
case 1: unsigned int state = 0;
return kButtonLeft; if (mask & KeyModifierShift)
state |= 1;
case 2: if (mask & KeyModifierControl)
return kButtonMiddle; state |= 4;
if (mask & KeyModifierAlt)
case 3: state |= 8;
return kButtonRight; if (mask & KeyModifierMeta)
state |= 32;
if (mask & KeyModifierCapsLock)
state |= 2;
if (mask & KeyModifierNumLock)
state |= 16;
if (mask & KeyModifierScrollLock)
state |= 128;
return state;
} }
KeyID CXScreen::mapKeyFromX(
KeyCode keycode, KeyModifierMask mask) const
{
int index;
if (mask & KeyModifierShift)
index = 1;
else
index = 0;
return static_cast<KeyID>(::XKeycodeToKeysym(m_display, keycode, index));
}
KeyCode CXScreen::mapKeyToX(KeyID keyID) const
{
return ::XKeysymToKeycode(m_display, static_cast<KeySym>(keyID));
}
ButtonID CXScreen::mapButtonFromX(unsigned int button) const
{
// FIXME -- should use button mapping?
if (button >= 1 && button <= 3)
return static_cast<ButtonID>(button);
else
return kButtonNone; return kButtonNone;
} }
unsigned int CXScreen::mapButtonToX(ButtonID buttonID) const
{
// FIXME -- should use button mapping?
return static_cast<unsigned int>(buttonID);
}
void CXScreen::onPrimaryEvents() void CXScreen::onPrimaryEvents()
{ {
while (XPending(m_display) > 0) { while (XPending(m_display) > 0) {
@ -459,11 +509,13 @@ void CXScreen::onPrimaryEvents()
switch (xevent.type) { switch (xevent.type) {
case KeyPress: { case KeyPress: {
const KeyID key = mapKey(xevent.xkey.keycode); const KeyModifierMask mask = mapModifierFromX(xevent.xkey.state);
const KeyID key = mapKeyFromX(xevent.xkey.keycode, mask);
if (key != kKeyNone) { if (key != kKeyNone) {
CEvent event; CEvent event;
event.m_key.m_type = CEventBase::kKeyDown; event.m_key.m_type = CEventBase::kKeyDown;
event.m_key.m_key = key; event.m_key.m_key = key;
event.m_key.m_mask = mask;
event.m_key.m_count = 0; event.m_key.m_count = 0;
CEQ->push(&event); CEQ->push(&event);
} }
@ -473,11 +525,13 @@ void CXScreen::onPrimaryEvents()
// FIXME -- simulate key repeat. X sends press/release for // FIXME -- simulate key repeat. X sends press/release for
// repeat. must detect auto repeat and use kKeyRepeat. // repeat. must detect auto repeat and use kKeyRepeat.
case KeyRelease: { case KeyRelease: {
const KeyID key = mapKey(xevent.xkey.keycode); const KeyModifierMask mask = mapModifierFromX(xevent.xkey.state);
const KeyID key = mapKeyFromX(xevent.xkey.keycode, mask);
if (key != kKeyNone) { if (key != kKeyNone) {
CEvent event; CEvent event;
event.m_key.m_type = CEventBase::kKeyUp; event.m_key.m_type = CEventBase::kKeyUp;
event.m_key.m_key = key; event.m_key.m_key = key;
event.m_key.m_mask = mask;
event.m_key.m_count = 0; event.m_key.m_count = 0;
CEQ->push(&event); CEQ->push(&event);
} }
@ -485,7 +539,7 @@ void CXScreen::onPrimaryEvents()
} }
case ButtonPress: { case ButtonPress: {
const ButtonID button = mapButton(xevent.xbutton.button); const ButtonID button = mapButtonFromX(xevent.xbutton.button);
if (button != kButtonNone) { if (button != kButtonNone) {
CEvent event; CEvent event;
event.m_mouse.m_type = CEventBase::kMouseDown; event.m_mouse.m_type = CEventBase::kMouseDown;
@ -498,7 +552,7 @@ void CXScreen::onPrimaryEvents()
} }
case ButtonRelease: { case ButtonRelease: {
const ButtonID button = mapButton(xevent.xbutton.button); const ButtonID button = mapButtonFromX(xevent.xbutton.button);
if (button != kButtonNone) { if (button != kButtonNone) {
CEvent event; CEvent event;
event.m_mouse.m_type = CEventBase::kMouseUp; event.m_mouse.m_type = CEventBase::kMouseUp;

View File

@ -17,10 +17,9 @@ class CXScreen : public IScreen {
virtual void warpCursor(SInt32 x, SInt32 y); virtual void warpCursor(SInt32 x, SInt32 y);
virtual void setClipboard(const IClipboard*); virtual void setClipboard(const IClipboard*);
virtual void onScreenSaver(bool); virtual void onScreenSaver(bool);
virtual void onKeyDown(KeyID); virtual void onKeyDown(KeyID, KeyModifierMask);
virtual void onKeyRepeat(KeyID, SInt32); virtual void onKeyRepeat(KeyID, KeyModifierMask, SInt32);
virtual void onKeyUp(KeyID); virtual void onKeyUp(KeyID, KeyModifierMask);
virtual void onKeyToggle(KeyToggleMask);
virtual void onMouseDown(ButtonID); virtual void onMouseDown(ButtonID);
virtual void onMouseUp(ButtonID); virtual void onMouseUp(ButtonID);
virtual void onMouseMove(SInt32, SInt32); virtual void onMouseMove(SInt32, SInt32);
@ -61,8 +60,12 @@ class CXScreen : public IScreen {
private: private:
void selectEvents(Window) const; void selectEvents(Window) const;
KeyID mapKey(unsigned int keycode) const; KeyModifierMask mapModifierFromX(unsigned int) const;
ButtonID mapButton(unsigned int button) const; unsigned int mapModifierToX(KeyModifierMask) const;
KeyID mapKeyFromX(KeyCode, KeyModifierMask) const;
KeyCode mapKeyToX(KeyID) const;
ButtonID mapButtonFromX(unsigned int button) const;
unsigned int mapButtonToX(ButtonID) const;
void onPrimaryEvents(); void onPrimaryEvents();
void onSecondaryEvents(); void onSecondaryEvents();

View File

@ -93,15 +93,13 @@ class IScreen {
// input simulation // input simulation
// //
// these methods must simulate the appropriate input event. // these methods must simulate the appropriate input event.
// these methods may only called on secondary screens. // these methods are only called on secondary screens.
// //
// keyboard input // keyboard input
// onKeyToggle() sets the keyboard toggle key states (e.g. num lock). virtual void onKeyDown(KeyID, KeyModifierMask) = 0;
virtual void onKeyDown(KeyID) = 0; virtual void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count) = 0;
virtual void onKeyRepeat(KeyID, SInt32 count) = 0; virtual void onKeyUp(KeyID, KeyModifierMask) = 0;
virtual void onKeyUp(KeyID) = 0;
virtual void onKeyToggle(KeyToggleMask) = 0;
// mouse input // mouse input
virtual void onMouseDown(ButtonID) = 0; virtual void onMouseDown(ButtonID) = 0;

View File

@ -4,15 +4,19 @@
// type to hold a key identifier // type to hold a key identifier
typedef UInt32 KeyID; typedef UInt32 KeyID;
// type to hold bitmask of keys that have toggle states // type to hold bitmask of key modifiers (i.e. shift keys)
typedef UInt16 KeyToggleMask; typedef UInt32 KeyModifierMask;
// toggle key bitmasks
static const UInt32 KeyToggleShiftLock = 0x0001;
static const UInt32 KeyToggleNumLock = 0x0002;
static const UInt32 KeyToggleScrollLock = 0x0004;
// key codes // key codes
static const KeyID kKeyNone = 0; static const KeyID kKeyNone = 0;
// modifier key bitmasks
static const KeyModifierMask KeyModifierShift = 0x0001;
static const KeyModifierMask KeyModifierControl = 0x0002;
static const KeyModifierMask KeyModifierAlt = 0x0004;
static const KeyModifierMask KeyModifierMeta = 0x0008;
static const KeyModifierMask KeyModifierCapsLock = 0x1000;
static const KeyModifierMask KeyModifierNumLock = 0x2000;
static const KeyModifierMask KeyModifierScrollLock = 0x4000;
#endif #endif