Module: wine Branch: master Commit: 3748c3930837dcdd93c01f19cf6992e359dc6720 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3748c3930837dcdd93c01f19cf...
Author: Ken Thomases ken@codeweavers.com Date: Sun Feb 10 19:09:12 2013 -0600
winemac: Implement MOUSE_SCROLL events.
---
dlls/winemac.drv/cocoa_window.m | 78 +++++++++++++++++++++++++++++++++++++++ dlls/winemac.drv/event.c | 7 +++ dlls/winemac.drv/macdrv.h | 1 + dlls/winemac.drv/macdrv_cocoa.h | 8 ++++ dlls/winemac.drv/mouse.c | 21 ++++++++++ 5 files changed, 115 insertions(+), 0 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index bd6f086..218ba3f 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -778,6 +778,84 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers) - (void) rightMouseDragged:(NSEvent *)theEvent { [self postMouseMovedEvent:theEvent]; } - (void) otherMouseDragged:(NSEvent *)theEvent { [self postMouseMovedEvent:theEvent]; }
+ - (void) scrollWheel:(NSEvent *)theEvent + { + CGPoint pt; + macdrv_event event; + CGEventRef cgevent; + CGFloat x, y; + BOOL continuous = FALSE; + + cgevent = [theEvent CGEvent]; + pt = CGEventGetLocation(cgevent); + + event.type = MOUSE_SCROLL; + event.window = (macdrv_window)[self retain]; + event.mouse_scroll.x = pt.x; + event.mouse_scroll.y = pt.y; + event.mouse_scroll.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; + + if (CGEventGetIntegerValueField(cgevent, kCGScrollWheelEventIsContinuous)) + { + continuous = TRUE; + + /* Continuous scroll wheel events come from high-precision scrolling + hardware like Apple's Magic Mouse, Mighty Mouse, and trackpads. + For these, we can get more precise data from the CGEvent API. */ + /* Axis 1 is vertical, axis 2 is horizontal. */ + x = CGEventGetDoubleValueField(cgevent, kCGScrollWheelEventPointDeltaAxis2); + y = CGEventGetDoubleValueField(cgevent, kCGScrollWheelEventPointDeltaAxis1); + } + else + { + double pixelsPerLine = 10; + CGEventSourceRef source; + + /* The non-continuous values are in units of "lines", not pixels. */ + if ((source = CGEventCreateSourceFromEvent(cgevent))) + { + pixelsPerLine = CGEventSourceGetPixelsPerLine(source); + CFRelease(source); + } + + x = pixelsPerLine * [theEvent deltaX]; + y = pixelsPerLine * [theEvent deltaY]; + } + + /* Mac: negative is right or down, positive is left or up. + Win32: negative is left or down, positive is right or up. + So, negate the X scroll value to translate. */ + x = -x; + + /* The x,y values so far are in pixels. Win32 expects to receive some + fraction of WHEEL_DELTA == 120. By my estimation, that's roughly + 6 times the pixel value. */ + event.mouse_scroll.x_scroll = 6 * x; + event.mouse_scroll.y_scroll = 6 * y; + + if (!continuous) + { + /* For non-continuous "clicky" wheels, if there was any motion, make + sure there was at least WHEEL_DELTA motion. This is so, at slow + speeds where the system's acceleration curve is actually reducing the + scroll distance, the user is sure to get some action out of each click. + For example, this is important for rotating though weapons in a + first-person shooter. */ + if (0 < event.mouse_scroll.x_scroll && event.mouse_scroll.x_scroll < 120) + event.mouse_scroll.x_scroll = 120; + else if (-120 < event.mouse_scroll.x_scroll && event.mouse_scroll.x_scroll < 0) + event.mouse_scroll.x_scroll = -120; + + if (0 < event.mouse_scroll.y_scroll && event.mouse_scroll.y_scroll < 120) + event.mouse_scroll.y_scroll = 120; + else if (-120 < event.mouse_scroll.y_scroll && event.mouse_scroll.y_scroll < 0) + event.mouse_scroll.y_scroll = -120; + } + + if (event.mouse_scroll.x_scroll || event.mouse_scroll.y_scroll) + [queue postEvent:&event]; + } +
/* * ---------- NSWindowDelegate methods ---------- diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index 1f90c04..f03fef4 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -39,6 +39,7 @@ static const char *dbgstr_event(int type) "MOUSE_BUTTON", "MOUSE_MOVED", "MOUSE_MOVED_ABSOLUTE", + "MOUSE_SCROLL", "WINDOW_CLOSE_REQUESTED", "WINDOW_DID_MINIMIZE", "WINDOW_DID_UNMINIMIZE", @@ -69,7 +70,10 @@ static macdrv_event_mask get_event_mask(DWORD mask) }
if (mask & QS_MOUSEBUTTON) + { event_mask |= event_mask_for_type(MOUSE_BUTTON); + event_mask |= event_mask_for_type(MOUSE_SCROLL); + }
if (mask & QS_MOUSEMOVE) { @@ -126,6 +130,9 @@ void macdrv_handle_event(macdrv_event *event) case MOUSE_MOVED_ABSOLUTE: macdrv_mouse_moved(hwnd, event); break; + case MOUSE_SCROLL: + macdrv_mouse_scroll(hwnd, event); + break; case WINDOW_CLOSE_REQUESTED: macdrv_window_close_requested(hwnd); break; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 5cfcb8b..8c4ce54 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -136,6 +136,7 @@ extern void macdrv_window_did_unminimize(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_mouse_button(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN; extern void macdrv_mouse_moved(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN; +extern void macdrv_mouse_scroll(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data) DECLSPEC_HIDDEN; extern void macdrv_keyboard_changed(const macdrv_event *event) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 388ffb7..23f0edf 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -132,6 +132,7 @@ enum { MOUSE_BUTTON, MOUSE_MOVED, MOUSE_MOVED_ABSOLUTE, + MOUSE_SCROLL, WINDOW_CLOSE_REQUESTED, WINDOW_DID_MINIMIZE, WINDOW_DID_UNMINIMIZE, @@ -170,6 +171,13 @@ typedef struct macdrv_event { unsigned long time_ms; } mouse_moved; struct { + int x_scroll; + int y_scroll; + int x; + int y; + unsigned long time_ms; + } mouse_scroll; + struct { CGRect frame; } window_frame_changed; struct { diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c index 4742e37..d251808 100644 --- a/dlls/winemac.drv/mouse.c +++ b/dlls/winemac.drv/mouse.c @@ -142,3 +142,24 @@ void macdrv_mouse_moved(HWND hwnd, const macdrv_event *event) send_mouse_input(hwnd, flags, event->mouse_moved.x, event->mouse_moved.y, 0, event->mouse_moved.time_ms); } + + +/*********************************************************************** + * macdrv_mouse_scroll + * + * Handler for MOUSE_SCROLL events. + */ +void macdrv_mouse_scroll(HWND hwnd, const macdrv_event *event) +{ + TRACE("win %p/%p scroll (%d,%d) at (%d,%d) time %lu (%lu ticks ago)\n", hwnd, + event->window, event->mouse_scroll.x_scroll, event->mouse_scroll.y_scroll, + event->mouse_scroll.x, event->mouse_scroll.y, + event->mouse_scroll.time_ms, (GetTickCount() - event->mouse_scroll.time_ms)); + + send_mouse_input(hwnd, MOUSEEVENTF_WHEEL | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, + event->mouse_scroll.x, event->mouse_scroll.y, + event->mouse_scroll.y_scroll, event->mouse_scroll.time_ms); + send_mouse_input(hwnd, MOUSEEVENTF_HWHEEL | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, + event->mouse_scroll.x, event->mouse_scroll.y, + event->mouse_scroll.x_scroll, event->mouse_scroll.time_ms); +}