File: PsychHIDGetCollections.c

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 (153 lines) | stat: -rw-r--r-- 7,367 bytes parent folder | download | duplicates (5)
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
/*
  PsychToolbox3/Source/Common/PsychHID/PsychHIDGetCollections.c		
  
  PROJECTS: PsychHID
  
  PLATFORMS:  OSX 
  
  AUTHORS:
  Allen.Ingling@nyu.edu             awi
  mario.kleiner@tuebingen.mpg.de    mk

  HISTORY:
  5/11/03  awi		Created.
  
  TO DO:

*/

#include "PsychHID.h"

#if PSYCH_SYSTEM == PSYCH_OSX

// ---------------------------------
// convert an element type to a mask
HIDElementTypeMask HIDConvertElementTypeToMask (const long type)
{
    HIDElementTypeMask result = kHIDElementTypeAll;
    
    switch (type)
    {
        case kIOHIDElementTypeInput_Misc:
        case kIOHIDElementTypeInput_Button:
        case kIOHIDElementTypeInput_Axis:
        case kIOHIDElementTypeInput_ScanCodes:
            result = kHIDElementTypeInput;
            break;
        case kIOHIDElementTypeOutput:
            result = kHIDElementTypeOutput;
            break;
        case kIOHIDElementTypeFeature:
            result = kHIDElementTypeFeature;
            break;
        case kIOHIDElementTypeCollection:
            result = kHIDElementTypeCollection;
            break;
        default:
            result = kHIDElementTypeAll;
            break;
    }
    return result;
}

static char useString[]= "collections=PsychHID('Collections', deviceNumber)";
static char synopsisString[] = 
        "Return a flat list of all collections on the specified USB HID device.\n"
        "A collection is a grouping of elements.\n"
        "Collections are hierarchical. A collection can contain other collections. "
        "Use the \"memberCollectionIndices\" field of the returned structures, "
        "which indexes the member collections, to expose the hierarchy.";

static char seeAlsoString[] = "";

PsychError PSYCHHIDGetCollections(void) 
{
    pRecDevice 			specDevice=NULL;
    UInt32              numDeviceElements;
    const char 			*elementFieldNames[]={"typeMaskName", "name", "deviceIndex", "collectionIndex", "typeValue", "typeName",    "usagePageValue", "usageValue", "usageName", "memberCollectionIndices", "memberElementIndices"};
    int                 i, numElementStructElements, numElementStructFieldNames=11, elementIndex, deviceIndex;
    PsychGenericScriptType	*elementStruct, *memberCollectionIndicesMat, *memberIOElementIndicesMat;	
    pRecElement			currentElement, lastElement = NULL;
    char                elementTypeName[PSYCH_HID_MAX_DEVICE_ELEMENT_TYPE_NAME_LENGTH];	
    char                usageName[PSYCH_HID_MAX_DEVICE_ELEMENT_USAGE_NAME_LENGTH];
    char                *typeMaskName;
    HIDElementTypeMask	typeMask;
    char                tmpName[1024];    
    pRecElement			*memberCollectionRecords, *memberIOElementRecords;     
    double              *memberCollectionIndices, *memberIOElementIndices; 
    int                 numSubCollections, numSubIOElements;
    

    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};

    PsychErrorExit(PsychCapNumOutputArgs(1));
    PsychErrorExit(PsychCapNumInputArgs(1));
        
    PsychCopyInIntegerArg(1, TRUE, &deviceIndex);
    PsychHIDVerifyInit();
    specDevice= PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex);
    PsychHIDVerifyOpenDeviceInterfaceFromDeviceIndex(deviceIndex);
    numDeviceElements= HIDCountDeviceElements(specDevice, kHIDElementTypeCollection);
    numElementStructElements = (int)numDeviceElements;
    PsychAllocOutStructArray(1, FALSE, numElementStructElements, numElementStructFieldNames, elementFieldNames, &elementStruct);
    elementIndex=0;
    for(currentElement=HIDGetFirstDeviceElement(specDevice,kHIDElementTypeCollection); 
        (currentElement != NULL) && (currentElement != lastElement);
        currentElement=HIDGetNextDeviceElement(currentElement, kHIDElementTypeCollection)) {
        lastElement = currentElement;

        // Needs HIDUtilities V2.0, available since OSX 10.5:
        IOHIDElementType type = IOHIDElementGetType(currentElement);
        typeMask = HIDConvertElementTypeToMask(type);

        tmpName[0] = 0;
        CFStringRef cfString = IOHIDElementGetName(currentElement);
        if (cfString) {
            CFStringGetCString(cfString, tmpName, sizeof(tmpName), kCFStringEncodingASCII);
            CFRelease(cfString);
        }
        PsychSetStructArrayStringElement("name",            elementIndex, 	tmpName, elementStruct);
    
        PsychSetStructArrayDoubleElement("typeValue", elementIndex, (double) type, elementStruct);
        HIDGetTypeName(type, elementTypeName);

        PsychSetStructArrayDoubleElement("usagePageValue", elementIndex, (double) IOHIDElementGetUsagePage(currentElement), elementStruct);
        PsychSetStructArrayDoubleElement("usageValue", elementIndex, (double) IOHIDElementGetUsage(currentElement), elementStruct);

        HIDGetUsageName(IOHIDElementGetUsagePage(currentElement), IOHIDElementGetUsage(currentElement), usageName);
        PsychSetStructArrayStringElement("usageName",		elementIndex, 	usageName,                  elementStruct);
        
        PsychHIDGetTypeMaskStringFromTypeMask(typeMask, &typeMaskName);
        PsychSetStructArrayStringElement("typeMaskName",	elementIndex, 	typeMaskName,	 			elementStruct);
        PsychSetStructArrayDoubleElement("deviceIndex",		elementIndex, 	(double)deviceIndex, 		elementStruct);
        PsychSetStructArrayDoubleElement("collectionIndex",	elementIndex, 	(double)elementIndex+1, 	elementStruct);
        PsychSetStructArrayStringElement("typeName",		elementIndex, 	elementTypeName,	 		elementStruct);
        //find and return the indices of this collection's member collections and indices
        numSubCollections=PsychHIDCountCollectionElements(currentElement, kHIDElementTypeCollection);
        numSubIOElements=PsychHIDCountCollectionElements(currentElement, kHIDElementTypeIO);
        memberCollectionRecords=(pRecElement*)PsychMallocTemp(sizeof(pRecElement) * numSubCollections);
        memberIOElementRecords=(pRecElement*)PsychMallocTemp(sizeof(pRecElement) * numSubIOElements);
        PsychHIDFindCollectionElements(currentElement, kHIDElementTypeCollection, memberCollectionRecords, numSubCollections);
        PsychHIDFindCollectionElements(currentElement, kHIDElementTypeIO, memberIOElementRecords, numSubIOElements);
        memberCollectionIndices=NULL;
        PsychAllocateNativeDoubleMat(1, numSubCollections, 1, &memberCollectionIndices, &memberCollectionIndicesMat);
        memberIOElementIndices=NULL;
        PsychAllocateNativeDoubleMat(1, numSubIOElements, 1, &memberIOElementIndices, &memberIOElementIndicesMat);
        
        for(i=0;i<numSubCollections;i++)
            memberCollectionIndices[i]=PsychHIDGetIndexFromRecord(specDevice, memberCollectionRecords[i], kHIDElementTypeCollection);
        for(i=0;i<numSubIOElements;i++)
            memberIOElementIndices[i]=PsychHIDGetIndexFromRecord(specDevice, memberIOElementRecords[i], kHIDElementTypeIO);
        PsychFreeTemp(memberCollectionRecords);
        PsychFreeTemp(memberIOElementRecords);
        PsychSetStructArrayNativeElement("memberCollectionIndices", 	elementIndex,	memberCollectionIndicesMat,	elementStruct);
        PsychSetStructArrayNativeElement("memberElementIndices", 	elementIndex,	memberIOElementIndicesMat,	elementStruct);

        ++elementIndex; 
    }

    return(PsychError_none);	
}

#endif