Update of /cvsroot/pure-data/externals/hcs/hid
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14844
Modified Files:
hid-help.pd hid.c hid.h hid_darwin.c hid_linux.c
Log Message:
completed moving GNU/Linux support into the new structure; flushed out Darwin a bit more
Index: hid_darwin.c
===================================================================
RCS file: /cvsroot/pure-data/externals/hcs/hid/hid_darwin.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** hid_darwin.c 22 Oct 2004 18:49:16 -0000 1.2
--- hid_darwin.c 25 Oct 2004 06:01:45 -0000 1.3
***************
*** 1,25 ****
#ifdef __APPLE__
/*
! * 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
- */
--- 1,42 ----
#ifdef __APPLE__
/*
! * Apple Darwin HID Manager support for Pd [hid] object
*
* 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
+ *
+ *
+ */
! /* struct IOHIDEventStruct */
! /* { */
! /* IOHIDElementType type; */
! /* IOHIDElementCookie elementCookie; */
! /* SInt32 value; */
! /* AbsoluteTime timestamp; */
! /* UInt32 longValueSize; */
! /* void * longValue; */
! /* }; */
! /* typedef struct { */
! /* natural_t hi; */
! /* natural_t lo; */
! /* } AbsoluteTime; */
***************
*** 41,63 ****
#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"
! */
!
!
! #define DEBUG(x)
! //#define DEBUG(x) x
/*==============================================================================
--- 58,63 ----
#include "hid.h"
! //#define DEBUG(x)
! #define DEBUG(x) x
/*==============================================================================
***************
*** 65,71 ****
*======================================================================== */
int gNumberOfHIDDevices = 0;
- EventLoopTimerRef gTimer = NULL; // timer for element data updates
/*==============================================================================
--- 65,79 ----
*======================================================================== */
+ /* count of total number of devices found */
int gNumberOfHIDDevices = 0;
+ /*
+ * an array of discovered devices, which is used for selecting the
+ * current device, by #, type, or name
+ */
+ pRecDevice discoveredDevices[256];
+
+ /* timer for element data updates */
+ EventLoopTimerRef gTimer = NULL;
/*==============================================================================
***************
*** 92,99 ****
DEBUG(post("prHIDBuildElementList"););
- /*
- PyrSlot *a = g->sp - 1; //class
- PyrSlot *b = g->sp; //locID device
- */
int locID = NULL;
int cookieNum = NULL;
--- 100,103 ----
***************
*** 104,146 ****
char cstrElementName [256];
! // 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);
! numElements = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeInput);
!
! //PyrObject* devAllElementsArray = newPyrArray(g->gc, numElements * sizeof(PyrObject), 0 , true);
- for(i=0; i<numElements; i++)
- {
- //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);
}
--- 108,143 ----
char cstrElementName [256];
! // Apple Trackpad locID for testing
! locID = 50397184;
! // look for the right device using locID
pCurrentHIDDevice = HIDGetFirstDevice ();
while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID))
! pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice);
if(!pCurrentHIDDevice) return (1);
! devElement = HIDGetFirstDeviceElement(pCurrentHIDDevice, kHIDElementTypeInput);
! numElements = HIDCountDeviceElements(pCurrentHIDDevice, kHIDElementTypeInput);
!
! post("[hid] found %d elements",numElements);
!
! for(i=0; i<numElements; i++)
! {
! //type
! HIDGetTypeName((IOHIDElementType) devElement->type, cstrElementName);
! post("Type: %s %d 0x%x",cstrElementName,devElement->type,devElement->type);
! //usage
! HIDGetUsageName (devElement->usagePage, devElement->usage, cstrElementName);
! post("Usage: %s %d 0x%x",cstrElementName,devElement->usage,devElement->usage);
//devstring = newPyrString(g->gc, cstrElementName, 0, true);
//SetObject(devElementArray->slots+devElementArray->size++, devstring);
//g->gc->GCWrite(devElementArray, (PyrObject*) devstring);
! //cookie
! post("Cookie: %d %d %d",devElement->cookie,devElement->min,devElement->max);
!
! devElement = HIDGetNextDeviceElement (devElement, kHIDElementTypeInput);
! }
! return (0);
}
***************
*** 151,185 ****
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();
--- 148,163 ----
int i,err;
UInt32 usagePage, usage;
! pRecElement devElement;
! pRecDevice pCurrentHIDDevice;
//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
! if(result) error("[hid]: no HID devices found\n");
int numdevs = HIDCountDevices();
***************
*** 191,234 ****
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);
--- 169,186 ----
char cstrDeviceName [256];
! pCurrentHIDDevice = HIDGetFirstDevice();
for(i=0; i<numdevs; i++)
{
! post("'%s' '%s' version %d",
! pCurrentHIDDevice->manufacturer,pCurrentHIDDevice->product,pCurrentHIDDevice->version);
//usage
HIDGetUsageName (pCurrentHIDDevice->usagePage, pCurrentHIDDevice->usage, cstrDeviceName);
! post("vendorID: %d productID: %d locID: %d",
! pCurrentHIDDevice->vendorID,pCurrentHIDDevice->productID,pCurrentHIDDevice->locID);
pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice);
}
! UInt32 outnum = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeOutput);
! post("number of outputs: %d \n", outnum);
return (0);
***************
*** 377,384 ****
DEBUG(post("GetTimerUPP"););
! static EventLoopTimerUPP sTimerUPP = NULL;
if (sTimerUPP == NULL)
! sTimerUPP = NewEventLoopTimerUPP (IdleTimer);
return sTimerUPP;
--- 329,336 ----
DEBUG(post("GetTimerUPP"););
! static EventLoopTimerUPP sTimerUPP = NULL;
if (sTimerUPP == NULL)
! sTimerUPP = NewEventLoopTimerUPP(IdleTimer);
return sTimerUPP;
***************
*** 402,409 ****
//PyrSlot *a = g->sp - 1; //class
! InstallEventLoopTimer (GetCurrentEventLoop(), 0, 0.001, GetTimerUPP (), 0, &gTimer);
//HIDSetQueueCallback(pCurrentHIDDevice, callback);
! return (0);
}
--- 354,361 ----
//PyrSlot *a = g->sp - 1; //class
! InstallEventLoopTimer(GetCurrentEventLoop(), 0, 0.001, GetTimerUPP (), 0, &gTimer);
//HIDSetQueueCallback(pCurrentHIDDevice, callback);
! return (0);
}
***************
*** 521,527 ****
RemoveEventLoopTimer(gTimer);
gTimer = NULL;
! return (0);
}
#endif /* #ifdef __APPLE__ */
--- 473,520 ----
RemoveEventLoopTimer(gTimer);
gTimer = NULL;
! return (0);
! }
!
!
! t_int hid_open_device(t_hid *x, t_int device_number)
! {
! post("open_device %d",device_number);
!
! return (1);
! }
!
! t_int hid_open_device(t_hid *x)
! {
! return (0);
! }
!
!
! t_int hid_devicelist_refresh(t_hid *x)
! {
! /* the device list should be refreshed here */
! if ( (prHIDBuildDeviceList()) && (prHIDBuildElementList()) )
! return (0);
! else
! return (1);
}
+ /* this is just a rough sketch */
+
+ /* getEvents(t_hid *x) { */
+ /* 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)) */
+ /* { */
+ /* SInt32 value = HIDGetElementValue (pCurrentHIDDevice, pCurrentHIDElement); */
+ /* SInt32 valueCal = HIDCalibrateValue (value, pCurrentHIDElement); */
+ /* SInt32 valueScale = HIDScaleValue (valueCal, pCurrentHIDElement); */
+ /* } */
+ /* } */
+
+
+
+
#endif /* #ifdef __APPLE__ */
Index: hid.h
===================================================================
RCS file: /cvsroot/pure-data/externals/hcs/hid/hid.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** hid.h 23 Oct 2004 03:40:39 -0000 1.3
--- hid.h 25 Oct 2004 06:01:45 -0000 1.4
***************
*** 2,8 ****
#define _HID_H
#include <m_pd.h>
! #include "hid.h"
static char *version = "$Revision$";
--- 2,14 ----
#define _HID_H
+ #include <stdio.h>
+
#include <m_pd.h>
! /*
! * this is automatically generated from linux/input.h by
! * make-arrays-from-input.h.pl to be the cross-platform event types and codes
! */
! #include "input_arrays.h"
static char *version = "$Revision$";
***************
*** 18,21 ****
--- 24,28 ----
t_int x_fd;
t_symbol *x_devname;
+ t_int x_device_number;
t_clock *x_clock;
t_int x_read_ok;
***************
*** 32,35 ****
--- 39,43 ----
*/
+ /* what are these for again? */
char *deviceList[64];
char *typeList[256];
***************
*** 40,49 ****
*/
! #ifdef __linux__
! void releaseDevices(void);
! void buildDeviceList(void);
! void buildTypeList(void);
- #endif
--- 48,59 ----
*/
! /* generic, cross-platform functions */
! t_int hid_open_device(t_hid *x, t_int device_number);
! t_int hid_close_device(t_hid *x);
! t_int hid_devicelist_refresh(t_hid* x);
! t_int hid_output_events(t_hid *x) ;
!
!
***************
*** 56,65 ****
void PushQueueEvents_CalibratedValue(void);
int prHIDReleaseDeviceList(void);
! int prHIDRunEventLoop(void);
int prHIDQueueDevice(void);
int prHIDQueueElement(void);
int prHIDDequeueElement(void);
int prHIDDequeueDevice(void);
! int prHIDStopEventLoop(void);
#endif /* #ifdef __APPLE__ */
--- 66,75 ----
void PushQueueEvents_CalibratedValue(void);
int prHIDReleaseDeviceList(void);
! //int prHIDRunEventLoop(void);
int prHIDQueueDevice(void);
int prHIDQueueElement(void);
int prHIDDequeueElement(void);
int prHIDDequeueDevice(void);
! //int prHIDStopEventLoop(void);
#endif /* #ifdef __APPLE__ */
Index: hid-help.pd
===================================================================
RCS file: /cvsroot/pure-data/externals/hcs/hid/hid-help.pd,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** hid-help.pd 23 Oct 2004 03:40:39 -0000 1.3
--- hid-help.pd 25 Oct 2004 06:01:45 -0000 1.4
***************
*** 1,36 ****
! #N canvas 124 73 911 579 10;
! #X msg 382 241 ev_rel rel_y 2 1.0985e+09;
! #X obj 382 220 prepend set;
! #X obj 144 386 route rel_x rel_y;
! #X floatatom 144 406 5 0 0 0 - - -;
! #X floatatom 201 406 5 0 0 0 - - -;
#X msg 148 77 start;
#X msg 167 96 stop;
! #X obj 240 184 hid /dev/input/event0;
! #X floatatom 486 360 12 0 0 1 time - -;
! #X obj 393 340 unpack s s f f;
! #X msg 248 57 open /dev/input/event1;
! #X msg 240 34 open /dev/input/event0;
! #X msg 264 79 open /dev/input/event2;
! #X msg 276 100 open /dev/input/event3;
! #X msg 288 120 open /dev/input/event4;
! #X obj 85 321 route ev_key ev_rel ev_abs;
! #X floatatom 203 367 7 0 0 0 - - -;
! #X floatatom 261 367 7 0 0 0 - - -;
! #X obj 203 346 route abs_x abs_y;
! #X obj 86 81 tgl 35 0 empty empty empty 0 -6 0 8 -24198 -1 -1 1 1;
! #X floatatom 455 377 12 0 0 1 value - -;
! #X symbolatom 423 394 10 0 0 1 eventcode - -;
! #X symbolatom 393 413 15 0 0 1 eventtype - -;
! #X floatatom 85 451 5 0 0 0 - - -;
! #X floatatom 160 452 5 0 0 0 - - -;
! #X obj 85 429 route key_f key_leftctrl btn_left;
! #X floatatom 235 452 5 0 0 0 - - -;
! #X obj 53 195 bng 35 250 50 0 empty empty event_received 38 18 1 8
-225280 -1 -1;
#X obj 2 2 cnv 15 900 20 empty empty hid 2 11 1 18 -233017 -66577 0
;
! #X text 354 263 outlet message format:;
! #X text 378 277 eventtype eventcode value timestamp;
#X obj 742 104 ev-list;
#X obj 742 155 ev_syn-list;
--- 1,34 ----
! #N canvas 124 73 923 591 10;
! #X msg 390 265 ev_key btn_left 0 1.09868e+09;
! #X obj 390 244 prepend set;
! #X obj 149 473 route rel_x rel_y;
! #X floatatom 149 493 5 0 0 0 - - -;
! #X floatatom 206 493 5 0 0 0 - - -;
#X msg 148 77 start;
#X msg 167 96 stop;
! #X floatatom 494 384 12 0 0 1 time - -;
! #X obj 401 364 unpack s s f f;
! #X msg 229 25 open 0;
! #X msg 237 48 open 1;
! #X msg 253 70 open 2;
! #X msg 265 91 open 3;
! #X msg 277 111 open 4;
! #X floatatom 206 454 7 0 0 0 - - -;
! #X floatatom 264 454 7 0 0 0 - - -;
! #X obj 206 433 route abs_x abs_y;
! #X obj 86 81 tgl 35 0 empty empty empty 0 -6 0 8 -24198 -1 -1 0 1;
! #X floatatom 463 401 12 0 0 1 value - -;
! #X symbolatom 431 418 10 0 0 1 eventcode - -;
! #X symbolatom 401 437 15 0 0 1 eventtype - -;
! #X floatatom 93 536 5 0 0 0 - - -;
! #X floatatom 168 537 5 0 0 0 - - -;
! #X obj 93 514 route key_f key_leftctrl btn_left;
! #X floatatom 243 537 5 0 0 0 - - -;
! #X obj 61 219 bng 35 250 50 0 empty empty event_received 38 18 1 8
-225280 -1 -1;
#X obj 2 2 cnv 15 900 20 empty empty hid 2 11 1 18 -233017 -66577 0
;
! #X text 362 287 outlet message format:;
! #X text 386 301 eventtype eventcode value timestamp;
#X obj 742 104 ev-list;
#X obj 742 155 ev_syn-list;
***************
*** 46,85 ****
#X text 710 85 Event Types:;
#X text 710 136 Event Codes:;
! #X msg 304 146 delay 2;
! #X obj 200 278 print INPUT_EVENT;
! #X obj 200 257 spigot;
! #X obj 237 239 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
! #X msg 373 147 delay 200;
#X connect 1 0 0 0;
#X connect 2 0 3 0;
#X connect 2 1 4 0;
! #X connect 5 0 7 0;
! #X connect 6 0 7 0;
! #X connect 7 0 1 0;
! #X connect 7 0 9 0;
! #X connect 7 0 15 0;
! #X connect 7 0 27 0;
! #X connect 7 0 46 0;
! #X connect 9 0 22 0;
! #X connect 9 1 21 0;
! #X connect 9 2 20 0;
! #X connect 9 3 8 0;
! #X connect 10 0 7 0;
! #X connect 11 0 7 0;
! #X connect 12 0 7 0;
! #X connect 13 0 7 0;
! #X connect 14 0 7 0;
! #X connect 15 0 25 0;
! #X connect 15 1 2 0;
! #X connect 15 2 18 0;
! #X connect 18 0 16 0;
! #X connect 18 1 17 0;
! #X connect 19 0 7 0;
! #X connect 25 0 23 0;
! #X connect 25 1 24 0;
! #X connect 25 2 26 0;
! #X connect 44 0 7 0;
! #X connect 46 0 45 0;
! #X connect 47 0 46 1;
! #X connect 48 0 7 0;
--- 44,96 ----
#X text 710 85 Event Types:;
#X text 710 136 Event Codes:;
! #X obj 208 302 print INPUT_EVENT;
! #X obj 208 281 spigot;
! #X obj 245 263 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
! #X obj 93 345 route ev_key ev_rel ev_abs ev_syn;
! #X floatatom 289 398 5 0 0 1 ev_syn - -;
! #X obj 262 397 +;
! #X msg 262 377 1;
! #X obj 248 209 hid 4;
! #X msg 295 142 close;
! #X msg 374 171 delay 20;
! #X msg 312 170 delay 2;
! #X msg 441 171 delay 200;
#X connect 1 0 0 0;
#X connect 2 0 3 0;
#X connect 2 1 4 0;
! #X connect 5 0 49 0;
! #X connect 6 0 49 0;
! #X connect 8 0 20 0;
! #X connect 8 1 19 0;
! #X connect 8 2 18 0;
! #X connect 8 3 7 0;
! #X connect 9 0 49 0;
! #X connect 10 0 49 0;
! #X connect 11 0 49 0;
! #X connect 12 0 49 0;
! #X connect 13 0 49 0;
! #X connect 16 0 14 0;
! #X connect 16 1 15 0;
! #X connect 17 0 49 0;
! #X connect 23 0 21 0;
! #X connect 23 1 22 0;
! #X connect 23 2 24 0;
! #X connect 43 0 42 0;
! #X connect 44 0 43 1;
! #X connect 45 0 23 0;
! #X connect 45 1 2 0;
! #X connect 45 2 16 0;
! #X connect 45 3 48 0;
! #X connect 46 0 47 1;
! #X connect 47 0 46 0;
! #X connect 48 0 47 0;
! #X connect 49 0 43 0;
! #X connect 49 0 25 0;
! #X connect 49 0 45 0;
! #X connect 49 0 1 0;
! #X connect 49 0 8 0;
! #X connect 50 0 49 0;
! #X connect 51 0 49 0;
! #X connect 52 0 49 0;
! #X connect 53 0 49 0;
Index: hid_linux.c
===================================================================
RCS file: /cvsroot/pure-data/externals/hcs/hid/hid_linux.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** hid_linux.c 23 Oct 2004 03:40:39 -0000 1.2
--- hid_linux.c 25 Oct 2004 06:01:45 -0000 1.3
***************
*** 5,8 ****
--- 5,16 ----
#include <sys/ioctl.h>
+ #include <sys/stat.h>
+ #include <string.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <sys/fcntl.h>
+ #include <unistd.h>
+
+ #include "hid.h"
#define DEBUG(x)
***************
*** 21,29 ****
- /* The application reading the device is supposed to queue all events up to */
- /* the SYN_REPORT event, and then process them, so that a mouse pointer */
- /* will move diagonally instead of following the sides of a rectangle, */
- /* which would be very annoying. */
--- 29,234 ----
+ /*
+ * from an email from Vojtech:
+ *
+ * The application reading the device is supposed to queue all events up to
+ * the SYN_REPORT event, and then process them, so that a mouse pointer
+ * will move diagonally instead of following the sides of a rectangle,
+ * which would be very annoying.
+ */
+
+ t_int hid_output_events(t_hid *x)
+ {
+ DEBUG(post("hid_output_events"););
+
+ /* for debugging, counts how many events are processed each time hid_read() is called */
+ t_int i;
+ DEBUG(t_int event_counter = 0;);
+ t_int read_bytes;
+ t_atom event_data[4];
+
+ /* this will go into the generic read function declared in hid.h and
+ * implemented in hid_linux.c
+ */
+ 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 */
+ /* type */
+ SETSYMBOL(event_data, gensym(ev[hid_input_event.type]));
+ /* code */
+ SETSYMBOL(event_data + 1, gensym(event_names[hid_input_event.type][hid_input_event.code]));
+ /* value */
+ SETFLOAT(event_data + 2, (t_float)hid_input_event.value);
+ /* time */
+ 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);
+ DEBUG(++event_counter;);
+ }
+ DEBUG(
+ if (event_counter > 0)
+ post("output %d events",event_counter);
+ );
+
+ return (0);
+ }
+
+
+ t_int hid_open_device(t_hid *x, t_int device_number)
+ {
+ DEBUG(post("hid_open_device"););
+
+ char arg[20];
+ struct input_event hid_input_event;
+ unsigned long bitmask[EV_MAX][NBITS(KEY_MAX)];
+ char devicename[256] = "Unknown";
+ t_int event_type, event_code;
+ char *event_typeName = "";
+ /* counts for various event types */
+ t_int synCount,keyCount,relCount,absCount,mscCount,ledCount,sndCount,repCount,ffCount,pwrCount,ff_statusCount;
+
+ x->x_fd = -1;
+
+ x->x_device_number = device_number;
+ sprintf(arg,"/dev/input/event%d",x->x_device_number);
+ x->x_devname = gensym(arg);
+
+ if (x->x_devname)
+ {
+ /* open the device read-only, non-exclusive */
+ x->x_fd = open(x->x_devname->s_name, O_RDONLY | O_NONBLOCK);
+ /* test if device open */
+ if (x->x_fd < 0 )
+ {
+ error("[hid] open %s failed",x->x_devname->s_name);
+ x->x_fd = -1;
+ return 1;
+ }
+ }
+
+ /* read input_events from the HID_DEVICE stream
+ * 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 */
+ ioctl(x->x_fd, EVIOCGNAME(sizeof(devicename)), devicename);
+ post ("\nConfiguring device %d as %s (%s)",
+ x->x_device_number,devicename,x->x_devname->s_name);
+
+ /* get bitmask representing supported events (axes, keys, etc.) */
+ memset(bitmask, 0, sizeof(bitmask));
+ ioctl(x->x_fd, EVIOCGBIT(0, EV_MAX), bitmask[0]);
+ post("\nSupported events:");
+
+ /* init all count vars */
+ synCount = keyCount = relCount = absCount = mscCount = ledCount = 0;
+ sndCount = repCount = ffCount = pwrCount = ff_statusCount = 0;
+
+ /* cycle through all possible event types */
+ for (event_type = 0; event_type < EV_MAX; event_type++)
+ {
+ if (test_bit(event_type, bitmask[0]))
+ {
+ /* make pretty names for event types */
+ switch(event_type)
+ {
+ case EV_SYN: event_typeName = "Synchronization"; break;
+ case EV_KEY: event_typeName = "Keys/Buttons"; break;
+ case EV_REL: event_typeName = "Relative Axes"; break;
+ case EV_ABS: event_typeName = "Absolute Axes"; break;
+ case EV_MSC: event_typeName = "Miscellaneous"; break;
+ case EV_LED: event_typeName = "LEDs"; break;
+ case EV_SND: event_typeName = "System Sounds"; break;
+ case EV_REP: event_typeName = "Autorepeat Values"; break;
+ case EV_FF: event_typeName = "Force Feedback"; break;
+ case EV_PWR: event_typeName = "Power"; break;
+ case EV_FF_STATUS: event_typeName = "Force Feedback Status"; break;
+ }
+ post(" %s (%s/type %d) ", event_typeName, ev[event_type] ? ev[event_type] : "?", event_type);
+
+ /* get bitmask representing supported button types */
+ ioctl(x->x_fd, EVIOCGBIT(event_type, KEY_MAX), bitmask[event_type]);
+
+ /* cycle through all possible event codes (axes, keys, etc.)
+ * testing to see which are supported
+ */
+ for (event_code = 0; event_code < KEY_MAX; event_code++)
+ {
+ if (test_bit(event_code, bitmask[event_type]))
+ {
+ post(" %s (%d)", event_names[event_type] ? (event_names[event_type][event_code] ? event_names[event_type][event_code] : "?") : "?", event_code);
+ /* post(" Event code %d (%s)", event_code, names[event_type] ? (names[event_type][event_code] ? names[event_type][event_code] : "?") : "?"); */
+
+ switch(event_type) {
+ /*
+ * the API changed at some point... EV_SYN seems to be the new name
+ * from "Reset" events to "Syncronization" events
+ */
+ #ifdef EV_RST
+ case EV_RST: synCount++; break;
+ #else
+ case EV_SYN: synCount++; break;
+ #endif
+ case EV_KEY: keyCount++; break;
+ case EV_REL: relCount++; break;
+ case EV_ABS: absCount++; break;
+ case EV_MSC: mscCount++; break;
+ case EV_LED: ledCount++; break;
+ case EV_SND: sndCount++; break;
+ case EV_REP: repCount++; break;
+ case EV_FF: ffCount++; break;
+ case EV_PWR: pwrCount++; break;
+ case EV_FF_STATUS: ff_statusCount++; break;
+ }
+ }
+ }
+ }
+ }
+
+ post("\nDetected:");
+ if (synCount > 0) post (" %d Sync types",synCount);
+ if (keyCount > 0) post (" %d Key/Button types",keyCount);
+ if (relCount > 0) post (" %d Relative Axis types",relCount);
+ if (absCount > 0) post (" %d Absolute Axis types",absCount);
+ if (mscCount > 0) post (" %d Misc types",mscCount);
+ if (ledCount > 0) post (" %d LED types",ledCount);
+ if (sndCount > 0) post (" %d System Sound types",sndCount);
+ if (repCount > 0) post (" %d Key Repeat types",repCount);
+ if (ffCount > 0) post (" %d Force Feedback types",ffCount);
+ if (pwrCount > 0) post (" %d Power types",pwrCount);
+ if (ff_statusCount > 0) post (" %d Force Feedback types",ff_statusCount);
+
+ return (0);
+ }
+
+ /*
+ * Under GNU/Linux, the device is a filehandle
+ */
+ t_int hid_close_device(t_hid *x)
+ {
+ DEBUG(post("hid_close_device"););
+ if (x->x_fd <0)
+ return 0;
+ else
+ return (close(x->x_fd));
+ }
+
+ t_int hid_devicelist_refresh(t_hid *x)
+ {
+ DEBUG(post("hid_devicelist_refresh"););
+ /* the device list should be refreshed here */
+ /*
+ * since in GNU/Linux the device list is the input event devices
+ * (/dev/input/event?), nothing needs to be done as of yet to refresh
+ * the device list. Once the device name can be other things in addition
+ * the current t_float, then this will probably need to be changed.
+ */
+ return (0);
+ }
Index: hid.c
===================================================================
RCS file: /cvsroot/pure-data/externals/hcs/hid/hid.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** hid.c 23 Oct 2004 03:40:39 -0000 1.6
--- hid.c 25 Oct 2004 06:01:45 -0000 1.7
***************
*** 26,33 ****
#include "hid.h"
- #include "input_arrays.h"
-
- /* this should be removed once things are ported to hid_linux.c */
- #include "../linuxhid.h"
/*------------------------------------------------------------------------------
--- 26,29 ----
***************
*** 35,42 ****
*/
! #define DEBUG(x)
! //#define DEBUG(x) x
! #define DEFAULT_DELAY 300
/*------------------------------------------------------------------------------
--- 31,38 ----
*/
! //#define DEBUG(x)
! #define DEBUG(x) x
! #define DEFAULT_DELAY 500
/*------------------------------------------------------------------------------
***************
*** 44,73 ****
*/
! void hid_devicelist_refresh(t_hid* x)
! {
! /* the device list should be refreshed here */
! }
!
!
! void hid_stop(t_hid* x)
{
DEBUG(post("hid_stop"););
! #ifdef __linux__
! if (x->x_fd >= 0 && x->x_started)
{
clock_unset(x->x_clock);
! post("hid: polling stopped");
x->x_started = 0;
}
! #elif __APPLE__
! prHIDStopEventLoop();
! #endif
!
hid_devicelist_refresh(x);
}
! static t_int hid_close(t_hid *x)
{
DEBUG(post("hid_close"););
--- 40,59 ----
*/
! void hid_stop(t_hid *x)
{
DEBUG(post("hid_stop"););
! if (x->x_started)
{
clock_unset(x->x_clock);
! post("[hid] polling stopped");
x->x_started = 0;
}
!
hid_devicelist_refresh(x);
}
! t_int hid_close(t_hid *x)
{
DEBUG(post("hid_close"););
***************
*** 76,215 ****
hid_stop(x);
! if (x->x_fd <0) return 0;
! close (x->x_fd);
! post ("[hid] closed %s",x->x_devname->s_name);
!
! return 1;
}
! static t_int hid_open(t_hid *x, t_symbol *s)
{
DEBUG(post("hid_open"););
! t_int eventType, eventCode;
! char *eventTypeName = "";
! /* counts for various event types */
! t_int synCount,keyCount,relCount,absCount,mscCount,ledCount,sndCount,repCount,ffCount,pwrCount,ff_statusCount;
! #ifdef __linux__
! struct input_event hid_input_event;
! unsigned long bitmask[EV_MAX][NBITS(KEY_MAX)];
! #endif
! char devicename[256] = "Unknown";
!
! hid_close(x);
/* set obj device name to parameter
* otherwise set to default
*/
! if (s != &s_)
! x->x_devname = s;
!
! #ifdef __linux__
! /* open device */
! if (x->x_devname)
! {
! /* open the device read-only, non-exclusive */
! x->x_fd = open (x->x_devname->s_name, O_RDONLY | O_NONBLOCK);
! /* test if device open */
! if (x->x_fd < 0 )
! {
! error("[hid] open %s failed",x->x_devname->s_name);
! x->x_fd = -1;
! return 0;
! }
! } else return 1;
!
! /* read input_events from the HID_DEVICE stream
! * 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 */
! ioctl(x->x_fd, EVIOCGNAME(sizeof(devicename)), devicename);
! post ("\nConfiguring %s on %s",devicename,x->x_devname->s_name);
!
! /* get bitmask representing supported events (axes, keys, etc.) */
! memset(bitmask, 0, sizeof(bitmask));
! ioctl(x->x_fd, EVIOCGBIT(0, EV_MAX), bitmask[0]);
! post("\nSupported events:");
!
! /* init all count vars */
! synCount=keyCount=relCount=absCount=mscCount=ledCount=0;
! sndCount=repCount=ffCount=pwrCount=ff_statusCount=0;
!
! /* cycle through all possible event types */
! for (eventType = 0; eventType < EV_MAX; eventType++)
{
! if (test_bit(eventType, bitmask[0]))
! {
! /* make pretty names for event types */
! switch(eventType)
! {
! case EV_SYN: eventTypeName = "Synchronization"; break;
! case EV_KEY: eventTypeName = "Keys/Buttons"; break;
! case EV_REL: eventTypeName = "Relative Axes"; break;
! case EV_ABS: eventTypeName = "Absolute Axes"; break;
! case EV_MSC: eventTypeName = "Miscellaneous"; break;
! case EV_LED: eventTypeName = "LEDs"; break;
! case EV_SND: eventTypeName = "System Sounds"; break;
! case EV_REP: eventTypeName = "Autorepeat Values"; break;
! case EV_FF: eventTypeName = "Force Feedback"; break;
! case EV_PWR: eventTypeName = "Power"; break;
! case EV_FF_STATUS: eventTypeName = "Force Feedback Status"; break;
! }
! post(" %s (%s/type %d) ", eventTypeName, ev[eventType] ? ev[eventType] : "?", eventType);
!
! /* get bitmask representing supported button types */
! ioctl(x->x_fd, EVIOCGBIT(eventType, KEY_MAX), bitmask[eventType]);
!
! /* cycle through all possible event codes (axes, keys, etc.)
! * testing to see which are supported
! */
! for (eventCode = 0; eventCode < KEY_MAX; eventCode++)
! {
! if (test_bit(eventCode, bitmask[eventType]))
! {
! post(" %s (%d)", event_names[eventType] ? (event_names[eventType][eventCode] ? event_names[eventType][eventCode] : "?") : "?", eventCode);
! /* post(" Event code %d (%s)", eventCode, names[eventType] ? (names[eventType][eventCode] ? names[eventType][eventCode] : "?") : "?"); */
!
! switch(eventType) {
! /*
! * the API changed at some point... EV_SYN seems to be the new name
! * from "Reset" events to "Syncronization" events
! */
! #ifdef EV_RST
! case EV_RST: synCount++; break;
! #else
! case EV_SYN: synCount++; break;
! #endif
! case EV_KEY: keyCount++; break;
! case EV_REL: relCount++; break;
! case EV_ABS: absCount++; break;
! case EV_MSC: mscCount++; break;
! case EV_LED: ledCount++; break;
! case EV_SND: sndCount++; break;
! case EV_REP: repCount++; break;
! case EV_FF: ffCount++; break;
! case EV_PWR: pwrCount++; break;
! case EV_FF_STATUS: ff_statusCount++; break;
! }
! }
! }
! }
}
-
- post("\nDetected:");
- if (synCount > 0) post (" %d Sync types",synCount);
- if (keyCount > 0) post (" %d Key/Button types",keyCount);
- if (relCount > 0) post (" %d Relative Axis types",relCount);
- if (absCount > 0) post (" %d Absolute Axis types",absCount);
- if (mscCount > 0) post (" %d Misc types",mscCount);
- if (ledCount > 0) post (" %d LED types",ledCount);
- if (sndCount > 0) post (" %d System Sound types",sndCount);
- if (repCount > 0) post (" %d Key Repeat types",repCount);
- if (ffCount > 0) post (" %d Force Feedback types",ffCount);
- if (pwrCount > 0) post (" %d Power types",pwrCount);
- if (ff_statusCount > 0) post (" %d Force Feedback types",ff_statusCount);
post("\nWARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING");
--- 62,90 ----
hid_stop(x);
! post("[hid] closed device number %d",x->x_device_number);
!
! return (hid_close_device(x));
}
! t_int hid_open(t_hid *x, t_float f)
{
DEBUG(post("hid_open"););
! hid_close(x);
/* set obj device name to parameter
* otherwise set to default
*/
! if (f > 0)
! x->x_device_number = f;
! else
! x->x_device_number = 1;
! if (hid_open_device(x,x->x_device_number))
{
! error("[hid] can not open device %d",x->x_device_number);
! return (1);
}
post("\nWARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING");
***************
*** 218,264 ****
post("WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING");
post("================================= [hid] =================================\n");
! #endif /* #ifdef __linux__ */
!
! return 1; /* why is this return 1? */
}
! static t_int hid_read(t_hid *x,int fd)
{
! t_atom event_data[5]; /* this should probably be 4, not 5 */
! 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);
! }
! #elif __APPLE__
! /* 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)) */
! /* { */
! /* SInt32 value = HIDGetElementValue (pCurrentHIDDevice, pCurrentHIDElement); */
! /* SInt32 valueCal = HIDCalibrateValue (value, pCurrentHIDElement); */
! /* SInt32 valueScale = HIDScaleValue (valueCal, pCurrentHIDElement); */
! /* } */
! #endif /* #ifdef __APPLE__ */
!
if (x->x_started)
{
clock_delay(x->x_clock, x->x_delay);
}
!
return 1; /* why is this 1? */
}
--- 93,109 ----
post("WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING");
post("================================= [hid] =================================\n");
! return (0);
}
! t_int hid_read(t_hid *x,int fd)
{
! hid_output_events(x);
!
if (x->x_started)
{
clock_delay(x->x_clock, x->x_delay);
}
!
return 1; /* why is this 1? */
}
***************
*** 284,288 ****
DEBUG(post("hid_start"););
! if (x->x_fd >= 0 && !x->x_started)
{
clock_delay(x->x_clock, DEFAULT_DELAY);
--- 129,133 ----
DEBUG(post("hid_start"););
! if (!x->x_started)
{
clock_delay(x->x_clock, DEFAULT_DELAY);
***************
*** 290,297 ****
x->x_started = 1;
}
- else
- {
- error("You need to set a input device (i.e /dev/input/event0)");
- }
}
--- 135,138 ----
***************
*** 310,324 ****
{
DEBUG(post("hid_free"););
!
! if (x->x_fd < 0) return;
!
! hid_stop(x);
clock_free(x->x_clock);
- close (x->x_fd);
}
! static void *hid_new(t_symbol *s)
{
- t_int i;
t_hid *x = (t_hid *)pd_new(hid_class);
--- 151,162 ----
{
DEBUG(post("hid_free"););
!
! hid_close(x);
!
clock_free(x->x_clock);
}
! static void *hid_new(t_float f)
{
t_hid *x = (t_hid *)pd_new(hid_class);
***************
*** 327,342 ****
post("================================= [hid] =================================");
post("[hid] %s, written by Hans-Christoph Steiner <hans(a)eds.org>",version);
! #ifndef __linux__
! error(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!");
! error(" This is a dummy, since this object only works with a Linux kernel!");
! error(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!");
! #endif /* __linux__ */
/* init vars */
- x->x_fd = -1;
x->x_read_ok = 1;
x->x_started = 0;
x->x_delay = DEFAULT_DELAY;
- x->x_devname = gensym("/dev/input/event0");
x->x_clock = clock_new(x, (t_method)hid_read);
--- 165,178 ----
post("================================= [hid] =================================");
post("[hid] %s, written by Hans-Christoph Steiner <hans(a)eds.org>",version);
! #if !defined(__linux__) && !defined(__APPLE__)
! error(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!");
! error(" This is a dummy, since this object only works GNU/Linux and MacOS X!");
! error(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!");
! #endif
/* init vars */
x->x_read_ok = 1;
x->x_started = 0;
x->x_delay = DEFAULT_DELAY;
x->x_clock = clock_new(x, (t_method)hid_read);
***************
*** 345,356 ****
outlet_new(&x->x_obj, 0);
- /* set to the value from the object argument, if that exists */
- if (s != &s_)
- x->x_devname = s;
-
/* Open the device and save settings */
!
! if (!hid_open(x,s)) return x;
!
return (x);
}
--- 181,188 ----
outlet_new(&x->x_obj, 0);
/* Open the device and save settings */
! if (hid_open(x,f))
! error("[hid] device %d did not open",(t_int)f);
!
return (x);
}
***************
*** 364,368 ****
sizeof(t_hid),
CLASS_DEFAULT,
! A_DEFSYM,0);
/* add inlet datatype methods */
--- 196,200 ----
sizeof(t_hid),
CLASS_DEFAULT,
! A_DEFFLOAT,0);
/* add inlet datatype methods */
***************
*** 372,376 ****
/* add inlet message methods */
class_addmethod(hid_class,(t_method) hid_delay,gensym("delay"),A_DEFFLOAT,0);
! class_addmethod(hid_class,(t_method) hid_open,gensym("open"),A_DEFSYM,0);
class_addmethod(hid_class,(t_method) hid_close,gensym("close"),0);
class_addmethod(hid_class,(t_method) hid_start,gensym("start"),0);
--- 204,208 ----
/* add inlet message methods */
class_addmethod(hid_class,(t_method) hid_delay,gensym("delay"),A_DEFFLOAT,0);
! class_addmethod(hid_class,(t_method) hid_open,gensym("open"),A_DEFFLOAT,0);
class_addmethod(hid_class,(t_method) hid_close,gensym("close"),0);
class_addmethod(hid_class,(t_method) hid_start,gensym("start"),0);