chore: CRLF to LF

This commit is contained in:
smpn2
2022-12-16 23:18:35 +09:00
parent b7a60638a4
commit 6c914266d9
725 changed files with 131020 additions and 131020 deletions
+132 -132
View File
@@ -1,132 +1,132 @@
#include <initguid.h>
#include "hotplug.h"
#include <dbt.h>
#include <devguid.h>
#include "misc/eamuse.h"
#include "rawinput.h"
#include "util/fileutils.h"
#include "util/logging.h"
namespace rawinput {
DEFINE_GUID(GUID_HID, 0x4D1E55B2L, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30);
HotplugManager::HotplugManager(RawInputManager *ri_mgr, HWND hWnd) : ri_mgr(ri_mgr) {
// init settings
DEV_BROADCAST_DEVICEINTERFACE settings_hid {
.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE),
.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE,
.dbcc_reserved = 0,
.dbcc_classguid = GUID_HID,
.dbcc_name = {0},
};
// register notifications
this->hotplug_hid = RegisterDeviceNotification(hWnd, &settings_hid, DEVICE_NOTIFY_WINDOW_HANDLE);
if (this->hotplug_hid == nullptr) {
log_warning("hotplug", "failed to register HID notifications: {}", GetLastError());
}
}
HotplugManager::~HotplugManager() {
// unregister notifications
if (this->hotplug_hid != nullptr) {
UnregisterDeviceNotification(this->hotplug_hid);
}
}
LRESULT CALLBACK HotplugManager::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
// check for device change
if (msg == WM_DEVICECHANGE) {
// check type
switch (wParam) {
case DBT_DEVICEARRIVAL: {
// check arrived device type
auto hdr = (DEV_BROADCAST_HDR*) lParam;
switch (hdr->dbch_devicetype) {
case DBT_DEVTYP_DEVICEINTERFACE: {
auto dev = (const DEV_BROADCAST_DEVICEINTERFACE *) hdr;
this->ri_mgr->devices_scan_midi();
// check if class is not HID
if (memcmp(&dev->dbcc_classguid, &GUID_HID, sizeof(GUID_HID)) != 0)
break;
// hotplug
std::string name(dev->dbcc_name);
this->ri_mgr->devices_scan_rawinput(name);
this->ri_mgr->devices_register();
break;
}
case DBT_DEVTYP_VOLUME: {
auto dev = (const DEV_BROADCAST_VOLUME *) hdr;
auto unitmask = dev->dbcv_unitmask;
// check drive
unsigned long bit;
while (_BitScanForward(&bit, unitmask)) {
// remove drive from unitmask so it is not scanned again
unitmask &= ~(1 << bit);
// convert bit to drive letter char
char drive = 'A' + bit;
log_info("hotplug", "detected volume arrival: {}", drive);
#ifndef SPICETOOLS_SPICECFG_STANDALONE
// auto insert cards
for (int player = 0; player <= 1; player++) {
std::string path = to_string(drive) + ":\\card" + to_string(player) + ".txt";
if (fileutils::file_exists(path)) {
uint8_t card_data[8];
if (eamuse_get_card(path, card_data)) {
eamuse_card_insert(player, card_data);
}
}
}
#endif
}
break;
}
}
// success
return TRUE;
}
case DBT_DEVICEREMOVECOMPLETE: {
// check arrived device type
auto hdr = (DEV_BROADCAST_HDR*) lParam;
switch (hdr->dbch_devicetype) {
case DBT_DEVTYP_DEVICEINTERFACE: {
auto dev = (DEV_BROADCAST_DEVICEINTERFACE*) hdr;
std::string name(dev->dbcc_name);
// destruct device
this->ri_mgr->devices_remove(name);
}
}
// success
return TRUE;
}
case 7: { // windows 10 reports this for MIDI?
this->ri_mgr->devices_scan_midi();
break;
}
}
}
// default
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
#include <initguid.h>
#include "hotplug.h"
#include <dbt.h>
#include <devguid.h>
#include "misc/eamuse.h"
#include "rawinput.h"
#include "util/fileutils.h"
#include "util/logging.h"
namespace rawinput {
DEFINE_GUID(GUID_HID, 0x4D1E55B2L, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30);
HotplugManager::HotplugManager(RawInputManager *ri_mgr, HWND hWnd) : ri_mgr(ri_mgr) {
// init settings
DEV_BROADCAST_DEVICEINTERFACE settings_hid {
.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE),
.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE,
.dbcc_reserved = 0,
.dbcc_classguid = GUID_HID,
.dbcc_name = {0},
};
// register notifications
this->hotplug_hid = RegisterDeviceNotification(hWnd, &settings_hid, DEVICE_NOTIFY_WINDOW_HANDLE);
if (this->hotplug_hid == nullptr) {
log_warning("hotplug", "failed to register HID notifications: {}", GetLastError());
}
}
HotplugManager::~HotplugManager() {
// unregister notifications
if (this->hotplug_hid != nullptr) {
UnregisterDeviceNotification(this->hotplug_hid);
}
}
LRESULT CALLBACK HotplugManager::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
// check for device change
if (msg == WM_DEVICECHANGE) {
// check type
switch (wParam) {
case DBT_DEVICEARRIVAL: {
// check arrived device type
auto hdr = (DEV_BROADCAST_HDR*) lParam;
switch (hdr->dbch_devicetype) {
case DBT_DEVTYP_DEVICEINTERFACE: {
auto dev = (const DEV_BROADCAST_DEVICEINTERFACE *) hdr;
this->ri_mgr->devices_scan_midi();
// check if class is not HID
if (memcmp(&dev->dbcc_classguid, &GUID_HID, sizeof(GUID_HID)) != 0)
break;
// hotplug
std::string name(dev->dbcc_name);
this->ri_mgr->devices_scan_rawinput(name);
this->ri_mgr->devices_register();
break;
}
case DBT_DEVTYP_VOLUME: {
auto dev = (const DEV_BROADCAST_VOLUME *) hdr;
auto unitmask = dev->dbcv_unitmask;
// check drive
unsigned long bit;
while (_BitScanForward(&bit, unitmask)) {
// remove drive from unitmask so it is not scanned again
unitmask &= ~(1 << bit);
// convert bit to drive letter char
char drive = 'A' + bit;
log_info("hotplug", "detected volume arrival: {}", drive);
#ifndef SPICETOOLS_SPICECFG_STANDALONE
// auto insert cards
for (int player = 0; player <= 1; player++) {
std::string path = to_string(drive) + ":\\card" + to_string(player) + ".txt";
if (fileutils::file_exists(path)) {
uint8_t card_data[8];
if (eamuse_get_card(path, card_data)) {
eamuse_card_insert(player, card_data);
}
}
}
#endif
}
break;
}
}
// success
return TRUE;
}
case DBT_DEVICEREMOVECOMPLETE: {
// check arrived device type
auto hdr = (DEV_BROADCAST_HDR*) lParam;
switch (hdr->dbch_devicetype) {
case DBT_DEVTYP_DEVICEINTERFACE: {
auto dev = (DEV_BROADCAST_DEVICEINTERFACE*) hdr;
std::string name(dev->dbcc_name);
// destruct device
this->ri_mgr->devices_remove(name);
}
}
// success
return TRUE;
}
case 7: { // windows 10 reports this for MIDI?
this->ri_mgr->devices_scan_midi();
break;
}
}
}
// default
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
+20 -20
View File
@@ -1,20 +1,20 @@
#pragma once
#include <windows.h>
namespace rawinput {
class RawInputManager;
class HotplugManager {
private:
RawInputManager *ri_mgr;
HANDLE hotplug_hid;
public:
HotplugManager(RawInputManager *ri_mgr, HWND hwnd);
~HotplugManager();
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
};
}
#pragma once
#include <windows.h>
namespace rawinput {
class RawInputManager;
class HotplugManager {
private:
RawInputManager *ri_mgr;
HANDLE hotplug_hid;
public:
HotplugManager(RawInputManager *ri_mgr, HWND hwnd);
~HotplugManager();
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
};
}
+394 -394
View File
@@ -1,394 +1,394 @@
#include "piuio.h"
#include <iostream>
#include <thread>
using namespace std;
// it's 2019 and I'm writing code to avoid issues with Windows XP.
static HINSTANCE WINUSB_INSTANCE = nullptr;
static std::string WINUSB_NAME = "winusb.dll";
static std::string WinUsb_InitializeStr = "WinUsb_Initialize";
typedef BOOL(__stdcall * WinUsb_Initialize_t)(
_In_ HANDLE DeviceHandle,
_Out_ PWINUSB_INTERFACE_HANDLE InterfaceHandle
);
static std::string WinUsb_ControlTransferStr = "WinUsb_ControlTransfer";
typedef BOOL(__stdcall * WinUsb_ControlTransfer_t)(
_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle,
_In_ WINUSB_SETUP_PACKET SetupPacket,
_Out_writes_bytes_to_opt_(BufferLength, *LengthTransferred) PUCHAR Buffer,
_In_ ULONG BufferLength,
_Out_opt_ PULONG LengthTransferred,
_In_opt_ LPOVERLAPPED Overlapped
);
static WinUsb_ControlTransfer_t pWinUsb_ControlTransfer = nullptr;
static WinUsb_Initialize_t pWinUsb_Initialize = nullptr;
const string rawinput::PIUIO::LIGHT_NAMES[rawinput::PIUIO::PIUIO_MAX_NUM_OF_LIGHTS] = {
"Unknown",
"Unknown",
"P2 Up",
"P2 Down",
"P2 Left",
"P2 Right",
"P2 Center",
"Unknown",
"Unknown",
"Unknown",
"Neon",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"P1 Up",
"P1 Down",
"P1 Left",
"P1 Right",
"P1 Center",
"Marquee Upper Left",
"Marquee Lower Right",
"Marquee Lower Left",
"Marquee Upper Right",
"USB Enable",
"Unknown",
"Unknown",
"Unknown",
"Unknown"
};
rawinput::PIUIO::PIUIO(Device *device) {
this->device = device;
button_state = 0;
light_data = 0;
current_sensor = 0;
prev_timeout = 0;
}
bool rawinput::PIUIO::LoadWinUSBFunctions() {
static bool functions_loaded = false;
if (functions_loaded)
return true;
// see if we even have winusb available.
WINUSB_INSTANCE = libutils::try_library(WINUSB_NAME);
// if windows didn't load it just now, then it's not on the system.
if (WINUSB_INSTANCE != nullptr) {
// load winusb functions
pWinUsb_Initialize = (WinUsb_Initialize_t) libutils::get_proc(
WINUSB_INSTANCE, WinUsb_InitializeStr.c_str());
pWinUsb_ControlTransfer = (WinUsb_ControlTransfer_t) libutils::get_proc(
WINUSB_INSTANCE, WinUsb_ControlTransferStr.c_str());
// make sure they actually loaded.
if(pWinUsb_Initialize != nullptr && pWinUsb_ControlTransfer!= nullptr)
functions_loaded = true;
} else {
log_warning("piuio", "Could not load \'{}\', skipping...", WINUSB_NAME);
}
return functions_loaded;
}
PSP_DEVICE_INTERFACE_DETAIL_DATA rawinput::PIUIO::GetDevicePath() {
// modified from https://forum.vellemanprojects.eu/t/k8090-how-to-identify-which-com-port-it-is-connected-to/3810
// https://www.velleman.eu/images/tmp/usbfind.c
HDEVINFO hDevInfo;
SP_DEVICE_INTERFACE_DATA DevIntfData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DevIntfDetailData;
SP_DEVINFO_DATA DevData;
DWORD dwSize, dwMemberIdx;
hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if (hDevInfo != INVALID_HANDLE_VALUE) {
DevIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
dwMemberIdx = 0;
SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE,
dwMemberIdx, &DevIntfData);
while (GetLastError() != ERROR_NO_MORE_ITEMS) {
DevData.cbSize = sizeof(DevData);
SetupDiGetDeviceInterfaceDetail(
hDevInfo, &DevIntfData, NULL, 0, &dwSize, NULL);
DevIntfDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData,
DevIntfDetailData, dwSize, &dwSize, &DevData)) {
if (strstr(DevIntfDetailData->DevicePath, VENDOR_PROD_ID) != 0) {
return DevIntfDetailData;
}
}
HeapFree(GetProcessHeap(), 0, DevIntfDetailData);
// continue looping
SetupDiEnumDeviceInterfaces(
hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, ++dwMemberIdx, &DevIntfData);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
return 0;
}
bool rawinput::PIUIO::IsPressed(int iKey) {
if (iKey < PIUIO_MAX_NUM_OF_INPUTS) {
// logic high is pressed, logic low is released.
return button_state & (1 << iKey);
}
return false;
}
bool rawinput::PIUIO::WasPressed(int iKey) {
if (iKey < PIUIO_MAX_NUM_OF_INPUTS)
return prev_button_state & (1 << iKey);
return false;
}
void rawinput::PIUIO::SetUSBPortState(bool bState) {
SetLight(USB_ENABLE_BIT, bState);
}
void rawinput::PIUIO::SetLight(int iLight, bool bState) {
if (iLight < PIUIO_MAX_NUM_OF_LIGHTS) {
// turn on a light by setting the bit, turn it off by clearing it.
if (bState)
light_data |= 1 << iLight;
else
light_data &= ~(1 << iLight);
}
}
bool rawinput::PIUIO::Open() {
// ensure the libs are loaded
// if we can't load them, then we shouldn't exist.
if (!LoadWinUSBFunctions())
return false;
bool bResult = false;
PSP_DEVICE_INTERFACE_DETAIL_DATA dev_detail;
dev_detail = GetDevicePath();
if (dev_detail == 0) {
HeapFree(GetProcessHeap(), 0, dev_detail);
return false;
}
device_handle = CreateFile(dev_detail->DevicePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
);
// no longer need dev_detail
HeapFree(GetProcessHeap(), 0, dev_detail);
if (device_handle == INVALID_HANDLE_VALUE)
return false;
if (pWinUsb_Initialize != nullptr)
bResult = pWinUsb_Initialize(device_handle, &win_usb_handle);
if (!bResult) {
CloseHandle(device_handle);
return false;
}
return bResult;
}
uint32_t rawinput::PIUIO::Read() {
WINUSB_SETUP_PACKET SetupPacket;
ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
ULONG cbSent = 0;
bool bResult = false;
// create the setup packet
SetupPacket.RequestType = 0x40 | 0x80; // EndPoint In, RequestType Vendor
SetupPacket.Request = PIUIO_CTL_REQ;
SetupPacket.Value = 0;
SetupPacket.Index = 0;
SetupPacket.Length = PACKET_SIZE_BYTES;
// ensure we loaded the pointer
unsigned char buffer[PACKET_SIZE_BYTES] {};
if (pWinUsb_ControlTransfer != nullptr)
bResult = pWinUsb_ControlTransfer(win_usb_handle, SetupPacket, buffer, PACKET_SIZE_BYTES, &cbSent, 0);
if (!bResult)
log_warning("piuio", "read error");
return Deserialize(buffer);
}
bool rawinput::PIUIO::Write(uint32_t p_Data) {
WINUSB_SETUP_PACKET SetupPacket;
ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
ULONG cbSent = 0;
bool bResult = false;
// create the setup packet
SetupPacket.RequestType = 0x40; //EndPoint Out, RequestType Vendor
SetupPacket.Request = PIUIO_CTL_REQ;
SetupPacket.Value = 0;
SetupPacket.Index = 0;
SetupPacket.Length = PACKET_SIZE_BYTES;
// ensure we loaded the pointer
if (pWinUsb_ControlTransfer != nullptr) {
bResult = pWinUsb_ControlTransfer(
win_usb_handle,
SetupPacket,
Serialize(light_data),
PACKET_SIZE_BYTES,
&cbSent,
0
);
}
if (!bResult)
log_warning("piuio", "write error");
return bResult;
}
unsigned char * rawinput::PIUIO::Serialize(uint32_t p_Data) {
static unsigned char buffer[PACKET_SIZE_BYTES];
buffer[0] = p_Data;
buffer[1] = p_Data >> 8;
buffer[2] = p_Data >> 16;
buffer[3] = p_Data >> 24;
// these bits don't matter for the piuio
buffer[4] = 0xFF;
buffer[5] = 0xFF;
buffer[6] = 0xFF;
buffer[7] = 0xFF;
return buffer;
}
uint32_t rawinput::PIUIO::Deserialize(unsigned char * p_Data) {
uint32_t result;
result = p_Data[0];
result |= p_Data[1] << 8;
result |= p_Data[2] << 16;
result |= p_Data[3] << 24;
return result;
}
void rawinput::PIUIO::IOThread() {
while (is_connected)
UpdateSingleButtonState();
}
void rawinput::PIUIO::UpdateSingleButtonState() {
// write a set of sensors to request
light_data &= 0xFFFCFFFC;
light_data |= (current_sensor | (current_sensor << 16));
// request this set of sensors
// this also updates the light status
this->Write(light_data);
// read from this set of sensors
input_data[current_sensor] = this->Read();
// piuio opens high; invert the input
input_data[current_sensor] = ~input_data[current_sensor];
// update high values ASAP, that's when the button is pressed.
// see: https://github.com/djpohly/piuio#usb-protocol-and-multiplexer
auto button_state_new = button_state | input_data[current_sensor];
if (button_state != button_state_new) {
this->device->mutex->lock();
button_state |= button_state_new;
this->device->updated = true;
this->device->mutex->unlock();
}
if (current_sensor >= SENSOR_NUM - 1) {
uint32_t temp_btn_state = 0;
// we have done a full sensor arrangement, let's see if the panel has been pulled away from.
// combine all the input.
for (int i = 0; i < 4; ++i)
temp_btn_state |= input_data[i];
// only store every 255th previous value since we are polling very quickly.
// only used by spicecfg to see if a user pressed a button, so not very important.
// unsigned ints rollover
prev_timeout++;
if (prev_timeout == 0)
prev_button_state = button_state;
if (button_state != temp_btn_state) {
this->device->mutex->lock();
button_state = temp_btn_state;
this->device->updated = true;
this->device->mutex->unlock();
}
current_sensor = 0;
} else {
current_sensor++;
}
}
bool rawinput::PIUIO::Init() {
is_connected = Open();
if (is_connected) {
// force the USB lines to be always on.
SetUSBPortState(true);
IOThreadObject = new std::thread(&rawinput::PIUIO::IOThread, this);
}
return is_connected;
}
bool rawinput::PIUIO::Stop() {
is_connected = false;
if (IOThreadObject != NULL) {
IOThreadObject->join();
}
return true;
}
rawinput::PIUIO::~PIUIO() {
Stop();
}
#include "piuio.h"
#include <iostream>
#include <thread>
using namespace std;
// it's 2019 and I'm writing code to avoid issues with Windows XP.
static HINSTANCE WINUSB_INSTANCE = nullptr;
static std::string WINUSB_NAME = "winusb.dll";
static std::string WinUsb_InitializeStr = "WinUsb_Initialize";
typedef BOOL(__stdcall * WinUsb_Initialize_t)(
_In_ HANDLE DeviceHandle,
_Out_ PWINUSB_INTERFACE_HANDLE InterfaceHandle
);
static std::string WinUsb_ControlTransferStr = "WinUsb_ControlTransfer";
typedef BOOL(__stdcall * WinUsb_ControlTransfer_t)(
_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle,
_In_ WINUSB_SETUP_PACKET SetupPacket,
_Out_writes_bytes_to_opt_(BufferLength, *LengthTransferred) PUCHAR Buffer,
_In_ ULONG BufferLength,
_Out_opt_ PULONG LengthTransferred,
_In_opt_ LPOVERLAPPED Overlapped
);
static WinUsb_ControlTransfer_t pWinUsb_ControlTransfer = nullptr;
static WinUsb_Initialize_t pWinUsb_Initialize = nullptr;
const string rawinput::PIUIO::LIGHT_NAMES[rawinput::PIUIO::PIUIO_MAX_NUM_OF_LIGHTS] = {
"Unknown",
"Unknown",
"P2 Up",
"P2 Down",
"P2 Left",
"P2 Right",
"P2 Center",
"Unknown",
"Unknown",
"Unknown",
"Neon",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"P1 Up",
"P1 Down",
"P1 Left",
"P1 Right",
"P1 Center",
"Marquee Upper Left",
"Marquee Lower Right",
"Marquee Lower Left",
"Marquee Upper Right",
"USB Enable",
"Unknown",
"Unknown",
"Unknown",
"Unknown"
};
rawinput::PIUIO::PIUIO(Device *device) {
this->device = device;
button_state = 0;
light_data = 0;
current_sensor = 0;
prev_timeout = 0;
}
bool rawinput::PIUIO::LoadWinUSBFunctions() {
static bool functions_loaded = false;
if (functions_loaded)
return true;
// see if we even have winusb available.
WINUSB_INSTANCE = libutils::try_library(WINUSB_NAME);
// if windows didn't load it just now, then it's not on the system.
if (WINUSB_INSTANCE != nullptr) {
// load winusb functions
pWinUsb_Initialize = (WinUsb_Initialize_t) libutils::get_proc(
WINUSB_INSTANCE, WinUsb_InitializeStr.c_str());
pWinUsb_ControlTransfer = (WinUsb_ControlTransfer_t) libutils::get_proc(
WINUSB_INSTANCE, WinUsb_ControlTransferStr.c_str());
// make sure they actually loaded.
if(pWinUsb_Initialize != nullptr && pWinUsb_ControlTransfer!= nullptr)
functions_loaded = true;
} else {
log_warning("piuio", "Could not load \'{}\', skipping...", WINUSB_NAME);
}
return functions_loaded;
}
PSP_DEVICE_INTERFACE_DETAIL_DATA rawinput::PIUIO::GetDevicePath() {
// modified from https://forum.vellemanprojects.eu/t/k8090-how-to-identify-which-com-port-it-is-connected-to/3810
// https://www.velleman.eu/images/tmp/usbfind.c
HDEVINFO hDevInfo;
SP_DEVICE_INTERFACE_DATA DevIntfData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DevIntfDetailData;
SP_DEVINFO_DATA DevData;
DWORD dwSize, dwMemberIdx;
hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if (hDevInfo != INVALID_HANDLE_VALUE) {
DevIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
dwMemberIdx = 0;
SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE,
dwMemberIdx, &DevIntfData);
while (GetLastError() != ERROR_NO_MORE_ITEMS) {
DevData.cbSize = sizeof(DevData);
SetupDiGetDeviceInterfaceDetail(
hDevInfo, &DevIntfData, NULL, 0, &dwSize, NULL);
DevIntfDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData,
DevIntfDetailData, dwSize, &dwSize, &DevData)) {
if (strstr(DevIntfDetailData->DevicePath, VENDOR_PROD_ID) != 0) {
return DevIntfDetailData;
}
}
HeapFree(GetProcessHeap(), 0, DevIntfDetailData);
// continue looping
SetupDiEnumDeviceInterfaces(
hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, ++dwMemberIdx, &DevIntfData);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
return 0;
}
bool rawinput::PIUIO::IsPressed(int iKey) {
if (iKey < PIUIO_MAX_NUM_OF_INPUTS) {
// logic high is pressed, logic low is released.
return button_state & (1 << iKey);
}
return false;
}
bool rawinput::PIUIO::WasPressed(int iKey) {
if (iKey < PIUIO_MAX_NUM_OF_INPUTS)
return prev_button_state & (1 << iKey);
return false;
}
void rawinput::PIUIO::SetUSBPortState(bool bState) {
SetLight(USB_ENABLE_BIT, bState);
}
void rawinput::PIUIO::SetLight(int iLight, bool bState) {
if (iLight < PIUIO_MAX_NUM_OF_LIGHTS) {
// turn on a light by setting the bit, turn it off by clearing it.
if (bState)
light_data |= 1 << iLight;
else
light_data &= ~(1 << iLight);
}
}
bool rawinput::PIUIO::Open() {
// ensure the libs are loaded
// if we can't load them, then we shouldn't exist.
if (!LoadWinUSBFunctions())
return false;
bool bResult = false;
PSP_DEVICE_INTERFACE_DETAIL_DATA dev_detail;
dev_detail = GetDevicePath();
if (dev_detail == 0) {
HeapFree(GetProcessHeap(), 0, dev_detail);
return false;
}
device_handle = CreateFile(dev_detail->DevicePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
);
// no longer need dev_detail
HeapFree(GetProcessHeap(), 0, dev_detail);
if (device_handle == INVALID_HANDLE_VALUE)
return false;
if (pWinUsb_Initialize != nullptr)
bResult = pWinUsb_Initialize(device_handle, &win_usb_handle);
if (!bResult) {
CloseHandle(device_handle);
return false;
}
return bResult;
}
uint32_t rawinput::PIUIO::Read() {
WINUSB_SETUP_PACKET SetupPacket;
ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
ULONG cbSent = 0;
bool bResult = false;
// create the setup packet
SetupPacket.RequestType = 0x40 | 0x80; // EndPoint In, RequestType Vendor
SetupPacket.Request = PIUIO_CTL_REQ;
SetupPacket.Value = 0;
SetupPacket.Index = 0;
SetupPacket.Length = PACKET_SIZE_BYTES;
// ensure we loaded the pointer
unsigned char buffer[PACKET_SIZE_BYTES] {};
if (pWinUsb_ControlTransfer != nullptr)
bResult = pWinUsb_ControlTransfer(win_usb_handle, SetupPacket, buffer, PACKET_SIZE_BYTES, &cbSent, 0);
if (!bResult)
log_warning("piuio", "read error");
return Deserialize(buffer);
}
bool rawinput::PIUIO::Write(uint32_t p_Data) {
WINUSB_SETUP_PACKET SetupPacket;
ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
ULONG cbSent = 0;
bool bResult = false;
// create the setup packet
SetupPacket.RequestType = 0x40; //EndPoint Out, RequestType Vendor
SetupPacket.Request = PIUIO_CTL_REQ;
SetupPacket.Value = 0;
SetupPacket.Index = 0;
SetupPacket.Length = PACKET_SIZE_BYTES;
// ensure we loaded the pointer
if (pWinUsb_ControlTransfer != nullptr) {
bResult = pWinUsb_ControlTransfer(
win_usb_handle,
SetupPacket,
Serialize(light_data),
PACKET_SIZE_BYTES,
&cbSent,
0
);
}
if (!bResult)
log_warning("piuio", "write error");
return bResult;
}
unsigned char * rawinput::PIUIO::Serialize(uint32_t p_Data) {
static unsigned char buffer[PACKET_SIZE_BYTES];
buffer[0] = p_Data;
buffer[1] = p_Data >> 8;
buffer[2] = p_Data >> 16;
buffer[3] = p_Data >> 24;
// these bits don't matter for the piuio
buffer[4] = 0xFF;
buffer[5] = 0xFF;
buffer[6] = 0xFF;
buffer[7] = 0xFF;
return buffer;
}
uint32_t rawinput::PIUIO::Deserialize(unsigned char * p_Data) {
uint32_t result;
result = p_Data[0];
result |= p_Data[1] << 8;
result |= p_Data[2] << 16;
result |= p_Data[3] << 24;
return result;
}
void rawinput::PIUIO::IOThread() {
while (is_connected)
UpdateSingleButtonState();
}
void rawinput::PIUIO::UpdateSingleButtonState() {
// write a set of sensors to request
light_data &= 0xFFFCFFFC;
light_data |= (current_sensor | (current_sensor << 16));
// request this set of sensors
// this also updates the light status
this->Write(light_data);
// read from this set of sensors
input_data[current_sensor] = this->Read();
// piuio opens high; invert the input
input_data[current_sensor] = ~input_data[current_sensor];
// update high values ASAP, that's when the button is pressed.
// see: https://github.com/djpohly/piuio#usb-protocol-and-multiplexer
auto button_state_new = button_state | input_data[current_sensor];
if (button_state != button_state_new) {
this->device->mutex->lock();
button_state |= button_state_new;
this->device->updated = true;
this->device->mutex->unlock();
}
if (current_sensor >= SENSOR_NUM - 1) {
uint32_t temp_btn_state = 0;
// we have done a full sensor arrangement, let's see if the panel has been pulled away from.
// combine all the input.
for (int i = 0; i < 4; ++i)
temp_btn_state |= input_data[i];
// only store every 255th previous value since we are polling very quickly.
// only used by spicecfg to see if a user pressed a button, so not very important.
// unsigned ints rollover
prev_timeout++;
if (prev_timeout == 0)
prev_button_state = button_state;
if (button_state != temp_btn_state) {
this->device->mutex->lock();
button_state = temp_btn_state;
this->device->updated = true;
this->device->mutex->unlock();
}
current_sensor = 0;
} else {
current_sensor++;
}
}
bool rawinput::PIUIO::Init() {
is_connected = Open();
if (is_connected) {
// force the USB lines to be always on.
SetUSBPortState(true);
IOThreadObject = new std::thread(&rawinput::PIUIO::IOThread, this);
}
return is_connected;
}
bool rawinput::PIUIO::Stop() {
is_connected = false;
if (IOThreadObject != NULL) {
IOThreadObject->join();
}
return true;
}
rawinput::PIUIO::~PIUIO() {
Stop();
}
+78 -78
View File
@@ -1,78 +1,78 @@
#pragma once
#include <thread>
#include <windows.h>
#include <winusb.h>
#include <setupapi.h>
#include <string>
#include "util/libutils.h"
#include "util/logging.h"
#include "device.h"
// This is the GUID for the USB device class
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
#pragma comment (lib, "setupapi.lib")
#pragma comment (lib , "winusb.lib" )
namespace rawinput {
class PIUIO
{
public:
static const size_t PACKET_SIZE_BYTES = 8;
static const size_t SENSOR_NUM = 4;
static const size_t USB_ENABLE_BIT = 27;
static const UCHAR PIUIO_CTL_REQ = 0xAE;
const char *VENDOR_PROD_ID = "vid_0547&pid_1002";
const static std::string LIGHT_NAMES[];
static const int PIUIO_MAX_NUM_OF_LIGHTS = 32;
static const int PIUIO_MAX_NUM_OF_INPUTS = 32;
bool is_connected;
Device *device;
bool IsPressed(int iKey);
bool WasPressed(int iKey);
void SetLight(int iLight, bool bState);
PIUIO(Device* device);
virtual ~PIUIO();
bool Init();
bool Stop();
void UpdateSingleButtonState();
void SetUSBPortState(bool bState);
private:
bool LoadWinUSBFunctions();
uint32_t light_data;
uint32_t input_data[SENSOR_NUM];
uint8_t current_sensor;
uint32_t button_state, prev_button_state;
uint8_t prev_timeout;
LPCWSTR device_path;
WINUSB_INTERFACE_HANDLE win_usb_handle = INVALID_HANDLE_VALUE;
HANDLE device_handle = INVALID_HANDLE_VALUE;
bool Open();
PSP_DEVICE_INTERFACE_DETAIL_DATA GetDevicePath();
void IOThread();
uint32_t Read();
bool Write(uint32_t p_Data);
unsigned char * Serialize(uint32_t p_Data);
uint32_t Deserialize(unsigned char * p_Data);
std::thread* IOThreadObject;
};
}
#pragma once
#include <thread>
#include <windows.h>
#include <winusb.h>
#include <setupapi.h>
#include <string>
#include "util/libutils.h"
#include "util/logging.h"
#include "device.h"
// This is the GUID for the USB device class
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
#pragma comment (lib, "setupapi.lib")
#pragma comment (lib , "winusb.lib" )
namespace rawinput {
class PIUIO
{
public:
static const size_t PACKET_SIZE_BYTES = 8;
static const size_t SENSOR_NUM = 4;
static const size_t USB_ENABLE_BIT = 27;
static const UCHAR PIUIO_CTL_REQ = 0xAE;
const char *VENDOR_PROD_ID = "vid_0547&pid_1002";
const static std::string LIGHT_NAMES[];
static const int PIUIO_MAX_NUM_OF_LIGHTS = 32;
static const int PIUIO_MAX_NUM_OF_INPUTS = 32;
bool is_connected;
Device *device;
bool IsPressed(int iKey);
bool WasPressed(int iKey);
void SetLight(int iLight, bool bState);
PIUIO(Device* device);
virtual ~PIUIO();
bool Init();
bool Stop();
void UpdateSingleButtonState();
void SetUSBPortState(bool bState);
private:
bool LoadWinUSBFunctions();
uint32_t light_data;
uint32_t input_data[SENSOR_NUM];
uint8_t current_sensor;
uint32_t button_state, prev_button_state;
uint8_t prev_timeout;
LPCWSTR device_path;
WINUSB_INTERFACE_HANDLE win_usb_handle = INVALID_HANDLE_VALUE;
HANDLE device_handle = INVALID_HANDLE_VALUE;
bool Open();
PSP_DEVICE_INTERFACE_DETAIL_DATA GetDevicePath();
void IOThread();
uint32_t Read();
bool Write(uint32_t p_Data);
unsigned char * Serialize(uint32_t p_Data);
uint32_t Deserialize(unsigned char * p_Data);
std::thread* IOThreadObject;
};
}
+178 -178
View File
@@ -1,178 +1,178 @@
#include "sextet.h"
#include <cstring>
#include <stdint.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include "util/logging.h"
using namespace std;
const string rawinput::SextetDevice::LIGHT_NAMES[LIGHT_COUNT] = {
"Neon",
"P1 Halogen Upper",
"P1 Halogen Lower",
"P2 Halogen Upper",
"P2 Halogen Lower",
"P1 Button",
"P2 Button",
"P1 Foot Up",
"P1 Foot Down",
"P1 Foot Left",
"P1 Foot Right",
"P2 Foot Up",
"P2 Foot Down",
"P2 Foot Left",
"P2 Foot Right"
};
inline void rawinput::SextetDevice::fill_packet(uint8_t *buffer, bool *light_state) {
/*
* Refer to this doucment for more info
* https://github.com/stepmania/stepmania/blob/master/src/arch/Lights/LightsDriver_SextetStream.md#bit-meanings
*/
buffer[0] = 0xC0 | (uint8_t) (
(light_state[SextetLights::BASS_NEON] << 5) |
(light_state[SextetLights::BASS_NEON] << 4) |
(light_state[SextetLights::MARQUEE_P2_LOWER] << 3) |
(light_state[SextetLights::MARQUEE_P1_LOWER] << 2) |
(light_state[SextetLights::MARQUEE_P2_UPPER] << 1) |
(light_state[SextetLights::MARQUEE_P1_UPPER] << 0)
);
buffer[1] = 0xC0 | (uint8_t) (
(light_state[SextetLights::P1_MENU] << 5) |
(light_state[SextetLights::P1_MENU] << 4)
);
buffer[2] = 0xC0;
buffer[3] = 0xC0 | (uint8_t) (
(light_state[SextetLights::P1_DOWN] << 3) |
(light_state[SextetLights::P1_UP] << 2) |
(light_state[SextetLights::P1_RIGHT] << 1) |
(light_state[SextetLights::P1_LEFT] << 0)
);
buffer[4] = 0xC0;
buffer[5] = 0xC0;
buffer[6] = 0xC0;
buffer[7] = 0xC0 | (uint8_t) (
(light_state[SextetLights::P2_MENU] << 5) |
(light_state[SextetLights::P2_MENU] << 4)
);
buffer[8] = 0xC0;
buffer[9] = 0xC0 | (uint8_t) (
(light_state[SextetLights::P2_DOWN] << 3) |
(light_state[SextetLights::P2_UP] << 2) |
(light_state[SextetLights::P2_RIGHT] << 1) |
(light_state[SextetLights::P2_LEFT] << 0)
);
buffer[10] = 0xC0;
buffer[11] = 0xC0;
buffer[12] = 0xC0;
// terminate with LF
buffer[13] = '\n';
}
rawinput::SextetDevice::SextetDevice(std::string device_name) {
this->device_name = device_name;
is_connected = false;
all_off();
}
rawinput::SextetDevice::~SextetDevice() {
disconnect();
}
void rawinput::SextetDevice::set_all(bool state) {
for (int i = 0; i < LIGHT_COUNT; i++)
light_state[i] = state;
}
void rawinput::SextetDevice::all_on() {
set_all(true);
}
void rawinput::SextetDevice::all_off() {
set_all(false);
}
bool rawinput::SextetDevice::connect() {
// open device
device = CreateFileA(
this->device_name.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
// check device
if (device == INVALID_HANDLE_VALUE)
return false;
// get comm state
DCB dcb;
SecureZeroMemory(&dcb, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(device, &dcb)) {
log_warning("sextet", "GetCommState failed: 0x{:08x}", GetLastError());
return false;
}
// set comm state
dcb.BaudRate = 115200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(device, &dcb)) {
log_warning("sextet", "SetCommState failed: 0x{:08x}", GetLastError());
return false;
}
// success
is_connected = true;
return true;
}
bool rawinput::SextetDevice::disconnect() {
return CloseHandle(device);
}
bool rawinput::SextetDevice::push_light_state() {
// build packet
uint8_t buffer[FULL_SEXTET_COUNT];
this->fill_packet(&(buffer[0]), &(light_state[0]));
// write data to device
DWORD bytes_written;
WriteFile(
device,
buffer,
FULL_SEXTET_COUNT,
&bytes_written,
NULL
);
// verify written bytes count
return bytes_written == FULL_SEXTET_COUNT;
}
#include "sextet.h"
#include <cstring>
#include <stdint.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include "util/logging.h"
using namespace std;
const string rawinput::SextetDevice::LIGHT_NAMES[LIGHT_COUNT] = {
"Neon",
"P1 Halogen Upper",
"P1 Halogen Lower",
"P2 Halogen Upper",
"P2 Halogen Lower",
"P1 Button",
"P2 Button",
"P1 Foot Up",
"P1 Foot Down",
"P1 Foot Left",
"P1 Foot Right",
"P2 Foot Up",
"P2 Foot Down",
"P2 Foot Left",
"P2 Foot Right"
};
inline void rawinput::SextetDevice::fill_packet(uint8_t *buffer, bool *light_state) {
/*
* Refer to this doucment for more info
* https://github.com/stepmania/stepmania/blob/master/src/arch/Lights/LightsDriver_SextetStream.md#bit-meanings
*/
buffer[0] = 0xC0 | (uint8_t) (
(light_state[SextetLights::BASS_NEON] << 5) |
(light_state[SextetLights::BASS_NEON] << 4) |
(light_state[SextetLights::MARQUEE_P2_LOWER] << 3) |
(light_state[SextetLights::MARQUEE_P1_LOWER] << 2) |
(light_state[SextetLights::MARQUEE_P2_UPPER] << 1) |
(light_state[SextetLights::MARQUEE_P1_UPPER] << 0)
);
buffer[1] = 0xC0 | (uint8_t) (
(light_state[SextetLights::P1_MENU] << 5) |
(light_state[SextetLights::P1_MENU] << 4)
);
buffer[2] = 0xC0;
buffer[3] = 0xC0 | (uint8_t) (
(light_state[SextetLights::P1_DOWN] << 3) |
(light_state[SextetLights::P1_UP] << 2) |
(light_state[SextetLights::P1_RIGHT] << 1) |
(light_state[SextetLights::P1_LEFT] << 0)
);
buffer[4] = 0xC0;
buffer[5] = 0xC0;
buffer[6] = 0xC0;
buffer[7] = 0xC0 | (uint8_t) (
(light_state[SextetLights::P2_MENU] << 5) |
(light_state[SextetLights::P2_MENU] << 4)
);
buffer[8] = 0xC0;
buffer[9] = 0xC0 | (uint8_t) (
(light_state[SextetLights::P2_DOWN] << 3) |
(light_state[SextetLights::P2_UP] << 2) |
(light_state[SextetLights::P2_RIGHT] << 1) |
(light_state[SextetLights::P2_LEFT] << 0)
);
buffer[10] = 0xC0;
buffer[11] = 0xC0;
buffer[12] = 0xC0;
// terminate with LF
buffer[13] = '\n';
}
rawinput::SextetDevice::SextetDevice(std::string device_name) {
this->device_name = device_name;
is_connected = false;
all_off();
}
rawinput::SextetDevice::~SextetDevice() {
disconnect();
}
void rawinput::SextetDevice::set_all(bool state) {
for (int i = 0; i < LIGHT_COUNT; i++)
light_state[i] = state;
}
void rawinput::SextetDevice::all_on() {
set_all(true);
}
void rawinput::SextetDevice::all_off() {
set_all(false);
}
bool rawinput::SextetDevice::connect() {
// open device
device = CreateFileA(
this->device_name.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
// check device
if (device == INVALID_HANDLE_VALUE)
return false;
// get comm state
DCB dcb;
SecureZeroMemory(&dcb, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(device, &dcb)) {
log_warning("sextet", "GetCommState failed: 0x{:08x}", GetLastError());
return false;
}
// set comm state
dcb.BaudRate = 115200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(device, &dcb)) {
log_warning("sextet", "SetCommState failed: 0x{:08x}", GetLastError());
return false;
}
// success
is_connected = true;
return true;
}
bool rawinput::SextetDevice::disconnect() {
return CloseHandle(device);
}
bool rawinput::SextetDevice::push_light_state() {
// build packet
uint8_t buffer[FULL_SEXTET_COUNT];
this->fill_packet(&(buffer[0]), &(light_state[0]));
// write data to device
DWORD bytes_written;
WriteFile(
device,
buffer,
FULL_SEXTET_COUNT,
&bytes_written,
NULL
);
// verify written bytes count
return bytes_written == FULL_SEXTET_COUNT;
}
+66 -66
View File
@@ -1,66 +1,66 @@
#pragma once
#include <string>
#include <windows.h>
namespace rawinput {
namespace SextetLights {
enum {
BASS_NEON = 0,
MARQUEE_P1_UPPER,
MARQUEE_P1_LOWER,
MARQUEE_P2_UPPER,
MARQUEE_P2_LOWER,
P1_MENU,
P2_MENU,
P1_UP,
P1_DOWN,
P1_LEFT,
P1_RIGHT,
P2_UP,
P2_DOWN,
P2_LEFT,
P2_RIGHT
};
}
class SextetDevice {
private:
// COM port handle
std::string device_name;
HANDLE device;
// number of bytes to contain the full sextet pack and a trailing LF
static const size_t FULL_SEXTET_COUNT = 14;
void set_all(bool state);
void fill_packet(uint8_t *buffer, bool *light_state);
public:
// only 15 lights are used on SD DDR Cabinets.
static const int LIGHT_COUNT = 15;
static const std::string LIGHT_NAMES[];
// state
bool is_connected;
bool light_state[LIGHT_COUNT];
SextetDevice(std::string device_name);
~SextetDevice();
bool connect();
bool disconnect();
bool push_light_state();
void all_on();
void all_off();
};
}
#pragma once
#include <string>
#include <windows.h>
namespace rawinput {
namespace SextetLights {
enum {
BASS_NEON = 0,
MARQUEE_P1_UPPER,
MARQUEE_P1_LOWER,
MARQUEE_P2_UPPER,
MARQUEE_P2_LOWER,
P1_MENU,
P2_MENU,
P1_UP,
P1_DOWN,
P1_LEFT,
P1_RIGHT,
P2_UP,
P2_DOWN,
P2_LEFT,
P2_RIGHT
};
}
class SextetDevice {
private:
// COM port handle
std::string device_name;
HANDLE device;
// number of bytes to contain the full sextet pack and a trailing LF
static const size_t FULL_SEXTET_COUNT = 14;
void set_all(bool state);
void fill_packet(uint8_t *buffer, bool *light_state);
public:
// only 15 lights are used on SD DDR Cabinets.
static const int LIGHT_COUNT = 15;
static const std::string LIGHT_NAMES[];
// state
bool is_connected;
bool light_state[LIGHT_COUNT];
SextetDevice(std::string device_name);
~SextetDevice();
bool connect();
bool disconnect();
bool push_light_state();
void all_on();
void all_off();
};
}
+567 -567
View File
File diff suppressed because it is too large Load Diff
+20 -20
View File
@@ -1,20 +1,20 @@
#pragma once
#include "device.h"
#include "rawinput.h"
namespace rawinput::touch {
// settings
extern bool DISABLED;
extern bool INVERTED;
bool is_touchscreen(Device *device);
void enable(Device *device);
void disable(Device *device);
void update_input(Device *device);
void update_timeouts(Device *device);
void update_timeouts(RawInputManager *manager);
bool is_enabled(RawInputManager *manager);
void display_update();
}
#pragma once
#include "device.h"
#include "rawinput.h"
namespace rawinput::touch {
// settings
extern bool DISABLED;
extern bool INVERTED;
bool is_touchscreen(Device *device);
void enable(Device *device);
void disable(Device *device);
void update_input(Device *device);
void update_timeouts(Device *device);
void update_timeouts(RawInputManager *manager);
bool is_enabled(RawInputManager *manager);
void display_update();
}