XQuartz: Use a mutex to ensure we only have one thread calling mieqEnqueue at a time.
(cherry picked from commit 7b087c965bce9f440ab5233d6383aa4a7de969b8)
This commit is contained in:
parent
55f80d7545
commit
2a1ba20af9
|
@ -54,6 +54,9 @@ in this Software without prior written authorization from The Open Group.
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <IOKit/hidsystem/IOLLEvent.h>
|
#include <IOKit/hidsystem/IOLLEvent.h>
|
||||||
|
|
||||||
/* Fake button press/release for scroll wheel move. */
|
/* Fake button press/release for scroll wheel move. */
|
||||||
|
@ -77,6 +80,25 @@ static int old_flags = 0; // last known modifier state
|
||||||
|
|
||||||
xEvent *darwinEvents = NULL;
|
xEvent *darwinEvents = NULL;
|
||||||
|
|
||||||
|
pthread_mutex_t mieqEnqueue_mutex;
|
||||||
|
static inline void mieqEnqueue_lock(void) {
|
||||||
|
int err;
|
||||||
|
if((err = pthread_mutex_lock(&mieqEnqueue_mutex))) {
|
||||||
|
ErrorF("%s:%s:%d: Failed to lock mieqEnqueue_mutex: %d\n",
|
||||||
|
__FILE__, __FUNCTION__, __LINE__, err);
|
||||||
|
spewCallStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mieqEnqueue_unlock(void) {
|
||||||
|
int err;
|
||||||
|
if((err = pthread_mutex_unlock(&mieqEnqueue_mutex))) {
|
||||||
|
ErrorF("%s:%s:%d: Failed to unlock mieqEnqueue_mutex: %d\n",
|
||||||
|
__FILE__, __FUNCTION__, __LINE__, err);
|
||||||
|
spewCallStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DarwinPressModifierMask
|
* DarwinPressModifierMask
|
||||||
* Press or release the given modifier key, specified by its mask.
|
* Press or release the given modifier key, specified by its mask.
|
||||||
|
@ -197,107 +219,119 @@ static void DarwinSimulateMouseClick(
|
||||||
mieqSetHandler. */
|
mieqSetHandler. */
|
||||||
|
|
||||||
void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) {
|
void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents);
|
TA_SERVER();
|
||||||
for (i=0; i<nevents; i++) {
|
|
||||||
switch(xe[i].u.u.type) {
|
|
||||||
case kXquartzControllerNotify:
|
|
||||||
DEBUG_LOG("kXquartzControllerNotify\n");
|
|
||||||
AppleWMSendEvent(AppleWMControllerNotify,
|
|
||||||
AppleWMControllerNotifyMask,
|
|
||||||
xe[i].u.clientMessage.u.l.longs0,
|
|
||||||
xe[i].u.clientMessage.u.l.longs1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kXquartzPasteboardNotify:
|
DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents);
|
||||||
DEBUG_LOG("kXquartzPasteboardNotify\n");
|
for (i=0; i<nevents; i++) {
|
||||||
AppleWMSendEvent(AppleWMPasteboardNotify,
|
switch(xe[i].u.u.type) {
|
||||||
AppleWMPasteboardNotifyMask,
|
case kXquartzControllerNotify:
|
||||||
xe[i].u.clientMessage.u.l.longs0,
|
DEBUG_LOG("kXquartzControllerNotify\n");
|
||||||
xe[i].u.clientMessage.u.l.longs1);
|
AppleWMSendEvent(AppleWMControllerNotify,
|
||||||
break;
|
AppleWMControllerNotifyMask,
|
||||||
|
xe[i].u.clientMessage.u.l.longs0,
|
||||||
|
xe[i].u.clientMessage.u.l.longs1);
|
||||||
|
break;
|
||||||
|
|
||||||
case kXquartzActivate:
|
case kXquartzPasteboardNotify:
|
||||||
DEBUG_LOG("kXquartzActivate\n");
|
DEBUG_LOG("kXquartzPasteboardNotify\n");
|
||||||
QuartzShow(xe[i].u.keyButtonPointer.rootX,
|
AppleWMSendEvent(AppleWMPasteboardNotify,
|
||||||
xe[i].u.keyButtonPointer.rootY);
|
AppleWMPasteboardNotifyMask,
|
||||||
AppleWMSendEvent(AppleWMActivationNotify,
|
xe[i].u.clientMessage.u.l.longs0,
|
||||||
AppleWMActivationNotifyMask,
|
xe[i].u.clientMessage.u.l.longs1);
|
||||||
AppleWMIsActive, 0);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case kXquartzDeactivate:
|
case kXquartzActivate:
|
||||||
DEBUG_LOG("kXquartzDeactivate\n");
|
DEBUG_LOG("kXquartzActivate\n");
|
||||||
DarwinReleaseModifiers();
|
QuartzShow(xe[i].u.keyButtonPointer.rootX,
|
||||||
AppleWMSendEvent(AppleWMActivationNotify,
|
xe[i].u.keyButtonPointer.rootY);
|
||||||
AppleWMActivationNotifyMask,
|
AppleWMSendEvent(AppleWMActivationNotify,
|
||||||
AppleWMIsInactive, 0);
|
AppleWMActivationNotifyMask,
|
||||||
QuartzHide();
|
AppleWMIsActive, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kXquartzWindowState:
|
case kXquartzDeactivate:
|
||||||
DEBUG_LOG("kXquartzWindowState\n");
|
DEBUG_LOG("kXquartzDeactivate\n");
|
||||||
RootlessNativeWindowStateChanged(xprGetXWindow(xe[i].u.clientMessage.u.l.longs0),
|
DarwinReleaseModifiers();
|
||||||
xe[i].u.clientMessage.u.l.longs1);
|
AppleWMSendEvent(AppleWMActivationNotify,
|
||||||
break;
|
AppleWMActivationNotifyMask,
|
||||||
|
AppleWMIsInactive, 0);
|
||||||
|
QuartzHide();
|
||||||
|
break;
|
||||||
|
|
||||||
case kXquartzWindowMoved:
|
case kXquartzWindowState:
|
||||||
DEBUG_LOG("kXquartzWindowMoved\n");
|
DEBUG_LOG("kXquartzWindowState\n");
|
||||||
RootlessNativeWindowMoved ((WindowPtr)xe[i].u.clientMessage.u.l.longs0);
|
RootlessNativeWindowStateChanged(xprGetXWindow(xe[i].u.clientMessage.u.l.longs0),
|
||||||
break;
|
xe[i].u.clientMessage.u.l.longs1);
|
||||||
|
break;
|
||||||
|
|
||||||
case kXquartzToggleFullscreen:
|
case kXquartzWindowMoved:
|
||||||
DEBUG_LOG("kXquartzToggleFullscreen\n");
|
DEBUG_LOG("kXquartzWindowMoved\n");
|
||||||
|
RootlessNativeWindowMoved ((WindowPtr)xe[i].u.clientMessage.u.l.longs0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kXquartzToggleFullscreen:
|
||||||
|
DEBUG_LOG("kXquartzToggleFullscreen\n");
|
||||||
#ifdef DARWIN_DDX_MISSING
|
#ifdef DARWIN_DDX_MISSING
|
||||||
if (quartzEnableRootless) QuartzSetFullscreen(!quartzHasRoot);
|
if (quartzEnableRootless)
|
||||||
else if (quartzHasRoot) QuartzHide();
|
QuartzSetFullscreen(!quartzHasRoot);
|
||||||
else QuartzShow();
|
else if (quartzHasRoot)
|
||||||
|
QuartzHide();
|
||||||
|
else
|
||||||
|
QuartzShow();
|
||||||
#else
|
#else
|
||||||
// ErrorF("kXquartzToggleFullscreen not implemented\n");
|
// ErrorF("kXquartzToggleFullscreen not implemented\n");
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kXquartzSetRootless:
|
case kXquartzSetRootless:
|
||||||
DEBUG_LOG("kXquartzSetRootless\n");
|
DEBUG_LOG("kXquartzSetRootless\n");
|
||||||
#ifdef DARWIN_DDX_MISSING
|
#ifdef DARWIN_DDX_MISSING
|
||||||
QuartzSetRootless(xe[i].u.clientMessage.u.l.longs0);
|
QuartzSetRootless(xe[i].u.clientMessage.u.l.longs0);
|
||||||
if (!quartzEnableRootless && !quartzHasRoot) QuartzHide();
|
if (!quartzEnableRootless && !quartzHasRoot)
|
||||||
|
QuartzHide();
|
||||||
#else
|
#else
|
||||||
// ErrorF("kXquartzSetRootless not implemented\n");
|
// ErrorF("kXquartzSetRootless not implemented\n");
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kXquartzSetRootClip:
|
case kXquartzSetRootClip:
|
||||||
QuartzSetRootClip((BOOL)xe[i].u.clientMessage.u.l.longs0);
|
QuartzSetRootClip((BOOL)xe[i].u.clientMessage.u.l.longs0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kXquartzQuit:
|
case kXquartzQuit:
|
||||||
GiveUp(0);
|
GiveUp(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kXquartzBringAllToFront:
|
case kXquartzBringAllToFront:
|
||||||
DEBUG_LOG("kXquartzBringAllToFront\n");
|
DEBUG_LOG("kXquartzBringAllToFront\n");
|
||||||
RootlessOrderAllWindows();
|
RootlessOrderAllWindows();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kXquartzSpaceChanged:
|
case kXquartzSpaceChanged:
|
||||||
DEBUG_LOG("kXquartzSpaceChanged\n");
|
DEBUG_LOG("kXquartzSpaceChanged\n");
|
||||||
QuartzSpaceChanged(xe[i].u.clientMessage.u.l.longs0);
|
QuartzSpaceChanged(xe[i].u.clientMessage.u.l.longs0);
|
||||||
|
break;
|
||||||
|
|
||||||
break;
|
default:
|
||||||
default:
|
ErrorF("Unknown application defined event type %d.\n", xe[i].u.u.type);
|
||||||
ErrorF("Unknown application defined event type %d.\n", xe[i].u.u.type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) {
|
Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) {
|
||||||
|
int err;
|
||||||
|
|
||||||
if (!darwinEvents)
|
if (!darwinEvents)
|
||||||
darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
|
darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
|
||||||
if (!darwinEvents)
|
if (!darwinEvents)
|
||||||
FatalError("Couldn't allocate event buffer\n");
|
FatalError("Couldn't allocate event buffer\n");
|
||||||
|
|
||||||
|
if((err = pthread_mutex_init(&mieqEnqueue_mutex, NULL))) {
|
||||||
|
FatalError("Couldn't allocate miEnqueue mutex: %d.\n", err);
|
||||||
|
}
|
||||||
|
|
||||||
mieqInit();
|
mieqInit();
|
||||||
mieqSetHandler(kXquartzReloadKeymap, DarwinKeyboardReloadHandler);
|
mieqSetHandler(kXquartzReloadKeymap, DarwinKeyboardReloadHandler);
|
||||||
mieqSetHandler(kXquartzActivate, DarwinEventHandler);
|
mieqSetHandler(kXquartzActivate, DarwinEventHandler);
|
||||||
|
@ -305,7 +339,7 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) {
|
||||||
mieqSetHandler(kXquartzSetRootClip, DarwinEventHandler);
|
mieqSetHandler(kXquartzSetRootClip, DarwinEventHandler);
|
||||||
mieqSetHandler(kXquartzQuit, DarwinEventHandler);
|
mieqSetHandler(kXquartzQuit, DarwinEventHandler);
|
||||||
mieqSetHandler(kXquartzReadPasteboard, QuartzReadPasteboard);
|
mieqSetHandler(kXquartzReadPasteboard, QuartzReadPasteboard);
|
||||||
mieqSetHandler(kXquartzWritePasteboard, QuartzWritePasteboard);
|
mieqSetHandler(kXquartzWritePasteboard, QuartzWritePasteboard);
|
||||||
mieqSetHandler(kXquartzToggleFullscreen, DarwinEventHandler);
|
mieqSetHandler(kXquartzToggleFullscreen, DarwinEventHandler);
|
||||||
mieqSetHandler(kXquartzSetRootless, DarwinEventHandler);
|
mieqSetHandler(kXquartzSetRootless, DarwinEventHandler);
|
||||||
mieqSetHandler(kXquartzSpaceChanged, DarwinEventHandler);
|
mieqSetHandler(kXquartzSpaceChanged, DarwinEventHandler);
|
||||||
|
@ -326,6 +360,8 @@ void ProcessInputEvents(void) {
|
||||||
xEvent xe;
|
xEvent xe;
|
||||||
int x = sizeof(xe);
|
int x = sizeof(xe);
|
||||||
|
|
||||||
|
TA_SERVER();
|
||||||
|
|
||||||
mieqProcessInputEvents();
|
mieqProcessInputEvents();
|
||||||
|
|
||||||
// Empty the signaling pipe
|
// Empty the signaling pipe
|
||||||
|
@ -336,7 +372,7 @@ void ProcessInputEvents(void) {
|
||||||
|
|
||||||
/* Sends a null byte down darwinEventWriteFD, which will cause the
|
/* Sends a null byte down darwinEventWriteFD, which will cause the
|
||||||
Dispatch() event loop to check out event queue */
|
Dispatch() event loop to check out event queue */
|
||||||
void DarwinPokeEQ(void) {
|
static void DarwinPokeEQ(void) {
|
||||||
char nullbyte=0;
|
char nullbyte=0;
|
||||||
input_check_flag++;
|
input_check_flag++;
|
||||||
// <daniels> oh, i ... er ... christ.
|
// <daniels> oh, i ... er ... christ.
|
||||||
|
@ -398,15 +434,18 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button,
|
mieqEnqueue_lock(); {
|
||||||
POINTER_ABSOLUTE, 0, 5, valuators);
|
num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button,
|
||||||
|
POINTER_ABSOLUTE, 0, 5, valuators);
|
||||||
|
for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]);
|
||||||
|
DarwinPokeEQ();
|
||||||
|
|
||||||
for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]);
|
} mieqEnqueue_unlock();
|
||||||
DarwinPokeEQ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DarwinSendKeyboardEvents(int ev_type, int keycode) {
|
void DarwinSendKeyboardEvents(int ev_type, int keycode) {
|
||||||
int i, num_events;
|
int i, num_events;
|
||||||
|
|
||||||
if(!darwinEvents) {
|
if(!darwinEvents) {
|
||||||
ErrorF("DarwinSendKeyboardEvents called before darwinEvents was initialized\n");
|
ErrorF("DarwinSendKeyboardEvents called before darwinEvents was initialized\n");
|
||||||
return;
|
return;
|
||||||
|
@ -425,9 +464,11 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE);
|
mieqEnqueue_lock(); {
|
||||||
for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,&darwinEvents[i]);
|
num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE);
|
||||||
DarwinPokeEQ();
|
for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,&darwinEvents[i]);
|
||||||
|
DarwinPokeEQ();
|
||||||
|
} mieqEnqueue_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y,
|
void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y,
|
||||||
|
@ -443,11 +484,12 @@ void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_events = GetProximityEvents(darwinEvents, darwinPointer, ev_type,
|
mieqEnqueue_lock(); {
|
||||||
0, 5, valuators);
|
num_events = GetProximityEvents(darwinEvents, darwinPointer, ev_type,
|
||||||
|
0, 5, valuators);
|
||||||
for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]);
|
for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]);
|
||||||
DarwinPokeEQ();
|
DarwinPokeEQ();
|
||||||
|
} mieqEnqueue_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -512,5 +554,7 @@ void DarwinSendDDXEvent(int type, int argc, ...) {
|
||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mieqEnqueue_lock();
|
||||||
mieqEnqueue(darwinPointer, &xe);
|
mieqEnqueue(darwinPointer, &xe);
|
||||||
|
mieqEnqueue_unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr);
|
||||||
void DarwinEQEnqueue(const xEventPtr e);
|
void DarwinEQEnqueue(const xEventPtr e);
|
||||||
void DarwinEQPointerPost(DeviceIntPtr pDev, xEventPtr e);
|
void DarwinEQPointerPost(DeviceIntPtr pDev, xEventPtr e);
|
||||||
void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX);
|
void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX);
|
||||||
void DarwinPokeEQ(void);
|
|
||||||
void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y,
|
void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y,
|
||||||
float pressure, float tilt_x, float tilt_y);
|
float pressure, float tilt_x, float tilt_y);
|
||||||
void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y,
|
void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y,
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
pthread_t SERVER_THREAD;
|
pthread_t SERVER_THREAD;
|
||||||
pthread_t APPKIT_THREAD;
|
pthread_t APPKIT_THREAD;
|
||||||
|
|
||||||
static inline void spewCallStack(void) {
|
void spewCallStack(void) {
|
||||||
void* callstack[128];
|
void* callstack[128];
|
||||||
int i, frames = backtrace(callstack, 128);
|
int i, frames = backtrace(callstack, 128);
|
||||||
char** strs = backtrace_symbols(callstack, frames);
|
char** strs = backtrace_symbols(callstack, frames);
|
||||||
|
|
|
@ -36,6 +36,9 @@ extern pthread_t APPKIT_THREAD;
|
||||||
|
|
||||||
#define threadSafetyID(tid) (pthread_equal((tid), SERVER_THREAD) ? "X Server Thread" : "Appkit Thread")
|
#define threadSafetyID(tid) (pthread_equal((tid), SERVER_THREAD) ? "X Server Thread" : "Appkit Thread")
|
||||||
|
|
||||||
|
/* Dump the call stack */
|
||||||
|
void spewCallStack(void);
|
||||||
|
|
||||||
/* Print message to ErrorF if we're in the wrong thread */
|
/* Print message to ErrorF if we're in the wrong thread */
|
||||||
void _threadAssert(pthread_t tid, const char *file, const char *fun, int line);
|
void _threadAssert(pthread_t tid, const char *file, const char *fun, int line);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue