.. _program_listing_file_include_input_runner_windows_InputLoop.cpp: Program Listing for File InputLoop.cpp ====================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include\input\runner\windows\InputLoop.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "ListDevice.hpp" #include "SubProcess.hpp" #include "windows_keyboard_fill.hpp" #include #include namespace PDJE_IPC { using namespace SUBPROC; void * TXRXListener::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 TXRXListener::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; MSG tmp; PeekMessageW(&tmp, nullptr, 0, 0, PM_NOREMOVE); auto killer = std::thread([&]() { terminate_event.Wait_Infinite(); PostThreadMessageW(ThreadID, WM_QUIT, 0, 0); }); input_loop_run_event.Wait_Infinite(); input_buffer->SendManageWorker(); 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(msg.lParam), RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0 || size == 0) { continue; } std::pmr::vector buf(&mono_arena); buf.resize(size); if (GetRawInputData(reinterpret_cast(msg.lParam), RID_INPUT, buf.data(), &size, sizeof(RAWINPUTHEADER)) != size) { continue; } const RAWINPUT *ri = reinterpret_cast(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; default: dtype = PDJE_Dev_Type::UNKNOWN; break; } handlestr = std::to_string( reinterpret_cast(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(); } }; // namespace PDJE_IPC