[PD-cvs] externals/hcs/hid hid.h,NONE,1.1 hid_darwin.c,NONE,1.1 hid.c,1.3,1.4
Hans-Christoph Steiner
eighthave at users.sourceforge.net
Fri Oct 22 07:43:20 CEST 2004
- Previous message: [PD-cvs] externals/hcs Makefile,1.10,1.11 linuxevent.c,1.8,1.9 linuxhid.h,1.8,1.9 linuxjoystick.c,1.6,1.7 linuxmouse.c,1.6,1.7
- Next message: [PD-cvs] externals/hcs/hid hid_linux.c,NONE,1.1 Makefile,1.3,1.4 hid.c,1.4,1.5 hid.h,1.1,1.2 hid_darwin.c,1.1,1.2 make-arrays-from-input.h.pl,1.3,1.4
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
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);
- Previous message: [PD-cvs] externals/hcs Makefile,1.10,1.11 linuxevent.c,1.8,1.9 linuxhid.h,1.8,1.9 linuxjoystick.c,1.6,1.7 linuxmouse.c,1.6,1.7
- Next message: [PD-cvs] externals/hcs/hid hid_linux.c,NONE,1.1 Makefile,1.3,1.4 hid.c,1.4,1.5 hid.h,1.1,1.2 hid_darwin.c,1.1,1.2 make-arrays-from-input.h.pl,1.3,1.4
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Pd-cvs
mailing list