aboutsummaryrefslogtreecommitdiff
path: root/hid_darwin.c
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2004-10-22 05:43:17 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2004-10-22 05:43:17 +0000
commitf59333ff17f17d8fa9e983ccee47f43cd77a3040 (patch)
tree70d61e79f5bf94dde7f67621e8e7bd6f946f1cff /hid_darwin.c
parent80bdb3696f585bd27168675a2cea0bc13b60b350 (diff)
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
Diffstat (limited to 'hid_darwin.c')
-rw-r--r--hid_darwin.c463
1 files changed, 463 insertions, 0 deletions
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 <Carbon/Carbon.h>
+
+#include "HID_Utilities_External.h"
+
+/*
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/hid/IOHIDKeys.h>
+*/
+#include <IOKit/hid/IOHIDUsageTables.h>
+
+#include <mach/mach.h>
+#include <mach/mach_error.h>
+
+#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; i<numElements; i++)
+ {
+ char cstrElementName [256];
+ //PyrObject* devElementArray = newPyrArray(g->gc, 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; i<numdevs; i++)
+ {
+ /*
+ //device:
+ /PyrObject* devNameArray = newPyrArray(g->gc, 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);
+}
+
+