Module: wine Branch: master Commit: 5c933c89ad1bddf44768085c0d3b22a2a936db3a URL: http://source.winehq.org/git/wine.git/?a=commit;h=5c933c89ad1bddf44768085c0d...
Author: Ken Thomases ken@codeweavers.com Date: Sun Feb 24 22:53:47 2013 -0600
winemac: Implement SetCursorPos().
---
dlls/winemac.drv/cocoa_app.h | 2 + dlls/winemac.drv/cocoa_app.m | 53 +++++++++++++++++++++++++++++++++++++ dlls/winemac.drv/macdrv_cocoa.h | 1 + dlls/winemac.drv/mouse.c | 14 ++++++++++ dlls/winemac.drv/winemac.drv.spec | 1 + 5 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h index 32e4180..3567595 100644 --- a/dlls/winemac.drv/cocoa_app.h +++ b/dlls/winemac.drv/cocoa_app.h @@ -58,6 +58,8 @@ int cursorFrame; NSTimer* cursorTimer; BOOL cursorHidden; + + NSTimeInterval lastSetCursorPositionTime; }
@property (nonatomic) CGEventSourceKeyboardType keyboardType; diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index 3744498..f1ad0bc 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -548,6 +548,31 @@ int macdrv_err_on; } }
+ - (BOOL) setCursorPosition:(CGPoint)pos + { + BOOL ret; + + ret = (CGWarpMouseCursorPosition(pos) == kCGErrorSuccess); + if (ret) + { + WineEventQueue* queue; + + lastSetCursorPositionTime = [[NSProcessInfo processInfo] systemUptime]; + + // Discard all pending mouse move events. + [eventQueuesLock lock]; + for (queue in eventQueues) + { + [queue discardEventsMatchingMask:event_mask_for_type(MOUSE_MOVED) | + event_mask_for_type(MOUSE_MOVED_ABSOLUTE) + forWindow:nil]; + } + [eventQueuesLock unlock]; + } + + return ret; + } +
/* * ---------- NSApplication method overrides ---------- @@ -587,6 +612,17 @@ int macdrv_err_on; BOOL absolute = forceNextMouseMoveAbsolute || (targetWindow != lastTargetWindow); forceNextMouseMoveAbsolute = FALSE;
+ // If we recently warped the cursor, discard mouse move events until + // we see an event which is later than that time. + if (lastSetCursorPositionTime) + { + if ([anEvent timestamp] <= lastSetCursorPositionTime) + return; + + lastSetCursorPositionTime = 0; + absolute = TRUE; + } + [targetWindow postMouseMovedEvent:anEvent absolute:absolute]; lastTargetWindow = targetWindow; } @@ -893,3 +929,20 @@ int macdrv_get_cursor_position(CGPoint *pos)
return TRUE; } + +/*********************************************************************** + * macdrv_set_cursor_position + * + * Sets the cursor position without generating events. Returns zero on + * failure, non-zero on success. + */ +int macdrv_set_cursor_position(CGPoint pos) +{ + __block int ret; + + OnMainThread(^{ + ret = [NSApp setCursorPosition:pos]; + }); + + return ret; +} diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index c3ad6ba..16f5595 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -121,6 +121,7 @@ extern void macdrv_beep(void) DECLSPEC_HIDDEN; /* cursor */ extern void macdrv_set_cursor(CFStringRef name, CFArrayRef frames) DECLSPEC_HIDDEN; extern int macdrv_get_cursor_position(CGPoint *pos) DECLSPEC_HIDDEN; +extern int macdrv_set_cursor_position(CGPoint pos) DECLSPEC_HIDDEN;
/* display */ diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c index b0288f6..d38a316 100644 --- a/dlls/winemac.drv/mouse.c +++ b/dlls/winemac.drv/mouse.c @@ -848,6 +848,20 @@ done:
/*********************************************************************** + * SetCursorPos (MACDRV.@) + */ +BOOL CDECL macdrv_SetCursorPos(INT x, INT y) +{ + BOOL ret = macdrv_set_cursor_position(CGPointMake(x, y)); + if (ret) + TRACE("warped to %d,%d\n", x, y); + else + ERR("failed to warp to %d,%d\n", x, y); + return ret; +} + + +/*********************************************************************** * macdrv_mouse_button * * Handler for MOUSE_BUTTON events. diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec index 99746b4..87cd0ee 100644 --- a/dlls/winemac.drv/winemac.drv.spec +++ b/dlls/winemac.drv/winemac.drv.spec @@ -22,6 +22,7 @@ @ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) macdrv_MsgWaitForMultipleObjectsEx @ cdecl ScrollDC(long long long ptr ptr long ptr) macdrv_ScrollDC @ cdecl SetCursor(long) macdrv_SetCursor +@ cdecl SetCursorPos(long long) macdrv_SetCursorPos @ cdecl SetFocus(long) macdrv_SetFocus @ cdecl SetLayeredWindowAttributes(long long long long) macdrv_SetLayeredWindowAttributes @ cdecl SetParent(long long long) macdrv_SetParent