Skip to content

Commit d3b9f93

Browse files
committed
AhkDll: Add single input versions of send_mouse_input and send_keyboard_input
Fix the thread safety issue of DD::send_keyboard_input
1 parent 81f5ea8 commit d3b9f93

4 files changed

Lines changed: 168 additions & 153 deletions

File tree

AhkDll/SendTypes/Base.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,23 @@ namespace Send::Type::Internal {
6464
return count;
6565
}
6666

67-
virtual uint32_t send_mouse_input(const INPUT inputs[], uint32_t n) = 0;
68-
virtual uint32_t send_keyboard_input(const INPUT inputs[], uint32_t n) = 0;
67+
virtual uint32_t send_mouse_input(const INPUT inputs[], uint32_t n) {
68+
uint32_t count = 0;
69+
for (uint32_t i = 0; i < n; i++)
70+
count += send_mouse_input(inputs[i].mi);
71+
return count;
72+
}
73+
74+
virtual bool send_mouse_input(const MOUSEINPUT& mi) = 0;
75+
76+
virtual uint32_t send_keyboard_input(const INPUT inputs[], uint32_t n) {
77+
uint32_t count = 0;
78+
for (uint32_t i = 0; i < n; i++)
79+
count += send_keyboard_input(inputs[i].ki);
80+
return count;
81+
}
82+
83+
virtual bool send_keyboard_input(const KEYBDINPUT& ki) = 0;
6984

7085
virtual SHORT get_key_state(int vKey) {
7186
return (*get_key_state_fallback)(vKey);

AhkDll/SendTypes/DD.hpp

Lines changed: 65 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -64,88 +64,83 @@ namespace Send::Type::Internal {
6464
FreeLibrary(dd);
6565
}
6666

67-
uint32_t send_mouse_input(const INPUT inputs[], uint32_t n) override {
68-
for(uint32_t i = 0; i < n; i++) {
69-
const MOUSEINPUT& mi = inputs[i].mi;
70-
71-
//#TODO: MOUSEEVENTF_MOVE_NOCOALESCE, MOUSEEVENTF_VIRTUALDESK
72-
if (mi.dwFlags & MOUSEEVENTF_MOVE) {
73-
POINT move{ mi.dx, mi.dy };
74-
if (mi.dwFlags & MOUSEEVENTF_ABSOLUTE) {
75-
mouse_absolute_to_screen(move);
76-
if constexpr (debug)
77-
DebugOStream() << L"DD_mov: (" << move.x << L", " << move.y << L")\n";
78-
DD_mov(move.x, move.y);
79-
} else {
80-
if constexpr (debug)
81-
DebugOStream() << L"DD_movR: (" << move.x << L", " << move.y << L")\n";
82-
DD_movR(move.x, move.y);
83-
}
67+
bool send_mouse_input(const MOUSEINPUT& mi) override {
68+
//#TODO: MOUSEEVENTF_MOVE_NOCOALESCE, MOUSEEVENTF_VIRTUALDESK
69+
if (mi.dwFlags & MOUSEEVENTF_MOVE) {
70+
POINT move{ mi.dx, mi.dy };
71+
if (mi.dwFlags & MOUSEEVENTF_ABSOLUTE) {
72+
mouse_absolute_to_screen(move);
73+
if constexpr (debug)
74+
DebugOStream() << L"DD_mov: (" << move.x << L", " << move.y << L")\n";
75+
DD_mov(move.x, move.y);
76+
} else {
77+
if constexpr (debug)
78+
DebugOStream() << L"DD_movR: (" << move.x << L", " << move.y << L")\n";
79+
DD_movR(move.x, move.y);
8480
}
81+
}
8582

86-
if (mi.dwFlags & 0x7E) {
87-
DWORD keys[] = { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP };
88-
for (DWORD key : keys)
89-
if (mi.dwFlags & key) {
90-
if constexpr (debug)
91-
DebugOStream() << L"DD_btn: " << (key >> 1) << L"\n";
92-
DD_btn(key >> 1);
93-
}
94-
}
95-
if (mi.dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) {
96-
bool down = mi.dwFlags & MOUSEEVENTF_XDOWN;
97-
switch (mi.mouseData) {
98-
case XBUTTON1: DD_btn(down ? 64 : 128); break;
99-
case XBUTTON2: DD_btn(down ? 256 : 512); break;
83+
if (mi.dwFlags & 0x7E) {
84+
DWORD keys[] = { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP };
85+
for (DWORD key : keys)
86+
if (mi.dwFlags & key) {
87+
if constexpr (debug)
88+
DebugOStream() << L"DD_btn: " << (key >> 1) << L"\n";
89+
DD_btn(key >> 1);
10090
}
101-
} else if (mi.dwFlags & MOUSEEVENTF_WHEEL) {
102-
int32_t v = std::bit_cast<int32_t>(mi.mouseData);
103-
int sign = v > 0 ? 1 : -1;
104-
if constexpr (debug)
105-
DebugOStream() << L"DD_whl: " << v << L"\n";
106-
for (DWORD i = 0; i < abs(v); i++)
107-
DD_whl(sign);
91+
}
92+
if (mi.dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) {
93+
bool down = mi.dwFlags & MOUSEEVENTF_XDOWN;
94+
switch (mi.mouseData) {
95+
case XBUTTON1: DD_btn(down ? 64 : 128); break;
96+
case XBUTTON2: DD_btn(down ? 256 : 512); break;
10897
}
98+
} else if (mi.dwFlags & MOUSEEVENTF_WHEEL) {
99+
int32_t v = std::bit_cast<int32_t>(mi.mouseData);
100+
int sign = v > 0 ? 1 : -1;
101+
if constexpr (debug)
102+
DebugOStream() << L"DD_whl: " << v << L"\n";
103+
for (DWORD i = 0; i < abs(v); i++)
104+
DD_whl(sign);
109105
}
110-
return n; //#TODO
106+
107+
return true; //#TODO
111108
}
112109

113-
uint32_t send_keyboard_input(const INPUT inputs[], uint32_t n) override {
114-
uint32_t count = 0;
115-
for (uint32_t i = 0; i < n; i++) {
116-
const KEYBDINPUT& ki = inputs[i].ki;
110+
bool send_keyboard_input(const KEYBDINPUT& ki) override {
111+
std::lock_guard lock(keyboard_mutex);
112+
113+
bool keydown = !(ki.dwFlags & KEYEVENTF_KEYUP);
114+
if (is_modifier(ki.wVk))
115+
set_modifier_state(ki.wVk, keydown);
116+
117+
int dd_code = DD_todc(ki.wVk);
118+
if (dd_code == -1) {
119+
// (some version) DD do not support left/right modifiers
120+
if (ki.wVk == VK_LSHIFT || ki.wVk == VK_RSHIFT)
121+
dd_code = DD_todc(VK_SHIFT);
122+
else if (ki.wVk == VK_LCONTROL || ki.wVk == VK_RCONTROL)
123+
dd_code = DD_todc(VK_CONTROL);
124+
else if (ki.wVk == VK_LMENU || ki.wVk == VK_RMENU)
125+
dd_code = DD_todc(VK_MENU);
117126

118-
bool keydown = !(ki.dwFlags & KEYEVENTF_KEYUP);
119-
if (is_modifier(ki.wVk))
120-
set_modifier_state(ki.wVk, keydown);
121-
122-
int dd_code = DD_todc(ki.wVk);
123127
if (dd_code == -1) {
124-
// (some version) DD do not support left/right modifiers
125-
if (ki.wVk == VK_LSHIFT || ki.wVk == VK_RSHIFT)
126-
dd_code = DD_todc(VK_SHIFT);
127-
else if (ki.wVk == VK_LCONTROL || ki.wVk == VK_RCONTROL)
128-
dd_code = DD_todc(VK_CONTROL);
129-
else if (ki.wVk == VK_LMENU || ki.wVk == VK_RMENU)
130-
dd_code = DD_todc(VK_MENU);
131-
132-
if (dd_code == -1) {
133-
if constexpr (debug)
134-
DebugOStream() << L"DD_todc: unsupported key " << ki.wVk << L"\n";
135-
continue;
136-
}
137-
else {
138-
if constexpr (debug)
139-
DebugOStream() << L"DD_todc: left/right modifier key (" << ki.wVk << ") is unsupported" << L"\n";
140-
}
128+
if constexpr (debug)
129+
DebugOStream() << L"DD_todc: unsupported key " << ki.wVk << L"\n";
130+
return false;
131+
}
132+
else {
133+
if constexpr (debug)
134+
DebugOStream() << L"DD_todc: left/right modifier key (" << ki.wVk << ") is unsupported" << L"\n";
141135
}
142-
if constexpr (debug)
143-
DebugOStream() << L"DD_key: " << dd_code << L" (vk" << ki.wVk << L"), " << (keydown ? 1 : 2) << L")\n";
144-
DD_key(dd_code, keydown ? 1 : 2); //#TODO: result?
145-
count++;
146136
}
147-
return count;
137+
if constexpr (debug)
138+
DebugOStream() << L"DD_key: " << dd_code << L" (vk" << ki.wVk << L"), " << (keydown ? 1 : 2) << L")\n";
139+
DD_key(dd_code, keydown ? 1 : 2); //#TODO: result?
140+
141+
return true;
148142
}
143+
149144
#pragma warning(suppress : 4250) //'class1' : inherits 'class2::member' via dominance
150145
};
151146
}

AhkDll/SendTypes/Logitech.hpp

Lines changed: 67 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -523,113 +523,102 @@ namespace Send::Type::Internal {
523523
std::mutex mouse_mutex;
524524

525525
public:
526-
uint32_t send_mouse_input(const INPUT inputs[], uint32_t n) override {
527-
uint32_t count = 0;
526+
bool send_mouse_input(const MOUSEINPUT& mi) override {
528527
std::lock_guard lock(mouse_mutex);
528+
529+
if constexpr (debug)
530+
DebugOStream() << L"send_mouse_input: " << mi.dwFlags << L", " << mi.dx << L", " << mi.dy << std::endl;
529531

530-
for (uint32_t i = 0; i < n; i++) {
531-
const MOUSEINPUT& mi = inputs[i].mi;
532-
if constexpr (debug)
533-
DebugOStream() << L"send_mouse_input: " << mi.dwFlags << L", " << mi.dx << L", " << mi.dy << std::endl;
532+
//#TODO: move and then click, or click and then move? former?
534533

535-
//#TODO: move and then click, or click and then move? former?
534+
//#TODO: MOUSEEVENTF_MOVE_NOCOALESCE, MOUSEEVENTF_VIRTUALDESK
535+
if (mi.dwFlags & MOUSEEVENTF_MOVE) {
536+
POINT move { mi.dx, mi.dy };
537+
if (mi.dwFlags & MOUSEEVENTF_ABSOLUTE) {
538+
mouse_absolute_to_screen(move);
539+
mouse_screen_to_relative(move);
540+
}
536541

537-
//#TODO: MOUSEEVENTF_MOVE_NOCOALESCE, MOUSEEVENTF_VIRTUALDESK
538-
if (mi.dwFlags & MOUSEEVENTF_MOVE) {
539-
POINT move { mi.dx, mi.dy };
540-
if (mi.dwFlags & MOUSEEVENTF_ABSOLUTE) {
541-
mouse_absolute_to_screen(move);
542-
mouse_screen_to_relative(move);
542+
while (abs(move.x) > 127 || abs(move.y) > 127) {
543+
if (abs(move.x) > 127) {
544+
mouse_report.x = move.x > 0 ? 127 : -127;
545+
move.x -= mouse_report.x;
546+
}
547+
else {
548+
mouse_report.x = 0;
543549
}
544550

545-
while (abs(move.x) > 127 || abs(move.y) > 127) {
546-
if (abs(move.x) > 127) {
547-
mouse_report.x = move.x > 0 ? 127 : -127;
548-
move.x -= mouse_report.x;
549-
}
550-
else {
551-
mouse_report.x = 0;
552-
}
553-
554-
if (abs(move.y) > 127) {
555-
mouse_report.y = move.y > 0 ? 127 : -127;
556-
move.y -= mouse_report.y;
557-
}
558-
else {
559-
mouse_report.y = 0;
560-
}
561-
562-
driver.report_mouse(mouse_report, compensate_switch = -compensate_switch);
551+
if (abs(move.y) > 127) {
552+
mouse_report.y = move.y > 0 ? 127 : -127;
553+
move.y -= mouse_report.y;
554+
}
555+
else {
556+
mouse_report.y = 0;
563557
}
564558

565-
mouse_report.x = (uint8_t)move.x;
566-
mouse_report.y = (uint8_t)move.y;
567-
} else {
568-
mouse_report.x = 0;
569-
mouse_report.y = 0;
559+
driver.report_mouse(mouse_report, compensate_switch = -compensate_switch);
570560
}
571561

562+
mouse_report.x = (uint8_t)move.x;
563+
mouse_report.y = (uint8_t)move.y;
564+
} else {
565+
mouse_report.x = 0;
566+
mouse_report.y = 0;
567+
}
568+
572569
#define CODE_GENERATE(down, up, member) \
573-
if (mi.dwFlags & down || mi.dwFlags & up) \
574-
mouse_report.button.##member = mi.dwFlags & down;
570+
if (mi.dwFlags & down || mi.dwFlags & up) \
571+
mouse_report.button.##member = mi.dwFlags & down;
575572

576-
CODE_GENERATE(MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, LButton) //#TODO: may be switched?
577-
CODE_GENERATE(MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, RButton)
578-
CODE_GENERATE(MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MButton)
573+
CODE_GENERATE(MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, LButton) //#TODO: may be switched?
574+
CODE_GENERATE(MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, RButton)
575+
CODE_GENERATE(MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MButton)
579576
#undef CODE_GENERATE
580-
if (mi.dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) {
581-
bool down = mi.dwFlags & MOUSEEVENTF_XDOWN;
582-
switch (mi.mouseData) {
583-
case XBUTTON1: mouse_report.button.XButton1 = down; break;
584-
case XBUTTON2: mouse_report.button.XButton2 = down; break;
585-
}
577+
if (mi.dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) {
578+
bool down = mi.dwFlags & MOUSEEVENTF_XDOWN;
579+
switch (mi.mouseData) {
580+
case XBUTTON1: mouse_report.button.XButton1 = down; break;
581+
case XBUTTON2: mouse_report.button.XButton2 = down; break;
586582
}
587-
588-
count += driver.report_mouse(mouse_report, compensate_switch = -compensate_switch);
589583
}
590-
591-
return count;
584+
585+
return driver.report_mouse(mouse_report, compensate_switch = -compensate_switch);
592586
}
593587

594588
private:
595589
LogitechDriver::KeyboardReport keyboard_report{};
596590
std::mutex keyboard_mutex;
597591
public:
598-
uint32_t send_keyboard_input(const INPUT inputs[], uint32_t n) override {
599-
uint32_t count = 0;
592+
bool send_keyboard_input(const KEYBDINPUT& ki) override {
600593
std::lock_guard lock(keyboard_mutex);
601594

602-
for (uint32_t i = 0; i < n; i++) {
603-
const KEYBDINPUT& ki = inputs[i].ki;
604-
605-
bool keydown = !(ki.dwFlags & KEYEVENTF_KEYUP);
606-
if (is_modifier(ki.wVk)) {
607-
set_modifier_state(ki.wVk, keydown);
608-
} else {
609-
uint8_t usage = driver.keyboard_vk_to_usage((uint8_t)ki.wVk);;
610-
if (keydown) {
611-
for (int i = 0; i < 6; i++) {
612-
if (keyboard_report.keys[i] == 0) {
613-
keyboard_report.keys[i] = usage;
614-
break;
615-
}
595+
bool keydown = !(ki.dwFlags & KEYEVENTF_KEYUP);
596+
if (is_modifier(ki.wVk)) {
597+
set_modifier_state(ki.wVk, keydown);
598+
}
599+
else {
600+
uint8_t usage = driver.keyboard_vk_to_usage((uint8_t)ki.wVk);;
601+
if (keydown) {
602+
for (int i = 0; i < 6; i++) {
603+
if (keyboard_report.keys[i] == 0) {
604+
keyboard_report.keys[i] = usage;
605+
break;
616606
}
617-
//full
618607
}
619-
else {
620-
for (int i = 0; i < 6; i++) {
621-
if (keyboard_report.keys[i] == usage) {
622-
keyboard_report.keys[i] = 0;
623-
//#TODO: move to left?
624-
break;
625-
}
608+
//full
609+
}
610+
else {
611+
for (int i = 0; i < 6; i++) {
612+
if (keyboard_report.keys[i] == usage) {
613+
keyboard_report.keys[i] = 0;
614+
//#TODO: move to left?
615+
break;
626616
}
627617
}
628618
}
629-
630-
count += driver.report_keyboard(keyboard_report);
631619
}
632-
return count;
620+
621+
return driver.report_keyboard(keyboard_report);
633622
}
634623
#pragma warning(suppress : 4250) //'class1' : inherits 'class2::member' via dominance
635624
};

AhkDll/SendTypes/SendInput.hpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,31 @@ namespace Send::Type::Internal {
1313
void destroy() override {}
1414

1515
uint32_t send_input(const INPUT inputs[], uint32_t n) override {
16-
return (*SendInput_true)(n, (INPUT*)inputs, sizeof INPUT);
16+
return (*SendInput_true)(n, const_cast<INPUT*>(inputs), sizeof INPUT);
1717
}
1818

19+
1920
uint32_t send_mouse_input(const INPUT inputs[], uint32_t n) override {
20-
return (*SendInput_true)(n, (INPUT*)inputs, sizeof INPUT);
21+
return (*SendInput_true)(n, const_cast<INPUT*>(inputs), sizeof INPUT);
22+
}
23+
24+
bool send_mouse_input(const MOUSEINPUT& mi) override {
25+
INPUT input;
26+
input.type = INPUT_MOUSE;
27+
input.mi = mi;
28+
return (*SendInput_true)(1, &input, sizeof INPUT);
2129
}
2230

31+
2332
uint32_t send_keyboard_input(const INPUT inputs[], uint32_t n) override {
24-
return (*SendInput_true)(n, (INPUT*)inputs, sizeof INPUT);
33+
return (*SendInput_true)(n, const_cast<INPUT*>(inputs), sizeof INPUT);
34+
}
35+
36+
bool send_keyboard_input(const KEYBDINPUT& ki) override {
37+
INPUT input;
38+
input.type = INPUT_KEYBOARD;
39+
input.ki = ki;
40+
return (*SendInput_true)(1, &input, sizeof INPUT);
2541
}
2642
};
2743
}

0 commit comments

Comments
 (0)