made calls to X thread safe.

This commit is contained in:
crs 2001-10-24 22:33:24 +00:00
parent fdb888102b
commit 066910fab8
4 changed files with 76 additions and 13 deletions

View File

@ -1,6 +1,7 @@
#include "CXWindowsPrimaryScreen.h" #include "CXWindowsPrimaryScreen.h"
#include "CServer.h" #include "CServer.h"
#include "CThread.h" #include "CThread.h"
#include "CLock.h"
#include "TMethodJob.h" #include "TMethodJob.h"
#include "CLog.h" #include "CLog.h"
#include <assert.h> #include <assert.h>
@ -107,6 +108,8 @@ void CXWindowsPrimaryScreen::enter(SInt32 x, SInt32 y)
assert(m_window != None); assert(m_window != None);
assert(m_active == true); assert(m_active == true);
CLock lock(&m_mutex);
// warp to requested location // warp to requested location
::XWarpPointer(m_display, None, m_window, 0, 0, 0, 0, x, y); ::XWarpPointer(m_display, None, m_window, 0, 0, 0, 0, x, y);
@ -135,6 +138,8 @@ void CXWindowsPrimaryScreen::leave()
assert(m_window != None); assert(m_window != None);
assert(m_active == false); assert(m_active == false);
CLock lock(&m_mutex);
// raise and show the input window // raise and show the input window
::XMapRaised(m_display, m_window); ::XMapRaised(m_display, m_window);
@ -169,7 +174,7 @@ void CXWindowsPrimaryScreen::leave()
log((CLOG_DEBUG "grabbed keyboard")); log((CLOG_DEBUG "grabbed keyboard"));
// move the mouse to the center of grab window // move the mouse to the center of grab window
warpCursor(m_w >> 1, m_h >> 1); warpCursorNoLock(m_w >> 1, m_h >> 1);
// local client now active // local client now active
m_active = true; m_active = true;
@ -177,7 +182,13 @@ void CXWindowsPrimaryScreen::leave()
void CXWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y) void CXWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
{ {
CLock lock(&m_mutex);
warpCursorNoLock(x, y);
}
void CXWindowsPrimaryScreen::warpCursorNoLock(
SInt32 x, SInt32 y)
{
// warp the mouse // warp the mouse
::XWarpPointer(m_display, None, m_root, 0, 0, 0, 0, x, y); ::XWarpPointer(m_display, None, m_root, 0, 0, 0, 0, x, y);
::XSync(m_display, False); ::XSync(m_display, False);
@ -271,18 +282,24 @@ void CXWindowsPrimaryScreen::eventThread(void*)
{ {
for (;;) { for (;;) {
// wait for and then get the next event // wait for and then get the next event
m_mutex.lock();
while (XPending(m_display) == 0) { while (XPending(m_display) == 0) {
m_mutex.unlock();
CThread::sleep(0.05); CThread::sleep(0.05);
m_mutex.lock();
} }
XEvent xevent; XEvent xevent;
XNextEvent(m_display, &xevent); XNextEvent(m_display, &xevent);
m_mutex.unlock();
// handle event // handle event
switch (xevent.type) { switch (xevent.type) {
case CreateNotify: case CreateNotify: {
// select events on new window // select events on new window
CLock lock(&m_mutex);
selectEvents(xevent.xcreatewindow.window); selectEvents(xevent.xcreatewindow.window);
break; break;
}
case KeyPress: { case KeyPress: {
log((CLOG_DEBUG "event: KeyPress code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state)); log((CLOG_DEBUG "event: KeyPress code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
@ -337,17 +354,21 @@ void CXWindowsPrimaryScreen::eventThread(void*)
// probably not since key strokes may go to wrong place. // probably not since key strokes may go to wrong place.
// get mouse deltas // get mouse deltas
Window root, window; {
int xRoot, yRoot, xWindow, yWindow; CLock lock(&m_mutex);
unsigned int mask; Window root, window;
if (!::XQueryPointer(m_display, m_window, &root, &window, int xRoot, yRoot, xWindow, yWindow;
unsigned int mask;
if (!::XQueryPointer(m_display, m_window, &root, &window,
&xRoot, &yRoot, &xWindow, &yWindow, &mask)) &xRoot, &yRoot, &xWindow, &yWindow, &mask))
break; break;
x = xRoot - (m_w >> 1);
y = yRoot - (m_h >> 1);
// warp mouse back to center x = xRoot - (m_w >> 1);
warpCursor(m_w >> 1, m_h >> 1); y = yRoot - (m_h >> 1);
// warp mouse back to center
warpCursorNoLock(m_w >> 1, m_h >> 1);
}
m_server->onMouseMoveSecondary(x, y); m_server->onMouseMoveSecondary(x, y);
} }

View File

@ -1,6 +1,7 @@
#ifndef CXWINDOWSPRIMARYSCREEN_H #ifndef CXWINDOWSPRIMARYSCREEN_H
#define CXWINDOWSPRIMARYSCREEN_H #define CXWINDOWSPRIMARYSCREEN_H
#include "CMutex.h"
#include "KeyTypes.h" #include "KeyTypes.h"
#include "MouseTypes.h" #include "MouseTypes.h"
#include "IPrimaryScreen.h" #include "IPrimaryScreen.h"
@ -25,6 +26,7 @@ class CXWindowsPrimaryScreen : public IPrimaryScreen {
private: private:
void selectEvents(Window) const; void selectEvents(Window) const;
Cursor createBlankCursor(); Cursor createBlankCursor();
void warpCursorNoLock(SInt32 xAbsolute, SInt32 yAbsolute);
void eventThread(void*); void eventThread(void*);
KeyModifierMask mapModifier(unsigned int state) const; KeyModifierMask mapModifier(unsigned int state) const;
@ -40,6 +42,9 @@ class CXWindowsPrimaryScreen : public IPrimaryScreen {
SInt32 m_w, m_h; SInt32 m_w, m_h;
Window m_window; Window m_window;
bool m_active; bool m_active;
// X is not thread safe
CMutex m_mutex;
}; };
#endif #endif

View File

@ -1,6 +1,7 @@
#include "CXWindowsSecondaryScreen.h" #include "CXWindowsSecondaryScreen.h"
#include "CClient.h" #include "CClient.h"
#include "CThread.h" #include "CThread.h"
#include "CLock.h"
#include "TMethodJob.h" #include "TMethodJob.h"
#include "CLog.h" #include "CLog.h"
#include <assert.h> #include <assert.h>
@ -111,8 +112,10 @@ void CXWindowsSecondaryScreen::enter(SInt32 x, SInt32 y)
assert(m_display != NULL); assert(m_display != NULL);
assert(m_window != None); assert(m_window != None);
CLock lock(&m_mutex);
// warp to requested location // warp to requested location
warpCursor(x, y); warpCursorNoLock(x, y);
// show cursor // show cursor
::XUnmapWindow(m_display, m_window); ::XUnmapWindow(m_display, m_window);
@ -123,6 +126,8 @@ void CXWindowsSecondaryScreen::leave()
assert(m_display != NULL); assert(m_display != NULL);
assert(m_window != None); assert(m_window != None);
CLock lock(&m_mutex);
// raise and show the hider window // raise and show the hider window
::XMapRaised(m_display, m_window); ::XMapRaised(m_display, m_window);
@ -131,6 +136,13 @@ void CXWindowsSecondaryScreen::leave()
} }
void CXWindowsSecondaryScreen::warpCursor(SInt32 x, SInt32 y) void CXWindowsSecondaryScreen::warpCursor(SInt32 x, SInt32 y)
{
CLock lock(&m_mutex);
warpCursorNoLock(x, y);
}
void CXWindowsSecondaryScreen::warpCursorNoLock(
SInt32 x, SInt32 y)
{ {
assert(m_display != NULL); assert(m_display != NULL);
@ -143,6 +155,8 @@ void CXWindowsSecondaryScreen::onKeyDown(
{ {
assert(m_display != NULL); assert(m_display != NULL);
CLock lock(&m_mutex);
::XTestFakeKeyEvent(m_display, mapKey(key, mask), True, CurrentTime); ::XTestFakeKeyEvent(m_display, mapKey(key, mask), True, CurrentTime);
::XSync(m_display, False); ::XSync(m_display, False);
} }
@ -152,6 +166,8 @@ void CXWindowsSecondaryScreen::onKeyRepeat(
{ {
assert(m_display != NULL); assert(m_display != NULL);
CLock lock(&m_mutex);
// FIXME // FIXME
} }
@ -160,6 +176,8 @@ void CXWindowsSecondaryScreen::onKeyUp(
{ {
assert(m_display != NULL); assert(m_display != NULL);
CLock lock(&m_mutex);
::XTestFakeKeyEvent(m_display, mapKey(key, mask), False, CurrentTime); ::XTestFakeKeyEvent(m_display, mapKey(key, mask), False, CurrentTime);
::XSync(m_display, False); ::XSync(m_display, False);
} }
@ -168,6 +186,8 @@ void CXWindowsSecondaryScreen::onMouseDown(ButtonID button)
{ {
assert(m_display != NULL); assert(m_display != NULL);
CLock lock(&m_mutex);
::XTestFakeButtonEvent(m_display, mapButton(button), True, CurrentTime); ::XTestFakeButtonEvent(m_display, mapButton(button), True, CurrentTime);
::XSync(m_display, False); ::XSync(m_display, False);
} }
@ -176,6 +196,8 @@ void CXWindowsSecondaryScreen::onMouseUp(ButtonID button)
{ {
assert(m_display != NULL); assert(m_display != NULL);
CLock lock(&m_mutex);
::XTestFakeButtonEvent(m_display, mapButton(button), False, CurrentTime); ::XTestFakeButtonEvent(m_display, mapButton(button), False, CurrentTime);
::XSync(m_display, False); ::XSync(m_display, False);
} }
@ -185,6 +207,8 @@ void CXWindowsSecondaryScreen::onMouseMove(
{ {
assert(m_display != NULL); assert(m_display != NULL);
CLock lock(&m_mutex);
::XTestFakeMotionEvent(m_display, m_screen, x, y, CurrentTime); ::XTestFakeMotionEvent(m_display, m_screen, x, y, CurrentTime);
::XSync(m_display, False); ::XSync(m_display, False);
} }
@ -193,6 +217,8 @@ void CXWindowsSecondaryScreen::onMouseWheel(SInt32)
{ {
assert(m_display != NULL); assert(m_display != NULL);
CLock lock(&m_mutex);
// FIXME // FIXME
} }
@ -255,18 +281,24 @@ void CXWindowsSecondaryScreen::eventThread(void*)
for (;;) { for (;;) {
// wait for and then get the next event // wait for and then get the next event
m_mutex.lock();
while (XPending(m_display) == 0) { while (XPending(m_display) == 0) {
m_mutex.unlock();
CThread::sleep(0.05); CThread::sleep(0.05);
m_mutex.lock();
} }
XEvent xevent; XEvent xevent;
XNextEvent(m_display, &xevent); XNextEvent(m_display, &xevent);
m_mutex.unlock();
// handle event // handle event
switch (xevent.type) { switch (xevent.type) {
case LeaveNotify: case LeaveNotify: {
// mouse moved out of hider window somehow. hide the window. // mouse moved out of hider window somehow. hide the window.
CLock lock(&m_mutex);
::XUnmapWindow(m_display, m_window); ::XUnmapWindow(m_display, m_window);
break; break;
}
/* /*
// FIXME -- handle screen resolution changes // FIXME -- handle screen resolution changes

View File

@ -1,6 +1,7 @@
#ifndef CXWINDOWSSECONDARYSCREEN_H #ifndef CXWINDOWSSECONDARYSCREEN_H
#define CXWINDOWSSECONDARYSCREEN_H #define CXWINDOWSSECONDARYSCREEN_H
#include "CMutex.h"
#include "ISecondaryScreen.h" #include "ISecondaryScreen.h"
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -29,6 +30,7 @@ class CXWindowsSecondaryScreen : public ISecondaryScreen {
private: private:
Cursor createBlankCursor(); Cursor createBlankCursor();
void warpCursorNoLock(SInt32 xAbsolute, SInt32 yAbsolute);
void eventThread(void*); void eventThread(void*);
KeyCode mapKey(KeyID, KeyModifierMask) const; KeyCode mapKey(KeyID, KeyModifierMask) const;
unsigned int mapButton(ButtonID button) const; unsigned int mapButton(ButtonID button) const;
@ -41,6 +43,9 @@ class CXWindowsSecondaryScreen : public ISecondaryScreen {
Window m_root; Window m_root;
Window m_window; Window m_window;
SInt32 m_w, m_h; SInt32 m_w, m_h;
// X is not thread safe
CMutex m_mutex;
}; };
#endif #endif