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 ();
110 while (pCurrentHIDDevice
&& (IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=locID
))
111 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
112 if(!pCurrentHIDDevice
) return errFailed
;
113 UInt32 numElements
= HIDCountDeviceElements (pCurrentHIDDevice
, kHIDElementTypeAll
);
114 SetInt(a
, numElements
);
118 int prHIDBuildElementList(VMGlobals
*g
, int numArgsPushed
);
119 int prHIDBuildElementList(VMGlobals
*g
, int numArgsPushed
)
122 PyrSlot
*a
= g
->sp
- 2; //class
123 PyrSlot
*b
= g
->sp
- 1; //locID device
124 PyrSlot
*c
= g
->sp
; //array
127 int err
= slotIntVal(b
, &locID
);
129 //look for the right device:
130 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
131 while (pCurrentHIDDevice
&& (IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=locID
))
132 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
133 if(!pCurrentHIDDevice
) return errFailed
;
135 IOHIDElementRef devElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
136 UInt32 numElements
= HIDCountDeviceElements (pCurrentHIDDevice
, kHIDElementTypeAll
);
138 // PyrObject* devAllElementsArray = newPyrArray(g->gc, numElements * sizeof(PyrObject), 0 , true);
139 PyrObject
*devAllElementsArray
= slotRawObject(c
);
140 // post("numElements: %d\n", numElements);
141 numElements
= sc_clip(numElements
, 0, devAllElementsArray
->size
);
142 for(uint i
=0; i
<numElements
; i
++){
144 char cstrElementName
[256];
145 PyrObject
* devElementArray
= newPyrArray(g
->gc
, 8 * sizeof(PyrObject
), 0 , true);
147 HIDGetTypeName(IOHIDElementGetType(devElement
), cstrElementName
);
148 PyrString
*devstring
= newPyrString(g
->gc
, cstrElementName
, 0, true);
149 SetObject(devElementArray
->slots
+devElementArray
->size
++, devstring
);
150 //g->gc->GCWrite(devElementArray, (PyrObject*) devstring);
152 HIDGetUsageName (IOHIDElementGetUsagePage(devElement
), IOHIDElementGetUsage(devElement
), cstrElementName
);
153 PyrString
*usestring
= newPyrString(g
->gc
, cstrElementName
, 0, true);
154 SetObject(devElementArray
->slots
+devElementArray
->size
++, usestring
);
155 //g->gc->GCWrite(devElementArray, (PyrObject*) usestring);
157 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetCookie(devElement
));
159 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetLogicalMin(devElement
));
161 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetLogicalMax(devElement
));
163 // IO type as int: (6)
164 SetInt(devElementArray
->slots
+devElementArray
->size
++, (int) IOHIDElementGetType(devElement
));
165 // Usage page as int: (7)
166 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetUsagePage(devElement
));
167 // Usage type as int: (8)
168 SetInt(devElementArray
->slots
+devElementArray
->size
++, (long) IOHIDElementGetUsage(devElement
));
170 SetObject(devAllElementsArray
->slots
+i
, devElementArray
);
171 //g->gc->GCWrite(devAllElementsArray, (PyrObject*) devElementArray);
173 devElement
= HIDGetNextDeviceElement (devElement
, kHIDElementTypeAll
);
175 SetObject(a
, devAllElementsArray
);
181 int prHIDBuildDeviceList(VMGlobals
*g
, int numArgsPushed
);
182 int prHIDBuildDeviceList(VMGlobals
*g
, int numArgsPushed
)
184 //build a device list
185 PyrSlot
*a
= g
->sp
- 2;
186 PyrSlot
*b
= g
->sp
- 1; //usagePage
187 PyrSlot
*c
= g
->sp
; //usage
189 int usagePage
, usage
, err
;
194 err
= slotIntVal(b
, &usagePage
);
201 err
= slotIntVal(c
, &usage
);
205 //pass in usage & usagepage
206 //kHIDUsage_GD_Joystick kHIDUsage_GD_GamePad
207 //UInt32 usagePage = kHIDPage_GenericDesktop;
208 //UInt32 usage = NULL;
210 Boolean result
= HIDBuildDeviceList (usagePage
, usage
);
211 #if(SC_MAC_HIDSTYLE_10_4)
212 // on 10.4, this should return false (!)
215 if(!result
) post("no HID devices found\n");
217 int numdevs
= HIDCountDevices();
218 gNumberOfHIDDevices
= numdevs
;
223 //post("number of devices: %d", numdevs);
225 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
226 PyrObject
* allDevsArray
= newPyrArray(g
->gc
, numdevs
* sizeof(PyrObject
), 0 , true);
227 for(int i
=0; i
<numdevs
; i
++){
229 CFStringRef stringref
;
231 PyrObject
* devNameArray
= newPyrArray(g
->gc
, 8 * sizeof(PyrObject
), 0 , true);
233 #if(SC_MAC_HIDSTYLE_10_4)
234 PyrString
*devstring
= newPyrString(g
->gc
, pCurrentHIDDevice
->manufacturer
, 0, true);
237 stringref
= IOHIDDevice_GetManufacturer(pCurrentHIDDevice
);
240 CFStringGetCString(stringref
, tmp
, 256, kCFStringEncodingASCII
);
241 CFRelease(stringref
);
243 PyrString
*devstring
= newPyrString(g
->gc
, tmp
, 0, true);
245 SetObject(devNameArray
->slots
+devNameArray
->size
++, devstring
);
246 g
->gc
->GCWrite(devNameArray
, (PyrObject
*) devstring
);
248 #if(SC_MAC_HIDSTYLE_10_4)
249 devstring
= newPyrString(g
->gc
, pCurrentHIDDevice
->product
, 0, true);
252 stringref
= IOHIDDevice_GetProduct(pCurrentHIDDevice
);
255 CFStringGetCString(stringref
, tmp
, 256, kCFStringEncodingASCII
);
256 CFRelease(stringref
);
258 devstring
= newPyrString(g
->gc
, tmp
, 0, true);
260 SetObject(devNameArray
->slots
+devNameArray
->size
++, devstring
);
261 g
->gc
->GCWrite(devNameArray
, (PyrObject
*) devstring
);
264 #if(SC_MAC_HIDSTYLE_10_4)
265 HIDGetUsageName (pCurrentHIDDevice
->usagePage
, pCurrentHIDDevice
->usage
, tmp
);
266 devstring
= newPyrString(g
->gc
, tmp
, 0, true);
269 HIDGetUsageName (IOHIDDevice_GetPrimaryUsagePage(pCurrentHIDDevice
), IOHIDDevice_GetPrimaryUsage(pCurrentHIDDevice
), tmp
);
270 devstring
= newPyrString(g
->gc
, tmp
, 0, true);
272 SetObject(devNameArray
->slots
+devNameArray
->size
++, devstring
);
273 g
->gc
->GCWrite(devNameArray
, (PyrObject
*) devstring
);
275 SetInt(devNameArray
->slots
+devNameArray
->size
++, IOHIDDevice_GetVendorID(pCurrentHIDDevice
));
277 SetInt(devNameArray
->slots
+devNameArray
->size
++, IOHIDDevice_GetProductID(pCurrentHIDDevice
));
279 SetInt(devNameArray
->slots
+devNameArray
->size
++, IOHIDDevice_GetLocationID(pCurrentHIDDevice
));
282 SetInt(devNameArray
->slots
+devNameArray
->size
++, IOHIDDevice_GetVersionNumber(pCurrentHIDDevice
));
285 #if(SC_MAC_HIDSTYLE_10_4)
286 devstring
= newPyrString(g
->gc
, pCurrentHIDDevice
->serial
, 0, true);
289 stringref
= IOHIDDevice_GetSerialNumber(pCurrentHIDDevice
);
292 CFStringGetCString(stringref
, tmp
, 256, kCFStringEncodingASCII
);
293 CFRelease(stringref
);
295 devstring
= newPyrString(g
->gc
, tmp
, 0, true);
297 SetObject(devNameArray
->slots
+devNameArray
->size
++, devstring
);
298 g
->gc
->GCWrite(devNameArray
, (PyrObject
*) devstring
);
300 SetObject(allDevsArray
->slots
+allDevsArray
->size
++, devNameArray
);
301 g
->gc
->GCWrite(allDevsArray
, (PyrObject
*) devNameArray
);
302 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
306 //UInt32 outnum = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeOutput);
307 //post("number of outputs: %d \n", outnum);
308 SetObject(a
, allDevsArray
);
314 int prHIDGetValue(VMGlobals
*g
, int numArgsPushed
);
315 int prHIDGetValue(VMGlobals
*g
, int numArgsPushed
)
317 PyrSlot
*a
= g
->sp
- 2; //class
318 PyrSlot
*b
= g
->sp
- 1; //locID device
319 PyrSlot
*c
= g
->sp
; //element cookie
320 int locID
, cookieNum
;
321 int err
= slotIntVal(b
, &locID
);
323 err
= slotIntVal(c
, &cookieNum
);
325 IOHIDElementCookie cookie
= (IOHIDElementCookie
) cookieNum
;
326 //look for the right device:
327 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
328 while (pCurrentHIDDevice
&& (IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=locID
))
329 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
330 if(!pCurrentHIDDevice
) return errFailed
;
331 //look for the right element:
332 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
333 // use gElementCookie to find current element
334 while (pCurrentHIDElement
&& (IOHIDElementGetCookie(pCurrentHIDElement
) != cookie
))
335 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
337 if (pCurrentHIDElement
)
339 #if(SC_MAC_HIDSTYLE_10_4)
340 SInt32 value
= HIDGetElementValue (pCurrentHIDDevice
, pCurrentHIDElement
);
341 // if it's not a button and it's not a hatswitch then calibrate
342 if(( pCurrentHIDElement
->type
!= kIOHIDElementTypeInput_Button
) &&
343 ( pCurrentHIDElement
->usagePage
== 0x01 && pCurrentHIDElement
->usage
!= kHIDUsage_GD_Hatswitch
))
344 value
= HIDCalibrateValue ( value
, pCurrentHIDElement
);
347 // if it's not a button and it's not a hatswitch then calibrate
348 if(( IOHIDElementGetType(pCurrentHIDElement
) != kIOHIDElementTypeInput_Button
) &&
349 ( IOHIDElementGetUsagePage(pCurrentHIDElement
) == 0x01 && IOHIDElementGetUsage(pCurrentHIDElement
) != kHIDUsage_GD_Hatswitch
))
351 value
= IOHIDElement_GetValue(pCurrentHIDElement
, kIOHIDValueScaleTypeCalibrated
);
355 value
= IOHIDElement_GetValue(pCurrentHIDElement
, kIOHIDValueScaleTypePhysical
);
366 int prHIDSetValue(VMGlobals
*g
, int numArgsPushed
);
367 int prHIDSetValue(VMGlobals
*g
, int numArgsPushed
)
369 PyrSlot
*a
= g
->sp
- 3; //class
370 PyrSlot
*b
= g
->sp
- 2; //locID
371 PyrSlot
*c
= g
->sp
- 1; //element device
372 PyrSlot
*d
= g
->sp
; //value cookie
373 int locID
, cookieNum
, value
;
374 int err
= slotIntVal(b
, &locID
);
376 err
= slotIntVal(c
, &cookieNum
);
378 IOHIDElementCookie cookie
= (IOHIDElementCookie
) cookieNum
;
379 err
= slotIntVal(d
, &value
);
381 //look for the right device:
382 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
383 while (pCurrentHIDDevice
&& (IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=locID
))
384 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
385 if(!pCurrentHIDDevice
) return errFailed
;
386 //look for the right element:
387 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
388 // use gElementCookie to find current element
389 while (pCurrentHIDElement
&& (IOHIDElementGetCookie(pCurrentHIDElement
) != cookie
))
390 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
391 //struct IOHIDEventStruct
393 // IOHIDElementType type;
394 // IOHIDElementCookie elementCookie;
396 // AbsoluteTime timestamp;
397 // UInt32 longValueSize;
401 if (pCurrentHIDElement
)
403 #if(SC_MAC_HIDSTYLE_10_4)
404 IOHIDEventStruct event
=
406 kIOHIDElementTypeOutput
,
407 pCurrentHIDElement
->cookie
,
413 SInt32 value
= HIDSetElementValue (pCurrentHIDDevice
, pCurrentHIDElement
, &event
);
414 // if it's not a button and it's not a hatswitch then calibrate
415 // if(( pCurrentHIDElement->type != kIOHIDElementTypeInput_Button ) &&
416 // ( pCurrentHIDElement->usagePage == 0x01 && pCurrentHIDElement->usage != kHIDUsage_GD_Hatswitch))
417 // value = HIDCalibrateValue ( value, pCurrentHIDElement );
419 IOHIDValueRef valueref
= IOHIDValueCreateWithIntegerValue(0, pCurrentHIDElement
, 0, value
);
420 IOHIDDeviceSetValue(pCurrentHIDDevice
, pCurrentHIDElement
, valueref
);
430 void PushQueueEvents_RawValue ();
431 void PushQueueEvents_RawValue (){
433 #if(SC_MAC_HIDSTYLE_10_4)
434 IOHIDEventStruct event
;
436 IOHIDValueRef value_ref
= 0;
438 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
439 int numdevs
= gNumberOfHIDDevices
;
440 unsigned char result
;
441 for(int i
=0; i
< numdevs
; i
++){
442 #if(SC_MAC_HIDSTYLE_10_4)
443 result
= HIDGetEvent(pCurrentHIDDevice
, (void*) &event
);
445 result
= HIDGetEvent(pCurrentHIDDevice
, &value_ref
);
447 if(result
&& compiledOK
) {
448 #if(SC_MAC_HIDSTYLE_10_4)
449 SInt32 value
= event
.value
;
451 SInt32 value
= IOHIDValueGetIntegerValue(value_ref
);
453 int vendorID
= IOHIDDevice_GetVendorID(pCurrentHIDDevice
);;
454 int productID
= IOHIDDevice_GetProductID(pCurrentHIDDevice
);
455 int locID
= IOHIDDevice_GetLocationID(pCurrentHIDDevice
);
456 #if(SC_MAC_HIDSTYLE_10_4)
457 IOHIDElementCookie cookie
= (IOHIDElementCookie
) event
.elementCookie
;
459 IOHIDElementCookie cookie
= IOHIDElementGetCookie(IOHIDValueGetElement(value_ref
));
460 CFRelease(value_ref
);
462 VMGlobals
*g
= gMainVMGlobals
;
463 pthread_mutex_lock (&gLangMutex
);
464 g
->canCallOS
= false; // cannot call the OS
465 ++g
->sp
; SetObject(g
->sp
, s_hid
->u
.classobj
); // Set the class HIDService
467 ++g
->sp
;SetInt(g
->sp
, vendorID
);
468 ++g
->sp
;SetInt(g
->sp
, productID
);
469 ++g
->sp
;SetInt(g
->sp
, locID
);
470 ++g
->sp
;SetInt(g
->sp
, (int) cookie
);
471 ++g
->sp
;SetInt(g
->sp
, value
);
472 runInterpreter(g
, s_hidAction
, 6);
473 g
->canCallOS
= false; // cannot call the OS
474 pthread_mutex_unlock (&gLangMutex
);
477 /* FIXME: this does not seem to be working
478 if ( !HIDIsValidDevice(pCurrentHIDDevice) )
480 post("HID: read Error\n");
481 int locID = pCurrentHIDDevice->locID;
482 VMGlobals *g = gMainVMGlobals;
483 pthread_mutex_lock (&gLangMutex);
484 g->canCallOS = false; // cannot call the OS
485 ++g->sp; SetObject(g->sp, s_hid->u.classobj); // Set the class HIDService
486 ++g->sp;SetInt(g->sp, locID);
487 runInterpreter(g, s_readError, 2);
488 g->canCallOS = false; // cannot call the OS
489 pthread_mutex_unlock (&gLangMutex);
492 pCurrentHIDDevice
= HIDGetNextDevice(pCurrentHIDDevice
);
496 void PushQueueEvents_CalibratedValue ();
497 void PushQueueEvents_CalibratedValue (){
499 #if(SC_MAC_HIDSTYLE_10_4)
500 IOHIDEventStruct event
;
502 IOHIDValueRef value_ref
= 0;
504 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
506 int numdevs
= gNumberOfHIDDevices
;
507 unsigned char result
;
508 for(int i
=0; i
< numdevs
; i
++){
510 #if(SC_MAC_HIDSTYLE_10_4)
511 result
= HIDGetEvent(pCurrentHIDDevice
, (void*) &event
);
513 result
= HIDGetEvent(pCurrentHIDDevice
, &value_ref
);
515 if(result
&& compiledOK
) {
516 #if(SC_MAC_HIDSTYLE_10_4)
517 SInt32 value
= event
.value
;
519 SInt32 value
= IOHIDValueGetScaledValue(value_ref
, kIOHIDValueScaleTypeCalibrated
);
521 int vendorID
= IOHIDDevice_GetVendorID(pCurrentHIDDevice
);;
522 int productID
= IOHIDDevice_GetProductID(pCurrentHIDDevice
);
523 int locID
= IOHIDDevice_GetLocationID(pCurrentHIDDevice
);
524 #if(SC_MAC_HIDSTYLE_10_4)
525 IOHIDElementCookie cookie
= (IOHIDElementCookie
) event
.elementCookie
;
527 IOHIDElementCookie cookie
= IOHIDElementGetCookie(IOHIDValueGetElement(value_ref
));
528 CFRelease(value_ref
);
530 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
531 // use gElementCookie to find current element
532 while (pCurrentHIDElement
&& ( (IOHIDElementGetCookie(pCurrentHIDElement
)) != cookie
))
533 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
535 if (pCurrentHIDElement
)
537 #if(SC_MAC_HIDSTYLE_10_4)
538 value
= HIDCalibrateValue(value
, pCurrentHIDElement
);
540 //find element to calibrate
541 VMGlobals
*g
= gMainVMGlobals
;
542 pthread_mutex_lock (&gLangMutex
);
543 g
->canCallOS
= false; // cannot call the OS
544 ++g
->sp
; SetObject(g
->sp
, s_hid
->u
.classobj
); // Set the class HIDService
546 ++g
->sp
;SetInt(g
->sp
, vendorID
);
547 ++g
->sp
;SetInt(g
->sp
, productID
);
548 ++g
->sp
;SetInt(g
->sp
, locID
);
549 ++g
->sp
;SetInt(g
->sp
, (int) cookie
);
550 ++g
->sp
;SetInt(g
->sp
, value
);
551 runInterpreter(g
, s_hidAction
, 6);
552 g
->canCallOS
= false; // cannot call the OS
553 pthread_mutex_unlock (&gLangMutex
);
556 /* FIXME: this does not seem to be working!
557 if ( !HIDIsValidDevice(pCurrentHIDDevice) )
559 post("HID: read Error\n");
560 int locID = pCurrentHIDDevice->locID;
561 VMGlobals *g = gMainVMGlobals;
562 pthread_mutex_lock (&gLangMutex);
563 g->canCallOS = false; // cannot call the OS
564 ++g->sp; SetObject(g->sp, s_hid->u.classobj); // Set the class HIDService
565 ++g->sp;SetInt(g->sp, locID);
566 runInterpreter(g, s_readError, 2);
567 g->canCallOS = false; // cannot call the OS
568 pthread_mutex_unlock (&gLangMutex);
570 pCurrentHIDDevice
= HIDGetNextDevice(pCurrentHIDDevice
);
574 static pascal void IdleTimer (EventLoopTimerRef inTimer
, void* userData
);
575 static pascal void IdleTimer (EventLoopTimerRef inTimer
, void* userData
)
577 #pragma unused (inTimer, userData)
578 PushQueueEvents_CalibratedValue ();
580 int prHIDReleaseDeviceList(VMGlobals
*g
, int numArgsPushed
);
581 int prHIDReleaseDeviceList(VMGlobals
*g
, int numArgsPushed
)
586 static EventLoopTimerUPP
GetTimerUPP (void);
587 static EventLoopTimerUPP
GetTimerUPP (void)
589 static EventLoopTimerUPP sTimerUPP
= NULL
;
591 if (sTimerUPP
== NULL
)
592 sTimerUPP
= NewEventLoopTimerUPP (IdleTimer
);
597 typedef void (*IOHIDCallbackFunction)
598 (void * target, IOReturn result, void * refcon, void * sender);
602 void callback (void * target, IOReturn result, void * refcon, void * sender);
603 void callback (void * target, IOReturn result, void * refcon, void * sender)
607 int prHIDRunEventLoop(VMGlobals
*g
, int numArgsPushed
);
608 int prHIDRunEventLoop(VMGlobals
*g
, int numArgsPushed
)
610 PyrSlot
*a
= g
->sp
- 1; //class
611 PyrSlot
*b
= g
->sp
; //num
613 int err
= slotDoubleVal(b
, &eventtime
);
617 RemoveEventLoopTimer(gTimer
);
620 InstallEventLoopTimer (GetCurrentEventLoop(), 0, (EventTimerInterval
) eventtime
, GetTimerUPP (), 0, &gTimer
);
621 //HIDSetQueueCallback(pCurrentHIDDevice, callback);
625 int prHIDQueueDevice(VMGlobals
*g
, int numArgsPushed
);
626 int prHIDQueueDevice(VMGlobals
*g
, int numArgsPushed
)
629 PyrSlot
*a
= g
->sp
- 1; //class
630 PyrSlot
*b
= g
->sp
; //locID device
632 int err
= slotIntVal(b
, &locID
);
634 //look for the right device:
635 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
636 while (pCurrentHIDDevice
&& (IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=locID
))
637 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
638 if(!pCurrentHIDDevice
) return errFailed
;
639 HIDQueueDevice(pCurrentHIDDevice
);
643 int prHIDQueueElement(VMGlobals
*g
, int numArgsPushed
);
644 int prHIDQueueElement(VMGlobals
*g
, int numArgsPushed
)
647 PyrSlot
*a
= g
->sp
- 2; //class
648 PyrSlot
*b
= g
->sp
- 1; //locID device
649 PyrSlot
*c
= g
->sp
; //element cookie
650 int locID
, cookieNum
;
651 int err
= slotIntVal(b
, &locID
);
653 err
= slotIntVal(c
, &cookieNum
);
655 IOHIDElementCookie cookie
= (IOHIDElementCookie
) cookieNum
;
656 //look for the right device:
657 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
658 while (pCurrentHIDDevice
&& (IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=locID
))
659 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
660 if(!pCurrentHIDDevice
) return errFailed
;
661 //look for the right element:
662 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
663 // use gElementCookie to find current element
664 while (pCurrentHIDElement
&& (IOHIDElementGetCookie(pCurrentHIDElement
) != cookie
))
665 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
666 if(!pCurrentHIDElement
) return errFailed
;
667 HIDQueueElement(pCurrentHIDDevice
, pCurrentHIDElement
);
671 int prHIDDequeueElement(VMGlobals
*g
, int numArgsPushed
);
672 int prHIDDequeueElement(VMGlobals
*g
, int numArgsPushed
)
675 PyrSlot
*a
= g
->sp
- 2; //class
676 PyrSlot
*b
= g
->sp
- 1; //locID device
677 PyrSlot
*c
= g
->sp
; //element cookie
678 int locID
, cookieNum
;
679 int err
= slotIntVal(b
, &locID
);
681 err
= slotIntVal(c
, &cookieNum
);
683 IOHIDElementCookie cookie
= (IOHIDElementCookie
) cookieNum
;
684 //look for the right device:
685 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
686 while (pCurrentHIDDevice
&& (IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=locID
))
687 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
688 if(!pCurrentHIDDevice
) return errFailed
;
689 //look for the right element:
690 IOHIDElementRef pCurrentHIDElement
= HIDGetFirstDeviceElement (pCurrentHIDDevice
, kHIDElementTypeAll
);
691 while (pCurrentHIDElement
&& (IOHIDElementGetCookie(pCurrentHIDElement
) != cookie
))
692 pCurrentHIDElement
= HIDGetNextDeviceElement (pCurrentHIDElement
, kHIDElementTypeAll
);
693 if(!pCurrentHIDElement
) return errFailed
;
694 HIDDequeueElement(pCurrentHIDDevice
, pCurrentHIDElement
);
698 int prHIDDequeueDevice(VMGlobals
*g
, int numArgsPushed
);
699 int prHIDDequeueDevice(VMGlobals
*g
, int numArgsPushed
)
702 PyrSlot
*a
= g
->sp
- 1; //class
703 PyrSlot
*b
= g
->sp
; //locID device
705 int err
= slotIntVal(b
, &locID
);
707 //look for the right device:
708 IOHIDDeviceRef pCurrentHIDDevice
= HIDGetFirstDevice ();
709 while (pCurrentHIDDevice
&& (IOHIDDevice_GetLocationID(pCurrentHIDDevice
) !=locID
))
710 pCurrentHIDDevice
= HIDGetNextDevice (pCurrentHIDDevice
);
711 if(!pCurrentHIDDevice
) return errFailed
;
712 HIDDequeueDevice(pCurrentHIDDevice
);
716 int prHIDStopEventLoop(VMGlobals
*g
, int numArgsPushed
);
717 int prHIDStopEventLoop(VMGlobals
*g
, int numArgsPushed
)
721 RemoveEventLoopTimer(gTimer
);
728 void initHIDPrimitives()
734 s_hid
= getsym("HIDDeviceService");
735 s_hidAction
= getsym("prHidAction");
736 s_readError
= getsym("prReadError");
738 base
= nextPrimitiveIndex();
740 definePrimitive(base
, index
++, "_HIDBuildDeviceList", prHIDBuildDeviceList
, 3, 0);
742 definePrimitive(base
, index
++, "_HIDGetElementListSize", prHIDGetElementListSize
, 2, 0);
743 definePrimitive(base
, index
++, "_HIDBuildElementList", prHIDBuildElementList
, 3, 0);
745 definePrimitive(base
, index
++, "_HIDGetValue", prHIDGetValue
, 3, 0);
746 definePrimitive(base
, index
++, "_HIDSetValue", prHIDSetValue
, 4, 0);
748 definePrimitive(base
, index
++, "_HIDReleaseDeviceList", prHIDReleaseDeviceList
, 1, 0);
749 definePrimitive(base
, index
++, "_HIDRunEventLoop", prHIDRunEventLoop
, 2, 0);
750 definePrimitive(base
, index
++, "_HIDStopEventLoop", prHIDStopEventLoop
, 1, 0);
751 definePrimitive(base
, index
++, "_HIDQueueDevice", prHIDQueueDevice
, 2, 0);
752 definePrimitive(base
, index
++, "_HIDDequeueDevice", prHIDDequeueDevice
, 2, 0);
753 definePrimitive(base
, index
++, "_HIDDequeueElement", prHIDDequeueElement
, 3, 0);
754 definePrimitive(base
, index
++, "_HIDQueueElement", prHIDQueueElement
, 3, 0);
758 void initHIDPrimitives()