5 * Created by Jan Truetzschler v. Falkenstein on Tue Sep 30 2003.
6 * Copyright (c) 2003 jan.t. All rights reserved.
7 * modifications by Marije Baalman in May 2007
9 SuperCollider real time audio synthesis system
10 Copyright (c) 2002 James McCartney. All rights reserved.
11 http://www.audiosynth.com
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include <Carbon/Carbon.h>
32 #include "HID_Utilities_External.h"
35 #include <IOKit/IOKitLib.h>
36 #include <IOKit/IOCFPlugIn.h>
37 #include <IOKit/hid/IOHIDLib.h>
38 #include <IOKit/hid/IOHIDKeys.h>
40 #include <IOKit/hid/IOHIDUsageTables.h>
42 #include <mach/mach.h>
43 #include <mach/mach_error.h>
45 #include "VMGlobals.h"
46 #include "PyrSymbolTable.h"
47 #include "PyrInterpreter.h"
48 #include "PyrKernel.h"
50 #include "PyrObjectProto.h"
51 #include "PyrPrimitiveProto.h"
52 #include "PyrKernelProto.h"
53 #include "SC_InlineUnaryOp.h"
54 #include "SC_InlineBinaryOp.h"
58 // Backward compatibility for the older (10.4) way of doing things:
59 #if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
60 #define SC_MAC_HIDSTYLE_10_4 1
61 #define IOHIDDeviceRef pRecDevice
62 #define IOHIDElementRef pRecElement
63 #define IOHIDDevice_GetLocationID(x) (x->locID)
64 #define IOHIDElementGetType(x) ((IOHIDElementType) x->type)
65 #define IOHIDElementGetCookie(x) (x->cookie)
66 #define IOHIDElementGetLogicalMin(x) (x->min)
67 #define IOHIDElementGetLogicalMax(x) (x->max)
68 #define IOHIDElementGetUsagePage(x) (x->usagePage)
69 #define IOHIDElementGetUsage(x) (x->usage)
70 #define IOHIDDevice_GetManufacturer(x) (x->manufacturer)
71 #define IOHIDDevice_GetProduct(x) (x->product)
72 #define IOHIDDevice_GetUsagePage(x) (x->usagePage)
73 #define IOHIDDevice_GetUsage(x) (x->usage)
74 #define IOHIDDevice_GetVendorID(x) (x->vendorID)
75 #define IOHIDDevice_GetProductID(x) (x->productID)
76 #define IOHIDDevice_GetLocationID(x) (x->locID)
77 #define IOHIDDevice_GetVersionNumber(x) (x->version)
78 #define IOHIDDevice_GetSerialNumber(x) (x->serial)
81 PyrSymbol
* s_readError
;
82 PyrSymbol
* s_hidAction
;
84 extern bool compiledOK
;
85 int gNumberOfHIDDevices
= 0;
86 EventLoopTimerRef gTimer
= NULL
; // timer for element data updates
88 void releaseHIDDevices ();
89 void releaseHIDDevices ()
93 RemoveEventLoopTimer(gTimer
);
96 HIDReleaseAllDeviceQueues();
97 HIDReleaseDeviceList();
98 gNumberOfHIDDevices
= 0;
101 int prHIDGetElementListSize(VMGlobals
*g
, int numArgsPushed
);
102 int prHIDGetElementListSize(VMGlobals
*g
, int numArgsPushed
)
104 PyrSlot
*a
= g
->sp
- 1; //class
105 PyrSlot
*b
= g
->sp
; //locID device
107 int err
= slotIntVal(b
, &locID
);
109 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
111 while (pCurrentHIDDevice
&& ((uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
) != (uint32
)locID
))
112 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
114 if(!pCurrentHIDDevice
) return errFailed
;
115 UInt32 numElements
= HIDCountDeviceElements (pCurrentHIDDevice
, kHIDElementTypeAll
);
116 SetInt(a
, numElements
);
120 int prHIDBuildElementList(VMGlobals
*g
, int numArgsPushed
);
121 int prHIDBuildElementList(VMGlobals
*g
, int numArgsPushed
)
124 PyrSlot
*a
= g
->sp
- 2; //class
125 PyrSlot
*b
= g
->sp
- 1; //locID device
126 PyrSlot
*c
= g
->sp
; //array
129 int err
= slotIntVal(b
, &locID
);
131 //look for the right device:
132 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
133 while (pCurrentHIDDevice
&& ((uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=(uint32
)locID
))
134 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
135 if(!pCurrentHIDDevice
) return errFailed
;
137 IOHIDElementRef devElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
138 UInt32 numElements
= HIDCountDeviceElements (pCurrentHIDDevice
, kHIDElementTypeAll
);
140 // PyrObject* devAllElementsArray = newPyrArray(g->gc, numElements * sizeof(PyrObject), 0 , true);
141 PyrObject
*devAllElementsArray
= slotRawObject(c
);
142 // post("numElements: %d\n", numElements);
143 numElements
= sc_clip(numElements
, 0, devAllElementsArray
->size
);
144 for(uint i
=0; i
<numElements
; i
++){
146 char cstrElementName
[256];
147 PyrObject
* devElementArray
= newPyrArray(g
->gc
, 8 * sizeof(PyrObject
), 0 , true);
149 HIDGetTypeName(IOHIDElementGetType(devElement
), cstrElementName
);
150 PyrString
*devstring
= newPyrString(g
->gc
, cstrElementName
, 0, true);
151 SetObject(devElementArray
->slots
+devElementArray
->size
++, devstring
);
152 //g->gc->GCWrite(devElementArray, (PyrObject*) devstring);
154 HIDGetUsageName (IOHIDElementGetUsagePage(devElement
), IOHIDElementGetUsage(devElement
), cstrElementName
);
155 PyrString
*usestring
= newPyrString(g
->gc
, cstrElementName
, 0, true);
156 SetObject(devElementArray
->slots
+devElementArray
->size
++, usestring
);
157 //g->gc->GCWrite(devElementArray, (PyrObject*) usestring);
159 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetCookie(devElement
));
161 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetLogicalMin(devElement
));
163 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetLogicalMax(devElement
));
165 // IO type as int: (6)
166 SetInt(devElementArray
->slots
+devElementArray
->size
++, (int) IOHIDElementGetType(devElement
));
167 // Usage page as int: (7)
168 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetUsagePage(devElement
));
169 // Usage type as int: (8)
170 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetUsage(devElement
));
172 SetObject(devAllElementsArray
->slots
+i
, devElementArray
);
173 //g->gc->GCWrite(devAllElementsArray, (PyrObject*) devElementArray);
175 devElement
= HIDGetNextDeviceElement (devElement
, kHIDElementTypeAll
);
177 SetObject(a
, devAllElementsArray
);
183 int prHIDBuildDeviceList(VMGlobals
*g
, int numArgsPushed
);
184 int prHIDBuildDeviceList(VMGlobals
*g
, int numArgsPushed
)
186 //build a device list
187 PyrSlot
*a
= g
->sp
- 2;
188 PyrSlot
*b
= g
->sp
- 1; //usagePage
189 PyrSlot
*c
= g
->sp
; //usage
191 int usagePage
, usage
, err
;
196 err
= slotIntVal(b
, &usagePage
);
203 err
= slotIntVal(c
, &usage
);
207 //pass in usage & usagepage
208 //kHIDUsage_GD_Joystick kHIDUsage_GD_GamePad
209 //UInt32 usagePage = kHIDPage_GenericDesktop;
210 //UInt32 usage = NULL;
212 Boolean result
= HIDBuildDeviceList ((uint32
)usagePage
, (uint32
)usage
);
214 #if(SC_MAC_HIDSTYLE_10_4)
215 // on 10.4, this should return false (!)
219 if(!result
) post("no HID devices found\n");
221 int numdevs
= HIDCountDevices();
222 gNumberOfHIDDevices
= numdevs
;
227 //post("number of devices: %d", numdevs);
229 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
230 PyrObject
* allDevsArray
= newPyrArray(g
->gc
, numdevs
* sizeof(PyrObject
), 0 , true);
231 for(int i
=0; i
<numdevs
; i
++){
233 CFStringRef stringref
;
235 PyrObject
* devNameArray
= newPyrArray(g
->gc
, 8 * sizeof(PyrObject
), 0 , true);
237 //#if(SC_MAC_HIDSTYLE_10_4)
238 // PyrString *devstring = newPyrString(g->gc, pCurrentHIDDevice->manufacturer, 0, true);
241 stringref
= IOHIDDevice_GetManufacturer(pCurrentHIDDevice
);
244 CFStringGetCString(stringref
, tmp
, 256, kCFStringEncodingASCII
);
245 CFRelease(stringref
);
247 PyrString
*devstring
= newPyrString(g
->gc
, tmp
, 0, true);
249 SetObject(devNameArray
->slots
+devNameArray
->size
++, devstring
);
250 g
->gc
->GCWrite(devNameArray
, (PyrObject
*) devstring
);
252 //#if(SC_MAC_HIDSTYLE_10_4)
253 // devstring = newPyrString(g->gc, pCurrentHIDDevice->product, 0, true);
256 stringref
= IOHIDDevice_GetProduct(pCurrentHIDDevice
);
259 CFStringGetCString(stringref
, tmp
, 256, kCFStringEncodingASCII
);
260 CFRelease(stringref
);
262 devstring
= newPyrString(g
->gc
, tmp
, 0, true);
264 SetObject(devNameArray
->slots
+devNameArray
->size
++, devstring
);
265 g
->gc
->GCWrite(devNameArray
, (PyrObject
*) devstring
);
268 //#if(SC_MAC_HIDSTYLE_10_4)
269 // HIDGetUsageName (pCurrentHIDDevice->usagePage, pCurrentHIDDevice->usage, tmp);
270 // devstring = newPyrString(g->gc, tmp, 0, true);
273 HIDGetUsageName (IOHIDDevice_GetPrimaryUsagePage(pCurrentHIDDevice
), IOHIDDevice_GetPrimaryUsage(pCurrentHIDDevice
), tmp
);
274 devstring
= newPyrString(g
->gc
, tmp
, 0, true);
276 SetObject(devNameArray
->slots
+devNameArray
->size
++, devstring
);
277 g
->gc
->GCWrite(devNameArray
, (PyrObject
*) devstring
);
279 SetInt(devNameArray
->slots
+devNameArray
->size
++, (int)IOHIDDevice_GetVendorID(pCurrentHIDDevice
));
281 SetInt(devNameArray
->slots
+devNameArray
->size
++, (int)IOHIDDevice_GetProductID(pCurrentHIDDevice
));
283 SetInt(devNameArray
->slots
+devNameArray
->size
++, (int)IOHIDDevice_GetLocationID(pCurrentHIDDevice
));
286 SetInt(devNameArray
->slots
+devNameArray
->size
++, (int)IOHIDDevice_GetVersionNumber(pCurrentHIDDevice
));
289 //#if(SC_MAC_HIDSTYLE_10_4)
290 // devstring = newPyrString(g->gc, pCurrentHIDDevice->serial, 0, true);
293 stringref
= IOHIDDevice_GetSerialNumber(pCurrentHIDDevice
);
296 CFStringGetCString(stringref
, tmp
, 256, kCFStringEncodingASCII
);
297 CFRelease(stringref
);
299 devstring
= newPyrString(g
->gc
, tmp
, 0, true);
301 SetObject(devNameArray
->slots
+devNameArray
->size
++, devstring
);
302 g
->gc
->GCWrite(devNameArray
, (PyrObject
*) devstring
);
304 SetObject(allDevsArray
->slots
+allDevsArray
->size
++, devNameArray
);
305 g
->gc
->GCWrite(allDevsArray
, (PyrObject
*) devNameArray
);
306 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
310 //UInt32 outnum = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeOutput);
311 //post("number of outputs: %d \n", outnum);
312 SetObject(a
, allDevsArray
);
318 int prHIDGetValue(VMGlobals
*g
, int numArgsPushed
);
319 int prHIDGetValue(VMGlobals
*g
, int numArgsPushed
)
321 PyrSlot
*a
= g
->sp
- 2; //class
322 PyrSlot
*b
= g
->sp
- 1; //locID device
323 PyrSlot
*c
= g
->sp
; //element cookie
324 int locID
, cookieNum
;
325 int err
= slotIntVal(b
, &locID
);
327 err
= slotIntVal(c
, &cookieNum
);
329 IOHIDElementCookie cookie
= (IOHIDElementCookie
) cookieNum
;
330 //look for the right device:
331 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
332 while (pCurrentHIDDevice
&& ((uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
) != (uint32
)locID
))
333 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
334 if(!pCurrentHIDDevice
) return errFailed
;
335 //look for the right element:
336 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
337 // use gElementCookie to find current element
338 while (pCurrentHIDElement
&& (IOHIDElementGetCookie(pCurrentHIDElement
) != cookie
))
339 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
341 if (pCurrentHIDElement
)
343 //#if(SC_MAC_HIDSTYLE_10_4)
344 // SInt32 value = HIDGetElementValue (pCurrentHIDDevice, pCurrentHIDElement);
345 // // if it's not a button and it's not a hatswitch then calibrate
346 // if(( pCurrentHIDElement->type != kIOHIDElementTypeInput_Button ) &&
347 // ( pCurrentHIDElement->usagePage == 0x01 && pCurrentHIDElement->usage != kHIDUsage_GD_Hatswitch))
348 // value = HIDCalibrateValue ( value, pCurrentHIDElement );
351 // if it's not a button and it's not a hatswitch then calibrate
352 if(( IOHIDElementGetType(pCurrentHIDElement
) != kIOHIDElementTypeInput_Button
) &&
353 ( IOHIDElementGetUsagePage(pCurrentHIDElement
) == 0x01 && IOHIDElementGetUsage(pCurrentHIDElement
) != kHIDUsage_GD_Hatswitch
))
355 value
= IOHIDElement_GetValue(pCurrentHIDElement
, kIOHIDValueScaleTypeCalibrated
);
359 value
= IOHIDElement_GetValue(pCurrentHIDElement
, kIOHIDValueScaleTypePhysical
);
370 int prHIDSetValue(VMGlobals
*g
, int numArgsPushed
);
371 int prHIDSetValue(VMGlobals
*g
, int numArgsPushed
)
373 PyrSlot
*a
= g
->sp
- 3; //class
374 PyrSlot
*b
= g
->sp
- 2; //locID
375 PyrSlot
*c
= g
->sp
- 1; //element device
376 PyrSlot
*d
= g
->sp
; //value cookie
377 int locID
, cookieNum
, value
;
378 int err
= slotIntVal(b
, &locID
);
380 err
= slotIntVal(c
, &cookieNum
);
382 IOHIDElementCookie cookie
= (IOHIDElementCookie
) cookieNum
;
383 err
= slotIntVal(d
, &value
);
385 //look for the right device:
386 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
387 while (pCurrentHIDDevice
&& ((uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=(uint32
)locID
))
388 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
389 if(!pCurrentHIDDevice
) return errFailed
;
390 //look for the right element:
391 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
392 // use gElementCookie to find current element
393 while (pCurrentHIDElement
&& (IOHIDElementGetCookie(pCurrentHIDElement
) != cookie
))
394 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
395 //struct IOHIDEventStruct
397 // IOHIDElementType type;
398 // IOHIDElementCookie elementCookie;
400 // AbsoluteTime timestamp;
401 // UInt32 longValueSize;
405 if (pCurrentHIDElement
)
407 //#if(SC_MAC_HIDSTYLE_10_4)
408 // IOHIDEventStruct event =
410 // kIOHIDElementTypeOutput,
411 // pCurrentHIDElement->cookie,
417 // SInt32 value = HIDSetElementValue (pCurrentHIDDevice, pCurrentHIDElement, &event);
418 // // if it's not a button and it's not a hatswitch then calibrate
419 // // if(( pCurrentHIDElement->type != kIOHIDElementTypeInput_Button ) &&
420 // // ( pCurrentHIDElement->usagePage == 0x01 && pCurrentHIDElement->usage != kHIDUsage_GD_Hatswitch))
421 // // value = HIDCalibrateValue ( value, pCurrentHIDElement );
423 IOHIDValueRef valueref
= IOHIDValueCreateWithIntegerValue(0, pCurrentHIDElement
, 0, value
);
424 IOHIDDeviceSetValue(pCurrentHIDDevice
, pCurrentHIDElement
, valueref
);
434 void PushQueueEvents_RawValue ();
435 void PushQueueEvents_RawValue (){
437 //#if(SC_MAC_HIDSTYLE_10_4)
438 // IOHIDEventStruct event;
440 IOHIDValueRef value_ref
= 0;
442 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
443 int numdevs
= gNumberOfHIDDevices
;
444 unsigned char result
;
445 for(int i
=0; i
< numdevs
; i
++){
446 //#if(SC_MAC_HIDSTYLE_10_4)
447 // result = HIDGetEvent(pCurrentHIDDevice, (void*) &event);
449 result
= HIDGetEvent(pCurrentHIDDevice
, &value_ref
);
451 if(result
&& compiledOK
) {
452 //#if(SC_MAC_HIDSTYLE_10_4)
453 // SInt32 value = event.value;
455 SInt32 value
= IOHIDValueGetIntegerValue(value_ref
);
457 int vendorID
= IOHIDDevice_GetVendorID(pCurrentHIDDevice
);;
458 int productID
= IOHIDDevice_GetProductID(pCurrentHIDDevice
);
459 uint32 locID
= (uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
);
460 //#if(SC_MAC_HIDSTYLE_10_4)
461 // IOHIDElementCookie cookie = (IOHIDElementCookie) event.elementCookie;
463 IOHIDElementCookie cookie
= IOHIDElementGetCookie(IOHIDValueGetElement(value_ref
));
464 CFRelease(value_ref
);
466 VMGlobals
*g
= gMainVMGlobals
;
467 pthread_mutex_lock (&gLangMutex
);
468 g
->canCallOS
= false; // cannot call the OS
469 ++g
->sp
; SetObject(g
->sp
, s_hid
->u
.classobj
); // Set the class HIDService
471 ++g
->sp
;SetInt(g
->sp
, vendorID
);
472 ++g
->sp
;SetInt(g
->sp
, productID
);
473 ++g
->sp
;SetInt(g
->sp
, (int)locID
);
474 ++g
->sp
;SetInt(g
->sp
, (int) cookie
);
475 ++g
->sp
;SetInt(g
->sp
, value
);
476 runInterpreter(g
, s_hidAction
, 6);
477 g
->canCallOS
= false; // cannot call the OS
478 pthread_mutex_unlock (&gLangMutex
);
481 /* FIXME: this does not seem to be working
482 if ( !HIDIsValidDevice(pCurrentHIDDevice) )
484 post("HID: read Error\n");
485 int locID = pCurrentHIDDevice->locID;
486 VMGlobals *g = gMainVMGlobals;
487 pthread_mutex_lock (&gLangMutex);
488 g->canCallOS = false; // cannot call the OS
489 ++g->sp; SetObject(g->sp, s_hid->u.classobj); // Set the class HIDService
490 ++g->sp;SetInt(g->sp, locID);
491 runInterpreter(g, s_readError, 2);
492 g->canCallOS = false; // cannot call the OS
493 pthread_mutex_unlock (&gLangMutex);
496 pCurrentHIDDevice
= HIDGetNextDevice(pCurrentHIDDevice
);
500 void PushQueueEvents_CalibratedValue ();
501 void PushQueueEvents_CalibratedValue (){
503 //#if(SC_MAC_HIDSTYLE_10_4)
504 // IOHIDEventStruct event;
506 IOHIDValueRef value_ref
= 0;
508 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
509 int numdevs
= gNumberOfHIDDevices
;
510 unsigned char result
;
511 for(int i
=0; i
< numdevs
; i
++){
513 //#if(SC_MAC_HIDSTYLE_10_4)
514 // result = HIDGetEvent(pCurrentHIDDevice, (void*) &event);
516 result
= HIDGetEvent(pCurrentHIDDevice
, &value_ref
);
518 printf("result is %d\n", (int)result
);
519 if(result
&& compiledOK
) {
520 //#if(SC_MAC_HIDSTYLE_10_4)
521 // SInt32 value = event.value;
523 SInt32 value
= IOHIDValueGetScaledValue(value_ref
, kIOHIDValueScaleTypeCalibrated
);
525 int vendorID
= IOHIDDevice_GetVendorID(pCurrentHIDDevice
);;
526 int productID
= IOHIDDevice_GetProductID(pCurrentHIDDevice
);
527 uint32 locID
= (uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
);
528 //#if(SC_MAC_HIDSTYLE_10_4)
529 // IOHIDElementCookie cookie = (IOHIDElementCookie) event.elementCookie;
531 IOHIDElementCookie cookie
= IOHIDElementGetCookie(IOHIDValueGetElement(value_ref
));
532 CFRelease(value_ref
);
534 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
535 // use gElementCookie to find current element
536 while (pCurrentHIDElement
&& ( (IOHIDElementGetCookie(pCurrentHIDElement
)) != cookie
))
537 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
539 if (pCurrentHIDElement
)
541 //#if(SC_MAC_HIDSTYLE_10_4)
542 // value = HIDCalibrateValue(value, pCurrentHIDElement);
544 //find element to calibrate
545 VMGlobals
*g
= gMainVMGlobals
;
546 pthread_mutex_lock (&gLangMutex
);
547 g
->canCallOS
= false; // cannot call the OS
548 ++g
->sp
; SetObject(g
->sp
, s_hid
->u
.classobj
); // Set the class HIDService
550 ++g
->sp
;SetInt(g
->sp
, vendorID
);
551 ++g
->sp
;SetInt(g
->sp
, productID
);
552 ++g
->sp
;SetInt(g
->sp
, (int)locID
);
553 ++g
->sp
;SetInt(g
->sp
, (int) cookie
);
554 ++g
->sp
;SetInt(g
->sp
, value
);
555 runInterpreter(g
, s_hidAction
, 6);
556 g
->canCallOS
= false; // cannot call the OS
557 pthread_mutex_unlock (&gLangMutex
);
560 /* FIXME: this does not seem to be working!
561 if ( !HIDIsValidDevice(pCurrentHIDDevice) )
563 post("HID: read Error\n");
564 int locID = pCurrentHIDDevice->locID;
565 VMGlobals *g = gMainVMGlobals;
566 pthread_mutex_lock (&gLangMutex);
567 g->canCallOS = false; // cannot call the OS
568 ++g->sp; SetObject(g->sp, s_hid->u.classobj); // Set the class HIDService
569 ++g->sp;SetInt(g->sp, locID);
570 runInterpreter(g, s_readError, 2);
571 g->canCallOS = false; // cannot call the OS
572 pthread_mutex_unlock (&gLangMutex);
574 pCurrentHIDDevice
= HIDGetNextDevice(pCurrentHIDDevice
);
578 static pascal void IdleTimer (EventLoopTimerRef inTimer
, void* userData
);
579 static pascal void IdleTimer (EventLoopTimerRef inTimer
, void* userData
)
581 #pragma unused (inTimer, userData)
582 PushQueueEvents_CalibratedValue ();
584 int prHIDReleaseDeviceList(VMGlobals
*g
, int numArgsPushed
);
585 int prHIDReleaseDeviceList(VMGlobals
*g
, int numArgsPushed
)
590 static EventLoopTimerUPP
GetTimerUPP (void);
591 static EventLoopTimerUPP
GetTimerUPP (void)
593 static EventLoopTimerUPP sTimerUPP
= NULL
;
595 if (sTimerUPP
== NULL
)
596 sTimerUPP
= NewEventLoopTimerUPP (IdleTimer
);
601 typedef void (*IOHIDCallbackFunction)
602 (void * target, IOReturn result, void * refcon, void * sender);
606 void callback (void * target, IOReturn result, void * refcon, void * sender);
607 void callback (void * target, IOReturn result, void * refcon, void * sender)
611 int prHIDRunEventLoop(VMGlobals
*g
, int numArgsPushed
);
612 int prHIDRunEventLoop(VMGlobals
*g
, int numArgsPushed
)
614 PyrSlot
*a
= g
->sp
- 1; //class
615 PyrSlot
*b
= g
->sp
; //num
617 int err
= slotDoubleVal(b
, &eventtime
);
621 RemoveEventLoopTimer(gTimer
);
624 InstallEventLoopTimer (GetCurrentEventLoop(), 0, (EventTimerInterval
) eventtime
, GetTimerUPP (), 0, &gTimer
);
625 //HIDSetQueueCallback(pCurrentHIDDevice, callback);
629 int prHIDQueueDevice(VMGlobals
*g
, int numArgsPushed
);
630 int prHIDQueueDevice(VMGlobals
*g
, int numArgsPushed
)
633 PyrSlot
*a
= g
->sp
- 1; //class
634 PyrSlot
*b
= g
->sp
; //locID device
636 int err
= slotIntVal(b
, &locID
);
638 //look for the right device:
639 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
640 while (pCurrentHIDDevice
&& ((uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
) != (uint32
)locID
)){
641 printf("current device wasn't found\n");
642 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
644 if(!pCurrentHIDDevice
) return errFailed
;
645 int thisreturn
= HIDQueueDevice(pCurrentHIDDevice
);
646 printf("%d the return\n", thisreturn
);
650 int prHIDQueueElement(VMGlobals
*g
, int numArgsPushed
);
651 int prHIDQueueElement(VMGlobals
*g
, int numArgsPushed
)
654 PyrSlot
*a
= g
->sp
- 2; //class
655 PyrSlot
*b
= g
->sp
- 1; //locID device
656 PyrSlot
*c
= g
->sp
; //element cookie
657 int locID
, cookieNum
;
658 int err
= slotIntVal(b
, &locID
);
660 err
= slotIntVal(c
, &cookieNum
);
662 IOHIDElementCookie cookie
= (IOHIDElementCookie
) cookieNum
;
663 //look for the right device:
664 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
665 while (pCurrentHIDDevice
&& ((uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=(uint32
)locID
))
666 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
667 if(!pCurrentHIDDevice
) return errFailed
;
668 //look for the right element:
669 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
670 // use gElementCookie to find current element
671 while (pCurrentHIDElement
&& (IOHIDElementGetCookie(pCurrentHIDElement
) != cookie
))
672 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
673 if(!pCurrentHIDElement
) return errFailed
;
674 HIDQueueElement(pCurrentHIDDevice
, pCurrentHIDElement
);
678 int prHIDDequeueElement(VMGlobals
*g
, int numArgsPushed
);
679 int prHIDDequeueElement(VMGlobals
*g
, int numArgsPushed
)
682 PyrSlot
*a
= g
->sp
- 2; //class
683 PyrSlot
*b
= g
->sp
- 1; //locID device
684 PyrSlot
*c
= g
->sp
; //element cookie
685 int locID
, cookieNum
;
686 int err
= slotIntVal(b
, &locID
);
688 err
= slotIntVal(c
, &cookieNum
);
690 IOHIDElementCookie cookie
= (IOHIDElementCookie
) cookieNum
;
691 //look for the right device:
692 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
693 while (pCurrentHIDDevice
&& ((uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=(uint32
)locID
))
694 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
695 if(!pCurrentHIDDevice
) return errFailed
;
696 //look for the right element:
697 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
698 while (pCurrentHIDElement
&& (IOHIDElementGetCookie(pCurrentHIDElement
) != cookie
))
699 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
700 if(!pCurrentHIDElement
) return errFailed
;
701 HIDDequeueElement(pCurrentHIDDevice
, pCurrentHIDElement
);
705 int prHIDDequeueDevice(VMGlobals
*g
, int numArgsPushed
);
706 int prHIDDequeueDevice(VMGlobals
*g
, int numArgsPushed
)
709 PyrSlot
*a
= g
->sp
- 1; //class
710 PyrSlot
*b
= g
->sp
; //locID device
712 int err
= slotIntVal(b
, &locID
);
714 //look for the right device:
715 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
716 while (pCurrentHIDDevice
&& ((uint32
)IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=(uint32
)locID
))
717 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
718 if(!pCurrentHIDDevice
) return errFailed
;
719 HIDDequeueDevice(pCurrentHIDDevice
);
723 int prHIDStopEventLoop(VMGlobals
*g
, int numArgsPushed
);
724 int prHIDStopEventLoop(VMGlobals
*g
, int numArgsPushed
)
728 RemoveEventLoopTimer(gTimer
);
735 void initHIDPrimitives()
741 s_hid
= getsym("HIDDeviceService");
742 s_hidAction
= getsym("prHidAction");
743 s_readError
= getsym("prReadError");
745 base
= nextPrimitiveIndex();
747 definePrimitive(base
, index
++, "_HIDBuildDeviceList", prHIDBuildDeviceList
, 3, 0);
749 definePrimitive(base
, index
++, "_HIDGetElementListSize", prHIDGetElementListSize
, 2, 0);
750 definePrimitive(base
, index
++, "_HIDBuildElementList", prHIDBuildElementList
, 3, 0);
752 definePrimitive(base
, index
++, "_HIDGetValue", prHIDGetValue
, 3, 0);
753 definePrimitive(base
, index
++, "_HIDSetValue", prHIDSetValue
, 4, 0);
755 definePrimitive(base
, index
++, "_HIDReleaseDeviceList", prHIDReleaseDeviceList
, 1, 0);
756 definePrimitive(base
, index
++, "_HIDRunEventLoop", prHIDRunEventLoop
, 2, 0);
757 definePrimitive(base
, index
++, "_HIDStopEventLoop", prHIDStopEventLoop
, 1, 0);
758 definePrimitive(base
, index
++, "_HIDQueueDevice", prHIDQueueDevice
, 2, 0);
759 definePrimitive(base
, index
++, "_HIDDequeueDevice", prHIDDequeueDevice
, 2, 0);
760 definePrimitive(base
, index
++, "_HIDDequeueElement", prHIDDequeueElement
, 3, 0);
761 definePrimitive(base
, index
++, "_HIDQueueElement", prHIDQueueElement
, 3, 0);
765 void initHIDPrimitives()