Merge remote-tracking branch 'jeremyhu/master'

This commit is contained in:
Keith Packard 2011-04-22 11:20:16 -07:00
commit 918a9c99cf
8 changed files with 135 additions and 58 deletions

View File

@ -725,9 +725,9 @@ case $host_os in
save_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -framework Carbon"
AC_LINK_IFELSE([char FSFindFolder(); int main() { FSFindFolder(); return 0;}],
[xorg_cv_Carbon_framework=yes],
[xorg_cv_Carbon_framework=no])
LDFLAGS=$save_LDFLAGS])
[xorg_cv_Carbon_framework=yes],
[xorg_cv_Carbon_framework=no])
LDFLAGS=$save_LDFLAGS])
if test "X$xorg_cv_Carbon_framework" = Xyes; then
XQUARTZ=yes
@ -736,6 +736,10 @@ case $host_os in
fi
fi
AC_CHECK_FUNC(dispatch_async,
AC_DEFINE([HAVE_LIBDISPATCH], 1, [Define to 1 if you have the libdispatch (GCD) available]),
[])
if test "x$XQUARTZ" = xyes ; then
XQUARTZ=yes
XVFB=no

View File

@ -61,6 +61,12 @@ extern int xpbproxy_run (void);
#define XSERVER_VERSION "?"
#endif
#ifdef HAVE_LIBDISPATCH
#include <dispatch/dispatch.h>
static dispatch_queue_t eventTranslationQueue;
#endif
/* Stuck modifier / button state... force release when we context switch */
static NSEventType keyState[NUM_KEYCODES];
@ -385,7 +391,15 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
if (for_appkit) [super sendEvent:e];
if (for_x) [self sendX11NSEvent:e];
if (for_x) {
#ifdef HAVE_LIBDISPATCH
dispatch_async(eventTranslationQueue, ^{
#endif
[self sendX11NSEvent:e];
#ifdef HAVE_LIBDISPATCH
});
#endif
}
}
- (void) set_window_menu:(NSArray *)list {
@ -950,7 +964,7 @@ environment the next time you start X11?", @"Startup xinitrc dialog");
[X11App prefs_synchronize];
}
static inline pthread_t create_thread(void *func, void *arg) {
static inline pthread_t create_thread(void *(*func)(void *), void *arg) {
pthread_attr_t attr;
pthread_t tid;
@ -999,6 +1013,11 @@ void X11ApplicationMain (int argc, char **argv, char **envp) {
aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) -
NSMaxY([[NSScreen mainScreen] visibleFrame]);
#ifdef HAVE_LIBDISPATCH
eventTranslationQueue = dispatch_queue_create(LAUNCHD_ID_PREFIX".X11.NSEventsToX11EventsQueue", NULL);
assert(eventTranslationQueue != NULL);
#endif
/* Set the key layout seed before we start the server */
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
last_key_layout = TISCopyCurrentKeyboardLayoutInputSource();
@ -1079,13 +1098,29 @@ static const char *untrusted_str(NSEvent *e) {
#endif
- (void) sendX11NSEvent:(NSEvent *)e {
NSPoint location = NSZeroPoint, tilt = NSZeroPoint;
NSPoint location = NSZeroPoint;
int ev_button, ev_type;
float pressure = 0.0;
static float pressure = 0.0; // static so ProximityOut will have the value from the previous tablet event
static NSPoint tilt; // static so ProximityOut will have the value from the previous tablet event
static DeviceIntPtr darwinTabletCurrent = NULL;
static BOOL needsProximityIn = NO; // Do we do need to handle a pending ProximityIn once we have pressure/tilt?
DeviceIntPtr pDev;
int modifierFlags;
BOOL isMouseOrTabletEvent, isTabletEvent;
#ifdef HAVE_LIBDISPATCH
static dispatch_once_t once_pred;
dispatch_once(&once_pred, ^{
tilt = NSZeroPoint;
darwinTabletCurrent = darwinTabletStylus;
});
#else
if(!darwinTabletCurrent) {
tilt = NSZeroPoint;
darwinTabletCurrent = darwinTabletStylus;
}
#endif
isMouseOrTabletEvent = [e type] == NSLeftMouseDown || [e type] == NSOtherMouseDown || [e type] == NSRightMouseDown ||
[e type] == NSLeftMouseUp || [e type] == NSOtherMouseUp || [e type] == NSRightMouseUp ||
[e type] == NSLeftMouseDragged || [e type] == NSOtherMouseDragged || [e type] == NSRightMouseDragged ||
@ -1207,19 +1242,14 @@ static const char *untrusted_str(NSEvent *e) {
darwinTabletCurrent=darwinTabletCursor;
break;
}
/* NSTabletProximityEventSubtype doesn't encode pressure ant tilt
* So we just pretend the motion was caused by the mouse. Hopefully
* we'll have a better solution for this in the future (like maybe
* NSTabletProximityEventSubtype will come from NSTabletPoint
* rather than NSMouseMoved.
pressure = [e pressure];
tilt = [e tilt];
pDev = darwinTabletCurrent;
*/
DarwinSendProximityEvents([e isEnteringProximity] ? ProximityIn : ProximityOut,
location.x, location.y);
if([e isEnteringProximity])
needsProximityIn = YES;
else
DarwinSendProximityEvents(darwinTabletCurrent, ProximityOut,
location.x, location.y, pressure,
tilt.x, tilt.y);
return;
}
if ([e type] == NSTabletPoint || [e subtype] == NSTabletPointEventSubtype) {
@ -1227,6 +1257,14 @@ static const char *untrusted_str(NSEvent *e) {
tilt = [e tilt];
pDev = darwinTabletCurrent;
if(needsProximityIn) {
DarwinSendProximityEvents(darwinTabletCurrent, ProximityIn,
location.x, location.y, pressure,
tilt.x, tilt.y);
needsProximityIn = NO;
}
}
if(!XQuartzServerVisible && noTestExtensions) {
@ -1280,8 +1318,12 @@ static const char *untrusted_str(NSEvent *e) {
break;
}
DarwinSendProximityEvents([e isEnteringProximity] ? ProximityIn : ProximityOut,
location.x, location.y);
if([e isEnteringProximity])
needsProximityIn = YES;
else
DarwinSendProximityEvents(darwinTabletCurrent, ProximityOut,
location.x, location.y, pressure,
tilt.x, tilt.y);
break;
case NSScrollWheel:

View File

@ -117,7 +117,6 @@ unsigned int windowItemModMask = NX_COMMANDMASK;
// devices
DeviceIntPtr darwinKeyboard = NULL;
DeviceIntPtr darwinPointer = NULL;
DeviceIntPtr darwinTabletCurrent = NULL;
DeviceIntPtr darwinTabletStylus = NULL;
DeviceIntPtr darwinTabletCursor = NULL;
DeviceIntPtr darwinTabletEraser = NULL;
@ -492,8 +491,6 @@ void InitInput( int argc, char **argv )
darwinTabletEraser = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
darwinTabletEraser->name = strdup("eraser");
darwinTabletCurrent = darwinTabletStylus;
DarwinEQInit();
QuartzInitInput(argc, argv);

View File

@ -56,7 +56,6 @@ extern io_connect_t darwinParamConnect;
extern int darwinEventReadFD;
extern int darwinEventWriteFD;
extern DeviceIntPtr darwinPointer;
extern DeviceIntPtr darwinTabletCurrent;
extern DeviceIntPtr darwinTabletCursor;
extern DeviceIntPtr darwinTabletStylus;
extern DeviceIntPtr darwinTabletEraser;

View File

@ -61,6 +61,7 @@ in this Software without prior written authorization from The Open Group.
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <time.h>
#include <IOKit/hidsystem/IOLLEvent.h>
@ -93,7 +94,7 @@ static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER;
/*** Pthread Magics ***/
static pthread_t create_thread(void *func, void *arg) {
static pthread_t create_thread(void *(*func)(void *), void *arg) {
pthread_attr_t attr;
pthread_t tid;
@ -304,7 +305,28 @@ void DarwinListenOnOpenFD(int fd) {
pthread_mutex_unlock(&fd_add_lock);
}
static void DarwinProcessFDAdditionQueue_thread(void *args) {
static void *DarwinProcessFDAdditionQueue_thread(void *args) {
/* TODO: Possibly adjust this to no longer be a race... maybe trigger this
* once a client connects and claims to be the WM.
*
* From ajax:
* There's already an internal callback chain for setting selection [in 1.5]
* ownership. See the CallSelectionCallback at the bottom of
* ProcSetSelectionOwner, and xfixes/select.c for an example of how to hook
* into it.
*/
struct timespec sleep_for;
struct timespec sleep_remaining;
sleep_for.tv_sec = 3;
sleep_for.tv_nsec = 0;
ErrorF("X11.app: DarwinProcessFDAdditionQueue_thread: Sleeping to allow xinitrc to catchup.\n");
while(nanosleep(&sleep_for, &sleep_remaining) != 0) {
sleep_for = sleep_remaining;
}
pthread_mutex_lock(&fd_add_lock);
while(true) {
while(fd_add_count) {
@ -312,6 +334,8 @@ static void DarwinProcessFDAdditionQueue_thread(void *args) {
}
pthread_cond_wait(&fd_add_ready_cond, &fd_add_lock);
}
return NULL;
}
Bool DarwinEQInit(void) {
@ -465,7 +489,7 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa
DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
darwinEvents_lock(); {
ValuatorMask mask;
valuator_mask_set_range(&mask, 0, (pDev == darwinTabletCurrent) ? 5 : 2, valuators);
valuator_mask_set_range(&mask, 0, (pDev == darwinPointer) ? 2 : 5, valuators);
num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button,
POINTER_ABSOLUTE, &mask);
for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event);
@ -488,18 +512,18 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
} darwinEvents_unlock();
}
void DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y) {
int i, num_events;
void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, float pointer_y,
float pressure, float tilt_x, float tilt_y) {
int i, num_events;
ScreenPtr screen;
DeviceIntPtr pDev = darwinTabletCurrent;
int valuators[5];
DEBUG_LOG("DarwinSendProximityEvents(%d, %f, %f)\n", ev_type, pointer_x, pointer_y);
DEBUG_LOG("DarwinSendProximityEvents: %d l:%f,%f p:%f t:%f,%f\n", ev_type, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
if(!darwinEvents) {
DEBUG_LOG("DarwinSendProximityEvents called before darwinEvents was initialized\n");
return;
}
if(!darwinEvents) {
DEBUG_LOG("DarwinSendProximityEvents called before darwinEvents was initialized\n");
return;
}
screen = miPointerGetScreen(pDev);
if(!screen) {
@ -507,7 +531,7 @@ void DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y) {
return;
}
DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, 0.0f, 0.0f, 0.0f);
DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
darwinEvents_lock(); {
ValuatorMask mask;
valuator_mask_set_range(&mask, 0, 5, valuators);

View File

@ -37,7 +37,8 @@ void DarwinEQPointerPost(DeviceIntPtr pDev, xEventPtr e);
void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX);
void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y,
float pressure, float tilt_x, float tilt_y);
void DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y);
void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, float pointer_y,
float pressure, float tilt_x, float tilt_y);
void DarwinSendKeyboardEvents(int ev_type, int keycode);
void DarwinSendScrollEvents(float count_x, float count_y, float pointer_x, float pointer_y,
float pressure, float tilt_x, float tilt_y);

View File

@ -40,14 +40,18 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdbool.h>
#include <signal.h>
#ifdef HAVE_LIBDISPATCH
#include <dispatch/dispatch.h>
#else
#include <pthread.h>
#endif
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <fcntl.h>
#include <mach/mach.h>
@ -95,8 +99,9 @@ int server_main(int argc, char **argv, char **envp);
static int execute(const char *command);
static char *command_from_prefs(const char *key, const char *default_value);
#ifndef HAVE_LIBDISPATCH
/*** Pthread Magics ***/
static pthread_t create_thread(void *func, void *arg) {
static pthread_t create_thread(void *(*func)(void *), void *arg) {
pthread_attr_t attr;
pthread_t tid;
@ -108,6 +113,7 @@ static pthread_t create_thread(void *func, void *arg) {
return tid;
}
#endif
/*** Mach-O IPC Stuffs ***/
@ -200,11 +206,15 @@ typedef struct {
/* This thread accepts an incoming connection and hands off the file
* descriptor for the new connection to accept_fd_handoff()
*/
static void socket_handoff_thread(void *arg) {
#ifdef HAVE_LIBDISPATCH
static void socket_handoff(socket_handoff_t *handoff_data) {
#else
static void *socket_handoff_thread(void *arg) {
socket_handoff_t *handoff_data = (socket_handoff_t *)arg;
#endif
int launchd_fd = -1;
int connected_fd;
unsigned remain;
/* Now actually get the passed file descriptor from this connection
* If we encounter an error, keep listening.
@ -227,22 +237,13 @@ static void socket_handoff_thread(void *arg) {
close(handoff_data->fd);
unlink(handoff_data->filename);
free(handoff_data);
/* TODO: Clean up this race better... giving xinitrc time to run... need to wait for 1.5 branch:
*
* From ajax:
* There's already an internal callback chain for setting selection [in 1.5]
* ownership. See the CallSelectionCallback at the bottom of
* ProcSetSelectionOwner, and xfixes/select.c for an example of how to hook
* into it.
*/
remain = 3000000;
fprintf(stderr, "X11.app: Received new $DISPLAY fd: %d ... sleeping to allow xinitrc to catchup.\n", launchd_fd);
while((remain = usleep(remain)) > 0);
fprintf(stderr, "X11.app Handing off fd to server thread via DarwinListenOnOpenFD(%d)\n", launchd_fd);
DarwinListenOnOpenFD(launchd_fd);
#ifndef HAVE_LIBDISPATCH
return NULL;
#endif
}
static int create_socket(char *filename_out) {
@ -311,8 +312,14 @@ kern_return_t do_request_fd_handoff_socket(mach_port_t port, string_t filename)
}
strlcpy(filename, handoff_data->filename, STRING_T_SIZE);
#ifdef HAVE_LIBDISPATCH
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
socket_handoff(handoff_data);
});
#else
create_thread(socket_handoff_thread, handoff_data);
#endif
#ifdef DEBUG
fprintf(stderr, "X11.app: Thread created for handoff. Returning success to tell caller to connect and push the fd.\n");

View File

@ -136,6 +136,9 @@
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* Define to 1 if you have the libdispatch (GCD) available */
#undef HAVE_LIBDISPATCH
/* Define to 1 if you have the `link' function. */
#undef HAVE_LINK