|
28 | 28 | #include "awt_Component.h" |
29 | 29 | #include <winuser.h> |
30 | 30 |
|
31 | | -static int signum(int i) { |
32 | | - // special version of signum which returns 1 when value is 0 |
33 | | - return i >= 0 ? 1 : -1; |
34 | | -} |
35 | | - |
36 | 31 | static void MouseMove(jint x, jint y) |
37 | 32 | { |
38 | 33 | INPUT mouseInput = {0}; |
39 | 34 | mouseInput.type = INPUT_MOUSE; |
40 | 35 | mouseInput.mi.time = 0; |
41 | | - mouseInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; |
42 | | - mouseInput.mi.dx = (x * 65536 /::GetSystemMetrics(SM_CXSCREEN)) + signum(x); |
43 | | - mouseInput.mi.dy = (y * 65536 /::GetSystemMetrics(SM_CYSCREEN)) + signum(y); |
| 36 | + |
| 37 | + // The following calculations take into account a multi-monitor setup using |
| 38 | + // a virtual screen for all monitors combined. |
| 39 | + // More details from Microsoft are here -- |
| 40 | + // https://docs.microsoft.com/en-us/windows/win32/gdi/the-virtual-screen |
| 41 | + |
| 42 | + x -= ::GetSystemMetrics(SM_XVIRTUALSCREEN); |
| 43 | + y -= ::GetSystemMetrics(SM_YVIRTUALSCREEN); |
| 44 | + |
| 45 | + mouseInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | |
| 46 | + MOUSEEVENTF_VIRTUALDESK; |
| 47 | + |
| 48 | + int scW = ::GetSystemMetrics(SM_CXVIRTUALSCREEN); |
| 49 | + int scH = ::GetSystemMetrics(SM_CYVIRTUALSCREEN); |
| 50 | + |
| 51 | + // The following calculation to deduce mouse coordinates is based on |
| 52 | + // empirical data |
| 53 | + mouseInput.mi.dx = (x * 65536 + scW - 1) / scW; |
| 54 | + mouseInput.mi.dy = (y * 65536 + scH - 1) / scH; |
| 55 | + |
44 | 56 | ::SendInput(1, &mouseInput, sizeof(mouseInput)); |
| 57 | + |
45 | 58 | } |
46 | 59 |
|
47 | 60 | static void MousePress(jint buttonMask) |
|
0 commit comments