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@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@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);