winemac: Implement a MOUSE_BUTTON event for mouse clicks.
This commit is contained in:
parent
a22be47fcf
commit
bd269786a5
|
@ -7,6 +7,7 @@ C_SRCS = \
|
|||
event.c \
|
||||
gdi.c \
|
||||
macdrv_main.c \
|
||||
mouse.c \
|
||||
surface.c \
|
||||
window.c
|
||||
|
||||
|
|
|
@ -158,6 +158,13 @@ - (void) drawRect:(NSRect)rect
|
|||
}
|
||||
}
|
||||
|
||||
/* By default, NSView will swallow right-clicks in an attempt to support contextual
|
||||
menus. We need to bypass that and allow the event to make it to the window. */
|
||||
- (void) rightMouseDown:(NSEvent*)theEvent
|
||||
{
|
||||
[[self window] rightMouseDown:theEvent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -417,6 +424,22 @@ - (void) setShape:(NSBezierPath*)newShape
|
|||
[self checkTransparency];
|
||||
}
|
||||
|
||||
- (void) postMouseButtonEvent:(NSEvent *)theEvent pressed:(int)pressed
|
||||
{
|
||||
CGPoint pt = CGEventGetLocation([theEvent CGEvent]);
|
||||
macdrv_event event;
|
||||
|
||||
event.type = MOUSE_BUTTON;
|
||||
event.window = (macdrv_window)[self retain];
|
||||
event.mouse_button.button = [theEvent buttonNumber];
|
||||
event.mouse_button.pressed = pressed;
|
||||
event.mouse_button.x = pt.x;
|
||||
event.mouse_button.y = pt.y;
|
||||
event.mouse_button.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]];
|
||||
|
||||
[queue postEvent:&event];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ---------- NSWindow method overrides ----------
|
||||
|
@ -445,6 +468,18 @@ - (BOOL) validateMenuItem:(NSMenuItem *)menuItem
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* ---------- NSResponder method overrides ----------
|
||||
*/
|
||||
- (void) mouseDown:(NSEvent *)theEvent { [self postMouseButtonEvent:theEvent pressed:1]; }
|
||||
- (void) rightMouseDown:(NSEvent *)theEvent { [self mouseDown:theEvent]; }
|
||||
- (void) otherMouseDown:(NSEvent *)theEvent { [self mouseDown:theEvent]; }
|
||||
|
||||
- (void) mouseUp:(NSEvent *)theEvent { [self postMouseButtonEvent:theEvent pressed:0]; }
|
||||
- (void) rightMouseUp:(NSEvent *)theEvent { [self mouseUp:theEvent]; }
|
||||
- (void) otherMouseUp:(NSEvent *)theEvent { [self mouseUp:theEvent]; }
|
||||
|
||||
|
||||
/*
|
||||
* ---------- NSWindowDelegate methods ----------
|
||||
*/
|
||||
|
|
|
@ -32,6 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(event);
|
|||
static const char *dbgstr_event(int type)
|
||||
{
|
||||
static const char * const event_names[] = {
|
||||
"MOUSE_BUTTON",
|
||||
"WINDOW_CLOSE_REQUESTED",
|
||||
"WINDOW_FRAME_CHANGED",
|
||||
};
|
||||
|
@ -50,6 +51,9 @@ static macdrv_event_mask get_event_mask(DWORD mask)
|
|||
|
||||
if ((mask & QS_ALLINPUT) == QS_ALLINPUT) return -1;
|
||||
|
||||
if (mask & QS_MOUSEBUTTON)
|
||||
event_mask |= event_mask_for_type(MOUSE_BUTTON);
|
||||
|
||||
if (mask & QS_POSTMESSAGE)
|
||||
{
|
||||
event_mask |= event_mask_for_type(WINDOW_CLOSE_REQUESTED);
|
||||
|
@ -77,6 +81,9 @@ void macdrv_handle_event(macdrv_event *event)
|
|||
|
||||
switch (event->type)
|
||||
{
|
||||
case MOUSE_BUTTON:
|
||||
macdrv_mouse_button(hwnd, event);
|
||||
break;
|
||||
case WINDOW_CLOSE_REQUESTED:
|
||||
macdrv_window_close_requested(hwnd);
|
||||
break;
|
||||
|
|
|
@ -120,4 +120,6 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
|
|||
extern void macdrv_window_close_requested(HWND hwnd) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_window_frame_changed(HWND hwnd, CGRect frame) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void macdrv_mouse_button(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_MACDRV_H */
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
|
||||
/* event */
|
||||
enum {
|
||||
MOUSE_BUTTON,
|
||||
WINDOW_CLOSE_REQUESTED,
|
||||
WINDOW_FRAME_CHANGED,
|
||||
NUM_EVENT_TYPES
|
||||
|
@ -133,6 +134,13 @@
|
|||
int type;
|
||||
macdrv_window window;
|
||||
union {
|
||||
struct {
|
||||
int button;
|
||||
int pressed;
|
||||
int x;
|
||||
int y;
|
||||
unsigned long time_ms;
|
||||
} mouse_button;
|
||||
struct {
|
||||
CGRect frame;
|
||||
} window_frame_changed;
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* MACDRV mouse driver
|
||||
*
|
||||
* Copyright 1998 Ulrich Weigand
|
||||
* Copyright 2007 Henri Verbeet
|
||||
* Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "macdrv.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/server.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(cursor);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* send_mouse_input
|
||||
*
|
||||
* Update the various window states on a mouse event.
|
||||
*/
|
||||
static void send_mouse_input(HWND hwnd, UINT flags, int x, int y,
|
||||
DWORD mouse_data, unsigned long time)
|
||||
{
|
||||
INPUT input;
|
||||
HWND top_level_hwnd;
|
||||
|
||||
top_level_hwnd = GetAncestor(hwnd, GA_ROOT);
|
||||
|
||||
if ((flags & MOUSEEVENTF_MOVE) && (flags & MOUSEEVENTF_ABSOLUTE))
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
/* update the wine server Z-order */
|
||||
SetRect(&rect, x, y, x + 1, y + 1);
|
||||
MapWindowPoints(0, top_level_hwnd, (POINT *)&rect, 2);
|
||||
|
||||
SERVER_START_REQ(update_window_zorder)
|
||||
{
|
||||
req->window = wine_server_user_handle(top_level_hwnd);
|
||||
req->rect.left = rect.left;
|
||||
req->rect.top = rect.top;
|
||||
req->rect.right = rect.right;
|
||||
req->rect.bottom = rect.bottom;
|
||||
wine_server_call(req);
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
input.mi.dx = x;
|
||||
input.mi.dy = y;
|
||||
input.mi.mouseData = mouse_data;
|
||||
input.mi.dwFlags = flags;
|
||||
input.mi.time = time;
|
||||
input.mi.dwExtraInfo = 0;
|
||||
|
||||
__wine_send_input(top_level_hwnd, &input);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_mouse_button
|
||||
*
|
||||
* Handler for MOUSE_BUTTON events.
|
||||
*/
|
||||
void macdrv_mouse_button(HWND hwnd, const macdrv_event *event)
|
||||
{
|
||||
UINT flags = 0;
|
||||
WORD data = 0;
|
||||
|
||||
TRACE("win %p button %d %s at (%d,%d) time %lu (%lu ticks ago)\n", hwnd, event->mouse_button.button,
|
||||
(event->mouse_button.pressed ? "pressed" : "released"),
|
||||
event->mouse_button.x, event->mouse_button.y,
|
||||
event->mouse_button.time_ms, (GetTickCount() - event->mouse_button.time_ms));
|
||||
|
||||
if (event->mouse_button.pressed)
|
||||
{
|
||||
switch (event->mouse_button.button)
|
||||
{
|
||||
case 0: flags |= MOUSEEVENTF_LEFTDOWN; break;
|
||||
case 1: flags |= MOUSEEVENTF_RIGHTDOWN; break;
|
||||
case 2: flags |= MOUSEEVENTF_MIDDLEDOWN; break;
|
||||
default:
|
||||
flags |= MOUSEEVENTF_XDOWN;
|
||||
data = 1 << (event->mouse_button.button - 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (event->mouse_button.button)
|
||||
{
|
||||
case 0: flags |= MOUSEEVENTF_LEFTUP; break;
|
||||
case 1: flags |= MOUSEEVENTF_RIGHTUP; break;
|
||||
case 2: flags |= MOUSEEVENTF_MIDDLEUP; break;
|
||||
default:
|
||||
flags |= MOUSEEVENTF_XUP;
|
||||
data = 1 << (event->mouse_button.button - 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
send_mouse_input(hwnd, flags | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
|
||||
event->mouse_button.x, event->mouse_button.y,
|
||||
data, event->mouse_button.time_ms);
|
||||
}
|
Loading…
Reference in New Issue