Rabbit Remote Control 0.0.30
Loading...
Searching...
No Matches
InputDeviceWindows.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include "InputDeviceWindows.h"
4#include <Windows.h>
5#include <QRect>
6#include <QSharedPointer>
7#include <QLoggingCategory>
8
9Q_DECLARE_LOGGING_CATEGORY(logDW)
10
11QSharedPointer<CInputDevice> CInputDevice::GenerateObject()
12{
13 return QSharedPointer<CInputDevice>(new CInputDeviceWindows());
14}
15
16CInputDeviceWindows::CInputDeviceWindows() : CInputDevice()
17{
18}
19
20CInputDeviceWindows::~CInputDeviceWindows()
21{
22 qDebug(logDW, "CInputDeviceX11::~CInputDeviceX11");
23}
24
25int CInputDeviceWindows::KeyEvent(quint32 keysym, quint32 keycode, bool down)
26{
27 return 0;
28}
29
30int CInputDeviceWindows::MouseEvent(MouseButtons buttons, QPoint pos)
31{
32 // - We are specifying absolute coordinates
33 DWORD flags = MOUSEEVENTF_ABSOLUTE;
34
35 // - Has the pointer moved since the last event?
36 if (m_LastPostion != pos)
37 flags |= MOUSEEVENTF_MOVE;
38
39 // - If the system swaps left and right mouse buttons then we must
40 // swap them here to negate the effect, so that we do the actual
41 // action we mean to do
42 if (::GetSystemMetrics(SM_SWAPBUTTON)) {
43 buttons = (buttons & ~(LeftButton | RightButton));
44 if (buttons & LeftButton) buttons |= LeftButton;
45 if (buttons & RightButton) buttons |= RightButton;
46 }
47
48 // Check the left button on change state
49 if((m_LastButtons & LeftButton) != (LeftButton & buttons))
50 {
51 if(buttons & LeftButton)
52 flags |= MOUSEEVENTF_LEFTDOWN;
53 else
54 flags |= MOUSEEVENTF_LEFTUP;
55 }
56
57 // Check the middle button on change state
58 if((m_LastButtons & MiddleButton) != (MiddleButton & buttons))
59 {
60 if(buttons & MiddleButton)
61 flags |= MOUSEEVENTF_MIDDLEDOWN;
62 else
63 flags |= MOUSEEVENTF_MIDDLEUP;
64 }
65
66 // Check the right button on change state
67 if((m_LastButtons & RightButton) != (RightButton & buttons))
68 {
69 if(buttons & RightButton)
70 flags |= MOUSEEVENTF_RIGHTDOWN;
71 else
72 flags |= MOUSEEVENTF_RIGHTUP;
73 }
74
75 //TODO: Check on a mouse wheel
76 DWORD mouseWheelValue = 0;
77 if(UWheelButton & buttons)
78 {
79 flags |= MOUSEEVENTF_WHEEL;
80 mouseWheelValue = 120;
81 }
82 if(DWheelButton & buttons)
83 {
84 flags |= MOUSEEVENTF_WHEEL;
85 mouseWheelValue = -120;
86 }
87 if(LWheelButton & buttons)
88 {
89 flags |= MOUSEEVENTF_HWHEEL;
90 mouseWheelValue = 120;
91 }
92 if(RWheelButton & buttons)
93 {
94 flags |= MOUSEEVENTF_HWHEEL;
95 mouseWheelValue = -120;
96 }
97
98 m_LastPostion = pos;
99 m_LastButtons = buttons;
100
101 // // Normilize pointer position
102 // UINT16 desktopWidth = GetSystemMetrics(SM_CXSCREEN);
103 // UINT16 desktopHeight = GetSystemMetrics(SM_CYSCREEN);
104 // int fbOffsetX = GetSystemMetrics(SM_XVIRTUALSCREEN);
105 // int fbOffsetY = GetSystemMetrics(SM_YVIRTUALSCREEN);
106 // INT32 x = (INT32)((pos.x() + fbOffsetX) * 65535 / (desktopWidth - 1));
107 // INT32 y = (INT32)((pos.y() + fbOffsetY)* 65535 / (desktopHeight - 1));
108
109 // INPUT input;
110 // memset(&input, 0, sizeof(INPUT));
111 // input.type = INPUT_MOUSE;
112 // input.mi.dwFlags = flags;
113 // input.mi.dx = x;
114 // input.mi.dy = y;
115 // input.mi.mouseData = mouseWheelValue;
116 // if(1 != SendInput(1, &input, sizeof(INPUT)))
117 // {
118 // qCritical(logDW, "SendInput fail: %d", GetLastError());
119 // return -1;
120 // }
121
122 QRect primaryDisplay(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
123 // qDebug(logDW, "primary screen:%d,%d;pos:%d,%d",
124 // primaryDisplay.width(), primaryDisplay.height(),
125 // pos.x(), pos.y());
126 if (primaryDisplay.contains(pos)) {
127 qDebug(logDW, "In primary screen");
128 // mouse_event wants coordinates specified as a proportion of the
129 // primary display's size, scaled to the range 0 to 65535
130 QPoint scaled;
131 scaled.setX((pos.x() * 65535) / (primaryDisplay.width() - 1));
132 scaled.setY((pos.y() * 65535) / (primaryDisplay.height() - 1));
133 ::mouse_event(flags, scaled.x(), scaled.y(), mouseWheelValue, 0);
134 } else {
135 // The event lies outside the primary monitor. Under Win2K, we can just use
136 // SendInput, which allows us to provide coordinates scaled to the virtual desktop.
137 // SendInput is available on all multi-monitor-aware platforms.
138 INPUT evt;
139 evt.type = INPUT_MOUSE;
140 QPoint vPos(pos.x() - GetSystemMetrics(SM_XVIRTUALSCREEN),
141 pos.y() - GetSystemMetrics(SM_YVIRTUALSCREEN));
142 evt.mi.dx = (vPos.x() * 65535) / (GetSystemMetrics(SM_CXVIRTUALSCREEN)-1);
143 evt.mi.dy = (vPos.y() * 65535) / (GetSystemMetrics(SM_CYVIRTUALSCREEN)-1);
144 evt.mi.dwFlags = flags | MOUSEEVENTF_VIRTUALDESK;
145 evt.mi.dwExtraInfo = 0;
146 evt.mi.mouseData = mouseWheelValue;
147 evt.mi.time = 0;
148 if (SendInput(1, &evt, sizeof(evt)) != 1)
149 {
150 qCritical(logDW, "SendInput fail: %d", GetLastError());
151 return -1;
152 }
153 }
154 return 0;
155}
156
157int CInputDeviceWindows::MouseEvent(MouseButtons buttons, int x, int y)
158{
159 return MouseEvent(buttons, QPoint(x, y));
160}