Skip to content

Commit 34d9622

Browse files
committed
Add send type Razer
Fix the incorrect dispatching behaviour of send_input
1 parent 9cdf5ae commit 34d9622

16 files changed

Lines changed: 566 additions & 321 deletions

AhkDll.Ahk/v1/IbAhkSend.ahk

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ IbSendInit(send_type := "AnyDriver", mode := 1, args*){
2424
result := DllCall("IbAhkSend\IbSendInit", "Int", 1, "Int", 0, "Ptr", 0, "Int")
2525
else if (send_type == "Logitech")
2626
result := DllCall("IbAhkSend\IbSendInit", "Int", 2, "Int", 0, "Ptr", 0, "Int")
27+
else if (send_type == "Razer")
28+
result := DllCall("IbAhkSend\IbSendInit", "Int", 3, "Int", 0, "Ptr", 0, "Int")
2729
else if (send_type == "DD"){
2830
if (args.MaxIndex() == 1)
29-
result := DllCall("IbAhkSend\IbSendInit", "Int", 3, "Int", 0, "WStr", args[1], "Int")
31+
result := DllCall("IbAhkSend\IbSendInit", "Int", 4, "Int", 0, "WStr", args[1], "Int")
3032
else
31-
result := DllCall("IbAhkSend\IbSendInit", "Int", 3, "Int", 0, "Ptr", 0, "Int")
33+
result := DllCall("IbAhkSend\IbSendInit", "Int", 4, "Int", 0, "Ptr", 0, "Int")
3234
} else
3335
throw "Invalid send type"
3436

AhkDll.Ahk/v1/test/type Razer.ahk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#Include ..\IbAhkSend.ahk
2+
IbSendInit("Razer")
3+
#include mode ahk.ahk

AhkDll.Ahk/v2/IbAhkSend.ahk

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ IbSendInit(send_type := "AnyDriver", mode := 1, args*){
2424
result := DllCall("IbAhkSend\IbSendInit", "Int", 1, "Int", 0, "Ptr", 0, "Int")
2525
else if (send_type == "Logitech")
2626
result := DllCall("IbAhkSend\IbSendInit", "Int", 2, "Int", 0, "Ptr", 0, "Int")
27+
else if (send_type == "Razer")
28+
result := DllCall("IbAhkSend\IbSendInit", "Int", 3, "Int", 0, "Ptr", 0, "Int")
2729
else if (send_type == "DD"){
2830
if (args.Length == 1)
29-
result := DllCall("IbAhkSend\IbSendInit", "Int", 3, "Int", 0, "WStr", args[1], "Int")
31+
result := DllCall("IbAhkSend\IbSendInit", "Int", 4, "Int", 0, "WStr", args[1], "Int")
3032
else
31-
result := DllCall("IbAhkSend\IbSendInit", "Int", 3, "Int", 0, "Ptr", 0, "Int")
33+
result := DllCall("IbAhkSend\IbSendInit", "Int", 4, "Int", 0, "Ptr", 0, "Int")
3234
} else
3335
throw "Invalid send type"
3436

AhkDll.Ahk/v2/test/type Razer.ahk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#Include "..\IbAhkSend.ahk"
2+
IbSendInit("Razer")
3+
#include "mode ahk.ahk"

AhkDll.Test/AhkDll.Test.cpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,12 @@ class KeyboardTest : public InitTest<TypeV>
137137
BOOST_TEST_MESSAGE(fmt::format(" Duration: {}ns", t1));
138138
//SendInput: 1000~3000us (1~3ms)
139139
//Logitech: 25~45us
140+
//Razer: 500~1000us
140141
//DD: 70~110us
141142
BOOST_TEST_MESSAGE(fmt::format(" Latency: {}ns", t2));
142143
//SendInput: 100ns (0)
143144
//Logitech: 0.8~4ms
145+
//Razer: 0.8~10ms
144146
//DD: 0.6~1ms
145147
}
146148
};
@@ -168,10 +170,13 @@ class MouseTest : public InitTest<TypeV> {
168170
}
169171
uint64_t t = measure.end();
170172

173+
Sleep(5000); //avoid bothering other tests (Razer will queue all movements)
174+
171175
BOOST_TEST_MESSAGE("TestMouseMove:");
172176
BOOST_TEST_MESSAGE(fmt::format(" Duration: {}ns", t / 10000));
173177
//SendInput: 200~800us
174178
//Logitech: 3~10us
179+
//Razer: 3~5us
175180
//DD: 500~1000us
176181
}
177182

@@ -199,6 +204,7 @@ class MouseTest : public InitTest<TypeV> {
199204
BOOST_TEST_MESSAGE(fmt::format(" Latency: {}ns", latency));
200205
//SendInput: 0.003~0.2ms (3~200us)
201206
//Logitech: 0.9~4ms
207+
//Razer: 0.7~4ms
202208
//DD: 1.1ms~1.3ms
203209
}
204210

@@ -225,28 +231,32 @@ class MouseTest : public InitTest<TypeV> {
225231
}
226232

227233
void TestMouseRelativeMove() {
228-
POINT p1, p2, d1, d2;
229-
GetCursorPos(&p1);
230-
231-
INPUT input;
232-
input.type = INPUT_MOUSE;
233-
input.mi = {};
234-
input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE;
235-
input.mi.dx = input.mi.dy = 100;
236-
IbSendInput(1, &input, sizeof INPUT);
234+
auto test = [](LONG movement) {
235+
POINT p1, p2, d1, d2;
236+
GetCursorPos(&p1);
237237

238-
GetCursorPos(&p2);
239-
d1 = { p2.x - p1.x, p2.y - p1.y };
238+
INPUT input;
239+
input.type = INPUT_MOUSE;
240+
input.mi = {};
241+
input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE;
242+
input.mi.dx = input.mi.dy = movement;
243+
IbSendInput(1, &input, sizeof INPUT);
240244

241-
Sleep(10);
245+
GetCursorPos(&p2);
246+
d1 = { p2.x - p1.x, p2.y - p1.y };
242247

243-
GetCursorPos(&p2);
244-
d2 = { p2.x - p1.x, p2.y - p1.y };
245-
BOOST_CHECK((abs(d2.x - 100) <= 10 && abs(d2.y - 100) <= 100));
248+
Sleep(10);
246249

247-
BOOST_TEST_MESSAGE("TestMouseRelativeMove:");
248-
BOOST_TEST_MESSAGE(fmt::format(" 0ms: ({}, {})", d1.x, d1.y));
249-
BOOST_TEST_MESSAGE(fmt::format(" 10ms: ({}, {})", d2.x, d2.y));
250+
GetCursorPos(&p2);
251+
d2 = { p2.x - p1.x, p2.y - p1.y };
252+
BOOST_CHECK((abs(d2.x - movement) <= 10 && abs(d2.y - movement) <= 10));
253+
254+
BOOST_TEST_MESSAGE("TestMouseRelativeMove(" << movement << "):");
255+
BOOST_TEST_MESSAGE(fmt::format(" 0ms: ({}, {})", d1.x, d1.y));
256+
BOOST_TEST_MESSAGE(fmt::format(" 10ms: ({}, {})", d2.x, d2.y));
257+
};
258+
test(100);
259+
test(-100);
250260
}
251261
};
252262

@@ -286,6 +296,7 @@ BOOST_AUTO_TEST_SUITE_END()
286296
CODE_GENERATE_TEST_NAME(SendInput_, SendInput)
287297
CODE_GENERATE_TEST(AnyDriver)
288298
CODE_GENERATE_TEST(Logitech)
299+
CODE_GENERATE_TEST(Razer)
289300

290301
BOOST_AUTO_TEST_SUITE(DD)
291302
BOOST_FIXTURE_TEST_SUITE(Keyboard, KeyboardTest<SendType::DD>)

AhkDll/AhkDll.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,11 @@
171171
<ClInclude Include="pch.h" />
172172
<ClInclude Include="SendTypes\DD.hpp" />
173173
<ClInclude Include="SendTypes\Logitech.hpp" />
174+
<ClInclude Include="SendTypes\Razer.hpp" />
174175
<ClInclude Include="SendTypes\SendInput.hpp" />
175176
<ClInclude Include="SendTypes\Base.hpp" />
176177
<ClInclude Include="SendTypes\Types.hpp" />
178+
<ClInclude Include="SendTypes\Usb.hpp" />
177179
</ItemGroup>
178180
<ItemGroup>
179181
<ClCompile Include="API 2.cpp" />

AhkDll/AhkDll.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@
4545
<ClInclude Include="SendTypes\Types.hpp">
4646
<Filter>Header Files\SendTypes</Filter>
4747
</ClInclude>
48+
<ClInclude Include="SendTypes\Razer.hpp">
49+
<Filter>Header Files\SendTypes</Filter>
50+
</ClInclude>
51+
<ClInclude Include="SendTypes\Usb.hpp">
52+
<Filter>Header Files\SendTypes</Filter>
53+
</ClInclude>
4854
</ItemGroup>
4955
<ItemGroup>
5056
<ClCompile Include="dllmain.cpp">

AhkDll/IbAhkSend.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace Send {
2424
AnyDriver,
2525
SendInput,
2626
Logitech,
27+
Razer,
2728
DD
2829
};
2930

AhkDll/SendTypes/Base.hpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,37 @@
33
#include <mutex>
44
#include <IbWinCppLib/WinCppLib.hpp>
55

6+
#include <winternl.h>
7+
#pragma comment(lib, "ntdll.lib")
8+
9+
extern "C" {
10+
constexpr NTSTATUS STATUS_SUCCESS = 0x00000000;
11+
constexpr NTSTATUS STATUS_MORE_ENTRIES = 0x00000105;
12+
constexpr NTSTATUS STATUS_BUFFER_TOO_SMALL = 0xC0000023;
13+
constexpr ACCESS_MASK DIRECTORY_QUERY = 0x0001;
14+
15+
NTSTATUS WINAPI NtOpenDirectoryObject(
16+
_Out_ PHANDLE DirectoryHandle,
17+
_In_ ACCESS_MASK DesiredAccess,
18+
_In_ POBJECT_ATTRIBUTES ObjectAttributes
19+
);
20+
21+
typedef struct _OBJECT_DIRECTORY_INFORMATION {
22+
UNICODE_STRING Name;
23+
UNICODE_STRING TypeName;
24+
} OBJECT_DIRECTORY_INFORMATION, * POBJECT_DIRECTORY_INFORMATION;
25+
26+
NTSTATUS WINAPI NtQueryDirectoryObject(
27+
_In_ HANDLE DirectoryHandle,
28+
_Out_opt_ PVOID Buffer,
29+
_In_ ULONG Length,
30+
_In_ BOOLEAN ReturnSingleEntry,
31+
_In_ BOOLEAN RestartScan,
32+
_Inout_ PULONG Context,
33+
_Out_opt_ PULONG ReturnLength
34+
);
35+
}
36+
637
namespace Send::Type::Internal {
738
class Base {
839
protected:
@@ -59,6 +90,8 @@ namespace Send::Type::Internal {
5990
count += send_mouse_input(inputs + i, j - i);
6091
break;
6192
}
93+
94+
i = j;
6295
}
6396

6497
return count;
@@ -163,4 +196,43 @@ namespace Send::Type::Internal {
163196
#undef CODE_GENERATE
164197
}
165198
};
199+
200+
inline std::wstring find_device(std::function<bool(std::wstring_view name)> p) {
201+
std::wstring result{};
202+
HANDLE dir_handle;
203+
204+
OBJECT_ATTRIBUTES obj_attr;
205+
UNICODE_STRING obj_name; //or RTL_CONSTANT_STRING
206+
RtlInitUnicodeString(&obj_name, LR"(\GLOBAL??)");
207+
InitializeObjectAttributes(&obj_attr, &obj_name, 0, NULL, NULL);
208+
209+
if (NT_SUCCESS(NtOpenDirectoryObject(&dir_handle, DIRECTORY_QUERY, &obj_attr))) { //or DIRECTORY_TRAVERSE?
210+
union {
211+
ib::Byte buf[2048]; //#TODO
212+
OBJECT_DIRECTORY_INFORMATION info[1];
213+
};
214+
ULONG context;
215+
216+
#pragma warning(suppress : 6001) //Warning C6001: Using uninitialized memory 'context'.
217+
NTSTATUS status = NtQueryDirectoryObject(dir_handle, buf, sizeof buf, false, true, &context, NULL);
218+
while (NT_SUCCESS(status)) { //STATUS_SUCCESS, STATUS_MORE_ENTRIES
219+
bool found = false;
220+
for (ULONG i = 0; info[i].Name.Buffer; i++) {
221+
std::wstring_view sv{ info[i].Name.Buffer, info[i].Name.Length / sizeof(wchar_t) };
222+
if (p(sv)) {
223+
result = LR"(\??\)" + std::wstring(sv);
224+
found = true;
225+
break;
226+
}
227+
}
228+
if (found || status != STATUS_MORE_ENTRIES)
229+
break;
230+
status = NtQueryDirectoryObject(dir_handle, buf, sizeof buf, false, false, &context, NULL);
231+
}
232+
233+
CloseHandle(dir_handle);
234+
}
235+
236+
return result;
237+
}
166238
}

0 commit comments

Comments
 (0)