1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
|
/*
* PsychToolbox-3/PsychSourceGL/Source/Common/PsychHID/PsychHID.h
*
* PROJECTS: PsychHID
*
* PLATFORMS: All
*
* AUTHORS:
*
* Allen.Ingling@nyu.edu awi
* mario.kleiner.de@gmail.com mk
*
* HISTORY:
*
* 4/29/03 awi Created.
* 3/15/05 dgp Added Get/SetReport
* 3/15/05 dgp Added missing prototypes from PsychHIDHelpers.c to make compiler happy.
* 4/3/05 dgp Added prototype for PsychHIDReceiveReportsCleanup.
* 8/23/07 rpw Added prototypes for PsychHIDKbTriggerWait and PsychHIDKbQueue suite.
* 12/17/09 rpw Added prototype for PsychHIDGetDeviceListByUsages.
*
*/
//begin include once
#ifndef PSYCH_IS_INCLUDED_PsychHID
#define PSYCH_IS_INCLUDED_PsychHID
//project includes
#include "Psych.h"
#include "PsychTimeGlue.h"
#define MAXREPORTSIZE 8192 // Maximum size of a single HID input report in bytes. Hard limit. Usercode can set lower per-device limits.
#define MAXDEVICEINDEXS 64 // Maximum number of simultaneously open HID devices.
// Define constants for use by PsychHID files.
#define PSYCH_HID_MAX_DEVICES 256
#define PSYCH_HID_MAX_DEVICE_ELEMENT_TYPE_NAME_LENGTH 256
#define PSYCH_HID_MAX_DEVICE_ELEMENT_USAGE_NAME_LENGTH 256
#define PSYCH_HID_MAX_DEVICE_ELEMENTS 1024
#define PSYCH_HID_MAX_GENERIC_USB_DEVICES 64
#define PSYCH_HID_MAX_VALUATORS 20
// OS/X specific includes:
#if PSYCH_SYSTEM == PSYCH_OSX
// Includes for Apple's HID utilities which are layered above the HID device interface. These are taken from
// Apple's "HID Explorer" example and used for all generic USB-HID interface support:
#include <Carbon/Carbon.h>
#include <IOKit/HID/IOHIDKeys.h>
#include <IOKit/hid/IOHIDUsageTables.h>
#include "HID_Utilities_External.h"
// Required for generic USB device support:
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/usb/IOUSBLib.h>
#include <IOKit/IOCFPlugIn.h>
#include <mach/mach.h>
#include <string.h>
typedef IOHIDDeviceRef pRecDevice;
typedef IOHIDElementRef pRecElement;
#else
// Non OS/X:
// Master include file for HIDAPI, as used on Linux and Windows:
#include "hidapi.h"
#if PSYCH_SYSTEM == PSYCH_WINDOWS
/* 'interface' is defined as a macro on Windows! We must
* undefine it to not break the definition of struct recDevice,
* which contains the "macro" interface as a variable name:
*/
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(interface)
#undef interface
#endif
#endif
#endif
// Dummy-Define so recDevice struct def works:
typedef int recElement;
struct recDevice
{
void* interface; // interface to device, NULL = no interface
void* queue; // device queue, NULL = no queue
void* queueRunLoopSource; // device queue run loop source, NULL == no source
void* transaction; // output transaction interface, NULL == no interface
void* notification; // notifications
char transport[256]; // device transport (c string)
long vendorID; // id for device vendor, unique across all devices
long productID; // id for particular product, unique across all of a vendors devices
long version; // version of product
char manufacturer[256]; // name of manufacturer
char product[256]; // name of product
char serial[256]; // serial number of specific product, can be assumed unique across specific product or specific vendor (not used often)
double locID; // double representing location in USB (or other I/O) chain which device is pluged into, can identify specific device on machine
long usage; // usage page which defines general usage
long usagePage; // usage within above page which defines specific usage
long interfaceId; // HIDAPI only: USB interface id.
long totalElements; // number of total elements (should be total of all elements on device including collections) (calculated, not reported by device)
long features; // number of elements of type kIOHIDElementTypeFeature
long inputs; // number of elements of type kIOHIDElementTypeInput_Misc or kIOHIDElementTypeInput_Button or kIOHIDElementTypeInput_Axis or kIOHIDElementTypeInput_ScanCodes
long outputs; // number of elements of type kIOHIDElementTypeOutput
long collections; // number of elements of type kIOHIDElementTypeCollection
long axis; // number of axis (calculated, not reported by device)
long buttons; // number of buttons (calculated, not reported by device)
long hats; // number of hat switches (calculated, not reported by device)
long sliders; // number of sliders (calculated, not reported by device)
long dials; // number of dials (calculated, not reported by device)
long wheels; // number of wheels (calculated, not reported by device)
recElement* pListElements; // head of linked list of elements
struct recDevice* pNext; // next device
};
typedef struct recDevice recDevice;
typedef recDevice* pRecDevice;
// Internal helpers:
psych_uint32 HIDCountDevices(void);
pRecDevice HIDGetFirstDevice(void);
pRecDevice HIDGetNextDevice(pRecDevice pDevice);
// End of Non OSX:
#endif
// Struct for storing keyboard(-like) events in KbQueue event buffer:
struct PsychHIDEventRecord_Struct {
double timestamp; // GetSecs timestamp of when event happened.
unsigned int type; // Event / Device type. 0 = Standard key/button event.
unsigned int status; // Status: Bit zero = press(1) or release(0) of key/button?
unsigned int buttonStates; // State of the first 32 device buttons, if any.
int rawEventCode; // Raw button/key code as returned by KbCheck, KbQueueCheck et al.
int cookedEventCode; // Translated key code, e.g., GetChar() style. May be same as rawEventCode
int numValuators; // Number of actual valuator values in this event.
float valuators[PSYCH_HID_MAX_VALUATORS];
float X; // X coordinate in native display space of operating system + winsys backend.
float Y; // Y coordinate in native display space of operating system + winsys backend.
float normX; // X coordinate normalized to 0. 0 - 1.0 range.
float normY; // Y coordinate normalized to 0. 0 - 1.0 range.
};
typedef struct PsychHIDEventRecord_Struct PsychHIDEventRecord;
// Structure which carries all required setup and matching parameters for
// finding, opening and configuring a generic USB device. This is passed
// to PsychHIDOSOpenUSBDevice(); to define what device should be opened,
// and with what parameters. It can be easily extended in the future:
struct PsychUSBSetupSpec_Struct {
int vendorID; // USB vendor ID.
int deviceID; // USB device ID / product ID.
int configurationID; // Index of USB configuration to select when configuring the device.
};
typedef struct PsychUSBSetupSpec_Struct PsychUSBSetupSpec;
// Structure to keep track of a generic USB device:
struct PsychUSBDeviceRecord_Struct {
int valid; // 0 = Unused/Free device record, 1 = Active device record.
int firstClaimedInterface; // -1 = No interface claimed yet. Otherwise number of 1st claimed interface.
void* device; // libusb device handle.
};
typedef struct PsychUSBDeviceRecord_Struct PsychUSBDeviceRecord;
// Function prototypes for module subfunctions.
PsychError MODULEVersion(void); // MODULEVersion.c
PsychError PSYCHHIDGetNumDevices(void); // PSYCHHIDGetNumDevices.c
PsychError PSYCHHIDGetDevices(void); // PsychHIDGetDeviceList.c
#if PSYCH_SYSTEM == PSYCH_OSX
PsychError PSYCHHIDGetNumElements(void); // PSYCHHIDGetNumElements.c
PsychError PSYCHHIDGetNumCollections(void); // PSYCHHIDGetNumCollections.c
PsychError PSYCHHIDGetElements(void); // PsychHIDGetElementList.c
PsychError PSYCHHIDGetCalibratedState(void); // PsychHIDGetCalibratedState.c
PsychError PSYCHHIDGetCollections(void); // PsychHIDGetCollections.c
PsychError PSYCHHIDKbWait(void); // PsychHIDKbWait.c
#endif
PsychError PSYCHHIDGetRawState(void); // PsychHIDGetRawElementState.c
PsychError PSYCHHIDKbTriggerWait(void); // PsychTriggerWait.c
PsychError PSYCHHIDKbQueueCreate(void); // PsychHIDKbQueueCreate.c
PsychError PSYCHHIDKbQueueStart(void); // PsychHIDKbQueueStart.c
PsychError PSYCHHIDKbQueueStop(void); // PsychHIDKbQueueStop.c
PsychError PSYCHHIDKbQueueCheck(void); // PsychHIDKbQueueCheck.c
PsychError PSYCHHIDKbQueueFlush(void); // PsychHIDKbQueueFlush.c
PsychError PSYCHHIDKbQueueRelease(void); // PsychHIDKbQueueRelease.c
PsychError PSYCHHIDKbCheck(void); // PsychHIDKbCheck.c
PsychError PSYCHHIDKbQueueGetEvent(void); // PsychHIDKbCheck.c
PsychError PSYCHHIDGetReport(void); // PsychHIDGetReport.c
PsychError PSYCHHIDSetReport(void); // PsychHIDSetReport.c
PsychError PSYCHHIDReceiveReports(void); // PsychHIDReceiveReports.c
PsychError PSYCHHIDReceiveReportsStop(void); // PsychHIDReceiveReportsStop.c
PsychError PSYCHHIDGiveMeReports(void); // PsychHIDGiveMeReports.c
PsychError PSYCHHIDOpenUSBDevice(void); // PSYCHHIDOpenUSBDevice.c
PsychError PSYCHHIDCloseUSBDevice(void); // PSYCHHIDCloseUSBDevice.c
PsychError PSYCHHIDUSBControlTransfer(void); // PSYCHHIDUSBControlTransfer.c
PsychError PSYCHHIDUSBBulkTransfer(void); // PSYCHHIDUSBControlTransfer.c
PsychError PSYCHHIDUSBInterruptTransfer(void); // PSYCHHIDUSBControlTransfer.c
PsychError PSYCHHIDUSBClaimInterface(void); // PSYCHHIDUSBControlTransfer.c
PsychError PSYCHHIDKeyboardHelper(void); // PSYCHHIDKeyboardHelper.c
// Internal function protototypes:
void ConsoleInputHelper(int ccode); // PsychHIDKeyboardHelper.c -- Called from kbqueue handling thread.
PsychError PsychHIDReceiveReportsCleanup(void); // PsychHIDReceiveReports.c
PsychError ReceiveReports(int deviceIndex); // PsychHIDReceiveReports.c
PsychError GiveMeReport(int deviceIndex, psych_bool *reportAvailablePtr, unsigned char *reportBuffer, psych_uint32 *reportBytesPtr, double *reportTimePtr); // PsychHIDReceiveReports.c
PsychError GiveMeReports(int deviceIndex, int reportBytes); // PsychHIDReceiveReports.c
PsychError ReceiveReportsStop(int deviceIndex);
PsychError PsychHIDCleanup(void); // PsychHIDHelpers.c
void PsychHIDVerifyInit(void); // PsychHIDHelpers.c
psych_bool PsychHIDWarnInputDisabled(const char* callerName); // PsychHIDHelpers.c
pRecDevice PsychHIDGetDeviceRecordPtrFromIndex(int deviceIndex); // PsychHIDHelpers.c
#if PSYCH_SYSTEM == PSYCH_OSX
int PsychHIDGetIndexFromRecord(pRecDevice deviceRecord, pRecElement elementRecord, HIDElementTypeMask typeMask);// PsychHIDHelpers.c
void PsychHIDGetTypeMaskStringFromTypeMask(HIDElementTypeMask maskValue, char **pStr); // PsychHIDHelpers.c
pRecElement PsychHIDGetElementRecordFromDeviceRecordAndElementIndex(pRecDevice deviceRecord, int elementIndex); // PsychHIDHelpers.c
pRecElement PsychHIDGetCollectionRecordFromDeviceRecordAndCollectionIndex(pRecDevice deviceRecord, int elementIndex); // PsychHIDHelpers.c
int PsychHIDCountCollectionElements(pRecElement collectionRecord, HIDElementTypeMask elementTypeMask); // PsychHIDHelpers.c
int PsychHIDFindCollectionElements(pRecElement collectionRecord, HIDElementTypeMask elementTypeMask, pRecElement *collectionMembers, int maxListElements); // PsychHIDHelpers.c
void PsychHIDGetDeviceListByUsage(long usagePage, long usage, int *numDeviceIndices, int *deviceIndices, pRecDevice *deviceRecords); //// PsychHIDHelpers.c
void PsychHIDGetDeviceListByUsages(int numUsages, long *usagePages, long *usages, int *numDeviceIndices, int *deviceIndices, pRecDevice *deviceRecords); //// PsychHIDHelpers.c
psych_bool PsychHIDQueryOpenDeviceInterfaceFromDeviceIndex(int deviceIndex); // PsychHIDHelpers.c
void PsychHIDVerifyOpenDeviceInterfaceFromDeviceIndex(int deviceIndex);
IOHIDDeviceInterface122** PsychHIDGetDeviceInterfacePtrFromIndex(int deviceIndex);
void HIDGetUsageName(const long valueUsagePage, const long valueUsage, char * cstrName);
HIDElementTypeMask HIDConvertElementTypeToMask(const long type);
psych_bool PsychHIDWarnAccessDenied(const char* callerName);
#endif
const char** InitializeSynopsis(void);
PsychError PsychDisplayPsychHIDSynopsis(void);
int PsychHIDErrors(void* device, int error, char **namePtr, char **descriptionPtr);
void PsychInitializePsychHID(void); // PsychHIDHelpers.c
void PsychHIDCloseAllUSBDevices(void);
PsychUSBDeviceRecord* PsychHIDGetFreeUSBDeviceSlot(int* usbHandle);
PsychUSBDeviceRecord* PsychHIDGetUSBDevice(int usbHandle);
// Helpers inside PsychHIDReceiveReports.c:
void PsychHIDReleaseAllReportMemory(void);
void PsychHIDAllocateReports(int deviceIndex);
// These must be defined for each OS in their own PsychHIDGenericUSBSupport.c.
psych_bool PsychHIDOSOpenUSBDevice(PsychUSBDeviceRecord* devRecord, int* errorcode, PsychUSBSetupSpec* spec);
void PsychHIDOSCloseUSBDevice(PsychUSBDeviceRecord* devRecord);
int PsychHIDOSControlTransfer(PsychUSBDeviceRecord* devRecord, psych_uint8 bmRequestType, psych_uint8 bRequest,
psych_uint16 wValue, psych_uint16 wIndex, psych_uint16 wLength, void *pData, unsigned int timeOutMSecs);
int PsychHIDOSBulkTransfer(PsychUSBDeviceRecord* devRecord, psych_uint8 endPoint, int length, psych_uint8* buffer, int* count, unsigned int timeOutMSecs);
int PsychHIDOSInterruptTransfer(PsychUSBDeviceRecord* devRecord, psych_uint8 endPoint, int length, psych_uint8* buffer, int* count, unsigned int timeOutMSecs);
int PsychHIDOSClaimInterface(PsychUSBDeviceRecord* devRecord, int interfaceId);
// These must be defined for each OS in their own PsychHIDStandardInterfaces.c:
#ifdef __cplusplus
extern "C" {
#endif
void PsychHIDInitializeHIDStandardInterfaces(void);
void PsychHIDShutdownHIDStandardInterfaces(void);
PsychError PsychHIDEnumerateHIDInputDevices(int deviceClass);
PsychError PsychHIDOSKbCheck(int deviceIndex, double* scanList);
PsychError PsychHIDOSGamePadAxisQuery(int deviceIndex, int axisId, double* min, double* max, double* val, char* axisLabel);
int PsychHIDGetDefaultKbQueueDevice(void);
PsychError PsychHIDOSKbQueueCreate(int deviceIndex, int numScankeys, int* scanKeys, int numValuators, int numSlots, unsigned int flags, psych_uint64 windowHandle);
void PsychHIDOSKbQueueRelease(int deviceIndex);
void PsychHIDOSKbQueueStop(int deviceIndex);
void PsychHIDOSKbQueueStart(int deviceIndex);
void PsychHIDOSKbQueueFlush(int deviceIndex);
void PsychHIDOSKbQueueCheck(int deviceIndex);
void PsychHIDOSKbTriggerWait(int deviceIndex, int numScankeys, int* scanKeys);
// Helpers for KbQueue event buffer: OS independent, but need C-linkage:
psych_bool PsychHIDCreateEventBuffer(int deviceIndex, int numValuators, int numSlots);
psych_bool PsychHIDDeleteEventBuffer(int deviceIndex);
psych_bool PsychHIDFlushEventBuffer(int deviceIndex);
unsigned int PsychHIDAvailEventBuffer(int deviceIndex, unsigned int flags);
int PsychHIDReturnEventFromEventBuffer(int deviceIndex, int outArgIndex, double maxWaitTimeSecs);
PsychHIDEventRecord* PsychHIDLastTouchEventFromEventBuffer(int deviceIndex, int touchID);
int PsychHIDAddEventToEventBuffer(int deviceIndex, PsychHIDEventRecord* evt);
#ifdef __cplusplus
}
#endif
//end include once
#endif
|