@mukea/uiohook-napi 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +77 -0
- package/binding.gyp +85 -0
- package/dist/index.d.ts +194 -0
- package/dist/index.js +206 -0
- package/dist/index.js.map +1 -0
- package/dist/prebuild-test-noop.d.ts +0 -0
- package/dist/prebuild-test-noop.js +3 -0
- package/dist/prebuild-test-noop.js.map +1 -0
- package/libuiohook/include/uiohook.h +457 -0
- package/libuiohook/src/darwin/input_helper.c +535 -0
- package/libuiohook/src/darwin/input_helper.h +203 -0
- package/libuiohook/src/darwin/input_hook.c +1436 -0
- package/libuiohook/src/darwin/post_event.c +303 -0
- package/libuiohook/src/darwin/system_properties.c +479 -0
- package/libuiohook/src/logger.c +40 -0
- package/libuiohook/src/logger.h +32 -0
- package/libuiohook/src/windows/input_helper.c +913 -0
- package/libuiohook/src/windows/input_helper.h +146 -0
- package/libuiohook/src/windows/input_hook.c +722 -0
- package/libuiohook/src/windows/post_event.c +248 -0
- package/libuiohook/src/windows/system_properties.c +231 -0
- package/libuiohook/src/x11/input_helper.c +1846 -0
- package/libuiohook/src/x11/input_helper.h +108 -0
- package/libuiohook/src/x11/input_hook.c +1116 -0
- package/libuiohook/src/x11/post_event.c +427 -0
- package/libuiohook/src/x11/system_properties.c +494 -0
- package/package.json +60 -0
- package/prebuilds/darwin/darwin-arm64/@mukea+uiohook-napi.node +0 -0
- package/prebuilds/darwin/darwin-x64/@mukea+uiohook-napi.node +0 -0
- package/prebuilds/linux/linux-arm64/@mukea+uiohook-napi.node +0 -0
- package/prebuilds/linux/linux-x64/@mukea+uiohook-napi.node +0 -0
- package/prebuilds/windows/win32-x64/@mukea+uiohook-napi.node +0 -0
- package/src/lib/addon.c +337 -0
- package/src/lib/napi_helpers.c +51 -0
- package/src/lib/napi_helpers.h +53 -0
- package/src/lib/uiohook_worker.c +200 -0
- package/src/lib/uiohook_worker.h +12 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/* libUIOHook: Cross-platform keyboard and mouse hooking from userland.
|
|
2
|
+
* Copyright (C) 2006-2023 Alexander Barker. All Rights Reserved.
|
|
3
|
+
* https://github.com/kwhat/libuiohook/
|
|
4
|
+
*
|
|
5
|
+
* libUIOHook is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU Lesser General Public License as published
|
|
7
|
+
* by the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* libUIOHook is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Lesser General Public License
|
|
16
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#include <stdio.h>
|
|
20
|
+
#include <uiohook.h>
|
|
21
|
+
#include <windows.h>
|
|
22
|
+
|
|
23
|
+
#include "input_helper.h"
|
|
24
|
+
#include "logger.h"
|
|
25
|
+
|
|
26
|
+
// Some buggy versions of MinGW and MSys do not include these constants in winuser.h.
|
|
27
|
+
#ifndef MAPVK_VK_TO_VSC
|
|
28
|
+
#define MAPVK_VK_TO_VSC 0
|
|
29
|
+
#define MAPVK_VSC_TO_VK 1
|
|
30
|
+
#define MAPVK_VK_TO_CHAR 2
|
|
31
|
+
#define MAPVK_VSC_TO_VK_EX 3
|
|
32
|
+
#endif
|
|
33
|
+
// Some buggy versions of MinGW and MSys only define this value for Windows
|
|
34
|
+
// versions >= 0x0600 (Windows Vista) when it should be 0x0500 (Windows 2000).
|
|
35
|
+
#ifndef MAPVK_VK_TO_VSC_EX
|
|
36
|
+
#define MAPVK_VK_TO_VSC_EX 4
|
|
37
|
+
#endif
|
|
38
|
+
|
|
39
|
+
#ifndef KEYEVENTF_SCANCODE
|
|
40
|
+
#define KEYEVENTF_EXTENDEDKEY 0x0001
|
|
41
|
+
#define KEYEVENTF_KEYUP 0x0002
|
|
42
|
+
#define KEYEVENTF_UNICODE 0x0004
|
|
43
|
+
#define KEYEVENTF_SCANCODE 0x0008
|
|
44
|
+
#endif
|
|
45
|
+
|
|
46
|
+
#ifndef KEYEVENTF_KEYDOWN
|
|
47
|
+
#define KEYEVENTF_KEYDOWN 0x0000
|
|
48
|
+
#endif
|
|
49
|
+
|
|
50
|
+
#define MAX_WINDOWS_COORD_VALUE (1 << 16)
|
|
51
|
+
|
|
52
|
+
// TODO I doubt this table is complete.
|
|
53
|
+
// http://letcoderock.blogspot.fr/2011/10/sendinput-with-shift-key-not-work.html
|
|
54
|
+
static const uint16_t extend_key_table[10] = {
|
|
55
|
+
VK_UP,
|
|
56
|
+
VK_DOWN,
|
|
57
|
+
VK_LEFT,
|
|
58
|
+
VK_RIGHT,
|
|
59
|
+
VK_HOME,
|
|
60
|
+
VK_END,
|
|
61
|
+
VK_PRIOR, // PgUp
|
|
62
|
+
VK_NEXT, // PgDn
|
|
63
|
+
VK_INSERT,
|
|
64
|
+
VK_DELETE
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
static LONG convert_to_relative_position(int coordinate, int screen_size) {
|
|
69
|
+
// See https://stackoverflow.com/a/4555214 and its comments
|
|
70
|
+
int offset = (coordinate > 0 ? 1 : -1); // Negative coordinates appear when using multiple monitors
|
|
71
|
+
return ((coordinate * MAX_WINDOWS_COORD_VALUE) / screen_size) + offset;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static int map_keyboard_event(uiohook_event * const event, INPUT * const input) {
|
|
75
|
+
input->type = INPUT_KEYBOARD; // | KEYEVENTF_SCANCODE
|
|
76
|
+
//input->ki.wScan = event->data.keyboard.rawcode;
|
|
77
|
+
//input->ki.time = GetSystemTime();
|
|
78
|
+
|
|
79
|
+
switch (event->type) {
|
|
80
|
+
case EVENT_KEY_PRESSED:
|
|
81
|
+
input->ki.dwFlags = KEYEVENTF_KEYDOWN;
|
|
82
|
+
break;
|
|
83
|
+
|
|
84
|
+
case EVENT_KEY_RELEASED:
|
|
85
|
+
input->ki.dwFlags = KEYEVENTF_KEYUP;
|
|
86
|
+
break;
|
|
87
|
+
|
|
88
|
+
default:
|
|
89
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: Invalid event for keyboard event mapping: %#X.\n",
|
|
90
|
+
__FUNCTION__, __LINE__, event->type);
|
|
91
|
+
return UIOHOOK_FAILURE;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
input->ki.wVk = (WORD) scancode_to_keycode(event->data.keyboard.keycode);
|
|
95
|
+
if (input->ki.wVk == 0x0000) {
|
|
96
|
+
logger(LOG_LEVEL_WARN, "%s [%u]: Unable to lookup scancode: %li\n",
|
|
97
|
+
__FUNCTION__, __LINE__, event->data.keyboard.keycode);
|
|
98
|
+
return UIOHOOK_FAILURE;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// FIXME Why is this checking MASK_SHIFT
|
|
102
|
+
if (event->mask & MASK_SHIFT) {
|
|
103
|
+
for (int i = 0; i < sizeof(extend_key_table) / sizeof(uint16_t)
|
|
104
|
+
&& input->ki.wVk == extend_key_table[i]; i++) {
|
|
105
|
+
input->ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return UIOHOOK_SUCCESS;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static int map_mouse_event(uiohook_event * const event, INPUT * const input) {
|
|
113
|
+
// FIXME implement multiple monitor support
|
|
114
|
+
uint16_t screen_width = GetSystemMetrics(SM_CXSCREEN);
|
|
115
|
+
uint16_t screen_height = GetSystemMetrics(SM_CYSCREEN);
|
|
116
|
+
|
|
117
|
+
input->type = INPUT_MOUSE;
|
|
118
|
+
input->mi.mouseData = 0;
|
|
119
|
+
input->mi.dwExtraInfo = 0;
|
|
120
|
+
input->mi.time = 0; // GetSystemTime();
|
|
121
|
+
|
|
122
|
+
input->mi.dx = convert_to_relative_position(event->data.mouse.x, screen_width);
|
|
123
|
+
input->mi.dy = convert_to_relative_position(event->data.mouse.y, screen_height);
|
|
124
|
+
|
|
125
|
+
switch (event->type) {
|
|
126
|
+
case EVENT_MOUSE_PRESSED:
|
|
127
|
+
if (event->data.mouse.button == MOUSE_NOBUTTON) {
|
|
128
|
+
logger(LOG_LEVEL_WARN, "%s [%u]: No button specified for mouse pressed event!\n",
|
|
129
|
+
__FUNCTION__, __LINE__);
|
|
130
|
+
return UIOHOOK_FAILURE;
|
|
131
|
+
} else if (event->data.mouse.button == MOUSE_BUTTON1) {
|
|
132
|
+
input->mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
|
|
133
|
+
} else if (event->data.mouse.button == MOUSE_BUTTON2) {
|
|
134
|
+
input->mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
|
|
135
|
+
} else if (event->data.mouse.button == MOUSE_BUTTON3) {
|
|
136
|
+
input->mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
|
|
137
|
+
} else {
|
|
138
|
+
input->mi.dwFlags = MOUSEEVENTF_XDOWN;
|
|
139
|
+
if (event->data.mouse.button == MOUSE_BUTTON4) {
|
|
140
|
+
input->mi.mouseData = XBUTTON1;
|
|
141
|
+
} else if (event->data.mouse.button == MOUSE_BUTTON5) {
|
|
142
|
+
input->mi.mouseData = XBUTTON2;
|
|
143
|
+
} else {
|
|
144
|
+
input->mi.mouseData = event->data.mouse.button - 3;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// We need to move the mouse to the correct location prior to clicking.
|
|
149
|
+
event->type = EVENT_MOUSE_MOVED;
|
|
150
|
+
// TODO Remember to check the status here.
|
|
151
|
+
hook_post_event(event);
|
|
152
|
+
event->type = EVENT_MOUSE_PRESSED;
|
|
153
|
+
break;
|
|
154
|
+
|
|
155
|
+
case EVENT_MOUSE_RELEASED:
|
|
156
|
+
if (event->data.mouse.button == MOUSE_NOBUTTON) {
|
|
157
|
+
logger(LOG_LEVEL_WARN, "%s [%u]: No button specified for mouse released event!\n",
|
|
158
|
+
__FUNCTION__, __LINE__);
|
|
159
|
+
return UIOHOOK_FAILURE;
|
|
160
|
+
} else if (event->data.mouse.button == MOUSE_BUTTON1) {
|
|
161
|
+
input->mi.dwFlags = MOUSEEVENTF_LEFTUP;
|
|
162
|
+
} else if (event->data.mouse.button == MOUSE_BUTTON2) {
|
|
163
|
+
input->mi.dwFlags = MOUSEEVENTF_RIGHTUP;
|
|
164
|
+
} else if (event->data.mouse.button == MOUSE_BUTTON3) {
|
|
165
|
+
input->mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
|
|
166
|
+
} else {
|
|
167
|
+
input->mi.dwFlags = MOUSEEVENTF_XUP;
|
|
168
|
+
if (event->data.mouse.button == MOUSE_BUTTON4) {
|
|
169
|
+
input->mi.mouseData = XBUTTON1;
|
|
170
|
+
} else if (event->data.mouse.button == MOUSE_BUTTON5) {
|
|
171
|
+
input->mi.mouseData = XBUTTON2;
|
|
172
|
+
} else {
|
|
173
|
+
input->mi.mouseData = event->data.mouse.button - 3;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// We need to move the mouse to the correct location prior to clicking.
|
|
178
|
+
event->type = EVENT_MOUSE_MOVED;
|
|
179
|
+
// TODO Remember to check the status here.
|
|
180
|
+
hook_post_event(event);
|
|
181
|
+
event->type = EVENT_MOUSE_PRESSED;
|
|
182
|
+
break;
|
|
183
|
+
|
|
184
|
+
case EVENT_MOUSE_WHEEL:
|
|
185
|
+
input->mi.dwFlags = MOUSEEVENTF_WHEEL;
|
|
186
|
+
|
|
187
|
+
// type, amount and rotation?
|
|
188
|
+
input->mi.mouseData = event->data.wheel.amount * event->data.wheel.rotation * WHEEL_DELTA;
|
|
189
|
+
break;
|
|
190
|
+
|
|
191
|
+
case EVENT_MOUSE_DRAGGED:
|
|
192
|
+
case EVENT_MOUSE_MOVED:
|
|
193
|
+
input->mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
|
194
|
+
break;
|
|
195
|
+
|
|
196
|
+
default:
|
|
197
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: Invalid event for mouse event mapping: %#X.\n",
|
|
198
|
+
__FUNCTION__, __LINE__, event->type);
|
|
199
|
+
return UIOHOOK_FAILURE;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return UIOHOOK_SUCCESS;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// TODO This should return a status code, UIOHOOK_SUCCESS or otherwise.
|
|
206
|
+
UIOHOOK_API void hook_post_event(uiohook_event * const event) {
|
|
207
|
+
int status = UIOHOOK_FAILURE;
|
|
208
|
+
|
|
209
|
+
INPUT *input = (INPUT *) calloc(1, sizeof(INPUT)) ;
|
|
210
|
+
if (input == NULL) {
|
|
211
|
+
logger(LOG_LEVEL_ERROR, "%s [%u]: failed to allocate memory: calloc!\n",
|
|
212
|
+
__FUNCTION__, __LINE__);
|
|
213
|
+
return; // UIOHOOK_ERROR_OUT_OF_MEMORY
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
switch (event->type) {
|
|
217
|
+
case EVENT_KEY_PRESSED:
|
|
218
|
+
case EVENT_KEY_RELEASED:
|
|
219
|
+
status = map_keyboard_event(event, input);
|
|
220
|
+
break;
|
|
221
|
+
|
|
222
|
+
case EVENT_MOUSE_PRESSED:
|
|
223
|
+
case EVENT_MOUSE_RELEASED:
|
|
224
|
+
case EVENT_MOUSE_WHEEL:
|
|
225
|
+
case EVENT_MOUSE_MOVED:
|
|
226
|
+
case EVENT_MOUSE_DRAGGED:
|
|
227
|
+
status = map_mouse_event(event, input);
|
|
228
|
+
break;
|
|
229
|
+
|
|
230
|
+
case EVENT_KEY_TYPED:
|
|
231
|
+
case EVENT_MOUSE_CLICKED:
|
|
232
|
+
|
|
233
|
+
case EVENT_HOOK_ENABLED:
|
|
234
|
+
case EVENT_HOOK_DISABLED:
|
|
235
|
+
|
|
236
|
+
default:
|
|
237
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: Ignoring post event: %#X.\n",
|
|
238
|
+
__FUNCTION__, __LINE__, event->type);
|
|
239
|
+
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (status != UIOHOOK_FAILURE && !SendInput(1, input, sizeof(INPUT))) {
|
|
243
|
+
logger(LOG_LEVEL_ERROR, "%s [%u]: SendInput() failed! (%#lX)\n",
|
|
244
|
+
__FUNCTION__, __LINE__, (unsigned long) GetLastError());
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
free(input);
|
|
248
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/* libUIOHook: Cross-platform keyboard and mouse hooking from userland.
|
|
2
|
+
* Copyright (C) 2006-2023 Alexander Barker. All Rights Reserved.
|
|
3
|
+
* https://github.com/kwhat/libuiohook/
|
|
4
|
+
*
|
|
5
|
+
* libUIOHook is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU Lesser General Public License as published
|
|
7
|
+
* by the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* libUIOHook is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Lesser General Public License
|
|
16
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#include <uiohook.h>
|
|
20
|
+
#include <windows.h>
|
|
21
|
+
|
|
22
|
+
#include "logger.h"
|
|
23
|
+
#include "input_helper.h"
|
|
24
|
+
|
|
25
|
+
// The handle to the DLL module pulled in DllMain on DLL_PROCESS_ATTACH.
|
|
26
|
+
HINSTANCE hInst;
|
|
27
|
+
|
|
28
|
+
// input_hook.c
|
|
29
|
+
extern void unregister_running_hooks();
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
// Structure for the monitor_enum_proc() callback so we can track the count.
|
|
33
|
+
typedef struct _screen_info {
|
|
34
|
+
uint8_t count;
|
|
35
|
+
screen_data *data;
|
|
36
|
+
} screen_info;
|
|
37
|
+
|
|
38
|
+
/* The following function was contributed by Anthony Liguori Jan 14, 2015.
|
|
39
|
+
* https://github.com/kwhat/libuiohook/pull/17
|
|
40
|
+
*
|
|
41
|
+
* callback function called by EnumDisplayMonitors for each enabled monitor
|
|
42
|
+
* http://msdn.microsoft.com/en-us/library/windows/desktop/dd162610(v=vs.85).aspx
|
|
43
|
+
* http://msdn.microsoft.com/en-us/library/dd162610%28VS.85%29.aspx
|
|
44
|
+
* http://msdn.microsoft.com/en-us/library/dd145061%28VS.85%29.aspx
|
|
45
|
+
* http://msdn.microsoft.com/en-us/library/dd144901(v=vs.85).aspx
|
|
46
|
+
*/
|
|
47
|
+
static BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
|
|
48
|
+
int width = lprcMonitor->right - lprcMonitor->left;
|
|
49
|
+
int height = lprcMonitor->bottom - lprcMonitor->top;
|
|
50
|
+
int origin_x = lprcMonitor->left;
|
|
51
|
+
int origin_y = lprcMonitor->top;
|
|
52
|
+
|
|
53
|
+
if (width > 0 && height > 0) {
|
|
54
|
+
screen_info *screens = (screen_info *) dwData;
|
|
55
|
+
|
|
56
|
+
int current_screen = screens->count++;
|
|
57
|
+
|
|
58
|
+
if (screens->data == NULL) {
|
|
59
|
+
screens->data = (screen_data *) malloc(sizeof(screen_data));
|
|
60
|
+
} else {
|
|
61
|
+
screens->data = (screen_data *) realloc(screens->data, sizeof(screen_data) * screens->count);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
screens->data[current_screen] = (screen_data) {
|
|
65
|
+
// Should monitor count start @ zero? Currently it starts at 1.
|
|
66
|
+
.number = screens->count,
|
|
67
|
+
.x = origin_x,
|
|
68
|
+
.y = origin_y,
|
|
69
|
+
.width = width,
|
|
70
|
+
.height = height
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: Monitor %d: %ldx%ld (%ld, %ld)\n",
|
|
74
|
+
__FUNCTION__, __LINE__, screens->count, width, height, origin_x, origin_y);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return TRUE;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* The following function was contributed by Anthony Liguori Jan 14, 2015.
|
|
81
|
+
* https://github.com/kwhat/libuiohook/pull/17
|
|
82
|
+
*/
|
|
83
|
+
UIOHOOK_API screen_data* hook_create_screen_info(unsigned char *count) {
|
|
84
|
+
// Initialize count to zero.
|
|
85
|
+
*count = 0;
|
|
86
|
+
|
|
87
|
+
// Create a simple structure to make working with monitor_enum_proc easier.
|
|
88
|
+
screen_info screens = {
|
|
89
|
+
.count = 0,
|
|
90
|
+
.data = NULL
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
BOOL status = EnumDisplayMonitors(NULL, NULL, monitor_enum_proc, (LPARAM) &screens);
|
|
94
|
+
|
|
95
|
+
if (!status || screens.count == 0) {
|
|
96
|
+
// Fallback in case EnumDisplayMonitors fails.
|
|
97
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: EnumDisplayMonitors failed. Fallback.\n",
|
|
98
|
+
__FUNCTION__, __LINE__);
|
|
99
|
+
|
|
100
|
+
int width = GetSystemMetrics(SM_CXSCREEN);
|
|
101
|
+
int height = GetSystemMetrics(SM_CYSCREEN);
|
|
102
|
+
|
|
103
|
+
if (width > 0 && height > 0) {
|
|
104
|
+
screens.data = (screen_data *) malloc(sizeof(screen_data));
|
|
105
|
+
|
|
106
|
+
if (screens.data != NULL) {
|
|
107
|
+
*count = 1;
|
|
108
|
+
screens.data[0] = (screen_data) {
|
|
109
|
+
.number = 1,
|
|
110
|
+
.x = 0,
|
|
111
|
+
.y = 0,
|
|
112
|
+
.width = width,
|
|
113
|
+
.height = height
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
// Populate the count.
|
|
119
|
+
*count = screens.count;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return screens.data;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
UIOHOOK_API long int hook_get_auto_repeat_rate() {
|
|
126
|
+
long int value = -1;
|
|
127
|
+
long int rate;
|
|
128
|
+
|
|
129
|
+
if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &rate, 0)) {
|
|
130
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: SPI_GETKEYBOARDSPEED: %li.\n",
|
|
131
|
+
__FUNCTION__, __LINE__, rate);
|
|
132
|
+
|
|
133
|
+
value = rate;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
UIOHOOK_API long int hook_get_auto_repeat_delay() {
|
|
140
|
+
long int value = -1;
|
|
141
|
+
long int delay;
|
|
142
|
+
|
|
143
|
+
if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &delay, 0)) {
|
|
144
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: SPI_GETKEYBOARDDELAY: %li.\n",
|
|
145
|
+
__FUNCTION__, __LINE__, delay);
|
|
146
|
+
|
|
147
|
+
value = delay;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return value;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
UIOHOOK_API long int hook_get_pointer_acceleration_multiplier() {
|
|
154
|
+
long int value = -1;
|
|
155
|
+
int mouse[3]; // 0-Threshold X, 1-Threshold Y and 2-Speed.
|
|
156
|
+
|
|
157
|
+
if (SystemParametersInfo(SPI_GETMOUSE, 0, &mouse, 0)) {
|
|
158
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: SPI_GETMOUSE[2]: %i.\n",
|
|
159
|
+
__FUNCTION__, __LINE__, mouse[2]);
|
|
160
|
+
|
|
161
|
+
value = mouse[2];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return value;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
UIOHOOK_API long int hook_get_pointer_acceleration_threshold() {
|
|
168
|
+
long int value = -1;
|
|
169
|
+
int mouse[3]; // 0-Threshold X, 1-Threshold Y and 2-Speed.
|
|
170
|
+
|
|
171
|
+
if (SystemParametersInfo(SPI_GETMOUSE, 0, &mouse, 0)) {
|
|
172
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: SPI_GETMOUSE[0]: %i.\n",
|
|
173
|
+
__FUNCTION__, __LINE__, mouse[0]);
|
|
174
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: SPI_GETMOUSE[1]: %i.\n",
|
|
175
|
+
__FUNCTION__, __LINE__, mouse[1]);
|
|
176
|
+
|
|
177
|
+
// Average the x and y thresholds.
|
|
178
|
+
value = (mouse[0] + mouse[1]) / 2;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return value;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
UIOHOOK_API long int hook_get_pointer_sensitivity() {
|
|
185
|
+
long int value = -1;
|
|
186
|
+
int sensitivity;
|
|
187
|
+
|
|
188
|
+
if (SystemParametersInfo(SPI_GETMOUSESPEED, 0, &sensitivity, 0)) {
|
|
189
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: SPI_GETMOUSESPEED: %i.\n",
|
|
190
|
+
__FUNCTION__, __LINE__, sensitivity);
|
|
191
|
+
|
|
192
|
+
value = sensitivity;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return value;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
UIOHOOK_API long int hook_get_multi_click_time() {
|
|
199
|
+
long int value = -1;
|
|
200
|
+
UINT clicktime;
|
|
201
|
+
|
|
202
|
+
clicktime = GetDoubleClickTime();
|
|
203
|
+
logger(LOG_LEVEL_DEBUG, "%s [%u]: GetDoubleClickTime: %u.\n",
|
|
204
|
+
__FUNCTION__, __LINE__, (unsigned int) clicktime);
|
|
205
|
+
|
|
206
|
+
value = (long int) clicktime;
|
|
207
|
+
|
|
208
|
+
return value;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// DLL Entry point.
|
|
212
|
+
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved) {
|
|
213
|
+
switch (fdwReason) {
|
|
214
|
+
case DLL_PROCESS_ATTACH:
|
|
215
|
+
// Save the DLL address.
|
|
216
|
+
hInst = hInstDLL;
|
|
217
|
+
break;
|
|
218
|
+
|
|
219
|
+
case DLL_PROCESS_DETACH:
|
|
220
|
+
// Unregister any hooks that may still be installed.
|
|
221
|
+
unregister_running_hooks();
|
|
222
|
+
break;
|
|
223
|
+
|
|
224
|
+
case DLL_THREAD_ATTACH:
|
|
225
|
+
case DLL_THREAD_DETACH:
|
|
226
|
+
// Do Nothing.
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return TRUE;
|
|
231
|
+
}
|