File: PsychHID.h

package info (click to toggle)
psychtoolbox-3 3.0.14.20170103%2Bgit6-g605ff5c.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 103,044 kB
  • ctags: 69,483
  • sloc: ansic: 167,371; cpp: 11,232; objc: 4,708; sh: 1,875; python: 383; php: 344; makefile: 207; java: 113
file content (298 lines) | stat: -rw-r--r-- 14,608 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
294
295
296
297
298
	/*
	PsychToolbox3/Source/Common/PsychHID/PsychHID.h		

	PROJECTS: PsychHID

	PLATFORMS:  All

	AUTHORS:

	Allen.Ingling@nyu.edu             awi 
	mario.kleiner@tuebingen.mpg.de    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.

	TO DO:

		DONE	1- Emulate KbCheck
				2- Add Queues
		DONE	3- Have structure returned b GetCollections include list of constituent elements
				4- Try outputs, such as force feedback joysticks
				5- Accept structs as input args as alternative to  device, element or collection indices.
				6- Report vendor-specific usages. 
				7- Return logical arrays
				8- Maintain an internal queue beyond the 50-elements stored by the kernel 
				9- KbCheck could read any device with elements of type button.
        


*/

//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.

// 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__)
//#include <windows.h>
#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);

#endif

// Struct for storing keyboard(-like) events in KbQueue event buffer:
struct PsychHIDEventRecord_Struct {
	double timestamp;		// GetSecs timestamp of when event happened.
	unsigned int status;	// Status: Bit zero = press(1) or release(0) of key/button?
	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
};

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.
	// More specs go here...
	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.

	// OS-Specific parts of the struct:
	
	#if PSYCH_SYSTEM == PSYCH_OSX
	// OS/X stuff:
	IOUSBDeviceInterface182**    device;  // Actual low-level device specific pointer for OS/X.
	#else
        // Linux & Windows stuff:
        void*     device;  // libusb device handle for other os'es.
	#endif
};

typedef struct PsychUSBDeviceRecord_Struct PsychUSBDeviceRecord;

// 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

// 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 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 
//psych_bool 	PsychHIDCheckOpenDeviceInterfaceFromDeviceIndex(int deviceIndex);						// PsychHIDHelpers.c 
//psych_bool 	PsychHIDCheckOpenDeviceInterfaceFromDeviceRecordPtr(pRecDevice deviceRecord);					// 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);
#endif

void InitializeSynopsis();
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);

// 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);
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);
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);
int PsychHIDAddEventToEventBuffer(int deviceIndex, PsychHIDEventRecord* evt);

#ifdef __cplusplus
}
#endif

//end include once
#endif