File: PsychHID.h

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (293 lines) | stat: -rw-r--r-- 16,951 bytes parent folder | download
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