diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index bbdccd7c090..236ba75a9fd 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -285,43 +285,6 @@ static HWND update_mouse_state( HWND hwnd, Window window, int x, int y, unsigned } -/*********************************************************************** - * queue_raw_mouse_message - */ -static void queue_raw_mouse_message( UINT message, HWND hwnd, DWORD x, DWORD y, - DWORD data, DWORD time, DWORD extra_info, UINT injected_flags ) -{ - MSLLHOOKSTRUCT hook; - - hook.pt.x = x; - hook.pt.y = y; - hook.mouseData = MAKELONG( 0, data ); - hook.flags = injected_flags; - hook.time = time; - hook.dwExtraInfo = extra_info; - - last_time_modified = GetTickCount(); - if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook, TRUE )) - message = 0; /* ignore it */ - - SERVER_START_REQ( send_hardware_message ) - { - req->win = wine_server_user_handle( hwnd ); - req->msg = message; - req->input.type = INPUT_MOUSE; - req->input.mouse.x = x; - req->input.mouse.y = y; - req->input.mouse.data = data; - req->input.mouse.flags = 0; /* FIXME */ - req->input.mouse.time = time; - req->input.mouse.info = extra_info; - if (injected_flags & LLMHF_INJECTED) req->flags = SEND_HWMSG_INJECTED; - wine_server_call( req ); - } - SERVER_END_REQ; -} - - /*********************************************************************** * X11DRV_send_mouse_input */ @@ -329,6 +292,7 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, DWORD data, DWORD time, DWORD extra_info, UINT injected_flags ) { POINT pt; + MSLLHOOKSTRUCT hook; if (!time) time = GetTickCount(); @@ -380,10 +344,17 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, wine_tsx11_unlock(); } + hook.pt.x = pt.x; + hook.pt.y = pt.y; + hook.mouseData = MAKELONG( 0, data ); + hook.flags = injected_flags; + hook.time = time; + hook.dwExtraInfo = extra_info; + last_time_modified = GetTickCount(); + if (flags & MOUSEEVENTF_MOVE) { - queue_raw_mouse_message( WM_MOUSEMOVE, hwnd, pt.x, pt.y, data, time, - extra_info, injected_flags ); + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_MOUSEMOVE, (LPARAM)&hook, TRUE )) return; if ((injected_flags & LLMHF_INJECTED) && ((flags & MOUSEEVENTF_ABSOLUTE) || x || y)) /* we have to actually move the cursor */ { @@ -399,32 +370,64 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, } } if (flags & MOUSEEVENTF_LEFTDOWN) - queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONDOWN : WM_LBUTTONDOWN, - hwnd, pt.x, pt.y, data, time, extra_info, injected_flags ); + { + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, + GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONDOWN : WM_LBUTTONDOWN, + (LPARAM)&hook, TRUE )) return; + } if (flags & MOUSEEVENTF_LEFTUP) - queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONUP : WM_LBUTTONUP, - hwnd, pt.x, pt.y, data, time, extra_info, injected_flags ); + { + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, + GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONUP : WM_LBUTTONUP, + (LPARAM)&hook, TRUE )) return; + } if (flags & MOUSEEVENTF_RIGHTDOWN) - queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN, - hwnd, pt.x, pt.y, data, time, extra_info, injected_flags ); + { + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, + GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN, + (LPARAM)&hook, TRUE )) return; + } if (flags & MOUSEEVENTF_RIGHTUP) - queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONUP : WM_RBUTTONUP, - hwnd, pt.x, pt.y, data, time, extra_info, injected_flags ); + { + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, + GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONUP : WM_RBUTTONUP, + (LPARAM)&hook, TRUE )) return; + } if (flags & MOUSEEVENTF_MIDDLEDOWN) - queue_raw_mouse_message( WM_MBUTTONDOWN, hwnd, pt.x, pt.y, - data, time, extra_info, injected_flags ); + { + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_MBUTTONDOWN, (LPARAM)&hook, TRUE )) return; + } if (flags & MOUSEEVENTF_MIDDLEUP) - queue_raw_mouse_message( WM_MBUTTONUP, hwnd, pt.x, pt.y, - data, time, extra_info, injected_flags ); + { + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_MBUTTONUP, (LPARAM)&hook, TRUE )) return; + } if (flags & MOUSEEVENTF_WHEEL) - queue_raw_mouse_message( WM_MOUSEWHEEL, hwnd, pt.x, pt.y, - data, time, extra_info, injected_flags ); + { + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_MOUSEWHEEL, (LPARAM)&hook, TRUE )) return; + } if (flags & MOUSEEVENTF_XDOWN) - queue_raw_mouse_message( WM_XBUTTONDOWN, hwnd, pt.x, pt.y, - data, time, extra_info, injected_flags ); + { + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_XBUTTONDOWN, (LPARAM)&hook, TRUE )) return; + } if (flags & MOUSEEVENTF_XUP) - queue_raw_mouse_message( WM_XBUTTONUP, hwnd, pt.x, pt.y, - data, time, extra_info, injected_flags ); + { + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_XBUTTONUP, (LPARAM)&hook, TRUE )) return; + } + + SERVER_START_REQ( send_hardware_message ) + { + req->win = wine_server_user_handle( hwnd ); + req->input.type = INPUT_MOUSE; + req->input.mouse.x = pt.x; + req->input.mouse.y = pt.y; + req->input.mouse.data = data; + req->input.mouse.flags = flags | MOUSEEVENTF_ABSOLUTE; + req->input.mouse.time = time; + req->input.mouse.info = extra_info; + if (injected_flags & LLMHF_INJECTED) req->flags = SEND_HWMSG_INJECTED; + wine_server_call( req ); + } + SERVER_END_REQ; } #ifdef SONAME_LIBXCURSOR diff --git a/server/queue.c b/server/queue.c index 19532e29aeb..13e3f47e180 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1329,35 +1329,84 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg } /* queue a hardware message for a mouse event */ -static void queue_mouse_message( struct desktop *desktop, user_handle_t win, unsigned int message, - const hw_input_t *input ) +static void queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input ) { struct hardware_msg_data *msg_data; struct message *msg; + unsigned int i, time, flags; + int x, y; - if (!(msg = mem_alloc( sizeof(*msg) ))) return; - if (!(msg_data = mem_alloc( sizeof(*msg_data) ))) + static const unsigned int messages[] = { - free( msg ); - return; + WM_MOUSEMOVE, /* 0x0001 = MOUSEEVENTF_MOVE */ + WM_LBUTTONDOWN, /* 0x0002 = MOUSEEVENTF_LEFTDOWN */ + WM_LBUTTONUP, /* 0x0004 = MOUSEEVENTF_LEFTUP */ + WM_RBUTTONDOWN, /* 0x0008 = MOUSEEVENTF_RIGHTDOWN */ + WM_RBUTTONUP, /* 0x0010 = MOUSEEVENTF_RIGHTUP */ + WM_MBUTTONDOWN, /* 0x0020 = MOUSEEVENTF_MIDDLEDOWN */ + WM_MBUTTONUP, /* 0x0040 = MOUSEEVENTF_MIDDLEUP */ + WM_XBUTTONDOWN, /* 0x0080 = MOUSEEVENTF_XDOWN */ + WM_XBUTTONUP, /* 0x0100 = MOUSEEVENTF_XUP */ + 0, /* 0x0200 = unused */ + 0, /* 0x0400 = unused */ + WM_MOUSEWHEEL, /* 0x0800 = MOUSEEVENTF_WHEEL */ + WM_MOUSEHWHEEL /* 0x1000 = MOUSEEVENTF_HWHEEL */ + }; + + flags = input->mouse.flags; + time = input->mouse.time; + if (!time) time = get_tick_count(); + + if (flags & MOUSEEVENTF_MOVE) + { + if (flags & MOUSEEVENTF_ABSOLUTE) + { + x = input->mouse.x; + y = input->mouse.y; + if (flags & ~(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE) && + x == desktop->cursor_x && y == desktop->cursor_y) + flags &= ~MOUSEEVENTF_MOVE; + } + else + { + x = desktop->cursor_x + input->mouse.x; + y = desktop->cursor_y + input->mouse.y; + } + } + else + { + x = desktop->cursor_x; + y = desktop->cursor_y; } - memset( msg_data, 0, sizeof(*msg_data) ); - msg->type = MSG_HARDWARE; - msg->win = get_user_full_handle( win ); - msg->msg = message; - msg->wparam = input->mouse.data << 16; - msg->lparam = 0; - msg->time = input->mouse.time; - msg->result = NULL; - msg->data = msg_data; - msg->data_size = sizeof(*msg_data); - msg_data->x = input->mouse.x; - msg_data->y = input->mouse.y; - msg_data->info = input->mouse.info; - if (!msg->time) msg->time = get_tick_count(); + for (i = 0; i < sizeof(messages)/sizeof(messages[0]); i++) + { + if (!messages[i]) continue; + if (!(flags & (1 << i))) continue; - queue_hardware_message( desktop, msg ); + if (!(msg = mem_alloc( sizeof(*msg) ))) return; + if (!(msg_data = mem_alloc( sizeof(*msg_data) ))) + { + free( msg ); + return; + } + memset( msg_data, 0, sizeof(*msg_data) ); + + msg->type = MSG_HARDWARE; + msg->win = get_user_full_handle( win ); + msg->msg = messages[i]; + msg->wparam = input->mouse.data << 16; + msg->lparam = 0; + msg->time = time; + msg->result = NULL; + msg->data = msg_data; + msg->data_size = sizeof(*msg_data); + msg_data->x = x; + msg_data->y = y; + msg_data->info = input->mouse.info; + + queue_hardware_message( desktop, msg ); + } } /* queue a hardware message for a keyboard event */ @@ -1917,7 +1966,7 @@ DECL_HANDLER(send_hardware_message) switch (req->input.type) { case INPUT_MOUSE: - queue_mouse_message( desktop, req->win, req->msg, &req->input ); + queue_mouse_message( desktop, req->win, &req->input ); break; case INPUT_KEYBOARD: queue_keyboard_message( desktop, req->win, &req->input );