summaryrefslogtreecommitdiff
path: root/wrapper/input.cpp
diff options
context:
space:
mode:
authora1xd <[email protected]>2021-08-28 01:19:18 -0400
committera1xd <[email protected]>2021-09-23 22:28:44 -0400
commit5b659e1cfbc4b8fbbd2f2bf41dc716929976c77d (patch)
tree4bffba32fa508494a268b6f53513fb3c7b1e3e5c /wrapper/input.cpp
parentMerge pull request #107 from a1xd/1.5.0-fix (diff)
downloadrawaccel-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.cpp119
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());
}
}
-
};