Update of /cvsroot/pure-data/externals/hcs/hid In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14734
Modified Files: hid.c Added Files: hid.h hid_darwin.c Log Message: started the process of organizing things for cross-platformness; sketched out MacOS X HID Manager implementation using SuperCollider3's SC_HID.cpp
--- NEW FILE: hid_darwin.c --- /* * 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); }
--- NEW FILE: hid.h ---
#include <m_pd.h>
#include "input_arrays.h"
static char *version = "$Revision: 1.1 $";
/*------------------------------------------------------------------------------ * CLASS DEF */ static t_class *hid_class;
typedef struct _hid { t_object x_obj; t_int x_fd; t_symbol *x_devname; t_clock *x_clock; t_int x_read_ok; t_int x_started; t_int x_delay; t_int x_vendorID; t_int x_productID; t_int x_locID; } t_hid;
Index: hid.c =================================================================== RCS file: /cvsroot/pure-data/externals/hcs/hid/hid.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** hid.c 20 Oct 2004 02:06:08 -0000 1.3 --- hid.c 22 Oct 2004 05:43:17 -0000 1.4 *************** *** 26,82 **** /* ---------------------------------------------------------------------------- */
! ! #include <stdio.h> ! #include <stdlib.h> ! #include <unistd.h> ! #include <ctype.h> ! ! #ifdef __APPLE__ ! #include <sys/errno.h> ! #include <sysexits.h> ! #include <mach/mach.h> ! #include <mach/mach_error.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 <CoreFoundation/CoreFoundation.h> ! #include <Carbon/Carbon.h> ! ! #ifndef __APPLE_CC__ ! #include "Carbon_Include.h" ! #endif /* #ifndef __APPLE_CC__ */ ! ! #include <HID_Utilities.h> ! #endif /* #ifdef __APPLE__ */ ! ! #include "linuxhid.h" ! #include "input_arrays.h" ! ! static char *version = "$Revision$"; ! ! /*------------------------------------------------------------------------------ ! * CLASS DEF ! */ ! static t_class *hid_class; ! ! typedef struct _hid ! { ! t_object x_obj; ! t_int x_fd; ! t_symbol *x_devname; ! t_clock *x_clock; ! t_int x_read_ok; ! t_int x_started; ! t_int x_delay; ! #ifdef __gnu_linux__ ! struct input_event x_input_event; ! #elif defined (__APPLE__) ! IOHIDEventStruct event; ! #endif ! t_outlet *x_event_outlet; ! }t_hid; !
/*------------------------------------------------------------------------------ --- 26,31 ---- /* ---------------------------------------------------------------------------- */
! #include "hid.h" ! #include "../linuxhid.h"
/*------------------------------------------------------------------------------ *************** *** 114,117 **** --- 63,69 ---- t_int eventType, eventCode; char *eventTypeName = ""; + #ifdef __linux__ + struct input_event hid_input_event; + #endif /* counts for various event types */ t_int synCount,keyCount,relCount,absCount,mscCount,ledCount,sndCount,repCount,ffCount,pwrCount,ff_statusCount; *************** *** 148,152 **** * It seems that is just there to flush the input event queue */ ! while (read (x->x_fd, &(x->x_input_event), sizeof(struct input_event)) > -1);
/* get name of device */ --- 100,104 ---- * It seems that is just there to flush the input event queue */ ! while (read (x->x_fd, &(hid_input_event), sizeof(struct input_event)) > -1);
/* get name of device */ *************** *** 252,273 **** char *eventType; char *eventCode;
- #ifdef __gnu_linux__ if (x->x_fd < 0) return 0;
! while (read (x->x_fd, &(x->x_input_event), sizeof(struct input_event)) > -1) { /* build event_data list from event data */ ! SETSYMBOL(event_data, gensym(ev[x->x_input_event.type])); ! SETSYMBOL(event_data + 1, gensym(event_names[x->x_input_event.type][x->x_input_event.code])); ! SETFLOAT(event_data + 2, (t_float)x->x_input_event.value); ! SETFLOAT(event_data + 3, (t_float)(x->x_input_event.time).tv_sec); outlet_anything(x->x_obj.te_outlet,atom_gensym(event_data),3,event_data+1); } #endif /* #ifdef__gnu_linux__ */ ! #ifdef __APPLE__ pRecDevice pCurrentHIDDevice = GetSetCurrentDevice (gWindow); pRecElement pCurrentHIDElement = GetSetCurrenstElement (gWindow); ! r/l // if we have a good device and element which is not a collecion if (pCurrentHIDDevice && pCurrentHIDElement && (pCurrentHIDElement->type != kIOHIDElementTypeCollection)) --- 204,226 ---- char *eventType; char *eventCode; + #ifdef __linux__ + struct input_event hid_input_event;
if (x->x_fd < 0) return 0;
! while (read (x->x_fd, &(hid_input_event), sizeof(struct input_event)) > -1) { /* build event_data list from event data */ ! SETSYMBOL(event_data, gensym(ev[hid_input_event.type])); ! SETSYMBOL(event_data + 1, gensym(event_names[hid_input_event.type][hid_input_event.code])); ! SETFLOAT(event_data + 2, (t_float)hid_input_event.value); ! SETFLOAT(event_data + 3, (t_float)(hid_input_event.time).tv_sec); outlet_anything(x->x_obj.te_outlet,atom_gensym(event_data),3,event_data+1); } #endif /* #ifdef__gnu_linux__ */ ! #ifdef IGNOREIGNOREIGNORE pRecDevice pCurrentHIDDevice = GetSetCurrentDevice (gWindow); pRecElement pCurrentHIDElement = GetSetCurrenstElement (gWindow); ! // if we have a good device and element which is not a collecion if (pCurrentHIDDevice && pCurrentHIDElement && (pCurrentHIDElement->type != kIOHIDElementTypeCollection)) *************** *** 365,369 **** x->x_clock = clock_new(x, (t_method)hid_read);
! /* create anything outlet */ outlet_new(&x->x_obj, 0);
--- 318,322 ---- x->x_clock = clock_new(x, (t_method)hid_read);
! /* create anything outlet used for HID data */ outlet_new(&x->x_obj, 0);