Program Listing for File InputLoop.cpp
↰ Return to documentation for file (include/input/IPC/transmission/windows/InputLoop.cpp)
#include "ChildProcess.hpp"
#include <Windows.h>
#include <bitset>
#include "windows_keyboard_fill.hpp"
#include "ListDevice.hpp"
namespace PDJE_IPC{
void*
ChildProcess::Init()
{
HINSTANCE hst = GetModuleHandleW(nullptr);
WNDCLASSW wc{};
wc.lpfnWndProc = DefWindowProc;
wc.hInstance = hst;
wc.lpszClassName = L"PDJE_Invisible_RawInput_Worker";
RegisterClassW(&wc);
return CreateWindowExW(0,
wc.lpszClassName,
L"",
0,
0,
0,
0,
0,
HWND_MESSAGE,
nullptr,
hst,
nullptr);
}
void
ChildProcess::Run()
{
MSG msg;
DWORD w;
UINT size = 0;
uint64_t now;
PDJE_Dev_Type dtype;
thread_local std::pmr::unsynchronized_pool_resource mono_arena;
std::string handlestr;
std::string namestr;
PDJE_Input_Event tempEv;
handlestr.reserve(100);
PDJE_HID_Event hidEv;
std::bitset<102> isPressed;
bool Writable = true;
auto killer = std::thread([&](){
while(*spinlock_run->ptr == 1){
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
PostThreadMessageW(ThreadID, WM_QUIT, 0, 0);
});
PDJE_Input_Log cachedLog;
while (true) {
try {
w = MsgWaitForMultipleObjectsEx(0,
nullptr,
INFINITE,
QS_RAWINPUT | QS_POSTMESSAGE,
MWMO_INPUTAVAILABLE |
MWMO_ALERTABLE);
if (w == WAIT_OBJECT_0) {
if (PeekMessageW(&msg, nullptr, WM_QUIT, WM_QUIT, PM_REMOVE)) {
break;
}
while (PeekMessageW(
&msg, nullptr, WM_INPUT, WM_INPUT, PM_REMOVE)) {
Writable = true;
now = timer.Get_MicroSecond();
if (GetRawInputData(reinterpret_cast<HRAWINPUT>(msg.lParam),
RID_INPUT,
nullptr,
&size,
sizeof(RAWINPUTHEADER)) != 0 ||
size == 0) {
continue;
}
std::pmr::vector<BYTE> buf(&mono_arena);
buf.reserve(size);
if (GetRawInputData(reinterpret_cast<HRAWINPUT>(msg.lParam),
RID_INPUT,
buf.data(),
&size,
sizeof(RAWINPUTHEADER)) != size) {
continue;
}
const RAWINPUT *ri =
reinterpret_cast<const RAWINPUT *>(buf.data());
switch (ri->header.dwType) {
case RIM_TYPEMOUSE:
dtype = PDJE_Dev_Type::MOUSE;
PDJE_RAWINPUT::FillMouseInput(tempEv, ri);
break;
case RIM_TYPEKEYBOARD:
dtype = PDJE_Dev_Type::KEYBOARD;
PDJE_RAWINPUT::FillKeyboardInput(tempEv, ri);
if (isPressed.test(tempEv.keyboard.k) &&
tempEv.keyboard.pressed) {
Writable = false;
} else {
isPressed.set(tempEv.keyboard.k,
tempEv.keyboard.pressed);
}
break;
case RIM_TYPEHID:
dtype = PDJE_Dev_Type::HID;
PDJE_RAWINPUT::FillHIDInput( hidEv.hid_buffer,
ri, hidEv.hid_byte_size);
break;
default:
dtype = PDJE_Dev_Type::UNKNOWN;
break;
}
handlestr = std::to_string(
reinterpret_cast<uintptr_t>(ri->header.hDevice));
if (!unlisted_targets.empty()) {
if (!id_name.contains(handlestr)) {
if (GetRawInputDeviceInfoW(ri->header.hDevice,
RIDI_DEVICENAME,
nullptr,
&size) == (UINT)-1 ||
size == 0) {
} else {
std::wstring path(size, L'\0');
if (GetRawInputDeviceInfoW(ri->header.hDevice,
RIDI_DEVICENAME,
path.data(),
&size) == (UINT)-1) {
} else {
if (!path.empty() && path.back() == L'\0')
path.pop_back();
std::string device_path =
wstring_to_utf8_nt(path);
if (unlisted_targets.contains(
device_path)) {
id_name[handlestr] =
unlisted_targets[device_path];
unlisted_targets.erase(device_path);
}
}
}
}
}
if (Writable) {
cachedLog.type = dtype;
cachedLog.event = tempEv;
cachedLog.hid_event = hidEv;
cachedLog.id_len = handlestr.size() > 256 ? 256 : handlestr.size();
memcpy(cachedLog.id, handlestr.data(), sizeof(char)*(cachedLog.id_len));
namestr = id_name[handlestr];
cachedLog.name_len = namestr.size() > 256 ? 256 : namestr.size();
memcpy(cachedLog.name, namestr.data(), sizeof(char)*(cachedLog.name_len));
cachedLog.microSecond = now;
input_buffer->Write(cachedLog);
}
}
while (PeekMessageW(&msg, nullptr, 0, WM_QUIT - 1, PM_REMOVE)) {
}
while (PeekMessageW(
&msg, nullptr, WM_QUIT + 1, 0xFFFF, PM_REMOVE)) {
}
}
} catch (const std::exception &e) {
critlog("runtime err. what: ");
critlog(e.what());
}
}
killer.join();
}
};