diff options
| author | a1xd <[email protected]> | 2021-08-28 01:19:18 -0400 |
|---|---|---|
| committer | a1xd <[email protected]> | 2021-09-23 22:28:44 -0400 |
| commit | 5b659e1cfbc4b8fbbd2f2bf41dc716929976c77d (patch) | |
| tree | 4bffba32fa508494a268b6f53513fb3c7b1e3e5c /wrapper/input.cpp | |
| parent | Merge pull request #107 from a1xd/1.5.0-fix (diff) | |
| download | rawaccel-5b659e1cfbc4b8fbbd2f2bf41dc716929976c77d.tar.xz rawaccel-5b659e1cfbc4b8fbbd2f2bf41dc716929976c77d.zip | |
add per-device configuration
adds input and [in, out] cap for classic mode
adds input cap for power mode
change wrapper/input, now gets useful device names
change (now dev specific) dpi to adjust sensitivity
change y sensitivity to y/x ratio
remove spaced LUTs
grapher and convert do not build
Diffstat (limited to 'wrapper/input.cpp')
| -rw-r--r-- | wrapper/input.cpp | 119 |
1 files changed, 65 insertions, 54 deletions
diff --git a/wrapper/input.cpp b/wrapper/input.cpp index 3ce257a..e34af4a 100644 --- a/wrapper/input.cpp +++ b/wrapper/input.cpp @@ -1,79 +1,90 @@ #include "input.h" -#include "interop-exception.h" - -#include <msclr\marshal_cppstd.h> -#include <algorithm> using namespace System; using namespace System::Collections::Generic; +using namespace System::Runtime::InteropServices; -std::vector<HANDLE> rawinput_handles_from_id(const std::wstring& device_id) -{ - std::vector<HANDLE> handles; +[StructLayout(LayoutKind::Sequential, CharSet = CharSet::Unicode)] +public ref struct RawInputDevice { + System::IntPtr handle; - rawinput_foreach([&](const auto& dev) { - if (dev.id == device_id) handles.push_back(dev.handle); - }); + [MarshalAs(UnmanagedType::ByValTStr, SizeConst = MAX_NAME_LEN)] + System::String^ name; - return handles; -} + [MarshalAs(UnmanagedType::ByValTStr, SizeConst = MAX_DEV_ID_LEN)] + System::String^ id; +}; -std::vector<std::wstring> rawinput_id_list() +static int CompareByID(RawInputDevice^ x, RawInputDevice^ y) { - std::vector<std::wstring> ids; - - rawinput_foreach([&](const auto& dev) { - ids.push_back(dev.id); - }); - - std::sort(ids.begin(), ids.end()); - ids.erase(std::unique(ids.begin(), ids.end()), ids.end()); - return ids; + return String::Compare(x->id, y->id); } -public ref struct RawInputInteropException : InteropException { - RawInputInteropException(System::String^ what) : - InteropException(what) {} - RawInputInteropException(const char* what) : - InteropException(what) {} - RawInputInteropException(const std::exception& e) : - InteropException(e) {} -}; +public ref struct MultiHandleDevice { + System::String^ name; + System::String^ id; + List<System::IntPtr>^ handles; -public ref struct RawInputInterop -{ - static void AddHandlesFromID(String^ deviceID, List<IntPtr>^ rawInputHandles) + // Each element in the list returned has a distinct id + // https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-ids + static List<MultiHandleDevice^>^ GetList() { - try - { - std::vector<HANDLE> nativeHandles = rawinput_handles_from_id( - msclr::interop::marshal_as<std::wstring>(deviceID)); + return ListMaker::MakeList(); + } - for (auto nh : nativeHandles) rawInputHandles->Add(IntPtr(nh)); - } - catch (const std::exception& e) + ref class ListMaker { + List<RawInputDevice^>^ devices = gcnew List<RawInputDevice^>(); + + delegate void NativeDevHandler(rawinput_device&); + + void Add(rawinput_device& dev) { - throw gcnew RawInputInteropException(e); + devices->Add(Marshal::PtrToStructure<RawInputDevice^>(IntPtr(&dev))); } - } - static List<String^>^ GetDeviceIDs() - { - try + ListMaker() {} + public: + static List<MultiHandleDevice^>^ MakeList() { - auto ids = gcnew List<String^>(); + auto maker = gcnew ListMaker(); + NativeDevHandler^ del = gcnew NativeDevHandler(maker, &Add); + GCHandle gch = GCHandle::Alloc(del); + auto fp = static_cast<void (*)(rawinput_device&)>( + Marshal::GetFunctionPointerForDelegate(del).ToPointer()); + rawinput_foreach(fp); + gch.Free(); - for (auto&& name : rawinput_id_list()) - { - ids->Add(msclr::interop::marshal_as<String^>(name)); + auto ret = gcnew List<MultiHandleDevice^>(); + auto count = maker->devices->Count; + auto first = 0; + auto last = 0; + + if (count > 0) { + maker->devices->Sort(gcnew Comparison<RawInputDevice^>(&CompareByID)); + while (++last != count) { + if (!String::Equals(maker->devices[first]->id, maker->devices[last]->id)) { + auto range = maker->devices->GetRange(first, last - first); + ret->Add(gcnew MultiHandleDevice(range)); + first = last; + } + } + auto range = maker->devices->GetRange(first, last - first); + ret->Add(gcnew MultiHandleDevice(range)); } - return ids; + return ret; } - catch (const std::exception& e) - { - throw gcnew RawInputInteropException(e); + }; + +private: + MultiHandleDevice(IEnumerable<RawInputDevice^>^ seq) + { + auto it = seq->GetEnumerator(); + if (it->MoveNext()) { + name = it->Current->name; + id = it->Current->id; + handles = gcnew List<IntPtr>(); + do handles->Add(it->Current->handle); while (it->MoveNext()); } } - }; |