checkpoint. now sending toggle modifier state when entering

a screen.  this allows the secondary screen to set it's
modifier state to match the primary screen's state.  this is
not strictly necessary since each keystroke should adjust the
modifier state as needed to get the right result.
This commit is contained in:
crs
2002-04-30 17:48:11 +00:00
parent 56877bcc7d
commit b279c80608
17 changed files with 224 additions and 32 deletions

View File

@@ -252,6 +252,18 @@ void CMSWindowsPrimaryScreen::getClipboard(
CClipboard::copy(dst, &src);
}
KeyModifierMask CXWindowsPrimaryScreen::getToggleMask() const
{
KeyModifierMask mask;
if ((m_keys[VK_CAPITAL] & 0x01) != 0)
mask |= KeyModifierCapsLock;
if ((m_keys[VK_NUMLOCK] & 0x01) != 0)
mask |= KeyModifierNumLock;
if ((m_keys[VK_SCROLL] & 0x01) != 0)
mask |= KeyModifierScrollLock;
return mask;
}
#include "resource.h" // FIXME
void CMSWindowsPrimaryScreen::onOpenDisplay()

View File

@@ -26,6 +26,7 @@ public:
virtual void getSize(SInt32* width, SInt32* height) const;
virtual SInt32 getJumpZoneSize() const;
virtual void getClipboard(ClipboardID, IClipboard*) const;
virtual KeyModifierMask getToggleMask() const;
protected:
// CMSWindowsScreen overrides

View File

@@ -537,7 +537,8 @@ void CServer::switchScreen(CScreenInfo* dst,
m_primary->enter(x, y);
}
else {
m_active->m_protocol->sendEnter(x, y, m_seqNum);
m_active->m_protocol->sendEnter(x, y, m_seqNum,
m_primary->getToggleMask());
}
// send the clipboard data to new active screen

View File

@@ -31,7 +31,8 @@ public:
virtual void run() = 0;
virtual void queryInfo() = 0;
virtual void sendClose() = 0;
virtual void sendEnter(SInt32 xAbs, SInt32 yAbs, UInt32 seqNum) = 0;
virtual void sendEnter(SInt32 xAbs, SInt32 yAbs,
UInt32 seqNum, KeyModifierMask mask) = 0;
virtual void sendLeave() = 0;
virtual void sendClipboard(ClipboardID, const CString&) = 0;
virtual void sendGrabClipboard(ClipboardID) = 0;

View File

@@ -91,10 +91,12 @@ void CServerProtocol1_0::sendClose()
}
void CServerProtocol1_0::sendEnter(
SInt32 xAbs, SInt32 yAbs, UInt32 seqNum)
SInt32 xAbs, SInt32 yAbs,
UInt32 seqNum, KeyModifierMask mask)
{
log((CLOG_DEBUG1 "send enter to \"%s\", %d,%d %d", getClient().c_str(), xAbs, yAbs, seqNum));
CProtocolUtil::writef(getOutputStream(), kMsgCEnter, xAbs, yAbs, seqNum);
log((CLOG_DEBUG1 "send enter to \"%s\", %d,%d %d %04x", getClient().c_str(), xAbs, yAbs, seqNum, mask));
CProtocolUtil::writef(getOutputStream(), kMsgCEnter,
xAbs, yAbs, seqNum, mask);
}
void CServerProtocol1_0::sendLeave()

View File

@@ -16,7 +16,8 @@ public:
virtual void run();
virtual void queryInfo();
virtual void sendClose();
virtual void sendEnter(SInt32 xAbs, SInt32 yAbs, UInt32 seqNum);
virtual void sendEnter(SInt32 xAbs, SInt32 yAbs,
UInt32 seqNum, KeyModifierMask mask);
virtual void sendLeave();
virtual void sendClipboard(ClipboardID, const CString&);
virtual void sendGrabClipboard(ClipboardID);

View File

@@ -47,6 +47,7 @@ void CXWindowsPrimaryScreen::run()
// keyboard mapping changed
CDisplayLock display(this);
XRefreshKeyboardMapping(&xevent.xmapping);
updateModifierMap(display);
break;
}
@@ -219,6 +220,12 @@ void CXWindowsPrimaryScreen::open(CServer* server)
// FIXME -- may have to get these from some database
m_capsLockHalfDuplex = false;
// m_capsLockHalfDuplex = true;
// update key state
{
CDisplayLock display(this);
updateModifierMap(display);
}
}
void CXWindowsPrimaryScreen::close()
@@ -365,6 +372,31 @@ void CXWindowsPrimaryScreen::getClipboard(
getDisplayClipboard(id, clipboard, m_window, getCurrentTime(m_window));
}
KeyModifierMask CXWindowsPrimaryScreen::getToggleMask() const
{
CDisplayLock display(this);
// query the pointer to get the keyboard state
// FIXME -- is there a better way to do this?
Window root, window;
int xRoot, yRoot, xWindow, yWindow;
unsigned int state;
if (!XQueryPointer(display, m_window, &root, &window,
&xRoot, &yRoot, &xWindow, &yWindow, &state))
return 0;
// convert to KeyModifierMask
KeyModifierMask mask;
if (state & m_numLockMask)
mask |= KeyModifierNumLock;
if (state & m_capsLockMask)
mask |= KeyModifierCapsLock;
if (state & m_scrollLockMask)
mask |= KeyModifierScrollLock;
return mask;
}
void CXWindowsPrimaryScreen::onOpenDisplay()
{
assert(m_window == None);
@@ -483,3 +515,38 @@ ButtonID CXWindowsPrimaryScreen::mapButton(
else
return kButtonNone;
}
void CXWindowsPrimaryScreen::updateModifierMap(
Display* display)
{
// get modifier map from server
XModifierKeymap* keymap = XGetModifierMapping(display);
// initialize
m_numLockMask = 0;
m_capsLockMask = 0;
m_scrollLockMask = 0;
// set keycodes and masks
for (unsigned int i = 0; i < 8; ++i) {
const unsigned int bit = (1 << i);
for (int j = 0; j < keymap->max_keypermod; ++j) {
KeyCode keycode = keymap->modifiermap[i *
keymap->max_keypermod + j];
// note toggle modifier bits
const KeySym keysym = XKeycodeToKeysym(display, keycode, 0);
if (keysym == XK_Num_Lock) {
m_numLockMask |= bit;
}
else if (keysym == XK_Caps_Lock) {
m_capsLockMask |= bit;
}
else if (keysym == XK_Scroll_Lock) {
m_scrollLockMask |= bit;
}
}
}
XFreeModifiermap(keymap);
}

View File

@@ -24,6 +24,7 @@ public:
virtual void getSize(SInt32* width, SInt32* height) const;
virtual SInt32 getJumpZoneSize() const;
virtual void getClipboard(ClipboardID, IClipboard*) const;
virtual KeyModifierMask getToggleMask() const;
protected:
// CXWindowsScreen overrides
@@ -40,12 +41,21 @@ private:
KeyID mapKey(XKeyEvent*) const;
ButtonID mapButton(unsigned int button) const;
void updateModifierMap(Display* display);
private:
CServer* m_server;
bool m_active;
Window m_window;
// note if caps lock key toggles on up/down (false) or on
// transition (true)
bool m_capsLockHalfDuplex;
// masks that indicate which modifier bits are for toggle keys
unsigned int m_numLockMask;
unsigned int m_capsLockMask;
unsigned int m_scrollLockMask;
};
#endif