made calls to X thread safe.
This commit is contained in:
parent
fdb888102b
commit
066910fab8
|
@ -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
|
||||||
|
{
|
||||||
|
CLock lock(&m_mutex);
|
||||||
Window root, window;
|
Window root, window;
|
||||||
int xRoot, yRoot, xWindow, yWindow;
|
int xRoot, yRoot, xWindow, yWindow;
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
if (!::XQueryPointer(m_display, m_window, &root, &window,
|
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);
|
x = xRoot - (m_w >> 1);
|
||||||
y = yRoot - (m_h >> 1);
|
y = yRoot - (m_h >> 1);
|
||||||
|
|
||||||
// warp mouse back to center
|
// warp mouse back to center
|
||||||
warpCursor(m_w >> 1, m_h >> 1);
|
warpCursorNoLock(m_w >> 1, m_h >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
m_server->onMouseMoveSecondary(x, y);
|
m_server->onMouseMoveSecondary(x, y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue