darwinEvents.c revision 6747b715
14642e01fSmrg/* 24642e01fSmrgDarwin event queue and event handling 34642e01fSmrg 44642e01fSmrgCopyright 2007-2008 Apple Inc. 54642e01fSmrgCopyright 2004 Kaleb S. KEITHLEY. All Rights Reserved. 64642e01fSmrgCopyright (c) 2002-2004 Torrey T. Lyons. All Rights Reserved. 74642e01fSmrg 84642e01fSmrgThis file is based on mieq.c by Keith Packard, 94642e01fSmrgwhich contains the following copyright: 104642e01fSmrgCopyright 1990, 1998 The Open Group 114642e01fSmrg 124642e01fSmrgPermission to use, copy, modify, distribute, and sell this software and its 134642e01fSmrgdocumentation for any purpose is hereby granted without fee, provided that 144642e01fSmrgthe above copyright notice appear in all copies and that both that 154642e01fSmrgcopyright notice and this permission notice appear in supporting 164642e01fSmrgdocumentation. 174642e01fSmrg 184642e01fSmrgThe above copyright notice and this permission notice shall be included in 194642e01fSmrgall copies or substantial portions of the Software. 204642e01fSmrg 214642e01fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 224642e01fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 234642e01fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 244642e01fSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 254642e01fSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 264642e01fSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 274642e01fSmrg 284642e01fSmrgExcept as contained in this notice, the name of The Open Group shall not be 294642e01fSmrgused in advertising or otherwise to promote the sale, use or other dealings 304642e01fSmrgin this Software without prior written authorization from The Open Group. 314642e01fSmrg */ 324642e01fSmrg 334642e01fSmrg#include "sanitizedCarbon.h" 344642e01fSmrg 354642e01fSmrg#ifdef HAVE_DIX_CONFIG_H 364642e01fSmrg#include <dix-config.h> 374642e01fSmrg#endif 384642e01fSmrg 394642e01fSmrg#include <X11/X.h> 404642e01fSmrg#include <X11/Xmd.h> 414642e01fSmrg#include <X11/Xproto.h> 424642e01fSmrg#include "misc.h" 434642e01fSmrg#include "windowstr.h" 444642e01fSmrg#include "pixmapstr.h" 454642e01fSmrg#include "inputstr.h" 466747b715Smrg#include "eventstr.h" 474642e01fSmrg#include "mi.h" 484642e01fSmrg#include "scrnintstr.h" 494642e01fSmrg#include "mipointer.h" 504642e01fSmrg#include "os.h" 514642e01fSmrg 524642e01fSmrg#include "darwin.h" 534642e01fSmrg#include "quartz.h" 544642e01fSmrg#include "quartzKeyboard.h" 556747b715Smrg#include "quartzRandR.h" 564642e01fSmrg#include "darwinEvents.h" 574642e01fSmrg 584642e01fSmrg#include <sys/types.h> 594642e01fSmrg#include <sys/uio.h> 604642e01fSmrg#include <unistd.h> 614642e01fSmrg#include <pthread.h> 624642e01fSmrg#include <errno.h> 634642e01fSmrg 644642e01fSmrg#include <IOKit/hidsystem/IOLLEvent.h> 654642e01fSmrg 664642e01fSmrg/* Fake button press/release for scroll wheel move. */ 674642e01fSmrg#define SCROLLWHEELUPFAKE 4 684642e01fSmrg#define SCROLLWHEELDOWNFAKE 5 694642e01fSmrg#define SCROLLWHEELLEFTFAKE 6 704642e01fSmrg#define SCROLLWHEELRIGHTFAKE 7 714642e01fSmrg 726747b715Smrg#include <X11/extensions/applewmconst.h> 734642e01fSmrg#include "applewmExt.h" 744642e01fSmrg 754642e01fSmrg/* FIXME: Abstract this better */ 766747b715Smrgextern Bool QuartzModeEventHandler(int screenNum, XQuartzEvent *e, DeviceIntPtr dev); 774642e01fSmrg 786747b715Smrgint darwin_all_modifier_flags = 0; // last known modifier state 796747b715Smrgint darwin_all_modifier_mask = 0; 806747b715Smrgint darwin_x11_modifier_mask = 0; 814642e01fSmrg 824642e01fSmrg#define FD_ADD_MAX 128 834642e01fSmrgstatic int fd_add[FD_ADD_MAX]; 844642e01fSmrgint fd_add_count = 0; 854642e01fSmrgstatic pthread_mutex_t fd_add_lock = PTHREAD_MUTEX_INITIALIZER; 864642e01fSmrgstatic pthread_cond_t fd_add_ready_cond = PTHREAD_COND_INITIALIZER; 874642e01fSmrgstatic pthread_t fd_add_tid = NULL; 884642e01fSmrg 896747b715Smrgstatic EventListPtr darwinEvents = NULL; 904642e01fSmrg 914642e01fSmrgstatic pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER; 924642e01fSmrgstatic pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER; 934642e01fSmrg 944642e01fSmrg/*** Pthread Magics ***/ 954642e01fSmrgstatic pthread_t create_thread(void *func, void *arg) { 964642e01fSmrg pthread_attr_t attr; 974642e01fSmrg pthread_t tid; 984642e01fSmrg 994642e01fSmrg pthread_attr_init (&attr); 1004642e01fSmrg pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM); 1014642e01fSmrg pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); 1024642e01fSmrg pthread_create (&tid, &attr, func, arg); 1034642e01fSmrg pthread_attr_destroy (&attr); 1044642e01fSmrg 1054642e01fSmrg return tid; 1064642e01fSmrg} 1074642e01fSmrg 1084642e01fSmrgvoid darwinEvents_lock(void); 1094642e01fSmrgvoid darwinEvents_lock(void) { 1104642e01fSmrg int err; 1114642e01fSmrg if((err = pthread_mutex_lock(&mieq_lock))) { 1124642e01fSmrg ErrorF("%s:%s:%d: Failed to lock mieq_lock: %d\n", 1134642e01fSmrg __FILE__, __FUNCTION__, __LINE__, err); 1144642e01fSmrg spewCallStack(); 1154642e01fSmrg } 1164642e01fSmrg if(darwinEvents == NULL) { 1174642e01fSmrg pthread_cond_wait(&mieq_ready_cond, &mieq_lock); 1184642e01fSmrg } 1194642e01fSmrg} 1204642e01fSmrg 1214642e01fSmrgvoid darwinEvents_unlock(void); 1224642e01fSmrgvoid darwinEvents_unlock(void) { 1234642e01fSmrg int err; 1244642e01fSmrg if((err = pthread_mutex_unlock(&mieq_lock))) { 1254642e01fSmrg ErrorF("%s:%s:%d: Failed to unlock mieq_lock: %d\n", 1264642e01fSmrg __FILE__, __FUNCTION__, __LINE__, err); 1274642e01fSmrg spewCallStack(); 1284642e01fSmrg } 1294642e01fSmrg} 1304642e01fSmrg 1314642e01fSmrg/* 1324642e01fSmrg * DarwinPressModifierKey 1334642e01fSmrg * Press or release the given modifier key (one of NX_MODIFIERKEY_* constants) 1344642e01fSmrg */ 1354642e01fSmrgstatic void DarwinPressModifierKey(int pressed, int key) { 1364642e01fSmrg int keycode = DarwinModifierNXKeyToNXKeycode(key, 0); 1374642e01fSmrg 1384642e01fSmrg if (keycode == 0) { 1394642e01fSmrg ErrorF("DarwinPressModifierKey bad keycode: key=%d\n", key); 1404642e01fSmrg return; 1414642e01fSmrg } 1424642e01fSmrg 1434642e01fSmrg DarwinSendKeyboardEvents(pressed, keycode); 1444642e01fSmrg} 1454642e01fSmrg 1464642e01fSmrg/* 1474642e01fSmrg * DarwinUpdateModifiers 1484642e01fSmrg * Send events to update the modifier state. 1494642e01fSmrg */ 1504642e01fSmrg 1516747b715Smrgstatic int darwin_x11_modifier_mask_list[] = { 1524642e01fSmrg#ifdef NX_DEVICELCMDKEYMASK 1534642e01fSmrg NX_DEVICELCTLKEYMASK, NX_DEVICERCTLKEYMASK, 1544642e01fSmrg NX_DEVICELSHIFTKEYMASK, NX_DEVICERSHIFTKEYMASK, 1554642e01fSmrg NX_DEVICELCMDKEYMASK, NX_DEVICERCMDKEYMASK, 1564642e01fSmrg NX_DEVICELALTKEYMASK, NX_DEVICERALTKEYMASK, 1574642e01fSmrg#else 1584642e01fSmrg NX_CONTROLMASK, NX_SHIFTMASK, NX_COMMANDMASK, NX_ALTERNATEMASK, 1594642e01fSmrg#endif 1604642e01fSmrg NX_ALPHASHIFTMASK, 1614642e01fSmrg 0 1624642e01fSmrg}; 1634642e01fSmrg 1646747b715Smrgstatic int darwin_all_modifier_mask_additions[] = { NX_SECONDARYFNMASK, }; 1656747b715Smrg 1664642e01fSmrgstatic void DarwinUpdateModifiers( 1674642e01fSmrg int pressed, // KeyPress or KeyRelease 1684642e01fSmrg int flags ) // modifier flags that have changed 1694642e01fSmrg{ 1704642e01fSmrg int *f; 1714642e01fSmrg int key; 1724642e01fSmrg 1734642e01fSmrg /* Capslock is special. This mask is the state of capslock (on/off), 1744642e01fSmrg * not the state of the button. Hopefully we can find a better solution. 1754642e01fSmrg */ 1764642e01fSmrg if(NX_ALPHASHIFTMASK & flags) { 1774642e01fSmrg DarwinPressModifierKey(KeyPress, NX_MODIFIERKEY_ALPHALOCK); 1784642e01fSmrg DarwinPressModifierKey(KeyRelease, NX_MODIFIERKEY_ALPHALOCK); 1794642e01fSmrg } 1804642e01fSmrg 1816747b715Smrg for(f=darwin_x11_modifier_mask_list; *f; f++) 1824642e01fSmrg if(*f & flags && *f != NX_ALPHASHIFTMASK) { 1834642e01fSmrg key = DarwinModifierNXMaskToNXKey(*f); 1844642e01fSmrg if(key == -1) 1854642e01fSmrg ErrorF("DarwinUpdateModifiers: Unsupported NXMask: 0x%x\n", *f); 1864642e01fSmrg else 1874642e01fSmrg DarwinPressModifierKey(pressed, key); 1884642e01fSmrg } 1894642e01fSmrg} 1904642e01fSmrg 1914642e01fSmrg/* Generic handler for Xquartz-specifc events. When possible, these should 1924642e01fSmrg be moved into their own individual functions and set as handlers using 1934642e01fSmrg mieqSetHandler. */ 1944642e01fSmrg 1956747b715Smrgstatic void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr dev) { 1966747b715Smrg XQuartzEvent *e = &(ie->xquartz_event); 1976747b715Smrg 1984642e01fSmrg TA_SERVER(); 1994642e01fSmrg 2006747b715Smrg switch(e->subtype) { 2016747b715Smrg case kXquartzControllerNotify: 2026747b715Smrg DEBUG_LOG("kXquartzControllerNotify\n"); 2036747b715Smrg AppleWMSendEvent(AppleWMControllerNotify, 2046747b715Smrg AppleWMControllerNotifyMask, 2056747b715Smrg e->data[0], 2066747b715Smrg e->data[1]); 2076747b715Smrg break; 2086747b715Smrg 2096747b715Smrg case kXquartzPasteboardNotify: 2106747b715Smrg DEBUG_LOG("kXquartzPasteboardNotify\n"); 2116747b715Smrg AppleWMSendEvent(AppleWMPasteboardNotify, 2126747b715Smrg AppleWMPasteboardNotifyMask, 2136747b715Smrg e->data[0], 2146747b715Smrg e->data[1]); 2156747b715Smrg break; 2166747b715Smrg 2176747b715Smrg case kXquartzActivate: 2186747b715Smrg DEBUG_LOG("kXquartzActivate\n"); 2196747b715Smrg QuartzShow(); 2206747b715Smrg AppleWMSendEvent(AppleWMActivationNotify, 2216747b715Smrg AppleWMActivationNotifyMask, 2226747b715Smrg AppleWMIsActive, 0); 2236747b715Smrg break; 2246747b715Smrg 2256747b715Smrg case kXquartzDeactivate: 2266747b715Smrg DEBUG_LOG("kXquartzDeactivate\n"); 2276747b715Smrg AppleWMSendEvent(AppleWMActivationNotify, 2286747b715Smrg AppleWMActivationNotifyMask, 2296747b715Smrg AppleWMIsInactive, 0); 2306747b715Smrg QuartzHide(); 2316747b715Smrg break; 2326747b715Smrg 2336747b715Smrg case kXquartzReloadPreferences: 2346747b715Smrg DEBUG_LOG("kXquartzReloadPreferences\n"); 2356747b715Smrg AppleWMSendEvent(AppleWMActivationNotify, 2366747b715Smrg AppleWMActivationNotifyMask, 2376747b715Smrg AppleWMReloadPreferences, 0); 2386747b715Smrg break; 2396747b715Smrg 2406747b715Smrg case kXquartzToggleFullscreen: 2416747b715Smrg DEBUG_LOG("kXquartzToggleFullscreen\n"); 2426747b715Smrg if(XQuartzIsRootless) 2436747b715Smrg ErrorF("Ignoring kXquartzToggleFullscreen because of rootless mode."); 2446747b715Smrg else 2456747b715Smrg QuartzRandRToggleFullscreen(); 2466747b715Smrg break; 2476747b715Smrg 2486747b715Smrg case kXquartzSetRootless: 2496747b715Smrg DEBUG_LOG("kXquartzSetRootless\n"); 2506747b715Smrg if(e->data[0]) { 2516747b715Smrg QuartzRandRSetFakeRootless(); 2526747b715Smrg } else { 2536747b715Smrg QuartzRandRSetFakeFullscreen(FALSE); 2546747b715Smrg } 2556747b715Smrg break; 2566747b715Smrg 2576747b715Smrg case kXquartzSetRootClip: 2586747b715Smrg QuartzSetRootClip((Bool)e->data[0]); 2596747b715Smrg break; 2606747b715Smrg 2616747b715Smrg case kXquartzQuit: 2626747b715Smrg GiveUp(0); 2636747b715Smrg break; 2646747b715Smrg 2656747b715Smrg case kXquartzSpaceChanged: 2666747b715Smrg DEBUG_LOG("kXquartzSpaceChanged\n"); 2676747b715Smrg QuartzSpaceChanged(e->data[0]); 2686747b715Smrg break; 2696747b715Smrg 2706747b715Smrg case kXquartzListenOnOpenFD: 2716747b715Smrg ErrorF("Calling ListenOnOpenFD() for new fd: %d\n", (int)e->data[0]); 2726747b715Smrg ListenOnOpenFD((int)e->data[0], 1); 2736747b715Smrg break; 2746747b715Smrg 2756747b715Smrg case kXquartzReloadKeymap: 2766747b715Smrg DarwinKeyboardReloadHandler(); 2776747b715Smrg break; 2786747b715Smrg 2796747b715Smrg case kXquartzDisplayChanged: 2806747b715Smrg DEBUG_LOG("kXquartzDisplayChanged\n"); 2816747b715Smrg QuartzUpdateScreens(); 2826747b715Smrg#ifdef RANDR 2836747b715Smrg /* Update our RandR info */ 2846747b715Smrg QuartzRandRUpdateFakeModes(TRUE); 2856747b715Smrg#endif 2866747b715Smrg break; 2876747b715Smrg 2886747b715Smrg default: 2896747b715Smrg if(!QuartzModeEventHandler(screenNum, e, dev)) 2906747b715Smrg ErrorF("Unknown application defined event type %d.\n", e->subtype); 2916747b715Smrg } 2924642e01fSmrg} 2934642e01fSmrg 2944642e01fSmrgvoid DarwinListenOnOpenFD(int fd) { 2954642e01fSmrg ErrorF("DarwinListenOnOpenFD: %d\n", fd); 2964642e01fSmrg 2974642e01fSmrg pthread_mutex_lock(&fd_add_lock); 2984642e01fSmrg if(fd_add_count < FD_ADD_MAX) 2994642e01fSmrg fd_add[fd_add_count++] = fd; 3004642e01fSmrg else 3014642e01fSmrg ErrorF("FD Addition buffer at max. Dropping fd addition request.\n"); 3024642e01fSmrg 3034642e01fSmrg pthread_cond_broadcast(&fd_add_ready_cond); 3044642e01fSmrg pthread_mutex_unlock(&fd_add_lock); 3054642e01fSmrg} 3064642e01fSmrg 3074642e01fSmrgstatic void DarwinProcessFDAdditionQueue_thread(void *args) { 3084642e01fSmrg pthread_mutex_lock(&fd_add_lock); 3094642e01fSmrg while(true) { 3104642e01fSmrg while(fd_add_count) { 3114642e01fSmrg DarwinSendDDXEvent(kXquartzListenOnOpenFD, 1, fd_add[--fd_add_count]); 3124642e01fSmrg } 3134642e01fSmrg pthread_cond_wait(&fd_add_ready_cond, &fd_add_lock); 3144642e01fSmrg } 3154642e01fSmrg} 3164642e01fSmrg 3176747b715SmrgBool DarwinEQInit(void) { 3186747b715Smrg int *p; 3196747b715Smrg 3206747b715Smrg for(p=darwin_x11_modifier_mask_list, darwin_all_modifier_mask=0; *p; p++) { 3216747b715Smrg darwin_x11_modifier_mask |= *p; 3226747b715Smrg } 3234642e01fSmrg 3246747b715Smrg for(p=darwin_all_modifier_mask_additions, darwin_all_modifier_mask= darwin_x11_modifier_mask; *p; p++) { 3256747b715Smrg darwin_all_modifier_mask |= *p; 3264642e01fSmrg } 3274642e01fSmrg 3286747b715Smrg mieqInit(); 3296747b715Smrg mieqSetHandler(ET_XQuartz, DarwinEventHandler); 3304642e01fSmrg 3314642e01fSmrg /* Note that this *could* cause a potential async issue, since we're checking 3324642e01fSmrg * darwinEvents without holding the lock, but darwinEvents is only ever set 3334642e01fSmrg * here, so I don't bother. 3344642e01fSmrg */ 3354642e01fSmrg if (!darwinEvents) { 3364642e01fSmrg darwinEvents = InitEventList(GetMaximumEventsNum());; 3374642e01fSmrg 3384642e01fSmrg if (!darwinEvents) 3394642e01fSmrg FatalError("Couldn't allocate event buffer\n"); 3404642e01fSmrg 3414642e01fSmrg darwinEvents_lock(); 3424642e01fSmrg pthread_cond_broadcast(&mieq_ready_cond); 3434642e01fSmrg darwinEvents_unlock(); 3444642e01fSmrg } 3454642e01fSmrg 3464642e01fSmrg if(!fd_add_tid) 3474642e01fSmrg fd_add_tid = create_thread(DarwinProcessFDAdditionQueue_thread, NULL); 3484642e01fSmrg 3494642e01fSmrg return TRUE; 3504642e01fSmrg} 3514642e01fSmrg 3524642e01fSmrg/* 3534642e01fSmrg * ProcessInputEvents 3544642e01fSmrg * Read and process events from the event queue until it is empty. 3554642e01fSmrg */ 3564642e01fSmrgvoid ProcessInputEvents(void) { 3576747b715Smrg char nullbyte; 3586747b715Smrg int x = sizeof(nullbyte); 3594642e01fSmrg 3604642e01fSmrg TA_SERVER(); 3614642e01fSmrg 3624642e01fSmrg mieqProcessInputEvents(); 3634642e01fSmrg 3644642e01fSmrg // Empty the signaling pipe 3656747b715Smrg while (x == sizeof(nullbyte)) { 3666747b715Smrg x = read(darwinEventReadFD, &nullbyte, sizeof(nullbyte)); 3674642e01fSmrg } 3684642e01fSmrg} 3694642e01fSmrg 3704642e01fSmrg/* Sends a null byte down darwinEventWriteFD, which will cause the 3714642e01fSmrg Dispatch() event loop to check out event queue */ 3724642e01fSmrgstatic void DarwinPokeEQ(void) { 3734642e01fSmrg char nullbyte=0; 3744642e01fSmrg // <daniels> oh, i ... er ... christ. 3756747b715Smrg write(darwinEventWriteFD, &nullbyte, sizeof(nullbyte)); 3764642e01fSmrg} 3774642e01fSmrg 3784642e01fSmrg/* Convert from Appkit pointer input values to X input values: 3794642e01fSmrg * Note: pointer_x and pointer_y are relative to the upper-left of primary 3804642e01fSmrg * display. 3814642e01fSmrg */ 3824642e01fSmrgstatic void DarwinPrepareValuators(DeviceIntPtr pDev, int *valuators, ScreenPtr screen, 3834642e01fSmrg float pointer_x, float pointer_y, 3844642e01fSmrg float pressure, float tilt_x, float tilt_y) { 3854642e01fSmrg /* Fix offset between darwin and X screens */ 3866747b715Smrg pointer_x -= darwinMainScreenX + screen->x; 3876747b715Smrg pointer_y -= darwinMainScreenY + screen->y; 3884642e01fSmrg 3894642e01fSmrg if(pointer_x < 0.0) 3904642e01fSmrg pointer_x = 0.0; 3914642e01fSmrg 3924642e01fSmrg if(pointer_y < 0.0) 3934642e01fSmrg pointer_y = 0.0; 3944642e01fSmrg 3954642e01fSmrg if(pDev == darwinPointer) { 3964642e01fSmrg valuators[0] = pointer_x; 3974642e01fSmrg valuators[1] = pointer_y; 3984642e01fSmrg valuators[2] = 0; 3994642e01fSmrg valuators[3] = 0; 4004642e01fSmrg valuators[4] = 0; 4014642e01fSmrg } else { 4024642e01fSmrg /* Setup our array of values */ 4034642e01fSmrg valuators[0] = XQUARTZ_VALUATOR_LIMIT * (pointer_x / (float)screenInfo.screens[0]->width); 4044642e01fSmrg valuators[1] = XQUARTZ_VALUATOR_LIMIT * (pointer_y / (float)screenInfo.screens[0]->height); 4054642e01fSmrg valuators[2] = XQUARTZ_VALUATOR_LIMIT * pressure; 4064642e01fSmrg valuators[3] = XQUARTZ_VALUATOR_LIMIT * tilt_x; 4074642e01fSmrg valuators[4] = XQUARTZ_VALUATOR_LIMIT * tilt_y; 4084642e01fSmrg } 4094642e01fSmrg //DEBUG_LOG("Pointer (%f, %f), Valuators: {%d,%d,%d,%d,%d}\n", pointer_x, pointer_y, 4104642e01fSmrg // valuators[0], valuators[1], valuators[2], valuators[3], valuators[4]); 4114642e01fSmrg} 4124642e01fSmrg 4134642e01fSmrgvoid DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y, 4144642e01fSmrg float pressure, float tilt_x, float tilt_y) { 4154642e01fSmrg static int darwinFakeMouseButtonDown = 0; 4164642e01fSmrg int i, num_events; 4174642e01fSmrg ScreenPtr screen; 4184642e01fSmrg int valuators[5]; 4194642e01fSmrg 4204642e01fSmrg //DEBUG_LOG("x=%f, y=%f, p=%f, tx=%f, ty=%f\n", pointer_x, pointer_y, pressure, tilt_x, tilt_y); 4214642e01fSmrg 4224642e01fSmrg if(!darwinEvents) { 4234642e01fSmrg DEBUG_LOG("DarwinSendPointerEvents called before darwinEvents was initialized\n"); 4244642e01fSmrg return; 4254642e01fSmrg } 4264642e01fSmrg 4274642e01fSmrg screen = miPointerGetScreen(pDev); 4284642e01fSmrg if(!screen) { 4294642e01fSmrg DEBUG_LOG("DarwinSendPointerEvents called before screen was initialized\n"); 4304642e01fSmrg return; 4314642e01fSmrg } 4324642e01fSmrg 4334642e01fSmrg /* Handle fake click */ 4344642e01fSmrg if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) { 4354642e01fSmrg if(darwinFakeMouseButtonDown != 0) { 4364642e01fSmrg /* We're currently "down" with another button, so release it first */ 4374642e01fSmrg DarwinSendPointerEvents(pDev, ButtonRelease, darwinFakeMouseButtonDown, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 4384642e01fSmrg darwinFakeMouseButtonDown=0; 4394642e01fSmrg } 4406747b715Smrg if (darwin_all_modifier_flags & darwinFakeMouse2Mask) { 4414642e01fSmrg ev_button = 2; 4424642e01fSmrg darwinFakeMouseButtonDown = 2; 4436747b715Smrg DarwinUpdateModKeys(darwin_all_modifier_flags & ~darwinFakeMouse2Mask); 4446747b715Smrg } else if (darwin_all_modifier_flags & darwinFakeMouse3Mask) { 4454642e01fSmrg ev_button = 3; 4464642e01fSmrg darwinFakeMouseButtonDown = 3; 4476747b715Smrg DarwinUpdateModKeys(darwin_all_modifier_flags & ~darwinFakeMouse3Mask); 4484642e01fSmrg } 4494642e01fSmrg } 4504642e01fSmrg 4514642e01fSmrg if (ev_type == ButtonRelease && ev_button == 1) { 4524642e01fSmrg if(darwinFakeMouseButtonDown) { 4534642e01fSmrg ev_button = darwinFakeMouseButtonDown; 4544642e01fSmrg } 4554642e01fSmrg 4564642e01fSmrg if(darwinFakeMouseButtonDown == 2) { 4576747b715Smrg DarwinUpdateModKeys(darwin_all_modifier_flags & ~darwinFakeMouse2Mask); 4584642e01fSmrg } else if(darwinFakeMouseButtonDown == 3) { 4596747b715Smrg DarwinUpdateModKeys(darwin_all_modifier_flags & ~darwinFakeMouse3Mask); 4604642e01fSmrg } 4614642e01fSmrg 4624642e01fSmrg darwinFakeMouseButtonDown = 0; 4634642e01fSmrg } 4644642e01fSmrg 4654642e01fSmrg DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 4664642e01fSmrg darwinEvents_lock(); { 4674642e01fSmrg num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button, 4684642e01fSmrg POINTER_ABSOLUTE, 0, pDev==darwinTabletCurrent?5:2, valuators); 4696747b715Smrg for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event); 4706747b715Smrg if(num_events > 0) DarwinPokeEQ(); 4714642e01fSmrg } darwinEvents_unlock(); 4724642e01fSmrg} 4734642e01fSmrg 4744642e01fSmrgvoid DarwinSendKeyboardEvents(int ev_type, int keycode) { 4754642e01fSmrg int i, num_events; 4764642e01fSmrg 4774642e01fSmrg if(!darwinEvents) { 4784642e01fSmrg DEBUG_LOG("DarwinSendKeyboardEvents called before darwinEvents was initialized\n"); 4794642e01fSmrg return; 4804642e01fSmrg } 4814642e01fSmrg 4824642e01fSmrg darwinEvents_lock(); { 4834642e01fSmrg num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE); 4846747b715Smrg for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard, (InternalEvent*)darwinEvents[i].event); 4856747b715Smrg if(num_events > 0) DarwinPokeEQ(); 4864642e01fSmrg } darwinEvents_unlock(); 4874642e01fSmrg} 4884642e01fSmrg 4894642e01fSmrgvoid DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y) { 4904642e01fSmrg int i, num_events; 4914642e01fSmrg ScreenPtr screen; 4924642e01fSmrg DeviceIntPtr pDev = darwinTabletCurrent; 4934642e01fSmrg int valuators[5]; 4944642e01fSmrg 4954642e01fSmrg DEBUG_LOG("DarwinSendProximityEvents(%d, %f, %f)\n", ev_type, pointer_x, pointer_y); 4964642e01fSmrg 4974642e01fSmrg if(!darwinEvents) { 4984642e01fSmrg DEBUG_LOG("DarwinSendProximityEvents called before darwinEvents was initialized\n"); 4994642e01fSmrg return; 5004642e01fSmrg } 5014642e01fSmrg 5024642e01fSmrg screen = miPointerGetScreen(pDev); 5034642e01fSmrg if(!screen) { 5044642e01fSmrg DEBUG_LOG("DarwinSendPointerEvents called before screen was initialized\n"); 5054642e01fSmrg return; 5064642e01fSmrg } 5074642e01fSmrg 5084642e01fSmrg DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, 0.0f, 0.0f, 0.0f); 5094642e01fSmrg darwinEvents_lock(); { 5104642e01fSmrg num_events = GetProximityEvents(darwinEvents, pDev, ev_type, 5114642e01fSmrg 0, 5, valuators); 5126747b715Smrg for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event); 5136747b715Smrg if(num_events > 0) DarwinPokeEQ(); 5144642e01fSmrg } darwinEvents_unlock(); 5154642e01fSmrg} 5164642e01fSmrg 5174642e01fSmrg 5184642e01fSmrg/* Send the appropriate number of button clicks to emulate scroll wheel */ 5194642e01fSmrgvoid DarwinSendScrollEvents(float count_x, float count_y, 5204642e01fSmrg float pointer_x, float pointer_y, 5214642e01fSmrg float pressure, float tilt_x, float tilt_y) { 5226747b715Smrg int sign_x, sign_y; 5234642e01fSmrg if(!darwinEvents) { 5244642e01fSmrg DEBUG_LOG("DarwinSendScrollEvents called before darwinEvents was initialized\n"); 5254642e01fSmrg return; 5264642e01fSmrg } 5274642e01fSmrg 5286747b715Smrg sign_x = count_x > 0.0f ? SCROLLWHEELLEFTFAKE : SCROLLWHEELRIGHTFAKE; 5296747b715Smrg sign_y = count_y > 0.0f ? SCROLLWHEELUPFAKE : SCROLLWHEELDOWNFAKE; 5304642e01fSmrg count_x = fabs(count_x); 5314642e01fSmrg count_y = fabs(count_y); 5324642e01fSmrg 5334642e01fSmrg while ((count_x > 0.0f) || (count_y > 0.0f)) { 5344642e01fSmrg if (count_x > 0.0f) { 5354642e01fSmrg DarwinSendPointerEvents(darwinPointer, ButtonPress, sign_x, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 5364642e01fSmrg DarwinSendPointerEvents(darwinPointer, ButtonRelease, sign_x, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 5374642e01fSmrg count_x = count_x - 1.0f; 5384642e01fSmrg } 5394642e01fSmrg if (count_y > 0.0f) { 5404642e01fSmrg DarwinSendPointerEvents(darwinPointer, ButtonPress, sign_y, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 5414642e01fSmrg DarwinSendPointerEvents(darwinPointer, ButtonRelease, sign_y, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 5424642e01fSmrg count_y = count_y - 1.0f; 5434642e01fSmrg } 5444642e01fSmrg } 5454642e01fSmrg} 5464642e01fSmrg 5474642e01fSmrg/* Send the appropriate KeyPress/KeyRelease events to GetKeyboardEvents to 5484642e01fSmrg reflect changing modifier flags (alt, control, meta, etc) */ 5494642e01fSmrgvoid DarwinUpdateModKeys(int flags) { 5506747b715Smrg DarwinUpdateModifiers(KeyRelease, darwin_all_modifier_flags & ~flags & darwin_x11_modifier_mask); 5516747b715Smrg DarwinUpdateModifiers(KeyPress, ~darwin_all_modifier_flags & flags & darwin_x11_modifier_mask); 5526747b715Smrg darwin_all_modifier_flags = flags; 5534642e01fSmrg} 5544642e01fSmrg 5554642e01fSmrg/* 5564642e01fSmrg * DarwinSendDDXEvent 5574642e01fSmrg * Send the X server thread a message by placing it on the event queue. 5584642e01fSmrg */ 5594642e01fSmrgvoid DarwinSendDDXEvent(int type, int argc, ...) { 5606747b715Smrg XQuartzEvent e; 5616747b715Smrg int i; 5624642e01fSmrg va_list args; 5634642e01fSmrg 5646747b715Smrg memset(&e, 0, sizeof(e)); 5656747b715Smrg e.header = ET_Internal; 5666747b715Smrg e.type = ET_XQuartz; 5676747b715Smrg e.length = sizeof(e); 5686747b715Smrg e.time = GetTimeInMillis(); 5696747b715Smrg e.subtype = type; 5704642e01fSmrg 5716747b715Smrg if (argc > 0 && argc < XQUARTZ_EVENT_MAXARGS) { 5724642e01fSmrg va_start (args, argc); 5734642e01fSmrg for (i = 0; i < argc; i++) 5746747b715Smrg e.data[i] = (uint32_t) va_arg (args, uint32_t); 5754642e01fSmrg va_end (args); 5764642e01fSmrg } 5774642e01fSmrg 5784642e01fSmrg darwinEvents_lock(); { 5796747b715Smrg mieqEnqueue(NULL, (InternalEvent*)&e); 5804642e01fSmrg DarwinPokeEQ(); 5814642e01fSmrg } darwinEvents_unlock(); 5824642e01fSmrg} 583