aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xquartz/darwinEvents.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xquartz/darwinEvents.c')
-rw-r--r--xorg-server/hw/xquartz/darwinEvents.c795
1 files changed, 457 insertions, 338 deletions
diff --git a/xorg-server/hw/xquartz/darwinEvents.c b/xorg-server/hw/xquartz/darwinEvents.c
index 827fd81b8..374c4e07e 100644
--- a/xorg-server/hw/xquartz/darwinEvents.c
+++ b/xorg-server/hw/xquartz/darwinEvents.c
@@ -1,7 +1,7 @@
/*
Darwin event queue and event handling
-Copyright 2007 Apple Inc.
+Copyright 2007-2008 Apple Inc.
Copyright 2004 Kaleb S. KEITHLEY. All Rights Reserved.
Copyright (c) 2002-2004 Torrey T. Lyons. All Rights Reserved.
@@ -30,6 +30,12 @@ used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
+#include "sanitizedCarbon.h"
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
#define NEED_EVENTS
#include <X11/X.h>
#include <X11/Xmd.h>
@@ -41,421 +47,534 @@ in this Software without prior written authorization from The Open Group.
#include "mi.h"
#include "scrnintstr.h"
#include "mipointer.h"
+#include "os.h"
#include "darwin.h"
#include "quartz.h"
-#include "darwinKeyboard.h"
+#include "quartzKeyboard.h"
#include "darwinEvents.h"
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+
#include <IOKit/hidsystem/IOLLEvent.h>
/* Fake button press/release for scroll wheel move. */
-#define SCROLLWHEELUPFAKE 4
-#define SCROLLWHEELDOWNFAKE 5
+#define SCROLLWHEELUPFAKE 4
+#define SCROLLWHEELDOWNFAKE 5
+#define SCROLLWHEELLEFTFAKE 6
+#define SCROLLWHEELRIGHTFAKE 7
-#define QUEUE_SIZE 256
+#define _APPLEWM_SERVER_
+#include "applewmExt.h"
+#include <X11/extensions/applewm.h>
-typedef struct _Event {
- xEvent event;
- ScreenPtr pScreen;
-} EventRec, *EventPtr;
+/* FIXME: Abstract this better */
+void QuartzModeEQInit(void);
-int input_check_zero, input_check_flag;
+int darwin_modifier_flags = 0; // last known modifier state
-static int old_flags = 0; // last known modifier state
+#define FD_ADD_MAX 128
+static int fd_add[FD_ADD_MAX];
+int fd_add_count = 0;
+static pthread_mutex_t fd_add_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t fd_add_ready_cond = PTHREAD_COND_INITIALIZER;
+static pthread_t fd_add_tid = NULL;
-typedef struct _EventQueue {
- HWEventQueueType head, tail; /* long for SetInputCheck */
- CARD32 lastEventTime; /* to avoid time running backwards */
- Bool lastMotion;
- EventRec events[QUEUE_SIZE]; /* static allocation for signals */
- DevicePtr pKbd, pPtr; /* device pointer, to get funcs */
- ScreenPtr pEnqueueScreen; /* screen events are being delivered to */
- ScreenPtr pDequeueScreen; /* screen events are being dispatched to */
-} EventQueueRec, *EventQueuePtr;
+static EventList *darwinEvents = NULL;
-static EventQueueRec darwinEventQueue;
-xEvent *darwinEvents;
+static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER;
-/*
- * DarwinPressModifierMask
- * Press or release the given modifier key, specified by its mask.
- */
-static void DarwinPressModifierMask(
- int pressed,
- int mask) // one of NX_*MASK constants
-{
- int key = DarwinModifierNXMaskToNXKey(mask);
+/*** Pthread Magics ***/
+static pthread_t create_thread(void *func, void *arg) {
+ pthread_attr_t attr;
+ pthread_t tid;
- if (key != -1) {
- int keycode = DarwinModifierNXKeyToNXKeycode(key, 0);
- if (keycode != 0)
- DarwinSendKeyboardEvents(pressed, keycode);
- }
-}
-
-#ifdef NX_DEVICELCTLKEYMASK
-#define CONTROL_MASK(flags) (flags & (NX_DEVICELCTLKEYMASK|NX_DEVICERCTLKEYMASK))
-#else
-#define CONTROL_MASK(flags) (NX_CONTROLMASK)
-#endif /* NX_DEVICELCTLKEYMASK */
-
-#ifdef NX_DEVICELSHIFTKEYMASK
-#define SHIFT_MASK(flags) (flags & (NX_DEVICELSHIFTKEYMASK|NX_DEVICERSHIFTKEYMASK))
-#else
-#define SHIFT_MASK(flags) (NX_SHIFTMASK)
-#endif /* NX_DEVICELSHIFTKEYMASK */
-
-#ifdef NX_DEVICELCMDKEYMASK
-#define COMMAND_MASK(flags) (flags & (NX_DEVICELCMDKEYMASK|NX_DEVICERCMDKEYMASK))
-#else
-#define COMMAND_MASK(flags) (NX_COMMANDMASK)
-#endif /* NX_DEVICELCMDKEYMASK */
+ pthread_attr_init (&attr);
+ pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
+ pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create (&tid, &attr, func, arg);
+ pthread_attr_destroy (&attr);
-#ifdef NX_DEVICELALTKEYMASK
-#define ALTERNATE_MASK(flags) (flags & (NX_DEVICELALTKEYMASK|NX_DEVICERALTKEYMASK))
-#else
-#define ALTERNATE_MASK(flags) (NX_ALTERNATEMASK)
-#endif /* NX_DEVICELALTKEYMASK */
+ return tid;
+}
-/*
- * DarwinUpdateModifiers
- * Send events to update the modifier state.
- */
-static void DarwinUpdateModifiers(
- int pressed, // KeyPress or KeyRelease
- int flags ) // modifier flags that have changed
-{
- if (flags & NX_ALPHASHIFTMASK) {
- DarwinPressModifierMask(pressed, NX_ALPHASHIFTMASK);
- }
- if (flags & NX_COMMANDMASK) {
- DarwinPressModifierMask(pressed, COMMAND_MASK(flags));
- }
- if (flags & NX_CONTROLMASK) {
- DarwinPressModifierMask(pressed, CONTROL_MASK(flags));
- }
- if (flags & NX_ALTERNATEMASK) {
- DarwinPressModifierMask(pressed, ALTERNATE_MASK(flags));
- }
- if (flags & NX_SHIFTMASK) {
- DarwinPressModifierMask(pressed, SHIFT_MASK(flags));
+void darwinEvents_lock(void);
+void darwinEvents_lock(void) {
+ int err;
+ if((err = pthread_mutex_lock(&mieq_lock))) {
+ ErrorF("%s:%s:%d: Failed to lock mieq_lock: %d\n",
+ __FILE__, __FUNCTION__, __LINE__, err);
+ spewCallStack();
}
- if (flags & NX_SECONDARYFNMASK) {
- DarwinPressModifierMask(pressed, NX_SECONDARYFNMASK);
+ if(darwinEvents == NULL) {
+ pthread_cond_wait(&mieq_ready_cond, &mieq_lock);
}
}
-/*
- * DarwinReleaseModifiers
- * This hacky function releases all modifier keys. It should be called when X11.app
- * is deactivated (kXDarwinDeactivate) to prevent modifiers from getting stuck if they
- * are held down during a "context" switch -- otherwise, we would miss the KeyUp.
- */
-static void DarwinReleaseModifiers(void) {
- DarwinUpdateModifiers(KeyRelease, COMMAND_MASK(-1) | CONTROL_MASK(-1) | ALTERNATE_MASK(-1) | SHIFT_MASK(-1));
+void darwinEvents_unlock(void);
+void darwinEvents_unlock(void) {
+ int err;
+ if((err = pthread_mutex_unlock(&mieq_lock))) {
+ ErrorF("%s:%s:%d: Failed to unlock mieq_lock: %d\n",
+ __FILE__, __FUNCTION__, __LINE__, err);
+ spewCallStack();
+ }
}
/*
- * DarwinSimulateMouseClick
- * Send a mouse click to X when multiple mouse buttons are simulated
- * with modifier-clicks, such as command-click for button 2. The dix
- * layer is told that the previously pressed modifier key(s) are
- * released, the simulated click event is sent. After the mouse button
- * is released, the modifier keys are reverted to their actual state,
- * which may or may not be pressed at that point. This is usually
- * closest to what the user wants. Ie. the user typically wants to
- * simulate a button 2 press instead of Command-button 2.
+ * DarwinPressModifierKey
+ * Press or release the given modifier key (one of NX_MODIFIERKEY_* constants)
*/
-static void DarwinSimulateMouseClick(
- int pointer_x,
- int pointer_y,
- int whichButton, // mouse button to be pressed
- int modifierMask) // modifiers used for the fake click
-{
- // first fool X into forgetting about the keys
- // for some reason, it's not enough to tell X we released the Command key --
- // it has to be the *left* Command key.
- if (modifierMask & NX_COMMANDMASK) modifierMask |=NX_DEVICELCMDKEYMASK ;
- DarwinUpdateModifiers(KeyRelease, modifierMask);
-
- // push the mouse button
- DarwinSendPointerEvents(ButtonPress, whichButton, pointer_x, pointer_y);
- DarwinSendPointerEvents(ButtonRelease, whichButton, pointer_x, pointer_y);
-
- // restore old modifiers
- DarwinUpdateModifiers(KeyPress, modifierMask);
-}
+static void DarwinPressModifierKey(int pressed, int key) {
+ int keycode = DarwinModifierNXKeyToNXKeycode(key, 0);
+ if (keycode == 0) {
+ ErrorF("DarwinPressModifierKey bad keycode: key=%d\n", key);
+ return;
+ }
-Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) {
- darwinEvents = (xEvent *)malloc(sizeof(xEvent) * GetMaximumEventsNum());
- mieqInit();
- darwinEventQueue.head = darwinEventQueue.tail = 0;
- darwinEventQueue.lastEventTime = GetTimeInMillis ();
- darwinEventQueue.pKbd = pKbd;
- darwinEventQueue.pPtr = pPtr;
- darwinEventQueue.pEnqueueScreen = screenInfo.screens[0];
- darwinEventQueue.pDequeueScreen = darwinEventQueue.pEnqueueScreen;
- SetInputCheck(&input_check_zero, &input_check_flag);
- return TRUE;
+ DarwinSendKeyboardEvents(pressed, keycode);
}
-
/*
- * DarwinEQEnqueue
- * Must be thread safe with ProcessInputEvents.
- * DarwinEQEnqueue - called from event gathering thread
- * ProcessInputEvents - called from X server thread
- * DarwinEQEnqueue should never be called from more than one thread.
- *
- * This should be deprecated in favor of miEQEnqueue -- BB
+ * DarwinUpdateModifiers
+ * Send events to update the modifier state.
*/
-void DarwinEQEnqueue(const xEventPtr e) {
- HWEventQueueType oldtail, newtail;
-
- oldtail = darwinEventQueue.tail;
- // mieqEnqueue() collapses successive motion events into one event.
- // This is difficult to do in a thread-safe way and rarely useful.
-
- newtail = oldtail + 1;
- if (newtail == QUEUE_SIZE) newtail = 0;
- /* Toss events which come in late */
- if (newtail == darwinEventQueue.head) return;
+int darwin_modifier_mask_list[] = {
+#ifdef NX_DEVICELCMDKEYMASK
+ NX_DEVICELCTLKEYMASK, NX_DEVICERCTLKEYMASK,
+ NX_DEVICELSHIFTKEYMASK, NX_DEVICERSHIFTKEYMASK,
+ NX_DEVICELCMDKEYMASK, NX_DEVICERCMDKEYMASK,
+ NX_DEVICELALTKEYMASK, NX_DEVICERALTKEYMASK,
+#else
+ NX_CONTROLMASK, NX_SHIFTMASK, NX_COMMANDMASK, NX_ALTERNATEMASK,
+#endif
+ NX_ALPHASHIFTMASK,
+ 0
+};
- darwinEventQueue.events[oldtail].event = *e;
+static void DarwinUpdateModifiers(
+ int pressed, // KeyPress or KeyRelease
+ int flags ) // modifier flags that have changed
+{
+ int *f;
+ int key;
- /*
- * Make sure that event times don't go backwards - this
- * is "unnecessary", but very useful
+ /* Capslock is special. This mask is the state of capslock (on/off),
+ * not the state of the button. Hopefully we can find a better solution.
*/
- if (e->u.keyButtonPointer.time < darwinEventQueue.lastEventTime &&
- darwinEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000)
- {
- darwinEventQueue.events[oldtail].event.u.keyButtonPointer.time =
- darwinEventQueue.lastEventTime;
+ if(NX_ALPHASHIFTMASK & flags) {
+ DarwinPressModifierKey(KeyPress, NX_MODIFIERKEY_ALPHALOCK);
+ DarwinPressModifierKey(KeyRelease, NX_MODIFIERKEY_ALPHALOCK);
}
- darwinEventQueue.events[oldtail].pScreen = darwinEventQueue.pEnqueueScreen;
+
+ for(f=darwin_modifier_mask_list; *f; f++)
+ if(*f & flags && *f != NX_ALPHASHIFTMASK) {
+ key = DarwinModifierNXMaskToNXKey(*f);
+ if(key == -1)
+ ErrorF("DarwinUpdateModifiers: Unsupported NXMask: 0x%x\n", *f);
+ else
+ DarwinPressModifierKey(pressed, key);
+ }
+}
- // Update the tail after the event is prepared
- darwinEventQueue.tail = newtail;
+/* Generic handler for Xquartz-specifc events. When possible, these should
+ be moved into their own individual functions and set as handlers using
+ mieqSetHandler. */
+
+static void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) {
+ int i;
+
+ TA_SERVER();
+
+// DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents);
+ 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("kXquartzPasteboardNotify\n");
+ AppleWMSendEvent(AppleWMPasteboardNotify,
+ AppleWMPasteboardNotifyMask,
+ xe[i].u.clientMessage.u.l.longs0,
+ xe[i].u.clientMessage.u.l.longs1);
+ break;
+
+ case kXquartzActivate:
+ DEBUG_LOG("kXquartzActivate\n");
+ QuartzShow(xe[i].u.keyButtonPointer.rootX,
+ xe[i].u.keyButtonPointer.rootY);
+ AppleWMSendEvent(AppleWMActivationNotify,
+ AppleWMActivationNotifyMask,
+ AppleWMIsActive, 0);
+ break;
+
+ case kXquartzDeactivate:
+ DEBUG_LOG("kXquartzDeactivate\n");
+ AppleWMSendEvent(AppleWMActivationNotify,
+ AppleWMActivationNotifyMask,
+ AppleWMIsInactive, 0);
+ QuartzHide();
+ break;
- // Signal there is an event ready to handle
- DarwinPokeEQ();
-}
+ case kXquartzReloadPreferences:
+ DEBUG_LOG("kXquartzReloadPreferences\n");
+ AppleWMSendEvent(AppleWMActivationNotify,
+ AppleWMActivationNotifyMask,
+ AppleWMReloadPreferences, 0);
+ break;
+
+ case kXquartzToggleFullscreen:
+ DEBUG_LOG("kXquartzToggleFullscreen\n");
+ if (quartzEnableRootless)
+ QuartzSetFullscreen(!quartzHasRoot);
+ else if (quartzHasRoot)
+ QuartzHide();
+ else
+ QuartzShow(xe[i].u.keyButtonPointer.rootX,
+ xe[i].u.keyButtonPointer.rootY);
+ break;
+
+ case kXquartzSetRootless:
+ DEBUG_LOG("kXquartzSetRootless\n");
+ QuartzSetRootless(xe[i].u.clientMessage.u.l.longs0);
+ if (!quartzEnableRootless && !quartzHasRoot)
+ QuartzHide();
+ break;
+
+ case kXquartzSetRootClip:
+ QuartzSetRootClip((Bool)xe[i].u.clientMessage.u.l.longs0);
+ break;
+
+ case kXquartzQuit:
+ GiveUp(0);
+ break;
+
+ case kXquartzSpaceChanged:
+ DEBUG_LOG("kXquartzSpaceChanged\n");
+ QuartzSpaceChanged(xe[i].u.clientMessage.u.l.longs0);
+ break;
+ default:
+ ErrorF("Unknown application defined event type %d.\n", xe[i].u.u.type);
+ }
+ }
+}
-/*
- * DarwinEQPointerPost
- * Post a pointer event. Used by the mipointer.c routines.
- */
-void DarwinEQPointerPost(DeviceIntPtr pdev, xEventPtr e) {
- (*darwinEventQueue.pPtr->processInputProc)
- (e, (DeviceIntPtr)darwinEventQueue.pPtr, 1);
+void DarwinListenOnOpenFD(int fd) {
+ ErrorF("DarwinListenOnOpenFD: %d\n", fd);
+
+ pthread_mutex_lock(&fd_add_lock);
+ if(fd_add_count < FD_ADD_MAX)
+ fd_add[fd_add_count++] = fd;
+ else
+ ErrorF("FD Addition buffer at max. Dropping fd addition request.\n");
+
+ pthread_cond_broadcast(&fd_add_ready_cond);
+ pthread_mutex_unlock(&fd_add_lock);
}
+static void DarwinProcessFDAdditionQueue_thread(void *args) {
+ pthread_mutex_lock(&fd_add_lock);
+ while(true) {
+ while(fd_add_count) {
+ DarwinSendDDXEvent(kXquartzListenOnOpenFD, 1, fd_add[--fd_add_count]);
+ }
+ pthread_cond_wait(&fd_add_ready_cond, &fd_add_lock);
+ }
+}
-void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX) {
- darwinEventQueue.pEnqueueScreen = pScreen;
- if (fromDIX)
- darwinEventQueue.pDequeueScreen = pScreen;
+static void kXquartzListenOnOpenFDHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) {
+ size_t i;
+ TA_SERVER();
+
+ for (i=0; i<nevents; i++) {
+ ErrorF("Calling ListenOnOpenFD() for new fd: %d\n", (int)xe[i].u.clientMessage.u.l.longs0);
+ ListenOnOpenFD((int)xe[i].u.clientMessage.u.l.longs0, 1);
+ }
}
+Bool DarwinEQInit(void) {
+ mieqInit();
+ mieqSetHandler(kXquartzReloadKeymap, DarwinKeyboardReloadHandler);
+ mieqSetHandler(kXquartzActivate, DarwinEventHandler);
+ mieqSetHandler(kXquartzDeactivate, DarwinEventHandler);
+ mieqSetHandler(kXquartzReloadPreferences, DarwinEventHandler);
+ mieqSetHandler(kXquartzSetRootClip, DarwinEventHandler);
+ mieqSetHandler(kXquartzQuit, DarwinEventHandler);
+ mieqSetHandler(kXquartzReadPasteboard, QuartzReadPasteboard);
+ mieqSetHandler(kXquartzWritePasteboard, QuartzWritePasteboard);
+ mieqSetHandler(kXquartzToggleFullscreen, DarwinEventHandler);
+ mieqSetHandler(kXquartzSetRootless, DarwinEventHandler);
+ mieqSetHandler(kXquartzSpaceChanged, DarwinEventHandler);
+ mieqSetHandler(kXquartzControllerNotify, DarwinEventHandler);
+ mieqSetHandler(kXquartzPasteboardNotify, DarwinEventHandler);
+ mieqSetHandler(kXquartzDisplayChanged, QuartzDisplayChangedHandler);
+ mieqSetHandler(kXquartzListenOnOpenFD, kXquartzListenOnOpenFDHandler);
+
+ QuartzModeEQInit();
+
+ /* Note that this *could* cause a potential async issue, since we're checking
+ * darwinEvents without holding the lock, but darwinEvents is only ever set
+ * here, so I don't bother.
+ */
+ if (!darwinEvents) {
+ darwinEvents = InitEventList(GetMaximumEventsNum());;
+
+ if (!darwinEvents)
+ FatalError("Couldn't allocate event buffer\n");
+
+ darwinEvents_lock();
+ pthread_cond_broadcast(&mieq_ready_cond);
+ darwinEvents_unlock();
+ }
+
+ if(!fd_add_tid)
+ fd_add_tid = create_thread(DarwinProcessFDAdditionQueue_thread, NULL);
+
+ return TRUE;
+}
/*
* ProcessInputEvents
* Read and process events from the event queue until it is empty.
*/
void ProcessInputEvents(void) {
- EventRec *e;
- int x, y;
xEvent xe;
- // button number and modifier mask of currently pressed fake button
- input_check_flag=0;
+ int x = sizeof(xe);
+
+ TA_SERVER();
- // ErrorF("calling mieqProcessInputEvents\n");
mieqProcessInputEvents();
// Empty the signaling pipe
- x = sizeof(xe);
- while (x == sizeof(xe))
- x = read(darwinEventReadFD, &xe, sizeof(xe));
-
- while (darwinEventQueue.head != darwinEventQueue.tail)
- {
- if (screenIsSaved == SCREEN_SAVER_ON)
- dixSaveScreens (serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
-
- e = &darwinEventQueue.events[darwinEventQueue.head];
- xe = e->event;
-
- // Shift from global screen coordinates to coordinates relative to
- // the origin of the current screen.
- xe.u.keyButtonPointer.rootX -= darwinMainScreenX +
- dixScreenOrigins[miPointerCurrentScreen()->myNum].x;
- xe.u.keyButtonPointer.rootY -= darwinMainScreenY +
- dixScreenOrigins[miPointerCurrentScreen()->myNum].y;
-
- /* ErrorF("old rootX = (%d,%d) darwinMainScreen = (%d,%d) dixScreenOrigins[%d]=(%d,%d)\n",
- xe.u.keyButtonPointer.rootX, xe.u.keyButtonPointer.rootY,
- darwinMainScreenX, darwinMainScreenY,
- miPointerCurrentScreen()->myNum,
- dixScreenOrigins[miPointerCurrentScreen()->myNum].x,
- dixScreenOrigins[miPointerCurrentScreen()->myNum].y); */
-
- //Assumption - screen switching can only occur on motion events
-
- if (e->pScreen != darwinEventQueue.pDequeueScreen)
- {
- darwinEventQueue.pDequeueScreen = e->pScreen;
- x = xe.u.keyButtonPointer.rootX;
- y = xe.u.keyButtonPointer.rootY;
- if (darwinEventQueue.head == QUEUE_SIZE - 1)
- darwinEventQueue.head = 0;
- else
- ++darwinEventQueue.head;
- NewCurrentScreen (darwinEventQueue.pDequeueScreen, x, y);
- }
- else
- {
- if (darwinEventQueue.head == QUEUE_SIZE - 1)
- darwinEventQueue.head = 0;
- else
- ++darwinEventQueue.head;
- switch (xe.u.u.type) {
- case KeyPress:
- case KeyRelease:
- ErrorF("Unexpected Keyboard event in DarwinProcessInputEvents\n");
- break;
-
- case ButtonPress:
- ErrorF("Unexpected ButtonPress event in DarwinProcessInputEvents\n");
- break;
-
- case ButtonRelease:
- ErrorF("Unexpected ButtonRelease event in DarwinProcessInputEvents\n");
- break;
-
- case MotionNotify:
- ErrorF("Unexpected ButtonRelease event in DarwinProcessInputEvents\n");
- break;
-
- case kXDarwinUpdateModifiers:
- ErrorF("Unexpected ButtonRelease event in DarwinProcessInputEvents\n");
- break;
-
- case kXDarwinUpdateButtons:
- ErrorF("Unexpected XDarwinScrollWheel event in DarwinProcessInputEvents\n");
- break;
-
- case kXDarwinScrollWheel:
- ErrorF("Unexpected XDarwinScrollWheel event in DarwinProcessInputEvents\n");
- break;
-
- case kXDarwinDeactivate:
- DarwinReleaseModifiers();
- // fall through
- default:
- // Check for mode specific event
- QuartzProcessEvent(&xe);
- }
- }
+ while (x == sizeof(xe)) {
+ x = read(darwinEventReadFD, &xe, sizeof(xe));
}
-
- // miPointerUpdate();
}
/* Sends a null byte down darwinEventWriteFD, which will cause the
Dispatch() event loop to check out event queue */
-void DarwinPokeEQ(void) {
- char nullbyte=0;
- input_check_flag++;
- // <daniels> bushing: oh, i ... er ... christ.
- write(darwinEventWriteFD, &nullbyte, 1);
+static void DarwinPokeEQ(void) {
+ char nullbyte=0;
+ // <daniels> oh, i ... er ... christ.
+ write(darwinEventWriteFD, &nullbyte, 1);
}
-void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y) {
- static int darwinFakeMouseButtonDown = 0;
- static int darwinFakeMouseButtonMask = 0;
- int i, num_events;
- int valuators[2] = {pointer_x, pointer_y};
- if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) {
- // Mimic multi-button mouse with modifier-clicks
- // If both sets of modifiers are pressed,
- // button 2 is clicked.
- if ((old_flags & darwinFakeMouse2Mask) == darwinFakeMouse2Mask) {
- DarwinSimulateMouseClick(pointer_x, pointer_y, 2, darwinFakeMouse2Mask);
- darwinFakeMouseButtonDown = 2;
- darwinFakeMouseButtonMask = darwinFakeMouse2Mask;
- } else if ((old_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) {
- DarwinSimulateMouseClick(pointer_x, pointer_y, 3, darwinFakeMouse3Mask);
- darwinFakeMouseButtonDown = 3;
- darwinFakeMouseButtonMask = darwinFakeMouse3Mask;
+/* Convert from Appkit pointer input values to X input values:
+ * Note: pointer_x and pointer_y are relative to the upper-left of primary
+ * display.
+ */
+static void DarwinPrepareValuators(DeviceIntPtr pDev, int *valuators, ScreenPtr screen,
+ float pointer_x, float pointer_y,
+ float pressure, float tilt_x, float tilt_y) {
+ /* Fix offset between darwin and X screens */
+ pointer_x -= darwinMainScreenX + dixScreenOrigins[screen->myNum].x;
+ pointer_y -= darwinMainScreenY + dixScreenOrigins[screen->myNum].y;
+
+ if(pointer_x < 0.0)
+ pointer_x = 0.0;
+
+ if(pointer_y < 0.0)
+ pointer_y = 0.0;
+
+ if(pDev == darwinPointer) {
+ valuators[0] = pointer_x;
+ valuators[1] = pointer_y;
+ valuators[2] = 0;
+ valuators[3] = 0;
+ valuators[4] = 0;
+ } else {
+ /* Setup our array of values */
+ valuators[0] = XQUARTZ_VALUATOR_LIMIT * (pointer_x / (float)screenInfo.screens[0]->width);
+ valuators[1] = XQUARTZ_VALUATOR_LIMIT * (pointer_y / (float)screenInfo.screens[0]->height);
+ valuators[2] = XQUARTZ_VALUATOR_LIMIT * pressure;
+ valuators[3] = XQUARTZ_VALUATOR_LIMIT * tilt_x;
+ valuators[4] = XQUARTZ_VALUATOR_LIMIT * tilt_y;
}
- }
- if (ev_type == ButtonRelease && darwinFakeButtons && darwinFakeMouseButtonDown) {
- // If last mousedown was a fake click, don't check for
- // mouse modifiers here. The user may have released the
- // modifiers before the mouse button.
- ev_button = darwinFakeMouseButtonDown;
- darwinFakeMouseButtonDown = 0;
- // Bring modifiers back up to date
- DarwinUpdateModifiers(KeyPress, darwinFakeMouseButtonMask & old_flags);
- darwinFakeMouseButtonMask = 0;
- }
-
- num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button,
- POINTER_ABSOLUTE, 0, 2, valuators);
-
- for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]);
- DarwinPokeEQ();
+ //DEBUG_LOG("Pointer (%f, %f), Valuators: {%d,%d,%d,%d,%d}\n", pointer_x, pointer_y,
+ // valuators[0], valuators[1], valuators[2], valuators[3], valuators[4]);
}
-void DarwinSendKeyboardEvents(int ev_type, int keycode) {
- int i, num_events;
- if (old_flags == 0 && darwinSyncKeymap && darwinKeymapFile == NULL) {
- /* See if keymap has changed. */
+void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y,
+ float pressure, float tilt_x, float tilt_y) {
+ static int darwinFakeMouseButtonDown = 0;
+ int i, num_events;
+ ScreenPtr screen;
+ int valuators[5];
+
+ //DEBUG_LOG("x=%f, y=%f, p=%f, tx=%f, ty=%f\n", pointer_x, pointer_y, pressure, tilt_x, tilt_y);
+
+ if(!darwinEvents) {
+ DEBUG_LOG("DarwinSendPointerEvents called before darwinEvents was initialized\n");
+ return;
+ }
+
+ screen = miPointerGetScreen(pDev);
+ if(!screen) {
+ DEBUG_LOG("DarwinSendPointerEvents called before screen was initialized\n");
+ return;
+ }
- static unsigned int last_seed;
- unsigned int this_seed;
+ /* Handle fake click */
+ if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) {
+ if(darwinFakeMouseButtonDown != 0) {
+ /* We're currently "down" with another button, so release it first */
+ DarwinSendPointerEvents(pDev, ButtonRelease, darwinFakeMouseButtonDown, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
+ darwinFakeMouseButtonDown=0;
+ }
+ if (darwin_modifier_flags & darwinFakeMouse2Mask) {
+ ev_button = 2;
+ darwinFakeMouseButtonDown = 2;
+ DarwinUpdateModKeys(darwin_modifier_flags & ~darwinFakeMouse2Mask);
+ } else if (darwin_modifier_flags & darwinFakeMouse3Mask) {
+ ev_button = 3;
+ darwinFakeMouseButtonDown = 3;
+ DarwinUpdateModKeys(darwin_modifier_flags & ~darwinFakeMouse3Mask);
+ }
+ }
+
+ if (ev_type == ButtonRelease && ev_button == 1) {
+ if(darwinFakeMouseButtonDown) {
+ ev_button = darwinFakeMouseButtonDown;
+ }
- this_seed = QuartzSystemKeymapSeed();
- if (this_seed != last_seed) {
- last_seed = this_seed;
- DarwinKeyboardReload(darwinKeyboard);
- }
- }
+ if(darwinFakeMouseButtonDown == 2) {
+ DarwinUpdateModKeys(darwin_modifier_flags & ~darwinFakeMouse2Mask);
+ } else if(darwinFakeMouseButtonDown == 3) {
+ DarwinUpdateModKeys(darwin_modifier_flags & ~darwinFakeMouse3Mask);
+ }
+
+ darwinFakeMouseButtonDown = 0;
+ }
- num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE);
- for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,&darwinEvents[i]);
- DarwinPokeEQ();
+ DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
+ darwinEvents_lock(); {
+ num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button,
+ POINTER_ABSOLUTE, 0, pDev==darwinTabletCurrent?5:2, valuators);
+ for(i=0; i<num_events; i++) mieqEnqueue (pDev, darwinEvents[i].event);
+ DarwinPokeEQ();
+ } darwinEvents_unlock();
}
-/* Send the appropriate number of button 4 / 5 clicks to emulate scroll wheel */
-void DarwinSendScrollEvents(float count, int pointer_x, int pointer_y) {
- int i;
- int ev_button = count > 0.0f ? 4 : 5;
- int valuators[2] = {pointer_x, pointer_y};
-
- for (count = fabs(count); count > 0.0; count = count - 1.0f) {
- int num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonPress, ev_button,
- POINTER_ABSOLUTE, 0, 2, valuators);
- for(i=0; i<num_events; i++) mieqEnqueue(darwinPointer,&darwinEvents[i]);
- num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonRelease, ev_button,
- POINTER_ABSOLUTE, 0, 2, valuators);
- for(i=0; i<num_events; i++) mieqEnqueue(darwinPointer,&darwinEvents[i]);
- }
- DarwinPokeEQ();
+void DarwinSendKeyboardEvents(int ev_type, int keycode) {
+ int i, num_events;
+
+ if(!darwinEvents) {
+ DEBUG_LOG("DarwinSendKeyboardEvents called before darwinEvents was initialized\n");
+ return;
+ }
+
+ darwinEvents_lock(); {
+ num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE);
+ for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,darwinEvents[i].event);
+ DarwinPokeEQ();
+ } darwinEvents_unlock();
+}
+
+void DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_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);
+
+ if(!darwinEvents) {
+ DEBUG_LOG("DarwinSendProximityEvents called before darwinEvents was initialized\n");
+ return;
+ }
+
+ screen = miPointerGetScreen(pDev);
+ if(!screen) {
+ DEBUG_LOG("DarwinSendPointerEvents called before screen was initialized\n");
+ return;
+ }
+
+ DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, 0.0f, 0.0f, 0.0f);
+ darwinEvents_lock(); {
+ num_events = GetProximityEvents(darwinEvents, pDev, ev_type,
+ 0, 5, valuators);
+ for(i=0; i<num_events; i++) mieqEnqueue (pDev,darwinEvents[i].event);
+ DarwinPokeEQ();
+ } darwinEvents_unlock();
+}
+
+
+/* Send the appropriate number of button clicks to emulate scroll wheel */
+void DarwinSendScrollEvents(float count_x, float count_y,
+ float pointer_x, float pointer_y,
+ float pressure, float tilt_x, float tilt_y) {
+ if(!darwinEvents) {
+ DEBUG_LOG("DarwinSendScrollEvents called before darwinEvents was initialized\n");
+ return;
+ }
+
+ int sign_x = count_x > 0.0f ? SCROLLWHEELLEFTFAKE : SCROLLWHEELRIGHTFAKE;
+ int sign_y = count_y > 0.0f ? SCROLLWHEELUPFAKE : SCROLLWHEELDOWNFAKE;
+ count_x = fabs(count_x);
+ count_y = fabs(count_y);
+
+ while ((count_x > 0.0f) || (count_y > 0.0f)) {
+ if (count_x > 0.0f) {
+ DarwinSendPointerEvents(darwinPointer, ButtonPress, sign_x, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
+ DarwinSendPointerEvents(darwinPointer, ButtonRelease, sign_x, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
+ count_x = count_x - 1.0f;
+ }
+ if (count_y > 0.0f) {
+ DarwinSendPointerEvents(darwinPointer, ButtonPress, sign_y, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
+ DarwinSendPointerEvents(darwinPointer, ButtonRelease, sign_y, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
+ count_y = count_y - 1.0f;
+ }
+ }
}
/* Send the appropriate KeyPress/KeyRelease events to GetKeyboardEvents to
reflect changing modifier flags (alt, control, meta, etc) */
void DarwinUpdateModKeys(int flags) {
- DarwinUpdateModifiers(KeyRelease, old_flags & ~flags);
- DarwinUpdateModifiers(KeyPress, ~old_flags & flags);
- old_flags = flags;
+ DarwinUpdateModifiers(KeyRelease, darwin_modifier_flags & ~flags);
+ DarwinUpdateModifiers(KeyPress, ~darwin_modifier_flags & flags);
+ darwin_modifier_flags = flags;
+}
+
+/*
+ * DarwinSendDDXEvent
+ * Send the X server thread a message by placing it on the event queue.
+ */
+void DarwinSendDDXEvent(int type, int argc, ...) {
+ xEvent xe;
+ INT32 *argv;
+ int i, max_args;
+ va_list args;
+
+ memset(&xe, 0, sizeof(xe));
+ xe.u.u.type = type;
+ xe.u.clientMessage.u.l.type = type;
+
+ argv = &xe.u.clientMessage.u.l.longs0;
+ max_args = 4;
+
+ if (argc > 0 && argc <= max_args) {
+ va_start (args, argc);
+ for (i = 0; i < argc; i++)
+ argv[i] = (int) va_arg (args, int);
+ va_end (args);
+ }
+
+ darwinEvents_lock(); {
+ mieqEnqueue(darwinPointer, &xe);
+ DarwinPokeEQ();
+ } darwinEvents_unlock();
}