scide: ScCodeEditor - remove duplication of code of GenericCodeEditor
[supercollider.git] / lang / LangPrimSource / SC_HID.cpp
blobdc4430756885c377f360b9f751cc902f0660d3fd
1 /*
2 * SC_HID.cpp
3 * SC3lang
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
8 * part of ...
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
28 #ifdef SC_DARWIN
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>
44 #include "SCBase.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"
55 #include "PyrSched.h"
56 #include "GC.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)
79 #endif
81 PyrSymbol * s_readError;
82 PyrSymbol * s_hidAction;
83 PyrSymbol * s_hid;
84 extern bool compiledOK;
85 int gNumberOfHIDDevices = 0;
86 EventLoopTimerRef gTimer = NULL; // timer for element data updates
88 void releaseHIDDevices ();
89 void releaseHIDDevices ()
91 if (gTimer)
93 RemoveEventLoopTimer(gTimer);
94 gTimer = NULL;
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
106 int locID;
107 int err = slotIntVal(b, &locID);
108 if (err) return err;
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);
117 return errNone;
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
128 int locID;
129 int err = slotIntVal(b, &locID);
130 if (err) return err;
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++){
145 if(devElement){
146 char cstrElementName [256];
147 PyrObject* devElementArray = newPyrArray(g->gc, 8 * sizeof(PyrObject), 0 , true);
148 // type name (1)
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);
153 //usage (2)
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);
158 //cookie (3)
159 SetInt(devElementArray->slots+devElementArray->size++, (long) IOHIDElementGetCookie(devElement));
160 // min (4)
161 SetInt(devElementArray->slots+devElementArray->size++, (long) IOHIDElementGetLogicalMin(devElement));
162 // max (5)
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);
178 return errNone;
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;
192 if(IsNil(b))
193 usagePage = 0;
194 else
196 err = slotIntVal(b, &usagePage);
197 if (err) return err;
199 if(IsNil(c))
200 usage = 0;
201 else
203 err = slotIntVal(c, &usage);
204 if (err) return err;
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 (!)
216 result = !result;
217 #endif
219 if(!result) post("no HID devices found\n");
221 int numdevs = HIDCountDevices();
222 gNumberOfHIDDevices = numdevs;
223 if(!numdevs){
224 SetNil(a);
225 return errNone;
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++){
232 char tmp[256];
233 CFStringRef stringref;
234 //device:
235 PyrObject* devNameArray = newPyrArray(g->gc, 8 * sizeof(PyrObject), 0 , true);
236 //manufacturer:
237 //#if(SC_MAC_HIDSTYLE_10_4)
238 // PyrString *devstring = newPyrString(g->gc, pCurrentHIDDevice->manufacturer, 0, true);
239 //#else
240 *tmp = 0;
241 stringref = IOHIDDevice_GetManufacturer(pCurrentHIDDevice);
242 if (stringref)
244 CFStringGetCString(stringref, tmp, 256, kCFStringEncodingASCII);
245 CFRelease(stringref);
247 PyrString *devstring = newPyrString(g->gc, tmp, 0, true);
248 //#endif
249 SetObject(devNameArray->slots+devNameArray->size++, devstring);
250 g->gc->GCWrite(devNameArray, (PyrObject*) devstring);
251 //product name:
252 //#if(SC_MAC_HIDSTYLE_10_4)
253 // devstring = newPyrString(g->gc, pCurrentHIDDevice->product, 0, true);
254 //#else
255 *tmp = 0;
256 stringref = IOHIDDevice_GetProduct(pCurrentHIDDevice);
257 if (stringref)
259 CFStringGetCString(stringref, tmp, 256, kCFStringEncodingASCII);
260 CFRelease(stringref);
262 devstring = newPyrString(g->gc, tmp, 0, true);
263 //#endif
264 SetObject(devNameArray->slots+devNameArray->size++, devstring);
265 g->gc->GCWrite(devNameArray, (PyrObject*) devstring);
267 //usage
268 //#if(SC_MAC_HIDSTYLE_10_4)
269 // HIDGetUsageName (pCurrentHIDDevice->usagePage, pCurrentHIDDevice->usage, tmp);
270 // devstring = newPyrString(g->gc, tmp, 0, true);
271 //#else
272 *tmp = 0;
273 HIDGetUsageName (IOHIDDevice_GetPrimaryUsagePage(pCurrentHIDDevice), IOHIDDevice_GetPrimaryUsage(pCurrentHIDDevice), tmp);
274 devstring = newPyrString(g->gc, tmp, 0, true);
275 //#endif
276 SetObject(devNameArray->slots+devNameArray->size++, devstring);
277 g->gc->GCWrite(devNameArray, (PyrObject*) devstring);
278 //vendor id
279 SetInt(devNameArray->slots+devNameArray->size++, (int)IOHIDDevice_GetVendorID(pCurrentHIDDevice));
280 //product id
281 SetInt(devNameArray->slots+devNameArray->size++, (int)IOHIDDevice_GetProductID(pCurrentHIDDevice));
282 //locID
283 SetInt(devNameArray->slots+devNameArray->size++, (int)IOHIDDevice_GetLocationID(pCurrentHIDDevice));
285 //version
286 SetInt(devNameArray->slots+devNameArray->size++, (int)IOHIDDevice_GetVersionNumber(pCurrentHIDDevice));
288 //serial
289 //#if(SC_MAC_HIDSTYLE_10_4)
290 // devstring = newPyrString(g->gc, pCurrentHIDDevice->serial, 0, true);
291 //#else
292 *tmp = 0;
293 stringref = IOHIDDevice_GetSerialNumber(pCurrentHIDDevice);
294 if (stringref)
296 CFStringGetCString(stringref, tmp, 256, kCFStringEncodingASCII);
297 CFRelease(stringref);
299 devstring = newPyrString(g->gc, tmp, 0, true);
300 //#endif
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);
314 return errNone;
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);
326 if (err) return err;
327 err = slotIntVal(c, &cookieNum);
328 if (err) return err;
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 );
349 //#else
350 SInt32 value;
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);
357 else
359 value = IOHIDElement_GetValue(pCurrentHIDElement, kIOHIDValueScaleTypePhysical);
361 //#endif
362 SetInt(a, value);
364 else SetNil(a);
365 return errNone;
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);
379 if (err) return err;
380 err = slotIntVal(c, &cookieNum);
381 if (err) return err;
382 IOHIDElementCookie cookie = (IOHIDElementCookie) cookieNum;
383 err = slotIntVal(d, &value);
384 if (err) return err;
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;
399 // SInt32 value;
400 // AbsoluteTime timestamp;
401 // UInt32 longValueSize;
402 // void * longValue;
403 //};
405 if (pCurrentHIDElement)
407 //#if(SC_MAC_HIDSTYLE_10_4)
408 // IOHIDEventStruct event =
409 // {
410 // kIOHIDElementTypeOutput,
411 // pCurrentHIDElement->cookie,
412 // value,
413 // {0},
414 // sizeof(int),
415 // NULL
416 // };
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 );
422 //#else
423 IOHIDValueRef valueref = IOHIDValueCreateWithIntegerValue(0, pCurrentHIDElement, 0, value);
424 IOHIDDeviceSetValue(pCurrentHIDDevice, pCurrentHIDElement, valueref);
425 CFRelease(valueref);
426 //#endif
427 SetInt(a, value);
429 else SetNil(a);
430 return errNone;
434 void PushQueueEvents_RawValue ();
435 void PushQueueEvents_RawValue (){
437 //#if(SC_MAC_HIDSTYLE_10_4)
438 // IOHIDEventStruct event;
439 //#else
440 IOHIDValueRef value_ref = 0;
441 //#endif
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);
448 //#else
449 result = HIDGetEvent(pCurrentHIDDevice, &value_ref);
450 //#endif
451 if(result && compiledOK) {
452 //#if(SC_MAC_HIDSTYLE_10_4)
453 // SInt32 value = event.value;
454 //#else
455 SInt32 value = IOHIDValueGetIntegerValue(value_ref);
456 //#endif
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;
462 //#else
463 IOHIDElementCookie cookie = IOHIDElementGetCookie(IOHIDValueGetElement(value_ref));
464 CFRelease(value_ref);
465 //#endif
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
470 //set arguments:
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) )
483 { // readError
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;
505 //#else
506 IOHIDValueRef value_ref = 0;
507 //#endif
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);
515 //#else
516 result = HIDGetEvent(pCurrentHIDDevice, &value_ref);
517 //#endif
518 printf("result is %d\n", (int)result);
519 if(result && compiledOK) {
520 //#if(SC_MAC_HIDSTYLE_10_4)
521 // SInt32 value = event.value;
522 //#else
523 SInt32 value = IOHIDValueGetScaledValue(value_ref, kIOHIDValueScaleTypeCalibrated);
524 //#endif
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;
530 //#else
531 IOHIDElementCookie cookie = IOHIDElementGetCookie(IOHIDValueGetElement(value_ref));
532 CFRelease(value_ref);
533 //#endif
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);
543 //#endif
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
549 //set arguments:
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) )
562 { // readError
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)
587 releaseHIDDevices();
588 return errNone;
590 static EventLoopTimerUPP GetTimerUPP (void);
591 static EventLoopTimerUPP GetTimerUPP (void)
593 static EventLoopTimerUPP sTimerUPP = NULL;
595 if (sTimerUPP == NULL)
596 sTimerUPP = NewEventLoopTimerUPP (IdleTimer);
598 return sTimerUPP;
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
616 double eventtime;
617 int err = slotDoubleVal(b, &eventtime);
618 if (err) return err;
619 if(gTimer)
621 RemoveEventLoopTimer(gTimer);
622 gTimer = NULL;
624 InstallEventLoopTimer (GetCurrentEventLoop(), 0, (EventTimerInterval) eventtime, GetTimerUPP (), 0, &gTimer);
625 //HIDSetQueueCallback(pCurrentHIDDevice, callback);
626 return errNone;
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
635 int locID;
636 int err = slotIntVal(b, &locID);
637 if (err) return err;
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);
647 return errNone;
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);
659 if (err) return err;
660 err = slotIntVal(c, &cookieNum);
661 if (err) return err;
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);
675 return errNone;
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);
687 if (err) return err;
688 err = slotIntVal(c, &cookieNum);
689 if (err) return err;
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);
702 return errNone;
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
711 int locID;
712 int err = slotIntVal(b, &locID);
713 if (err) return err;
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);
720 return errNone;
723 int prHIDStopEventLoop(VMGlobals *g, int numArgsPushed);
724 int prHIDStopEventLoop(VMGlobals *g, int numArgsPushed)
726 if (gTimer)
728 RemoveEventLoopTimer(gTimer);
729 gTimer = NULL;
731 return errNone;
735 void initHIDPrimitives()
737 int base, index;
739 releaseHIDDevices();
741 s_hid = getsym("HIDDeviceService");
742 s_hidAction = getsym("prHidAction");
743 s_readError = getsym("prReadError");
745 base = nextPrimitiveIndex();
746 index = 0;
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);
764 #else // !SC_DARWIN
765 void initHIDPrimitives()
767 //other platforms?
769 #endif // SC_DARWIN