darwinEvents.c revision 9ace9065
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" 469ace9065Smrg#include "inpututils.h" 476747b715Smrg#include "eventstr.h" 484642e01fSmrg#include "mi.h" 494642e01fSmrg#include "scrnintstr.h" 504642e01fSmrg#include "mipointer.h" 514642e01fSmrg#include "os.h" 524642e01fSmrg 534642e01fSmrg#include "darwin.h" 544642e01fSmrg#include "quartz.h" 554642e01fSmrg#include "quartzKeyboard.h" 566747b715Smrg#include "quartzRandR.h" 574642e01fSmrg#include "darwinEvents.h" 584642e01fSmrg 594642e01fSmrg#include <sys/types.h> 604642e01fSmrg#include <sys/uio.h> 614642e01fSmrg#include <unistd.h> 624642e01fSmrg#include <pthread.h> 634642e01fSmrg#include <errno.h> 649ace9065Smrg#include <time.h> 654642e01fSmrg 664642e01fSmrg#include <IOKit/hidsystem/IOLLEvent.h> 674642e01fSmrg 684642e01fSmrg/* Fake button press/release for scroll wheel move. */ 694642e01fSmrg#define SCROLLWHEELUPFAKE 4 704642e01fSmrg#define SCROLLWHEELDOWNFAKE 5 714642e01fSmrg#define SCROLLWHEELLEFTFAKE 6 724642e01fSmrg#define SCROLLWHEELRIGHTFAKE 7 734642e01fSmrg 746747b715Smrg#include <X11/extensions/applewmconst.h> 754642e01fSmrg#include "applewmExt.h" 764642e01fSmrg 774642e01fSmrg/* FIXME: Abstract this better */ 786747b715Smrgextern Bool QuartzModeEventHandler(int screenNum, XQuartzEvent *e, DeviceIntPtr dev); 794642e01fSmrg 806747b715Smrgint darwin_all_modifier_flags = 0; // last known modifier state 816747b715Smrgint darwin_all_modifier_mask = 0; 826747b715Smrgint darwin_x11_modifier_mask = 0; 834642e01fSmrg 844642e01fSmrg#define FD_ADD_MAX 128 854642e01fSmrgstatic int fd_add[FD_ADD_MAX]; 864642e01fSmrgint fd_add_count = 0; 874642e01fSmrgstatic pthread_mutex_t fd_add_lock = PTHREAD_MUTEX_INITIALIZER; 884642e01fSmrgstatic pthread_cond_t fd_add_ready_cond = PTHREAD_COND_INITIALIZER; 894642e01fSmrgstatic pthread_t fd_add_tid = NULL; 904642e01fSmrg 916747b715Smrgstatic EventListPtr darwinEvents = NULL; 924642e01fSmrg 934642e01fSmrgstatic pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER; 944642e01fSmrgstatic pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER; 954642e01fSmrg 964642e01fSmrg/*** Pthread Magics ***/ 979ace9065Smrgstatic pthread_t create_thread(void *(*func)(void *), void *arg) { 984642e01fSmrg pthread_attr_t attr; 994642e01fSmrg pthread_t tid; 1004642e01fSmrg 1014642e01fSmrg pthread_attr_init (&attr); 1024642e01fSmrg pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM); 1034642e01fSmrg pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); 1044642e01fSmrg pthread_create (&tid, &attr, func, arg); 1054642e01fSmrg pthread_attr_destroy (&attr); 1064642e01fSmrg 1074642e01fSmrg return tid; 1084642e01fSmrg} 1094642e01fSmrg 1104642e01fSmrgvoid darwinEvents_lock(void); 1114642e01fSmrgvoid darwinEvents_lock(void) { 1124642e01fSmrg int err; 1134642e01fSmrg if((err = pthread_mutex_lock(&mieq_lock))) { 1144642e01fSmrg ErrorF("%s:%s:%d: Failed to lock mieq_lock: %d\n", 1154642e01fSmrg __FILE__, __FUNCTION__, __LINE__, err); 1164642e01fSmrg spewCallStack(); 1174642e01fSmrg } 1184642e01fSmrg if(darwinEvents == NULL) { 1194642e01fSmrg pthread_cond_wait(&mieq_ready_cond, &mieq_lock); 1204642e01fSmrg } 1214642e01fSmrg} 1224642e01fSmrg 1234642e01fSmrgvoid darwinEvents_unlock(void); 1244642e01fSmrgvoid darwinEvents_unlock(void) { 1254642e01fSmrg int err; 1264642e01fSmrg if((err = pthread_mutex_unlock(&mieq_lock))) { 1274642e01fSmrg ErrorF("%s:%s:%d: Failed to unlock mieq_lock: %d\n", 1284642e01fSmrg __FILE__, __FUNCTION__, __LINE__, err); 1294642e01fSmrg spewCallStack(); 1304642e01fSmrg } 1314642e01fSmrg} 1324642e01fSmrg 1334642e01fSmrg/* 1344642e01fSmrg * DarwinPressModifierKey 1354642e01fSmrg * Press or release the given modifier key (one of NX_MODIFIERKEY_* constants) 1364642e01fSmrg */ 1374642e01fSmrgstatic void DarwinPressModifierKey(int pressed, int key) { 1384642e01fSmrg int keycode = DarwinModifierNXKeyToNXKeycode(key, 0); 1394642e01fSmrg 1404642e01fSmrg if (keycode == 0) { 1414642e01fSmrg ErrorF("DarwinPressModifierKey bad keycode: key=%d\n", key); 1424642e01fSmrg return; 1434642e01fSmrg } 1444642e01fSmrg 1454642e01fSmrg DarwinSendKeyboardEvents(pressed, keycode); 1464642e01fSmrg} 1474642e01fSmrg 1484642e01fSmrg/* 1494642e01fSmrg * DarwinUpdateModifiers 1504642e01fSmrg * Send events to update the modifier state. 1514642e01fSmrg */ 1524642e01fSmrg 1536747b715Smrgstatic int darwin_x11_modifier_mask_list[] = { 1544642e01fSmrg#ifdef NX_DEVICELCMDKEYMASK 1554642e01fSmrg NX_DEVICELCTLKEYMASK, NX_DEVICERCTLKEYMASK, 1564642e01fSmrg NX_DEVICELSHIFTKEYMASK, NX_DEVICERSHIFTKEYMASK, 1574642e01fSmrg NX_DEVICELCMDKEYMASK, NX_DEVICERCMDKEYMASK, 1584642e01fSmrg NX_DEVICELALTKEYMASK, NX_DEVICERALTKEYMASK, 1594642e01fSmrg#else 1604642e01fSmrg NX_CONTROLMASK, NX_SHIFTMASK, NX_COMMANDMASK, NX_ALTERNATEMASK, 1614642e01fSmrg#endif 1624642e01fSmrg NX_ALPHASHIFTMASK, 1634642e01fSmrg 0 1644642e01fSmrg}; 1654642e01fSmrg 1666747b715Smrgstatic int darwin_all_modifier_mask_additions[] = { NX_SECONDARYFNMASK, }; 1676747b715Smrg 1684642e01fSmrgstatic void DarwinUpdateModifiers( 1694642e01fSmrg int pressed, // KeyPress or KeyRelease 1704642e01fSmrg int flags ) // modifier flags that have changed 1714642e01fSmrg{ 1724642e01fSmrg int *f; 1734642e01fSmrg int key; 1744642e01fSmrg 1754642e01fSmrg /* Capslock is special. This mask is the state of capslock (on/off), 1764642e01fSmrg * not the state of the button. Hopefully we can find a better solution. 1774642e01fSmrg */ 1784642e01fSmrg if(NX_ALPHASHIFTMASK & flags) { 1794642e01fSmrg DarwinPressModifierKey(KeyPress, NX_MODIFIERKEY_ALPHALOCK); 1804642e01fSmrg DarwinPressModifierKey(KeyRelease, NX_MODIFIERKEY_ALPHALOCK); 1814642e01fSmrg } 1824642e01fSmrg 1836747b715Smrg for(f=darwin_x11_modifier_mask_list; *f; f++) 1844642e01fSmrg if(*f & flags && *f != NX_ALPHASHIFTMASK) { 1854642e01fSmrg key = DarwinModifierNXMaskToNXKey(*f); 1864642e01fSmrg if(key == -1) 1874642e01fSmrg ErrorF("DarwinUpdateModifiers: Unsupported NXMask: 0x%x\n", *f); 1884642e01fSmrg else 1894642e01fSmrg DarwinPressModifierKey(pressed, key); 1904642e01fSmrg } 1914642e01fSmrg} 1924642e01fSmrg 1934642e01fSmrg/* Generic handler for Xquartz-specifc events. When possible, these should 1944642e01fSmrg be moved into their own individual functions and set as handlers using 1954642e01fSmrg mieqSetHandler. */ 1964642e01fSmrg 1976747b715Smrgstatic void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr dev) { 1986747b715Smrg XQuartzEvent *e = &(ie->xquartz_event); 1996747b715Smrg 2004642e01fSmrg TA_SERVER(); 2014642e01fSmrg 2026747b715Smrg switch(e->subtype) { 2036747b715Smrg case kXquartzControllerNotify: 2046747b715Smrg DEBUG_LOG("kXquartzControllerNotify\n"); 2056747b715Smrg AppleWMSendEvent(AppleWMControllerNotify, 2066747b715Smrg AppleWMControllerNotifyMask, 2076747b715Smrg e->data[0], 2086747b715Smrg e->data[1]); 2096747b715Smrg break; 2106747b715Smrg 2116747b715Smrg case kXquartzPasteboardNotify: 2126747b715Smrg DEBUG_LOG("kXquartzPasteboardNotify\n"); 2136747b715Smrg AppleWMSendEvent(AppleWMPasteboardNotify, 2146747b715Smrg AppleWMPasteboardNotifyMask, 2156747b715Smrg e->data[0], 2166747b715Smrg e->data[1]); 2176747b715Smrg break; 2186747b715Smrg 2196747b715Smrg case kXquartzActivate: 2206747b715Smrg DEBUG_LOG("kXquartzActivate\n"); 2216747b715Smrg QuartzShow(); 2226747b715Smrg AppleWMSendEvent(AppleWMActivationNotify, 2236747b715Smrg AppleWMActivationNotifyMask, 2246747b715Smrg AppleWMIsActive, 0); 2256747b715Smrg break; 2266747b715Smrg 2276747b715Smrg case kXquartzDeactivate: 2286747b715Smrg DEBUG_LOG("kXquartzDeactivate\n"); 2296747b715Smrg AppleWMSendEvent(AppleWMActivationNotify, 2306747b715Smrg AppleWMActivationNotifyMask, 2316747b715Smrg AppleWMIsInactive, 0); 2326747b715Smrg QuartzHide(); 2336747b715Smrg break; 2346747b715Smrg 2356747b715Smrg case kXquartzReloadPreferences: 2366747b715Smrg DEBUG_LOG("kXquartzReloadPreferences\n"); 2376747b715Smrg AppleWMSendEvent(AppleWMActivationNotify, 2386747b715Smrg AppleWMActivationNotifyMask, 2396747b715Smrg AppleWMReloadPreferences, 0); 2406747b715Smrg break; 2416747b715Smrg 2426747b715Smrg case kXquartzToggleFullscreen: 2436747b715Smrg DEBUG_LOG("kXquartzToggleFullscreen\n"); 2446747b715Smrg if(XQuartzIsRootless) 2456747b715Smrg ErrorF("Ignoring kXquartzToggleFullscreen because of rootless mode."); 2466747b715Smrg else 2476747b715Smrg QuartzRandRToggleFullscreen(); 2486747b715Smrg break; 2496747b715Smrg 2506747b715Smrg case kXquartzSetRootless: 2516747b715Smrg DEBUG_LOG("kXquartzSetRootless\n"); 2526747b715Smrg if(e->data[0]) { 2536747b715Smrg QuartzRandRSetFakeRootless(); 2546747b715Smrg } else { 2556747b715Smrg QuartzRandRSetFakeFullscreen(FALSE); 2566747b715Smrg } 2576747b715Smrg break; 2586747b715Smrg 2596747b715Smrg case kXquartzSetRootClip: 2606747b715Smrg QuartzSetRootClip((Bool)e->data[0]); 2616747b715Smrg break; 2626747b715Smrg 2636747b715Smrg case kXquartzQuit: 2646747b715Smrg GiveUp(0); 2656747b715Smrg break; 2666747b715Smrg 2676747b715Smrg case kXquartzSpaceChanged: 2686747b715Smrg DEBUG_LOG("kXquartzSpaceChanged\n"); 2696747b715Smrg QuartzSpaceChanged(e->data[0]); 2706747b715Smrg break; 2716747b715Smrg 2726747b715Smrg case kXquartzListenOnOpenFD: 2736747b715Smrg ErrorF("Calling ListenOnOpenFD() for new fd: %d\n", (int)e->data[0]); 2746747b715Smrg ListenOnOpenFD((int)e->data[0], 1); 2756747b715Smrg break; 2766747b715Smrg 2776747b715Smrg case kXquartzReloadKeymap: 2786747b715Smrg DarwinKeyboardReloadHandler(); 2796747b715Smrg break; 2806747b715Smrg 2816747b715Smrg case kXquartzDisplayChanged: 2826747b715Smrg DEBUG_LOG("kXquartzDisplayChanged\n"); 2836747b715Smrg QuartzUpdateScreens(); 2848223e2f2Smrg 2856747b715Smrg /* Update our RandR info */ 2866747b715Smrg QuartzRandRUpdateFakeModes(TRUE); 2876747b715Smrg break; 2886747b715Smrg 2896747b715Smrg default: 2906747b715Smrg if(!QuartzModeEventHandler(screenNum, e, dev)) 2916747b715Smrg ErrorF("Unknown application defined event type %d.\n", e->subtype); 2926747b715Smrg } 2934642e01fSmrg} 2944642e01fSmrg 2954642e01fSmrgvoid DarwinListenOnOpenFD(int fd) { 2964642e01fSmrg ErrorF("DarwinListenOnOpenFD: %d\n", fd); 2974642e01fSmrg 2984642e01fSmrg pthread_mutex_lock(&fd_add_lock); 2994642e01fSmrg if(fd_add_count < FD_ADD_MAX) 3004642e01fSmrg fd_add[fd_add_count++] = fd; 3014642e01fSmrg else 3024642e01fSmrg ErrorF("FD Addition buffer at max. Dropping fd addition request.\n"); 3034642e01fSmrg 3044642e01fSmrg pthread_cond_broadcast(&fd_add_ready_cond); 3054642e01fSmrg pthread_mutex_unlock(&fd_add_lock); 3064642e01fSmrg} 3074642e01fSmrg 3089ace9065Smrgstatic void *DarwinProcessFDAdditionQueue_thread(void *args) { 3099ace9065Smrg /* TODO: Possibly adjust this to no longer be a race... maybe trigger this 3109ace9065Smrg * once a client connects and claims to be the WM. 3119ace9065Smrg * 3129ace9065Smrg * From ajax: 3139ace9065Smrg * There's already an internal callback chain for setting selection [in 1.5] 3149ace9065Smrg * ownership. See the CallSelectionCallback at the bottom of 3159ace9065Smrg * ProcSetSelectionOwner, and xfixes/select.c for an example of how to hook 3169ace9065Smrg * into it. 3179ace9065Smrg */ 3189ace9065Smrg 3199ace9065Smrg struct timespec sleep_for; 3209ace9065Smrg struct timespec sleep_remaining; 3219ace9065Smrg 3229ace9065Smrg sleep_for.tv_sec = 3; 3239ace9065Smrg sleep_for.tv_nsec = 0; 3249ace9065Smrg 3259ace9065Smrg ErrorF("X11.app: DarwinProcessFDAdditionQueue_thread: Sleeping to allow xinitrc to catchup.\n"); 3269ace9065Smrg while(nanosleep(&sleep_for, &sleep_remaining) != 0) { 3279ace9065Smrg sleep_for = sleep_remaining; 3289ace9065Smrg } 3299ace9065Smrg 3304642e01fSmrg pthread_mutex_lock(&fd_add_lock); 3314642e01fSmrg while(true) { 3324642e01fSmrg while(fd_add_count) { 3334642e01fSmrg DarwinSendDDXEvent(kXquartzListenOnOpenFD, 1, fd_add[--fd_add_count]); 3344642e01fSmrg } 3354642e01fSmrg pthread_cond_wait(&fd_add_ready_cond, &fd_add_lock); 3364642e01fSmrg } 3379ace9065Smrg 3389ace9065Smrg return NULL; 3394642e01fSmrg} 3404642e01fSmrg 3416747b715SmrgBool DarwinEQInit(void) { 3426747b715Smrg int *p; 3436747b715Smrg 3446747b715Smrg for(p=darwin_x11_modifier_mask_list, darwin_all_modifier_mask=0; *p; p++) { 3456747b715Smrg darwin_x11_modifier_mask |= *p; 3466747b715Smrg } 3474642e01fSmrg 3486747b715Smrg for(p=darwin_all_modifier_mask_additions, darwin_all_modifier_mask= darwin_x11_modifier_mask; *p; p++) { 3496747b715Smrg darwin_all_modifier_mask |= *p; 3504642e01fSmrg } 3514642e01fSmrg 3526747b715Smrg mieqInit(); 3536747b715Smrg mieqSetHandler(ET_XQuartz, DarwinEventHandler); 3544642e01fSmrg 3554642e01fSmrg /* Note that this *could* cause a potential async issue, since we're checking 3564642e01fSmrg * darwinEvents without holding the lock, but darwinEvents is only ever set 3574642e01fSmrg * here, so I don't bother. 3584642e01fSmrg */ 3594642e01fSmrg if (!darwinEvents) { 3604642e01fSmrg darwinEvents = InitEventList(GetMaximumEventsNum());; 3614642e01fSmrg 3624642e01fSmrg if (!darwinEvents) 3634642e01fSmrg FatalError("Couldn't allocate event buffer\n"); 3644642e01fSmrg 3654642e01fSmrg darwinEvents_lock(); 3664642e01fSmrg pthread_cond_broadcast(&mieq_ready_cond); 3674642e01fSmrg darwinEvents_unlock(); 3684642e01fSmrg } 3694642e01fSmrg 3704642e01fSmrg if(!fd_add_tid) 3714642e01fSmrg fd_add_tid = create_thread(DarwinProcessFDAdditionQueue_thread, NULL); 3724642e01fSmrg 3734642e01fSmrg return TRUE; 3744642e01fSmrg} 3754642e01fSmrg 3764642e01fSmrg/* 3774642e01fSmrg * ProcessInputEvents 3784642e01fSmrg * Read and process events from the event queue until it is empty. 3794642e01fSmrg */ 3804642e01fSmrgvoid ProcessInputEvents(void) { 3816747b715Smrg char nullbyte; 3826747b715Smrg int x = sizeof(nullbyte); 3834642e01fSmrg 3844642e01fSmrg TA_SERVER(); 3854642e01fSmrg 3864642e01fSmrg mieqProcessInputEvents(); 3874642e01fSmrg 3884642e01fSmrg // Empty the signaling pipe 3896747b715Smrg while (x == sizeof(nullbyte)) { 3906747b715Smrg x = read(darwinEventReadFD, &nullbyte, sizeof(nullbyte)); 3914642e01fSmrg } 3924642e01fSmrg} 3934642e01fSmrg 3944642e01fSmrg/* Sends a null byte down darwinEventWriteFD, which will cause the 3954642e01fSmrg Dispatch() event loop to check out event queue */ 3964642e01fSmrgstatic void DarwinPokeEQ(void) { 3974642e01fSmrg char nullbyte=0; 3984642e01fSmrg // <daniels> oh, i ... er ... christ. 3996747b715Smrg write(darwinEventWriteFD, &nullbyte, sizeof(nullbyte)); 4004642e01fSmrg} 4014642e01fSmrg 4024642e01fSmrg/* Convert from Appkit pointer input values to X input values: 4034642e01fSmrg * Note: pointer_x and pointer_y are relative to the upper-left of primary 4044642e01fSmrg * display. 4054642e01fSmrg */ 4064642e01fSmrgstatic void DarwinPrepareValuators(DeviceIntPtr pDev, int *valuators, ScreenPtr screen, 4074642e01fSmrg float pointer_x, float pointer_y, 4084642e01fSmrg float pressure, float tilt_x, float tilt_y) { 4094642e01fSmrg /* Fix offset between darwin and X screens */ 4106747b715Smrg pointer_x -= darwinMainScreenX + screen->x; 4116747b715Smrg pointer_y -= darwinMainScreenY + screen->y; 4124642e01fSmrg 4134642e01fSmrg if(pointer_x < 0.0) 4144642e01fSmrg pointer_x = 0.0; 4154642e01fSmrg 4164642e01fSmrg if(pointer_y < 0.0) 4174642e01fSmrg pointer_y = 0.0; 4184642e01fSmrg 4194642e01fSmrg if(pDev == darwinPointer) { 4204642e01fSmrg valuators[0] = pointer_x; 4214642e01fSmrg valuators[1] = pointer_y; 4224642e01fSmrg valuators[2] = 0; 4234642e01fSmrg valuators[3] = 0; 4244642e01fSmrg valuators[4] = 0; 4254642e01fSmrg } else { 4264642e01fSmrg /* Setup our array of values */ 4274642e01fSmrg valuators[0] = XQUARTZ_VALUATOR_LIMIT * (pointer_x / (float)screenInfo.screens[0]->width); 4284642e01fSmrg valuators[1] = XQUARTZ_VALUATOR_LIMIT * (pointer_y / (float)screenInfo.screens[0]->height); 4294642e01fSmrg valuators[2] = XQUARTZ_VALUATOR_LIMIT * pressure; 4304642e01fSmrg valuators[3] = XQUARTZ_VALUATOR_LIMIT * tilt_x; 4314642e01fSmrg valuators[4] = XQUARTZ_VALUATOR_LIMIT * tilt_y; 4324642e01fSmrg } 4334642e01fSmrg //DEBUG_LOG("Pointer (%f, %f), Valuators: {%d,%d,%d,%d,%d}\n", pointer_x, pointer_y, 4344642e01fSmrg // valuators[0], valuators[1], valuators[2], valuators[3], valuators[4]); 4354642e01fSmrg} 4364642e01fSmrg 4374642e01fSmrgvoid DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y, 4384642e01fSmrg float pressure, float tilt_x, float tilt_y) { 4394642e01fSmrg static int darwinFakeMouseButtonDown = 0; 4404642e01fSmrg int i, num_events; 4414642e01fSmrg ScreenPtr screen; 4424642e01fSmrg int valuators[5]; 4434642e01fSmrg 4444642e01fSmrg //DEBUG_LOG("x=%f, y=%f, p=%f, tx=%f, ty=%f\n", pointer_x, pointer_y, pressure, tilt_x, tilt_y); 4454642e01fSmrg 4464642e01fSmrg if(!darwinEvents) { 4474642e01fSmrg DEBUG_LOG("DarwinSendPointerEvents called before darwinEvents was initialized\n"); 4484642e01fSmrg return; 4494642e01fSmrg } 4504642e01fSmrg 4514642e01fSmrg screen = miPointerGetScreen(pDev); 4524642e01fSmrg if(!screen) { 4534642e01fSmrg DEBUG_LOG("DarwinSendPointerEvents called before screen was initialized\n"); 4544642e01fSmrg return; 4554642e01fSmrg } 4564642e01fSmrg 4574642e01fSmrg /* Handle fake click */ 4584642e01fSmrg if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) { 4594642e01fSmrg if(darwinFakeMouseButtonDown != 0) { 4604642e01fSmrg /* We're currently "down" with another button, so release it first */ 4614642e01fSmrg DarwinSendPointerEvents(pDev, ButtonRelease, darwinFakeMouseButtonDown, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 4624642e01fSmrg darwinFakeMouseButtonDown=0; 4634642e01fSmrg } 4646747b715Smrg if (darwin_all_modifier_flags & darwinFakeMouse2Mask) { 4654642e01fSmrg ev_button = 2; 4664642e01fSmrg darwinFakeMouseButtonDown = 2; 4676747b715Smrg DarwinUpdateModKeys(darwin_all_modifier_flags & ~darwinFakeMouse2Mask); 4686747b715Smrg } else if (darwin_all_modifier_flags & darwinFakeMouse3Mask) { 4694642e01fSmrg ev_button = 3; 4704642e01fSmrg darwinFakeMouseButtonDown = 3; 4716747b715Smrg DarwinUpdateModKeys(darwin_all_modifier_flags & ~darwinFakeMouse3Mask); 4724642e01fSmrg } 4734642e01fSmrg } 4744642e01fSmrg 4754642e01fSmrg if (ev_type == ButtonRelease && ev_button == 1) { 4764642e01fSmrg if(darwinFakeMouseButtonDown) { 4774642e01fSmrg ev_button = darwinFakeMouseButtonDown; 4784642e01fSmrg } 4794642e01fSmrg 4804642e01fSmrg if(darwinFakeMouseButtonDown == 2) { 4816747b715Smrg DarwinUpdateModKeys(darwin_all_modifier_flags & ~darwinFakeMouse2Mask); 4824642e01fSmrg } else if(darwinFakeMouseButtonDown == 3) { 4836747b715Smrg DarwinUpdateModKeys(darwin_all_modifier_flags & ~darwinFakeMouse3Mask); 4844642e01fSmrg } 4854642e01fSmrg 4864642e01fSmrg darwinFakeMouseButtonDown = 0; 4874642e01fSmrg } 4884642e01fSmrg 4894642e01fSmrg DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 4904642e01fSmrg darwinEvents_lock(); { 4919ace9065Smrg ValuatorMask mask; 4929ace9065Smrg valuator_mask_set_range(&mask, 0, (pDev == darwinTabletCurrent) ? 5 : 2, valuators); 4934642e01fSmrg num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button, 4949ace9065Smrg POINTER_ABSOLUTE, &mask); 4956747b715Smrg for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event); 4966747b715Smrg if(num_events > 0) DarwinPokeEQ(); 4974642e01fSmrg } darwinEvents_unlock(); 4984642e01fSmrg} 4994642e01fSmrg 5004642e01fSmrgvoid DarwinSendKeyboardEvents(int ev_type, int keycode) { 5014642e01fSmrg int i, num_events; 5024642e01fSmrg 5034642e01fSmrg if(!darwinEvents) { 5044642e01fSmrg DEBUG_LOG("DarwinSendKeyboardEvents called before darwinEvents was initialized\n"); 5054642e01fSmrg return; 5064642e01fSmrg } 5074642e01fSmrg 5084642e01fSmrg darwinEvents_lock(); { 5094642e01fSmrg num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE); 5106747b715Smrg for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard, (InternalEvent*)darwinEvents[i].event); 5116747b715Smrg if(num_events > 0) DarwinPokeEQ(); 5124642e01fSmrg } darwinEvents_unlock(); 5134642e01fSmrg} 5144642e01fSmrg 5154642e01fSmrgvoid DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y) { 5164642e01fSmrg int i, num_events; 5174642e01fSmrg ScreenPtr screen; 5184642e01fSmrg DeviceIntPtr pDev = darwinTabletCurrent; 5194642e01fSmrg int valuators[5]; 5204642e01fSmrg 5214642e01fSmrg DEBUG_LOG("DarwinSendProximityEvents(%d, %f, %f)\n", ev_type, pointer_x, pointer_y); 5224642e01fSmrg 5234642e01fSmrg if(!darwinEvents) { 5244642e01fSmrg DEBUG_LOG("DarwinSendProximityEvents called before darwinEvents was initialized\n"); 5254642e01fSmrg return; 5264642e01fSmrg } 5274642e01fSmrg 5284642e01fSmrg screen = miPointerGetScreen(pDev); 5294642e01fSmrg if(!screen) { 5304642e01fSmrg DEBUG_LOG("DarwinSendPointerEvents called before screen was initialized\n"); 5314642e01fSmrg return; 5324642e01fSmrg } 5334642e01fSmrg 5344642e01fSmrg DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, 0.0f, 0.0f, 0.0f); 5354642e01fSmrg darwinEvents_lock(); { 5369ace9065Smrg ValuatorMask mask; 5379ace9065Smrg valuator_mask_set_range(&mask, 0, 5, valuators); 5389ace9065Smrg num_events = GetProximityEvents(darwinEvents, pDev, ev_type, &mask); 5396747b715Smrg for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event); 5406747b715Smrg if(num_events > 0) DarwinPokeEQ(); 5414642e01fSmrg } darwinEvents_unlock(); 5424642e01fSmrg} 5434642e01fSmrg 5444642e01fSmrg 5454642e01fSmrg/* Send the appropriate number of button clicks to emulate scroll wheel */ 5464642e01fSmrgvoid DarwinSendScrollEvents(float count_x, float count_y, 5474642e01fSmrg float pointer_x, float pointer_y, 5484642e01fSmrg float pressure, float tilt_x, float tilt_y) { 5496747b715Smrg int sign_x, sign_y; 5504642e01fSmrg if(!darwinEvents) { 5514642e01fSmrg DEBUG_LOG("DarwinSendScrollEvents called before darwinEvents was initialized\n"); 5524642e01fSmrg return; 5534642e01fSmrg } 5544642e01fSmrg 5556747b715Smrg sign_x = count_x > 0.0f ? SCROLLWHEELLEFTFAKE : SCROLLWHEELRIGHTFAKE; 5566747b715Smrg sign_y = count_y > 0.0f ? SCROLLWHEELUPFAKE : SCROLLWHEELDOWNFAKE; 5574642e01fSmrg count_x = fabs(count_x); 5584642e01fSmrg count_y = fabs(count_y); 5594642e01fSmrg 5604642e01fSmrg while ((count_x > 0.0f) || (count_y > 0.0f)) { 5614642e01fSmrg if (count_x > 0.0f) { 5624642e01fSmrg DarwinSendPointerEvents(darwinPointer, ButtonPress, sign_x, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 5634642e01fSmrg DarwinSendPointerEvents(darwinPointer, ButtonRelease, sign_x, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 5644642e01fSmrg count_x = count_x - 1.0f; 5654642e01fSmrg } 5664642e01fSmrg if (count_y > 0.0f) { 5674642e01fSmrg DarwinSendPointerEvents(darwinPointer, ButtonPress, sign_y, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 5684642e01fSmrg DarwinSendPointerEvents(darwinPointer, ButtonRelease, sign_y, pointer_x, pointer_y, pressure, tilt_x, tilt_y); 5694642e01fSmrg count_y = count_y - 1.0f; 5704642e01fSmrg } 5714642e01fSmrg } 5724642e01fSmrg} 5734642e01fSmrg 5744642e01fSmrg/* Send the appropriate KeyPress/KeyRelease events to GetKeyboardEvents to 5754642e01fSmrg reflect changing modifier flags (alt, control, meta, etc) */ 5764642e01fSmrgvoid DarwinUpdateModKeys(int flags) { 5776747b715Smrg DarwinUpdateModifiers(KeyRelease, darwin_all_modifier_flags & ~flags & darwin_x11_modifier_mask); 5786747b715Smrg DarwinUpdateModifiers(KeyPress, ~darwin_all_modifier_flags & flags & darwin_x11_modifier_mask); 5796747b715Smrg darwin_all_modifier_flags = flags; 5804642e01fSmrg} 5814642e01fSmrg 5824642e01fSmrg/* 5834642e01fSmrg * DarwinSendDDXEvent 5844642e01fSmrg * Send the X server thread a message by placing it on the event queue. 5854642e01fSmrg */ 5864642e01fSmrgvoid DarwinSendDDXEvent(int type, int argc, ...) { 5876747b715Smrg XQuartzEvent e; 5886747b715Smrg int i; 5894642e01fSmrg va_list args; 5904642e01fSmrg 5916747b715Smrg memset(&e, 0, sizeof(e)); 5926747b715Smrg e.header = ET_Internal; 5936747b715Smrg e.type = ET_XQuartz; 5946747b715Smrg e.length = sizeof(e); 5956747b715Smrg e.time = GetTimeInMillis(); 5966747b715Smrg e.subtype = type; 5974642e01fSmrg 5986747b715Smrg if (argc > 0 && argc < XQUARTZ_EVENT_MAXARGS) { 5994642e01fSmrg va_start (args, argc); 6004642e01fSmrg for (i = 0; i < argc; i++) 6016747b715Smrg e.data[i] = (uint32_t) va_arg (args, uint32_t); 6024642e01fSmrg va_end (args); 6034642e01fSmrg } 6044642e01fSmrg 6054642e01fSmrg darwinEvents_lock(); { 6066747b715Smrg mieqEnqueue(NULL, (InternalEvent*)&e); 6074642e01fSmrg DarwinPokeEQ(); 6084642e01fSmrg } darwinEvents_unlock(); 6094642e01fSmrg} 610