Checkpoint. Converted X11 to new keyboard state tracking design.

This new design is simpler.  For keyboard support, clients need only
implement 4 virtual methods on a class derived from CKeyState and
one trivial method in the class derived from CPlatformScreen, which
is now the superclass of platform screens instead of IPlatformScreen.
Keyboard methods have been removed from IPlatformScreen, IPrimaryScreen
and ISecondaryScreen.  Also, all keyboard state tracking is now in
exactly one place (the CKeyState subclass) rather than in CScreen,
the platform screen, and the key mapper.  Still need to convert Win32.
This commit is contained in:
crs
2004-03-21 20:01:41 +00:00
parent 19559d4b4e
commit 8d99fd2511
20 changed files with 1306 additions and 1027 deletions

View File

@@ -15,6 +15,7 @@
#include "CXWindowsScreen.h"
#include "CXWindowsClipboard.h"
#include "CXWindowsEventQueueBuffer.h"
#include "CXWindowsKeyState.h"
#include "CXWindowsScreenSaver.h"
#include "CXWindowsUtil.h"
#include "CClipboard.h"
@@ -131,7 +132,6 @@ CXWindowsScreen::CXWindowsScreen(bool isPrimary) :
m_xCenter(0), m_yCenter(0),
m_xCursor(0), m_yCursor(0),
m_keyState(NULL),
m_keyMapper(),
m_im(NULL),
m_ic(NULL),
m_lastKeycode(0),
@@ -154,6 +154,7 @@ CXWindowsScreen::CXWindowsScreen(bool isPrimary) :
m_window = openWindow();
m_screensaver = new CXWindowsScreenSaver(m_display,
m_window, getEventTarget());
m_keyState = new CXWindowsKeyState(m_display);
LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d %s", m_x, m_y, m_w, m_h, m_xinerama ? "(xinerama)" : ""));
LOG((CLOG_DEBUG "window is 0x%08x", m_window));
}
@@ -201,7 +202,9 @@ CXWindowsScreen::~CXWindowsScreen()
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
delete m_clipboard[id];
}
delete m_keyState;
delete m_screensaver;
m_keyState = NULL;
m_screensaver = NULL;
if (m_display != NULL) {
// FIXME -- is it safe to clean up the IC and IM without a display?
@@ -219,12 +222,6 @@ CXWindowsScreen::~CXWindowsScreen()
s_screen = NULL;
}
void
CXWindowsScreen::setKeyState(IKeyState* keyState)
{
m_keyState = keyState;
}
void
CXWindowsScreen::enable()
{
@@ -319,7 +316,6 @@ CXWindowsScreen::leave()
}
// raise and show the window
// FIXME -- take focus?
XMapRaised(m_display, m_window);
// grab the mouse and keyboard, if primary and possible
@@ -328,6 +324,9 @@ CXWindowsScreen::leave()
return false;
}
// take focus
XSetInputFocus(m_display, m_window, RevertToPointerRoot, CurrentTime);
// now warp the mouse. we warp after showing the window so we're
// guaranteed to get the mouse leave event and to prevent the
// keyboard focus from changing under point-to-focus policies.
@@ -428,14 +427,6 @@ CXWindowsScreen::setOptions(const COptionsList& options)
}
}
void
CXWindowsScreen::updateKeys()
{
// update keyboard and mouse button mappings
m_keyMapper.update(m_display, m_keyState);
updateButtons();
}
void
CXWindowsScreen::setSequenceNumber(UInt32 seqNum)
{
@@ -547,21 +538,6 @@ CXWindowsScreen::isAnyMouseButtonDown() const
return false;
}
KeyModifierMask
CXWindowsScreen::getActiveModifiers() const
{
// query the pointer to get the modifier state
Window root, window;
int xRoot, yRoot, xWindow, yWindow;
unsigned int state;
if (XQueryPointer(m_display, m_root, &root, &window,
&xRoot, &yRoot, &xWindow, &yWindow, &state)) {
return m_keyMapper.mapModifier(state);
}
return 0;
}
void
CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
{
@@ -569,28 +545,6 @@ CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
y = m_yCenter;
}
const char*
CXWindowsScreen::getKeyName(KeyButton keycode) const
{
KeySym keysym = XKeycodeToKeysym(m_display, keycode, 0);
char* name = XKeysymToString(keysym);
if (name != NULL) {
return name;
}
else {
static char buffer[20];
return strcpy(buffer,
CStringUtil::print("keycode %d", keycode).c_str());
}
}
void
CXWindowsScreen::fakeKeyEvent(KeyButton keycode, bool press) const
{
XTestFakeKeyEvent(m_display, keycode, press ? True : False, CurrentTime);
XFlush(m_display);
}
bool
CXWindowsScreen::fakeCtrlAltDel() const
{
@@ -645,15 +599,6 @@ CXWindowsScreen::fakeMouseWheel(SInt32 delta) const
XFlush(m_display);
}
KeyButton
CXWindowsScreen::mapKey(IKeyState::Keystrokes& keys,
const IKeyState& keyState, KeyID id,
KeyModifierMask desiredMask,
bool isAutoRepeat) const
{
return m_keyMapper.mapKey(keys, keyState, id, desiredMask, isAutoRepeat);
}
Display*
CXWindowsScreen::openDisplay() const
{
@@ -788,6 +733,7 @@ CXWindowsScreen::openIM()
// open the input methods
XIM im = XOpenIM(m_display, NULL, NULL, NULL);
if (im == NULL) {
LOG((CLOG_INFO "no support for IM"));
return;
}
@@ -811,7 +757,7 @@ CXWindowsScreen::openIM()
}
XFree(styles);
if (style == 0) {
LOG((CLOG_WARN "no supported IM styles"));
LOG((CLOG_INFO "no supported IM styles"));
XCloseIM(im);
return;
}
@@ -859,6 +805,12 @@ CXWindowsScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id)
sendEvent(type, info);
}
IKeyState*
CXWindowsScreen::getKeyState() const
{
return m_keyState;
}
Bool
CXWindowsScreen::findKeyEvent(Display*, XEvent* xevent, XPointer arg)
{
@@ -1063,7 +1015,7 @@ void
CXWindowsScreen::onKeyPress(XKeyEvent& xkey)
{
LOG((CLOG_DEBUG1 "event: KeyPress code=%d, state=0x%04x", xkey.keycode, xkey.state));
const KeyModifierMask mask = m_keyMapper.mapModifier(xkey.state);
const KeyModifierMask mask = m_keyState->mapModifiersFromX(xkey.state);
KeyID key = mapKeyFromX(&xkey);
if (key != kKeyNone) {
// check for ctrl+alt+del emulation
@@ -1083,19 +1035,15 @@ CXWindowsScreen::onKeyPress(XKeyEvent& xkey)
}
// handle key
sendEvent(getKeyDownEvent(), CKeyInfo::alloc(key, mask, keycode, 1));
KeyModifierMask keyMask = m_keyState->getMaskForKey(keycode);
if (m_keyState->isHalfDuplex(keyMask)) {
sendEvent(getKeyUpEvent(),
CKeyInfo::alloc(key, mask | keyMask, keycode, 1));
}
m_keyState->sendKeyEvent(getEventTarget(),
true, false, key, mask, 1, keycode);
}
}
void
CXWindowsScreen::onKeyRelease(XKeyEvent& xkey, bool isRepeat)
{
const KeyModifierMask mask = m_keyMapper.mapModifier(xkey.state);
const KeyModifierMask mask = m_keyState->mapModifiersFromX(xkey.state);
KeyID key = mapKeyFromX(&xkey);
if (key != kKeyNone) {
// check for ctrl+alt+del emulation
@@ -1112,12 +1060,8 @@ CXWindowsScreen::onKeyRelease(XKeyEvent& xkey, bool isRepeat)
if (!isRepeat) {
// no press event follows so it's a plain release
LOG((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", keycode, xkey.state));
KeyModifierMask keyMask = m_keyState->getMaskForKey(keycode);
if (m_keyState->isHalfDuplex(keyMask)) {
sendEvent(getKeyDownEvent(),
CKeyInfo::alloc(key, mask, keycode, 1));
}
sendEvent(getKeyUpEvent(), CKeyInfo::alloc(key, mask, keycode, 1));
m_keyState->sendKeyEvent(getEventTarget(),
false, false, key, mask, 1, keycode);
}
else {
// found a press event following so it's a repeat.
@@ -1125,8 +1069,8 @@ CXWindowsScreen::onKeyRelease(XKeyEvent& xkey, bool isRepeat)
// repeats but we'll just send a repeat of 1.
// note that we discard the press event.
LOG((CLOG_DEBUG1 "event: repeat code=%d, state=0x%04x", keycode, xkey.state));
sendEvent(getKeyRepeatEvent(),
CKeyInfo::alloc(key, mask, keycode, 1));
m_keyState->sendKeyEvent(getEventTarget(),
false, true, key, mask, 1, keycode);
}
}
}