21#include "../../SDL_internal.h"
23#if SDL_VIDEO_DRIVER_COCOA
36#include "../../thread/SDL_systhread.h"
38#include "../../events/SDL_mouse_c.h"
43 CFRunLoopSourceRef runloopSource;
45 SDL_sem *runloopStartedSemaphore;
46} SDL_MouseEventTapData;
48static const CGEventMask movementEventsMask =
49 CGEventMaskBit(kCGEventLeftMouseDragged)
50 | CGEventMaskBit(kCGEventRightMouseDragged)
51 | CGEventMaskBit(kCGEventMouseMoved);
53static const CGEventMask allGrabbedEventsMask =
54 CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp)
55 | CGEventMaskBit(kCGEventRightMouseDown) | CGEventMaskBit(kCGEventRightMouseUp)
56 | CGEventMaskBit(kCGEventOtherMouseDown) | CGEventMaskBit(kCGEventOtherMouseUp)
57 | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged)
58 | CGEventMaskBit(kCGEventMouseMoved);
61Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType
type, CGEventRef
event,
void *refcon)
63 SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)refcon;
68 CGPoint eventLocation;
71 case kCGEventTapDisabledByTimeout:
73 CGEventTapEnable(tapdata->tap,
true);
76 case kCGEventTapDisabledByUserInput:
99 eventLocation = CGEventGetUnflippedLocation(
event);
100 windowRect = [nswindow contentRectForFrameRect:[nswindow frame]];
102 if (!NSMouseInRect(NSPointFromCGPoint(eventLocation), windowRect, NO)) {
107 CGPoint newLocation = CGEventGetLocation(
event);
109 if (eventLocation.x < NSMinX(windowRect)) {
110 newLocation.x = NSMinX(windowRect);
111 }
else if (eventLocation.x >= NSMaxX(windowRect)) {
112 newLocation.x = NSMaxX(windowRect) - 1.0;
115 if (eventLocation.y <= NSMinY(windowRect)) {
116 newLocation.y -= (NSMinY(windowRect) - eventLocation.
y + 1);
117 }
else if (eventLocation.y > NSMaxY(windowRect)) {
118 newLocation.y += (eventLocation.
y - NSMaxY(windowRect));
121 CGWarpMouseCursorPosition(newLocation);
122 CGAssociateMouseAndMouseCursorPosition(YES);
124 if ((CGEventMaskBit(
type) & movementEventsMask) == 0) {
130 CGEventSetLocation(
event, newLocation);
138SemaphorePostCallback(CFRunLoopTimerRef timer,
void *info)
144Cocoa_MouseTapThread(
void *
data)
146 SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)
data;
149 CFMachPortRef eventTap = tapdata->tap;
152 CFRunLoopSourceRef runloopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
154 tapdata->runloopSource = runloopSource;
170 tapdata->runloop = CFRunLoopGetCurrent();
171 CFRunLoopAddSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes);
172 CFRunLoopTimerContext
context = {.info = tapdata->runloopStartedSemaphore};
174 CFRunLoopTimerRef timer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0, 0, 0, &SemaphorePostCallback, &
context);
175 CFRunLoopAddTimer(tapdata->runloop, timer, kCFRunLoopCommonModes);
181 if (
SDL_SemValue(tapdata->runloopStartedSemaphore) < 1) {
184 CFRunLoopRemoveSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes);
187 CGEventTapEnable(tapdata->tap,
false);
188 CFRelease(tapdata->runloopSource);
189 CFRelease(tapdata->tap);
190 tapdata->runloopSource =
NULL;
199 SDL_MouseEventTapData *tapdata;
201 tapdata = (SDL_MouseEventTapData*)driverdata->
tapdata;
204 if (tapdata->runloopStartedSemaphore) {
205 tapdata->tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
206 kCGEventTapOptionDefault, allGrabbedEventsMask,
207 &Cocoa_MouseTapCallback, tapdata);
210 CGEventTapEnable(tapdata->tap,
false);
212 if (tapdata->thread) {
216 CFRelease(tapdata->tap);
227 SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->
tapdata;
228 if (tapdata && tapdata->tap)
230 CGEventTapEnable(tapdata->tap, !!
enabled);
237 SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->
tapdata;
240 if (tapdata ==
NULL) {
255 CFRunLoopStop(tapdata->runloop);
void Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
void Cocoa_InitMouseEventTap(SDL_MouseData *driverdata)
void Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
#define SDL_GetKeyboardFocus
#define SDL_SemWaitTimeout
#define SDL_DestroySemaphore
#define SDL_CreateSemaphore
SDL_Mouse * SDL_GetMouse(void)
GLint GLint GLint GLint GLint GLint y
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLuint GLuint GLsizei GLenum type
GLenum GLenum GLsizei const GLuint GLboolean enabled
SDL_Thread * SDL_CreateThreadInternal(int(*fn)(void *), const char *name, const size_t stacksize, void *data)
@ SDL_WINDOW_INPUT_GRABBED
EGLSurface EGLNativeWindowType * window
The type used to identify a window.
static screen_context_t context