Commit bd269786 authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

winemac: Implement a MOUSE_BUTTON event for mouse clicks.

parent a22be47f
......@@ -7,6 +7,7 @@ C_SRCS = \
event.c \
gdi.c \
macdrv_main.c \
mouse.c \
surface.c \
window.c
......
......@@ -158,6 +158,13 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
}
}
/* 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 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
[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 ----------
......@@ -446,6 +469,18 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
/*
* ---------- 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 ----------
*/
- (void)windowDidMove:(NSNotification *)notification
......
......@@ -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 @@ extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL us
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 @@ extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDE
/* event */
enum {
MOUSE_BUTTON,
WINDOW_CLOSE_REQUESTED,
WINDOW_FRAME_CHANGED,
NUM_EVENT_TYPES
......@@ -134,6 +135,13 @@ typedef struct macdrv_event {
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;
};
......
/*
* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment