Last active
April 13, 2019 17:35
-
-
Save YellowAfterlife/81e9c06eb6bad915658e4eee5b503fb2 to your computer and use it in GitHub Desktop.
My tweaks to multi-device polling code by Jake Stookey (http://www.jstookey.com/arcade/rawmouse/)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//================================================================ | |
// | |
// raw_mouse.c - Win XP access to multiple mice via raw input | |
// | |
// To do: | |
// | |
// - Improve the method for weeding out the RDP Mouse. Find "status bits" (see below). | |
// | |
//================================================================ | |
#define _WIN32_WINNT 0x501 // This specifies WinXP or later - it is needed to access rawmouse from the user32.dll | |
#include "stdafx.h" | |
#include <stdlib.h> | |
#include <malloc.h> | |
#include <windows.h> | |
#include <stdio.h> | |
#include "raw_mouse.h" | |
#include "hidusage.h" | |
//============================================================ | |
// Dynamically linked functions from rawinput | |
//============================================================ | |
typedef WINUSERAPI INT(WINAPI *pGetRawInputDeviceList)(OUT PRAWINPUTDEVICELIST pRawInputDeviceList, IN OUT PINT puiNumDevices, IN UINT cbSize); | |
typedef WINUSERAPI INT(WINAPI *pGetRawInputData)(IN HRAWINPUT hRawInput, IN UINT uiCommand, OUT LPVOID pData, IN OUT PINT pcbSize, IN UINT cbSizeHeader); | |
typedef WINUSERAPI INT(WINAPI *pGetRawInputDeviceInfoA)(IN HANDLE hDevice, IN UINT uiCommand, OUT LPVOID pData, IN OUT PINT pcbSize); | |
typedef WINUSERAPI BOOL(WINAPI *pRegisterRawInputDevices)(IN PCRAWINPUTDEVICE pRawInputDevices, IN UINT uiNumDevices, IN UINT cbSize); | |
pGetRawInputDeviceList _GRIDL; | |
pGetRawInputData _GRID; | |
pGetRawInputDeviceInfoA _GRIDIA; | |
pRegisterRawInputDevices _RRID; | |
int nraw_mouse_count; | |
int nraw_keyboard_count; | |
//============================================================ | |
// PARAMETERS | |
//============================================================ | |
#define RAW_SYS_MOUSE 0 // The sys mouse combines all the other usb mice into one | |
#define MAX_RAW_MOUSE_BUTTONS 3 | |
//============================================================ | |
// DATA TYPES | |
//============================================================ | |
typedef struct STRUCT_RAW_MOUSE { | |
// Identifier for the mouse. WM_INPUT passes the device HANDLE as lparam when registering a mousemove | |
HANDLE device_handle; | |
// VD: may as well | |
char* device_name; | |
// The running tally of mouse moves received from WM_INPUT (mouse delta). | |
// Calling get_raw_mouse_[x | y] will reset the value so that every time | |
// get_raw_mouse_[x | y] is called, the relative value from the last time | |
// get_raw_mouse_[x | y] was called will be returned. | |
ULONG x; | |
ULONG y; | |
ULONG z; | |
// Used to determine if the HID is using absolute mode or relative mode | |
// The Act Labs PC USB Light Gun is absolute mode (returns screen coordinates) | |
// and mice are relative mode (returns delta) | |
// NOTE: this value isn't updated until the device registers a WM_INPUT message | |
BOOL is_absolute; | |
// This indicates if the coordinates are coming from a multi-monitor setup | |
// NOTE: this value isn't updated until the device registers a WM_INPUT message | |
BOOL is_virtual_desktop; | |
int buttonpressed[MAX_RAW_MOUSE_BUTTONS]; | |
// Identifying the name of the button may be useful in the future as a way to | |
// use a mousewheel as a button and other neat tricks (button name: "wheel up", "wheel down") | |
// -- not a bad way to look at it for a rotary joystick | |
char *button_name[MAX_RAW_MOUSE_BUTTONS]; | |
} RAW_MOUSE, *PRAW_MOUSE; | |
// VD: simpler in comparison | |
typedef struct STRUCT_RAW_KEYBOARD { | |
HANDLE device_handle; | |
char* device_name; | |
// Event uses ushort but I'm not seeing any keycodes>=256 | |
bool keysdown[256]; | |
} RAW_KEYBOARD, *PRAW_KEYBOARD; | |
//============================================================ | |
// LOCAL VARIABLES | |
//============================================================ | |
// Pointer to our array of raw mice. Created by called init_raw_mouse() | |
static PRAW_MOUSE raw_mice; | |
static PRAW_KEYBOARD raw_keyboards; | |
static BOOL include_sys_mouse; | |
static BOOL include_rdp_mouse; | |
static BOOL include_individual_mice; | |
static int excluded_sysmouse_devices_count; | |
//============================================================ | |
// PROTOTYPES | |
//============================================================ | |
// A weak solution to weeding out the Terminal Services virtual mouse from the list of devices. | |
// I read somewhere that you shouldn't trust the device name's format. In other words, you shouldn't do what I'm doing. | |
// Here's the quote from http://www.jsiinc.com/SUBJ/tip4600/rh4628.htm: | |
// "Note that you should not make any programmatic assumption about how an instance ID is formatted. | |
// To determine root devices, you can check device status bits." | |
// So tell me, what are these (how you say) "status bits" and where can I get some? | |
static BOOL is_rm_rdp_mouse(char cDeviceString[]); | |
static BOOL read_raw_input(PRAWINPUT); | |
// register to reviece WM_INPUT messages in WNDPROC | |
static BOOL register_raw_mouse(void); | |
//============================================================ | |
// raw_mouse_count | |
//============================================================ | |
int raw_mouse_count() { | |
return nraw_mouse_count; | |
} | |
//============================================================ | |
// is_rm_rdp_mouse | |
//============================================================ | |
static BOOL is_rm_rdp_mouse(char cDeviceString[]) | |
{ | |
int i; | |
char cRDPString[] = "\\??\\Root#RDP_MOU#0000#"; | |
if (strlen(cDeviceString) < 22) { | |
return 0; | |
} | |
for (i = 0; i < 22; i++) { | |
if (cRDPString[i] != cDeviceString[i]) { | |
return 0; | |
} | |
} | |
return 1; | |
} | |
//============================================================ | |
// init_raw_mouse | |
//============================================================ | |
BOOL init_raw_mouse(int in_flags) | |
{ | |
BOOL in_include_individual_mice = (in_flags & 1) != 0; | |
BOOL in_include_sys_mouse = (in_flags & 2) != 0; | |
BOOL in_include_rdp_mouse = (in_flags & 4) != 0; | |
BOOL in_include_keyboards = (in_flags & 8) != 0; | |
// "0" to exclude, "1" to include | |
int nInputDevices, i, j; | |
PRAWINPUTDEVICELIST pRawInputDeviceList; | |
static BOOL bHasBeenInitialized = 0; | |
int nSize; | |
char *psName; | |
char buffer[80]; | |
// Return 0 if rawinput is not available | |
HMODULE user32 = LoadLibrary("user32.dll"); | |
if (!user32) return 0; | |
_RRID = (pRegisterRawInputDevices)GetProcAddress(user32, "RegisterRawInputDevices"); | |
if (!_RRID) return 0; | |
_GRIDL = (pGetRawInputDeviceList)GetProcAddress(user32, "GetRawInputDeviceList"); | |
if (!_GRIDL) return 0; | |
_GRIDIA = (pGetRawInputDeviceInfoA)GetProcAddress(user32, "GetRawInputDeviceInfoA"); | |
if (!_GRIDIA) return 0; | |
_GRID = (pGetRawInputData)GetProcAddress(user32, "GetRawInputData"); | |
if (!_GRID) return 0; | |
excluded_sysmouse_devices_count = 0; | |
nraw_mouse_count = 0; | |
if (bHasBeenInitialized) { | |
fprintf(stderr, "WARNING: rawmouse init called after initialization already completed."); | |
bHasBeenInitialized = 1; | |
return 0; | |
} | |
include_sys_mouse = in_include_sys_mouse; | |
include_rdp_mouse = in_include_rdp_mouse; | |
include_individual_mice = in_include_individual_mice; | |
// 1st call to GetRawInputDeviceList: Pass NULL to get the number of devices. | |
if (/* GetRawInputDeviceList */ (*_GRIDL)(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0) { | |
fprintf(stderr, "ERROR: Unable to count raw input devices.\n"); | |
return 0; | |
} | |
// Allocate the array to hold the DeviceList | |
if ((pRawInputDeviceList = (PRAWINPUTDEVICELIST)malloc(sizeof(RAWINPUTDEVICELIST) * nInputDevices)) == NULL) { | |
fprintf(stderr, "ERROR: Unable to allocate memory for raw input device list.\n"); | |
return 0; | |
} | |
// 2nd call to GetRawInputDeviceList: Pass the pointer to our DeviceList and GetRawInputDeviceList() will fill the array | |
if (/* GetRawInputDeviceList */ (*_GRIDL)(pRawInputDeviceList, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) == -1) { | |
fprintf(stderr, "ERROR: Unable to get raw input device list.\n"); | |
return 0; | |
} | |
// Loop through all devices and count the mice | |
for (i = 0; i < nInputDevices; i++) { | |
auto t = pRawInputDeviceList[i].dwType; | |
if (t == RIM_TYPEMOUSE || t == RIM_TYPEKEYBOARD && in_include_keyboards) { | |
/* Get the device name and use it to determine if it's the RDP Terminal Services virtual device. */ | |
// 1st call to GetRawInputDeviceInfo: Pass NULL to get the size of the device name | |
if (/* GetRawInputDeviceInfo */ (*_GRIDIA)(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, NULL, &nSize) != 0) { | |
fprintf(stderr, "ERROR: Unable to get size of raw input device name.\n"); | |
return 0; | |
} | |
// Allocate the array to hold the name | |
if ((psName = (char *)malloc(sizeof(TCHAR) * nSize)) == NULL) { | |
fprintf(stderr, "ERROR: Unable to allocate memory for device name.\n"); | |
return 0; | |
} | |
// 2nd call to GetRawInputDeviceInfo: Pass our pointer to get the device name | |
if ((int)/* GetRawInputDeviceInfo */ (*_GRIDIA)(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, psName, &nSize) < 0) { | |
fprintf(stderr, "ERROR: Unable to get raw input device name.\n"); | |
return 0; | |
} | |
if (t == RIM_TYPEKEYBOARD) { | |
// VD: IDK how RDP keyboards are named, I'm not going to test this right now | |
nraw_keyboard_count++; | |
} else { | |
// Count this mouse for allocation if it's not an RDP mouse or if we want to include the rdp mouse | |
if (is_rm_rdp_mouse(psName)) { | |
if (include_rdp_mouse) nraw_mouse_count++; | |
} else { // It's an ordinary mouse | |
nraw_mouse_count++; | |
if (!include_individual_mice) excluded_sysmouse_devices_count++; // Don't count this in the final nraw_mouse_count value | |
} | |
} | |
} | |
} | |
if (include_sys_mouse) | |
nraw_mouse_count++; | |
// Allocate the array for the raw mice | |
if ((raw_mice = (PRAW_MOUSE)malloc(sizeof(RAW_MOUSE) * nraw_mouse_count)) == NULL) { | |
fprintf(stderr, "ERROR: Unable to allocate memory for raw input mice.\n"); | |
return 0; | |
} | |
if ((raw_keyboards = (PRAW_KEYBOARD)malloc(sizeof(RAW_KEYBOARD) * nraw_keyboard_count)) == NULL) { | |
fprintf(stderr, "ERROR: Unable to allocate memory for raw input keyboards.\n"); | |
return 0; | |
} | |
// Define the sys mouse | |
int currentmouse = 0; | |
if (include_sys_mouse) { | |
raw_mice[RAW_SYS_MOUSE].device_handle = 0; | |
raw_mice[RAW_SYS_MOUSE].x = 0; | |
raw_mice[RAW_SYS_MOUSE].y = 0; | |
raw_mice[RAW_SYS_MOUSE].z = 0; | |
raw_mice[RAW_SYS_MOUSE].is_absolute = 0; | |
raw_mice[RAW_SYS_MOUSE].is_virtual_desktop = 0; | |
currentmouse++; | |
} | |
int currentkeyboard = 0; | |
// Loop through all devices and set the device handles and initialize the mouse values | |
for (i = 0; i < nInputDevices; i++) { | |
DWORD dwType = pRawInputDeviceList[i].dwType; | |
if (dwType == RIM_TYPEMOUSE || dwType == RIM_TYPEKEYBOARD && in_include_keyboards) { | |
// 1st call to GetRawInputDeviceInfo: Pass NULL to get the size of the device name | |
if (/* GetRawInputDeviceInfo */ (*_GRIDIA)(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, NULL, &nSize) != 0) { | |
fprintf(stderr, "ERROR: Unable to get size of raw input device name (2).\n"); | |
return 0; | |
} | |
// Allocate the array to hold the name | |
if ((psName = (char *)malloc(sizeof(TCHAR) * nSize)) == NULL) { | |
fprintf(stderr, "ERROR: Unable to allocate memory for raw input device name (2).\n"); | |
return 0; | |
} | |
// 2nd call to GetRawInputDeviceInfo: Pass our pointer to get the device name | |
if ((int)/* GetRawInputDeviceInfo */ (*_GRIDIA)(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, psName, &nSize) < 0) { | |
fprintf(stderr, "ERROR: Unable to get raw input device name (2).\n"); | |
return 0; | |
} | |
if (dwType == RIM_TYPEKEYBOARD) { | |
raw_keyboards[currentkeyboard].device_handle = pRawInputDeviceList[i].hDevice; | |
raw_keyboards[currentkeyboard].device_name = psName; | |
for (int k = 0; k < 256; k++) { | |
raw_keyboards[currentkeyboard].keysdown[k] = false; | |
} | |
currentkeyboard++; | |
} else { | |
// Add this mouse to the array if it's not an RDPMouse or if we wish to include the RDP mouse | |
if ((!is_rm_rdp_mouse(psName)) || include_rdp_mouse) { | |
raw_mice[currentmouse].device_handle = pRawInputDeviceList[i].hDevice; | |
raw_mice[currentmouse].device_name = psName; | |
raw_mice[currentmouse].x = 0; | |
raw_mice[currentmouse].y = 0; | |
raw_mice[currentmouse].z = 0; | |
raw_mice[currentmouse].is_absolute = 0; | |
raw_mice[currentmouse].is_virtual_desktop = 0; | |
currentmouse++; | |
} | |
} | |
} | |
} | |
// free the RAWINPUTDEVICELIST | |
free(pRawInputDeviceList); | |
for (i = 0; i < nraw_mouse_count; i++) { | |
for (j = 0; j < MAX_RAW_MOUSE_BUTTONS; j++) { | |
raw_mice[i].buttonpressed[j] = 0; | |
// Create the name for this button | |
sprintf(buffer, "Button %i", j); | |
raw_mice[i].button_name[j] = (char *)malloc(strlen(buffer) + 1); | |
sprintf(raw_mice[i].button_name[j], "%s", buffer); | |
} | |
} | |
nraw_mouse_count -= excluded_sysmouse_devices_count; | |
// finally, register to recieve raw input WM_INPUT messages | |
if (!register_raw_mouse()) { | |
fprintf(stderr, "ERROR: Unable to register raw input (2).\n"); | |
return 0; | |
} | |
bHasBeenInitialized = 1; | |
return 1; | |
} | |
//============================================================ | |
// register_raw_mouse | |
//============================================================ | |
BOOL register_raw_mouse(void) | |
{ | |
// This function registers to receive the WM_INPUT messages | |
RAWINPUTDEVICE Rid[2]; // Register only for mouse messages from wm_input. | |
//register to get wm_input messages | |
Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC; | |
Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE; | |
Rid[0].dwFlags = 0;// RIDEV_NOLEGACY; // adds HID mouse and also ignores legacy mouse messages | |
Rid[0].hwndTarget = NULL; | |
Rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC; | |
Rid[1].usUsage = HID_USAGE_GENERIC_KEYBOARD; | |
Rid[1].dwFlags = 0;// RIDEV_NOLEGACY; // adds HID mouse and also ignores legacy mouse messages | |
Rid[1].hwndTarget = NULL; | |
// Register to receive the WM_INPUT message for any change in mouse (buttons, wheel, and movement will all generate the same message) | |
if (!/* RegisterRawInputDevices*/ (*_RRID)(Rid, 2, sizeof(Rid[0]))) | |
return 0; | |
return 1; | |
} | |
//============================================================ | |
// destroy_raw_mouse | |
//============================================================ | |
void destroy_raw_mouse(void) | |
{ | |
free(raw_mice); | |
} | |
//============================================================ | |
// read_raw_input | |
//============================================================ | |
BOOL read_raw_input(PRAWINPUT raw) | |
{ | |
//printf("t=%d\n", raw->header.dwType); fflush(stdout); | |
// mouse 0 is sysmouse, so if there is not sysmouse start loop @0 | |
int i = 0; | |
if (include_sys_mouse) i++; | |
for (; i < (nraw_mouse_count + excluded_sysmouse_devices_count); i++) { | |
if (raw_mice[i].device_handle == raw->header.hDevice) | |
{ | |
// Update the values for the specified mouse | |
if (include_individual_mice) { | |
if (raw_mice[i].is_absolute) { | |
raw_mice[i].x = raw->data.mouse.lLastX; | |
raw_mice[i].y = raw->data.mouse.lLastY; | |
} else { // relative | |
raw_mice[i].x += raw->data.mouse.lLastX; | |
raw_mice[i].y += raw->data.mouse.lLastY; | |
} | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) raw_mice[i].buttonpressed[0] = 1; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) raw_mice[i].buttonpressed[0] = 0; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) raw_mice[i].buttonpressed[1] = 1; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) raw_mice[i].buttonpressed[1] = 0; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) raw_mice[i].buttonpressed[2] = 1; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) raw_mice[i].buttonpressed[2] = 0; | |
if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) raw_mice[i].is_absolute = 1; | |
else if (raw->data.mouse.usFlags & MOUSE_MOVE_RELATIVE) raw_mice[i].is_absolute = 0; | |
if (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) raw_mice[i].is_virtual_desktop = 1; | |
else raw_mice[i].is_virtual_desktop = 0; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { // If the current message has a mouse_wheel message | |
if ((SHORT)raw->data.mouse.usButtonData > 0) { | |
raw_mice[i].z++; | |
} | |
if ((SHORT)raw->data.mouse.usButtonData < 0) { | |
raw_mice[i].z--; | |
} | |
} | |
} | |
// Feed the values for every mouse into the system mouse | |
if (include_sys_mouse) { | |
if (raw_mice[i].is_absolute) { | |
raw_mice[RAW_SYS_MOUSE].x = raw->data.mouse.lLastX; | |
raw_mice[RAW_SYS_MOUSE].y = raw->data.mouse.lLastY; | |
} else { // relative | |
raw_mice[RAW_SYS_MOUSE].x += raw->data.mouse.lLastX; | |
raw_mice[RAW_SYS_MOUSE].y += raw->data.mouse.lLastY; | |
} | |
// This is innacurate: If 2 mice have their buttons down and I lift up on one, this will register the | |
// system mouse as being "up". I checked out on my windows desktop, and Microsoft was just as | |
// lazy as I'm going to be. Drag an icon with the 2 left mouse buttons held down & let go of one. | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) raw_mice[RAW_SYS_MOUSE].buttonpressed[0] = 1; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) raw_mice[RAW_SYS_MOUSE].buttonpressed[0] = 0; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) raw_mice[RAW_SYS_MOUSE].buttonpressed[1] = 1; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) raw_mice[RAW_SYS_MOUSE].buttonpressed[1] = 0; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) raw_mice[RAW_SYS_MOUSE].buttonpressed[2] = 1; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) raw_mice[RAW_SYS_MOUSE].buttonpressed[2] = 0; | |
// If an absolute mouse is triggered, sys mouse will be considered absolute till the end of time. | |
if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) raw_mice[RAW_SYS_MOUSE].is_absolute = 1; | |
// Same goes for virtual desktop | |
if (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) raw_mice[RAW_SYS_MOUSE].is_virtual_desktop = 1; | |
if (raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { // If the current message has a mouse_wheel message | |
if ((SHORT)raw->data.mouse.usButtonData > 0) { | |
raw_mice[RAW_SYS_MOUSE].z++; | |
} | |
if ((SHORT)raw->data.mouse.usButtonData < 0) { | |
raw_mice[RAW_SYS_MOUSE].z--; | |
} | |
} | |
} | |
} | |
} | |
for (i = 0; i < nraw_keyboard_count; i++) { | |
if (raw_keyboards[i].device_handle != raw->header.hDevice) continue; | |
int key = raw->data.keyboard.VKey; | |
if (key < 0 || key >= 0x100) continue; | |
switch (raw->data.keyboard.Message) { | |
case WM_KEYDOWN: | |
if (!raw_keyboards[i].keysdown[key]) { | |
//printf("key %d pressed on kb %d", key, i); fflush(stdout); | |
raw_keyboards[i].keysdown[key] = true; | |
} | |
break; | |
case WM_KEYUP: | |
//printf("key %d released on kb %d", key, i); fflush(stdout); | |
raw_keyboards[i].keysdown[key] = false; | |
break; | |
} | |
} | |
return 1; | |
} | |
//============================================================ | |
// is_raw_mouse_button_pressed | |
//============================================================ | |
BOOL is_raw_mouse_button_pressed(int mousenum, int buttonnum) { | |
// It's ok to ask if buttons are pressed for unitialized mice - just tell 'em no button's pressed | |
if (mousenum >= nraw_mouse_count || buttonnum >= MAX_RAW_MOUSE_BUTTONS || raw_mice == NULL) return 0; | |
return (raw_mice[mousenum].buttonpressed[buttonnum]); | |
} | |
//============================================================ | |
// is_raw_mouse_absolute | |
//============================================================ | |
BOOL is_raw_mouse_absolute(int mousenum) | |
{ | |
return (raw_mice[mousenum].is_absolute); | |
} | |
//============================================================ | |
// is_raw_mouse_virtual_desktop | |
//============================================================ | |
BOOL is_raw_mouse_virtual_desktop(int mousenum) | |
{ | |
return (raw_mice[mousenum].is_virtual_desktop); | |
} | |
//============================================================ | |
// get_raw_mouse_button_name | |
//============================================================ | |
char *get_raw_mouse_button_name(int mousenum, int buttonnum) { | |
if (mousenum >= nraw_mouse_count || buttonnum >= MAX_RAW_MOUSE_BUTTONS || raw_mice == NULL) return NULL; | |
return (raw_mice[mousenum].button_name[buttonnum]); | |
} | |
//============================================================ | |
// add_to_raw_mouse_x_and_y | |
//============================================================ | |
BOOL add_to_raw_mouse_x_and_y(HANDLE in_device_handle) | |
{ | |
// When the WM_INPUT message is received, the lparam must be passed to this function to keep a running tally of | |
// every mouse moves to maintain accurate results for get_raw_mouse_?_delta(). | |
// This function will take the HANDLE of the device and find the device in the raw_mice arrayand add the | |
// x and y mousemove values according to the information stored in the RAWINPUT structure. | |
LPBYTE lpb; | |
int dwSize; | |
if (/* GetRawInputData */(*_GRID)((HRAWINPUT)in_device_handle, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) { | |
fprintf(stderr, "ERROR: Unable to add to get size of raw input header.\n"); | |
return 0; | |
} | |
lpb = (LPBYTE)malloc(sizeof(LPBYTE) * dwSize); | |
if (lpb == NULL) { | |
fprintf(stderr, "ERROR: Unable to allocate memory for raw input header.\n"); | |
return 0; | |
} | |
if (/* GetRawInputData */(*_GRID)((HRAWINPUT)in_device_handle, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) { | |
fprintf(stderr, "ERROR: Unable to add to get raw input header.\n"); | |
return 0; | |
} | |
read_raw_input((RAWINPUT*)lpb); | |
free(lpb); | |
return 1; | |
} | |
//============================================================ | |
// get_raw_mouse_x_delta | |
//============================================================ | |
ULONG get_raw_mouse_x_delta(int mousenum) | |
{ | |
ULONG nReturn = 0; | |
if (raw_mice != NULL && mousenum < nraw_mouse_count) { | |
nReturn = raw_mice[mousenum].x; | |
if (!raw_mice[mousenum].is_absolute) raw_mice[mousenum].x = 0; | |
} | |
return nReturn; | |
} | |
//============================================================ | |
// get_raw_mouse_y_delta | |
//============================================================ | |
ULONG get_raw_mouse_y_delta(int mousenum) | |
{ | |
ULONG nReturn = 0; | |
if (raw_mice != NULL && mousenum < nraw_mouse_count) { | |
nReturn = raw_mice[mousenum].y; | |
if (!raw_mice[mousenum].is_absolute) raw_mice[mousenum].y = 0; | |
} | |
return nReturn; | |
} | |
//============================================================ | |
// get_raw_mouse_z_delta | |
//============================================================ | |
ULONG get_raw_mouse_z_delta(int mousenum) | |
{ | |
ULONG nReturn = 0; | |
if (raw_mice != NULL && mousenum < nraw_mouse_count) { | |
nReturn = raw_mice[mousenum].z; | |
if (!raw_mice[mousenum].is_absolute) raw_mice[mousenum].z = 0; | |
} | |
return nReturn; | |
} | |
// VD: keyboard additions | |
char* get_raw_mouse_device_name(int mousenum) { | |
return raw_mice[mousenum].device_name; | |
} | |
int raw_keyboard_count() { | |
return nraw_keyboard_count; | |
} | |
BOOL is_raw_keyboard_button_pressed(int kb, int key) { | |
return raw_keyboards[kb].keysdown[key]; | |
} | |
// out is an array filled with bit flags (1: down, 2: pressed, 4: released) | |
// and this should only be called once per frame for that reason | |
BOOL get_raw_keyboard_buttons(int kb, char* out) { | |
for (int k = 0; k < 256; k++) { | |
bool v0 = (out[k] & 1) != 0; | |
bool v1 = raw_keyboards[kb].keysdown[k]; | |
char v = v1 ? 1 : 0; | |
if (v1 && !v0) v |= 2; | |
if (!v1 && v0) v |= 4; | |
out[k] = v; | |
} | |
return true; | |
} | |
char* get_raw_keyboard_device_name(int index) { | |
return raw_keyboards[index].device_name; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment