From f59333ff17f17d8fa9e983ccee47f43cd77a3040 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 22 Oct 2004 05:43:17 +0000 Subject: started the process of organizing things for cross-platformness; sketched out MacOS X HID Manager implementation using SuperCollider3's SC_HID.cpp svn path=/trunk/externals/hcs/hid/; revision=2140 --- hid_darwin.c | 463 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 463 insertions(+) create mode 100644 hid_darwin.c (limited to 'hid_darwin.c') diff --git a/hid_darwin.c b/hid_darwin.c new file mode 100644 index 0000000..dc84ae2 --- /dev/null +++ b/hid_darwin.c @@ -0,0 +1,463 @@ +/* + * Apple Darwin HID Manager support for [hid] + * + * based on SC_HID.cpp from SuperCollider3 by Jan Truetzschler v. Falkenstein + * + * Copyright (c) 2004 Hans-Christoph All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + */ +#include + +#include "HID_Utilities_External.h" + +/* +#include +#include +#include +#include +*/ +#include + +#include +#include + +#include "hid.h" + +/* +#include "SCBase.h" +#include "VMGlobals.h" +#include "PyrSymbolTable.h" +#include "PyrInterpreter.h" +#include "PyrKernel.h" + +#include "PyrObjectProto.h" +#include "PyrPrimitiveProto.h" +#include "PyrKernelProto.h" +#include "SC_InlineUnaryOp.h" +#include "SC_InlineBinaryOp.h" +#include "PyrSched.h" +#include "GC.h" +*/ + +int gNumberOfHIDDevices = 0; +EventLoopTimerRef gTimer = NULL; // timer for element data updates + + +void releaseHIDDevices () +{ + if (gTimer) + { + RemoveEventLoopTimer(gTimer); + gTimer = NULL; + } + HIDReleaseAllDeviceQueues(); + HIDReleaseDeviceList(); + gNumberOfHIDDevices = 0; +} + +int prHIDBuildElementList() +{ +/* + PyrSlot *a = g->sp - 1; //class + PyrSlot *b = g->sp; //locID device +*/ + int i, locID, cookieNum; + pRecElement devElement; + pRecDevice pCurrentHIDDevice; +// int err; + +// int err = slotIntVal(b, &locID); +// if (err) return err; + + // look for the right device: + pCurrentHIDDevice = HIDGetFirstDevice (); + while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID)) + pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); + if(!pCurrentHIDDevice) return (1); + + devElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeInput); + UInt32 numElements = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeInput); + + //PyrObject* devAllElementsArray = newPyrArray(g->gc, numElements * sizeof(PyrObject), 0 , true); + + for(i=0; igc, 5 * sizeof(PyrObject), 0 , true); + HIDGetTypeName((IOHIDElementType) devElement->type, cstrElementName); + //PyrString *devstring = newPyrString(g->gc, cstrElementName, 0, true); + //SetObject(devElementArray->slots+devElementArray->size++, devstring); + //g->gc->GCWrite(devElementArray, (PyrObject*) devstring); + //usage + HIDGetUsageName (devElement->usagePage, devElement->usage, cstrElementName); + //devstring = newPyrString(g->gc, cstrElementName, 0, true); + //SetObject(devElementArray->slots+devElementArray->size++, devstring); + //g->gc->GCWrite(devElementArray, (PyrObject*) devstring); + //cookie + //SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->cookie); + //SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->min); + //SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->max); + + //SetObject(devAllElementsArray->slots+devAllElementsArray->size++, devElementArray); + //g->gc->GCWrite(devAllElementsArray, (PyrObject*) devElementArray); + + devElement = HIDGetNextDeviceElement (devElement, kHIDElementTypeInput); + } + //SetObject(a, devAllElementsArray); + + return (0); +} + +int prHIDBuildDeviceList() +{ + int i,err; + UInt32 usagePage, usage; +/* + //build a device list + PyrSlot *a = g->sp - 2; + PyrSlot *b = g->sp - 1; //usagePage + PyrSlot *c = g->sp; //usage + + if(IsNil(b)) + usagePage = NULL; + else + { + err = slotIntVal(b, &usagePage); + if (err) return err; + } + if(IsNil(c)) + usage = NULL; + else + { + err = slotIntVal(c, &usage); + if (err) return err; + } + + //pass in usage & usagepage + //kHIDUsage_GD_Joystick kHIDUsage_GD_GamePad + */ + usagePage = kHIDPage_GenericDesktop; + usage = NULL; + + Boolean result = HIDBuildDeviceList (usagePage, usage); + // returns false if no device found (ignored in this case) - returns always false ? + + if(result) post("no HID devices found\n"); + + int numdevs = HIDCountDevices(); + gNumberOfHIDDevices = numdevs; + // exit if no devices found + if(!numdevs) return (0); + + post("number of devices: %d", numdevs); + char cstrDeviceName [256]; + + pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); + pRecElement devElement; + //PyrObject* allDevsArray = newPyrArray(g->gc, numdevs * sizeof(PyrObject), 0 , true); + for(i=0; igc, 6 * sizeof(PyrObject), 0 , true); + //manufacturer: + PyrString *devstring = newPyrString(g->gc, pCurrentHIDDevice->manufacturer, 0, true); + SetObject(devNameArray->slots+devNameArray->size++, devstring); + g->gc->GCWrite(devNameArray, (PyrObject*) devstring); + //product name: + devstring = newPyrString(g->gc, pCurrentHIDDevice->product, 0, true); + SetObject(devNameArray->slots+devNameArray->size++, devstring); + g->gc->GCWrite(devNameArray, (PyrObject*) devstring); + */ + //usage + HIDGetUsageName (pCurrentHIDDevice->usagePage, pCurrentHIDDevice->usage, cstrDeviceName); + /* + devstring = newPyrString(g->gc, cstrDeviceName, 0, true); + SetObject(devNameArray->slots+devNameArray->size++, devstring); + g->gc->GCWrite(devNameArray, (PyrObject*) devstring); + //vendor id + SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->vendorID); + //product id + SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->productID); + //locID + SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->locID); + + SetObject(allDevsArray->slots+allDevsArray->size++, devNameArray); + g->gc->GCWrite(allDevsArray, (PyrObject*) devNameArray); + */ + pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); + + } + + //UInt32 outnum = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeOutput); + //post("number of outputs: %d \n", outnum); +// SetObject(a, allDevsArray); + + return (0); +} + +/* +int prHIDGetValue(VMGlobals *g); +int prHIDGetValue(VMGlobals *g) +{ + PyrSlot *a = g->sp - 2; //class + PyrSlot *b = g->sp - 1; //locID device + PyrSlot *c = g->sp; //element cookie + int locID, cookieNum; + int err = slotIntVal(b, &locID); + if (err) return err; + err = slotIntVal(c, &cookieNum); + if (err) return err; + IOHIDElementCookie cookie = (IOHIDElementCookie) cookieNum; + // look for the right device: + pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); + while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID)) + pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); + if(!pCurrentHIDDevice) return (1); + // look for the right element: + pRecElement pCurrentHIDElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeIO); + // use gElementCookie to find current element + while (pCurrentHIDElement && (pCurrentHIDElement->cookie != cookie)) + pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeIO); + + if (pCurrentHIDElement) + { + SInt32 value = HIDGetElementValue (pCurrentHIDDevice, pCurrentHIDElement); + // if it's not a button and it's not a hatswitch then calibrate + if(( pCurrentHIDElement->type != kIOHIDElementTypeInput_Button ) && + ( pCurrentHIDElement->usagePage == 0x01 && pCurrentHIDElement->usage != kHIDUsage_GD_Hatswitch)) + value = HIDCalibrateValue ( value, pCurrentHIDElement ); + SetInt(a, value); + } + else SetNil(a); + return (0); + +} +*/ +void PushQueueEvents_RawValue () +{ + int i; + + IOHIDEventStruct event; + pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); + int numdevs = gNumberOfHIDDevices; + unsigned char result; + for(i=0; i< numdevs; i++) + { + result = HIDGetEvent(pCurrentHIDDevice, (void*) &event); + if(result) + { + SInt32 value = event.value; + int vendorID = pCurrentHIDDevice->vendorID; + int productID = pCurrentHIDDevice->productID; + int locID = pCurrentHIDDevice->locID; + IOHIDElementCookie cookie = (IOHIDElementCookie) event.elementCookie; + //set arguments: +// ++g->sp;SetInt(g->sp, vendorID); +// ++g->sp;SetInt(g->sp, productID); +// ++g->sp;SetInt(g->sp, locID); +// ++g->sp;SetInt(g->sp, (int) cookie); +// ++g->sp;SetInt(g->sp, value); + } + pCurrentHIDDevice = HIDGetNextDevice(pCurrentHIDDevice); + } +} + +void PushQueueEvents_CalibratedValue () +{ + int i; + + IOHIDEventStruct event; + pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); + + int numdevs = gNumberOfHIDDevices; + unsigned char result; + for(i=0; i< numdevs; i++) + { + + result = HIDGetEvent(pCurrentHIDDevice, (void*) &event); + if(result) + { + SInt32 value = event.value; + int vendorID = pCurrentHIDDevice->vendorID; + int productID = pCurrentHIDDevice->productID; + int locID = pCurrentHIDDevice->locID; + IOHIDElementCookie cookie = (IOHIDElementCookie) event.elementCookie; + pRecElement pCurrentHIDElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeIO); + // use gElementCookie to find current element + while (pCurrentHIDElement && ( (pCurrentHIDElement->cookie) != cookie)) + pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeIO); + + if (pCurrentHIDElement) + { + value = HIDCalibrateValue(value, pCurrentHIDElement); + //find element to calibrate + //set arguments: +// ++g->sp;SetInt(g->sp, vendorID); +// ++g->sp;SetInt(g->sp, productID); +// ++g->sp;SetInt(g->sp, locID); +// ++g->sp;SetInt(g->sp, (int) cookie); +// ++g->sp;SetInt(g->sp, value); + } + } + pCurrentHIDDevice = HIDGetNextDevice(pCurrentHIDDevice); + } +} + +static pascal void IdleTimer (EventLoopTimerRef inTimer, void* userData) +{ + #pragma unused (inTimer, userData) + PushQueueEvents_CalibratedValue (); +} + +int prHIDReleaseDeviceList() +{ + releaseHIDDevices(); + return (0); +} + +static EventLoopTimerUPP GetTimerUPP (void) +{ + static EventLoopTimerUPP sTimerUPP = NULL; + + if (sTimerUPP == NULL) + sTimerUPP = NewEventLoopTimerUPP (IdleTimer); + + return sTimerUPP; +} +/* +typedef void (*IOHIDCallbackFunction) + (void * target, IOReturn result, void * refcon, void * sender); + +*/ +/* +void callback (void * target, IOReturn result, void * refcon, void * sender); +void callback (void * target, IOReturn result, void * refcon, void * sender) +{ +} +*/ +/* +int prHIDRunEventLoop(VMGlobals *g); +int prHIDRunEventLoop(VMGlobals *g) +{ + PyrSlot *a = g->sp - 1; //class + + InstallEventLoopTimer (GetCurrentEventLoop(), 0, 0.001, GetTimerUPP (), 0, &gTimer); + + //HIDSetQueueCallback(pCurrentHIDDevice, callback); + return (0); +} +*/ + +int prHIDQueueDevice() +{ + int locID, cookieNum; + + //PyrSlot *a = g->sp - 1; //class + //PyrSlot *b = g->sp; //locID device + //int err = slotIntVal(b, &locID); + //if (err) return err; + //look for the right device: + pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); + while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID)) + pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); + if(!pCurrentHIDDevice) return (1); + HIDQueueDevice(pCurrentHIDDevice); + return (0); +} + +int prHIDQueueElement() +{ + int locID, cookieNum; + + //PyrSlot *a = g->sp - 2; //class + //PyrSlot *b = g->sp - 1; //locID device + //PyrSlot *c = g->sp; //element cookie + //int err = slotIntVal(b, &locID); + //if (err) return err; + //err = slotIntVal(c, &cookieNum); + //if (err) return err; + IOHIDElementCookie cookie = (IOHIDElementCookie) cookieNum; + //look for the right device: + pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); + while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID)) + pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); + if(!pCurrentHIDDevice) return (1); + //look for the right element: + pRecElement pCurrentHIDElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeIO); + // use gElementCookie to find current element + while (pCurrentHIDElement && (pCurrentHIDElement->cookie != cookie)) + pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeIO); + if(!pCurrentHIDElement) return (1); + HIDQueueElement(pCurrentHIDDevice, pCurrentHIDElement); + return (0); +} + +int prHIDDequeueElement() +{ + int locID, cookieNum; + + //PyrSlot *a = g->sp - 2; //class + //PyrSlot *b = g->sp - 1; //locID device + //PyrSlot *c = g->sp; //element cookie + //int err = slotIntVal(b, &locID); + //if (err) return err; + //err = slotIntVal(c, &cookieNum); + //if (err) return err; + IOHIDElementCookie cookie = (IOHIDElementCookie) cookieNum; + //look for the right device: + pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); + while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID)) + pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); + if(!pCurrentHIDDevice) return (1); + //look for the right element: + pRecElement pCurrentHIDElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeIO); + while (pCurrentHIDElement && (pCurrentHIDElement->cookie != cookie)) + pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeIO); + if(!pCurrentHIDElement) return (1); + HIDDequeueElement(pCurrentHIDDevice, pCurrentHIDElement); + return (0); +} + +int prHIDDequeueDevice() +{ + int locID, cookieNum; + + /* + PyrSlot *a = g->sp - 1; //class + PyrSlot *b = g->sp; //locID device + int err = slotIntVal(b, &locID); + if (err) return err; + */ + //look for the right device: + pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); + while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID)) + pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); + if(!pCurrentHIDDevice) return (1); + HIDDequeueDevice(pCurrentHIDDevice); + return (0); +} + +int prHIDStopEventLoop() +{ + if (gTimer) + RemoveEventLoopTimer(gTimer); + gTimer = NULL; + return (0); +} + + -- cgit v1.2.1