Ken Thomases : winemac: Implement MOUSE_SCROLL events.
Alexandre Julliard
julliard at winehq.org
Mon Feb 11 13:06:31 CST 2013
Module: wine
Branch: master
Commit: 3748c3930837dcdd93c01f19cf6992e359dc6720
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3748c3930837dcdd93c01f19cf6992e359dc6720
Author: Ken Thomases <ken at 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);
+}
More information about the wine-cvs
mailing list