aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2004-11-28 01:27:47 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2004-11-28 01:27:47 +0000
commit923e18b2face0b0b0f13e202a894be56242fe4e0 (patch)
tree838186d3232da6a4dfd754a8665d5831d736fff7
parenta88927720982bada5b9da445bac7653858cde587 (diff)
fixed a number of annoying bugs in MacOS X; cleaned up code; now multiple [hid]s work at the same time
svn path=/trunk/externals/hcs/hid/; revision=2329
-rw-r--r--TODO101
-rw-r--r--doc/buttongate-help.pd3
-rw-r--r--doc/hid-help.pd157
-rw-r--r--doc/keyboard-help.pd9
-rw-r--r--doc/keygate-help.pd3
-rw-r--r--doc/mouse-help.pd7
-rw-r--r--hid.c90
-rw-r--r--hid.h23
-rw-r--r--hid_darwin.c154
-rw-r--r--hid_linux.c241
-rw-r--r--joystick.pd35
11 files changed, 438 insertions, 385 deletions
diff --git a/TODO b/TODO
index ad767b8..635cca0 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,11 @@
+
+==============================================================================
+= write hid_print()
+
+- MacOS X (device/element list)
+
+- GNU/Linux
+
==============================================================================
= define generic event timestamp struct (probably Pd-ized input_event )
@@ -5,17 +13,10 @@ The question is whether the timeval is needed at all. Linux and Darwin
support it. Currently, I can only think of UPS PWR events actually using
timevals.
-
-
-===============================================================================
-= HID Manager Type/Usage/UsagePage -> Linux Type/Code mapping
-
- UsagePage
-
-
-LED UsagePage => ev_led
-LED Usages == Linux ev_led codes
-
+The timestamps should be in seconds since the first [hid] object was
+instantiated since Pd limits float resolution to 6 digits. If there were two
+floats, one for seconds, and the other for microseconds, then the [hid]
+timestamp could represent up to 11.5 days (999999 seconds).
==============================================================================
@@ -24,17 +25,6 @@ LED Usages == Linux ev_led codes
by # (1,2,...), generic name (mouse1, joystick2, tablet3...), or device name
("Trackpad", "Microsoft 5-button Mouse with IntelliEye(TM)", etc.)
- first get # working, that's probably the easiest
-
-by #
-------------------------------
-GNU/Linux
- sprintf(x_devname->s_name,"/dev/input/event%d",deviceNum + 1);
-
-Darwin
- prHIDBuildDeviceList();
- currentHIDDevice = discoveredDevices[gNumberOfHIDDevices];
-
==============================================================================
= figure out how to store device ID in obj struct
@@ -69,11 +59,7 @@ Darwin
==============================================================================
= control input messages
-- the [delay( message should be replaced by the [poll( msg
-
-- should [poll( also start things, or should it just set polling time?
-
-- are [start( and [stop( needed? is 0/1 enough?
+- are [poll(, [start(, and [stop( needed? is 0/1/del# enough?
==============================================================================
@@ -83,28 +69,21 @@ void hid_post(const char *format, const char *);
==============================================================================
-= if device is closed and obj is started, open device and start
-
-==============================================================================
-= catalog Linux device behavior
-
-- more data needed to make the proper [hid] output for MacOS X
-
-- catalog hatswitch behavior
-
-- catalog axis directions: right/down positive? left/up negative?
-
-==============================================================================
= event name changes
- make key/button Type btn rather than key (undecided on this one)
+
==============================================================================
-= make [macosxevent]
+= make [linuxhid] [darwinhid] and [windowshid]
- so much info is lost in the translation to a common event scheme that it
- would be quite handy to have a [macosxevent] object. This would give
- access to the entire range of devices supported by HID Manager.
+ would be quite handy to have platform-specific objects. This would give
+ access to the entire range of devices supported by HID Manager, Linux input
+ events, etc.
+
+- these objects should follow the same conventions as [hid]
+
==============================================================================
= device 0 gets events for all available devices
@@ -112,35 +91,12 @@ void hid_post(const char *format, const char *);
- it might be useful to have device #0 open all available devices and output
the events.
-==============================================================================
-= mapping object ideas
-- log
-
-- exponential
-
-- [noterange] scale an input range to an output range of MIDI note #s
-
-______________________________________________________________________________
-------------------------------------------------------------------------------
-BUGS
-______________________________________________________________________________
-------------------------------------------------------------------------------
-
-______________________________________________________________________________
-- BUG x->x_delay reset to default when device is opened
-
-______________________________________________________________________________
-- BUG: [mouse] and [joystick] arguments don't work to open device
-
-______________________________________________________________________________
-- BUG: [open('ing a device causes all other active [hid] objs to have their
-devices closed
-
-- this means only one [hid] object can have an open device at one time
-
-- I thought this was due to the hid_close_device() call in hid_open(), which releases
- the device list, but this doesn't seem to be the case.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
______________________________________________________________________________
- BUG: getting events from the queue doesn't output a 0 value event when the
@@ -169,10 +125,11 @@ ______________________________________________________________________________
the screen. Hopefully the HID Manager API will allow raw mouse data
access. It must since its used with games.
-_________________________________________________________________________________________
+______________________________________________________________________________
- BUG: on MacOS X, two keyboard key codes are reported as hatswitches
abs abs_hat0x Button Input, Keyboard Usage 0x39
abs abs_hat0y Button Input, Keyboard Usage 0x39
-I am pretty sure this is just a display problem, but it might not be.
+I am pretty sure this is just a hid_print_element_list() display problem.
+
diff --git a/doc/buttongate-help.pd b/doc/buttongate-help.pd
index a412cad..fa46447 100644
--- a/doc/buttongate-help.pd
+++ b/doc/buttongate-help.pd
@@ -1,4 +1,4 @@
-#N canvas 345 96 473 510 10;
+#N canvas 345 96 463 514 10;
#X obj 5 2 cnv 15 450 20 empty empty [buttongate] 2 11 1 18 -233017
-66577 0;
#X obj 160 287 bng 25 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
@@ -29,6 +29,7 @@ optional control messages to the HID.;
#X text 23 348 Keyboard keys can also be used to control this object.
You can get the [hid] keycode from here:;
#X obj 324 368 ev_key-list;
+#X obj 422 3 pddp;
#X connect 2 0 3 0;
#X connect 3 0 4 0;
#X connect 4 0 10 0;
diff --git a/doc/hid-help.pd b/doc/hid-help.pd
index cc52481..543fddc 100644
--- a/doc/hid-help.pd
+++ b/doc/hid-help.pd
@@ -1,20 +1,20 @@
-#N canvas 307 79 928 648 10;
-#X msg 455 295 abs abs_y 114 1.23605e+09;
+#N canvas 67 163 909 622 10;
+#X msg 455 295 rel rel_x -1 4.06142e+09;
#X obj 455 274 prepend set;
#X floatatom 37 484 5 0 0 0 - - -;
#X floatatom 89 484 5 0 0 0 - - -;
-#X msg 148 77 start;
-#X msg 174 96 stop;
+#X msg 158 121 start;
+#X msg 158 141 stop;
#X floatatom 548 354 12 0 0 1 time - -;
#X obj 455 335 unpack s s f f;
-#X msg 239 37 open 0;
-#X msg 246 55 open 1;
-#X msg 253 73 open 2;
-#X msg 259 91 open 3;
-#X msg 265 109 open 4;
+#X msg 261 34 open 0;
+#X msg 268 52 open 1;
+#X msg 275 70 open 2;
+#X msg 281 88 open 3;
+#X msg 287 106 open 4;
#X floatatom 84 439 7 0 0 0 - - -;
#X floatatom 138 439 7 0 0 0 - - -;
-#X obj 86 81 tgl 35 0 empty empty empty 0 -6 0 8 -24198 -1 -1 25 25
+#X obj 68 122 tgl 35 0 empty empty empty 0 -6 0 8 -24198 -1 -1 25 25
;
#X floatatom 517 370 12 0 0 1 value - -;
#X symbolatom 486 386 15 0 0 1 event_code - -;
@@ -44,25 +44,22 @@
#X floatatom 289 383 5 0 0 1 ev_syn - -;
#X obj 262 382 +;
#X msg 262 362 1;
-#X msg 336 136 close;
-#X msg 336 113 refresh;
-#X text 397 111 refresh device list;
-#X obj 717 512 all_about_hid;
-#X text 608 513 For more info:;
+#X msg 366 124 close;
+#X msg 366 103 refresh;
+#X text 427 101 refresh device list;
+#X text 607 531 For more info:;
#X text 49 588 (C) Copyright 2004 Hans-Christoph Steiner <hans@at.or.at>
;
#X text 266 602 released under the GNU GPL;
-#X text 472 589 $Revision: 1.12 $$Date: 2004-11-16 01:35:35 $;
+#X text 472 589 $Revision: 1.13 $$Date: 2004-11-28 01:27:47 $;
#X text 473 602 $Author: eighthave $;
#X floatatom 192 439 7 0 0 0 - - -;
-#X msg 398 180 poll 20;
-#X msg 336 180 poll 2;
-#X text 332 159 start polling and set the poll delay in ms;
+#X msg 428 185 poll 20;
+#X msg 366 185 poll 2;
+#X text 362 170 start polling and set the poll delay in ms;
#X text 387 248 event_type event_code value timestamp;
-#X msg 465 180 poll 2000;
-#X text 371 56 !!! This software is very much alpha \, so any aspect
+#X text 358 42 !!! This software is very much alpha \, so any aspect
of it could change without notice !!!;
-#X obj 248 225 hid 1;
#X obj 93 330 route key rel abs syn;
#X obj 9 537 tgl 25 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0 1
;
@@ -82,7 +79,7 @@ of it could change without notice !!!;
1;
#X obj 335 537 tgl 25 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0
1;
-#X msg 270 129 open 5;
+#X msg 292 126 open 5;
#X obj 9 504 route btn_0 btn_1 btn_2 btn_3 btn_4 btn_5 btn_6 btn_7
btn_8 btn_9;
#X obj 376 537 tgl 25 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0
@@ -308,64 +305,80 @@ btn_8 btn_9;
#X floatatom 640 459 7 0 0 0 - - -;
#X obj 640 475 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
+#X msg 118 121 1;
+#X msg 118 141 0;
+#X obj 868 3 pddp;
+#X obj 716 530 all_about_hid;
+#X msg 366 145 print;
+#X obj 247 223 hid 0;
+#X text 429 125 close the device;
+#X text 429 146 print the device and element lists;
+#X text 10 50 Any non-zero value starts polling \,;
+#X text 10 63 0 stops the polling. If the number;
+#X text 10 76 is greater than 1 \, then the poll;
+#X text 10 89 delay is set to that number.;
+#X msg 496 185 poll 2000;
#X connect 1 0 0 0;
-#X connect 4 0 57 0;
-#X connect 5 0 57 0;
+#X connect 4 0 91 0;
+#X connect 5 0 91 0;
#X connect 7 0 18 0;
#X connect 7 1 17 0;
#X connect 7 2 16 0;
#X connect 7 3 6 0;
-#X connect 8 0 57 0;
-#X connect 9 0 57 0;
-#X connect 10 0 57 0;
-#X connect 11 0 57 0;
-#X connect 12 0 57 0;
-#X connect 15 0 57 0;
+#X connect 8 0 91 0;
+#X connect 9 0 91 0;
+#X connect 10 0 91 0;
+#X connect 11 0 91 0;
+#X connect 12 0 91 0;
+#X connect 15 0 91 0;
#X connect 36 0 35 0;
#X connect 36 0 19 0;
#X connect 37 0 36 1;
#X connect 38 0 39 1;
#X connect 39 0 38 0;
#X connect 40 0 39 0;
-#X connect 41 0 57 0;
-#X connect 42 0 57 0;
-#X connect 51 0 57 0;
-#X connect 52 0 57 0;
-#X connect 55 0 57 0;
-#X connect 57 0 36 0;
-#X connect 57 0 1 0;
-#X connect 57 0 7 0;
-#X connect 57 0 58 0;
-#X connect 58 0 69 0;
-#X connect 58 1 74 0;
-#X connect 58 2 76 0;
-#X connect 58 3 40 0;
-#X connect 68 0 57 0;
-#X connect 69 0 59 0;
-#X connect 69 1 60 0;
-#X connect 69 2 61 0;
-#X connect 69 3 62 0;
-#X connect 69 4 63 0;
-#X connect 69 5 64 0;
-#X connect 69 6 65 0;
-#X connect 69 7 66 0;
-#X connect 69 8 67 0;
-#X connect 69 9 70 0;
-#X connect 74 0 2 0;
-#X connect 74 1 3 0;
-#X connect 74 2 75 0;
-#X connect 76 0 13 0;
-#X connect 76 1 14 0;
-#X connect 76 2 50 0;
-#X connect 76 3 77 0;
-#X connect 76 4 78 0;
-#X connect 76 5 79 0;
-#X connect 76 6 80 0;
+#X connect 41 0 91 0;
+#X connect 42 0 91 0;
+#X connect 50 0 91 0;
+#X connect 51 0 91 0;
+#X connect 55 0 66 0;
+#X connect 55 1 71 0;
+#X connect 55 2 73 0;
+#X connect 55 3 40 0;
+#X connect 65 0 91 0;
+#X connect 66 0 56 0;
+#X connect 66 1 57 0;
+#X connect 66 2 58 0;
+#X connect 66 3 59 0;
+#X connect 66 4 60 0;
+#X connect 66 5 61 0;
+#X connect 66 6 62 0;
+#X connect 66 7 63 0;
+#X connect 66 8 64 0;
+#X connect 66 9 67 0;
+#X connect 71 0 2 0;
+#X connect 71 1 3 0;
+#X connect 71 2 72 0;
+#X connect 73 0 13 0;
+#X connect 73 1 14 0;
+#X connect 73 2 49 0;
+#X connect 73 3 74 0;
+#X connect 73 4 75 0;
+#X connect 73 5 76 0;
+#X connect 73 6 77 0;
+#X connect 77 0 78 0;
+#X connect 77 1 80 0;
+#X connect 77 2 82 0;
+#X connect 77 3 84 0;
+#X connect 78 0 79 0;
#X connect 80 0 81 0;
-#X connect 80 1 83 0;
-#X connect 80 2 85 0;
-#X connect 80 3 87 0;
-#X connect 81 0 82 0;
-#X connect 83 0 84 0;
-#X connect 85 0 86 0;
-#X connect 87 0 88 0;
+#X connect 82 0 83 0;
+#X connect 84 0 85 0;
+#X connect 86 0 91 0;
+#X connect 87 0 91 0;
+#X connect 90 0 91 0;
+#X connect 91 0 36 0;
+#X connect 91 0 1 0;
+#X connect 91 0 7 0;
+#X connect 91 0 55 0;
+#X connect 98 0 91 0;
diff --git a/doc/keyboard-help.pd b/doc/keyboard-help.pd
index 90a45b4..bced959 100644
--- a/doc/keyboard-help.pd
+++ b/doc/keyboard-help.pd
@@ -1,5 +1,5 @@
-#N canvas 109 184 569 474 10;
-#X obj 168 91 tgl 25 0 empty empty empty 0 -6 0 8 -225271 -1 -1 1 1
+#N canvas 109 184 567 478 10;
+#X obj 168 91 tgl 25 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1
;
#X obj 11 369 tgl 20 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0 1
;
@@ -14,7 +14,7 @@
;
#X text 218 446 released under the GNU GPL;
#X text 414 446 $Author: eighthave $;
-#X text 414 433 $Revision: 1.1 $;
+#X text 414 433 $Revision: 1.2 $;
#X obj 348 402 all_about_hid;
#X text 239 403 For more info:;
#X msg 220 112 open 3;
@@ -54,7 +54,7 @@
1;
#X obj 368 369 tgl 20 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0
1;
-#X obj 389 369 tgl 20 0 empty empty empty 0 -6 0 8 -195568 -1 -1 1
+#X obj 389 369 tgl 20 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0
1;
#X obj 410 369 tgl 20 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0
1;
@@ -76,6 +76,7 @@ will get keyboard events.;
#X obj 75 315 route key_4 key_5 key_6 key_7 key_8 key_9 key_10 key_11
key_12 key_13 key_14 key_15 key_16 key_17 key_18 key_19 key_20 key_21
key_22 key_23 key_24 key_25 key_26 key_27;
+#X obj 519 3 pddp;
#X connect 0 0 16 0;
#X connect 4 0 2 0;
#X connect 4 1 3 0;
diff --git a/doc/keygate-help.pd b/doc/keygate-help.pd
index e6fe9ee..f73d193 100644
--- a/doc/keygate-help.pd
+++ b/doc/keygate-help.pd
@@ -1,4 +1,4 @@
-#N canvas 525 201 473 470 10;
+#N canvas 525 201 462 476 10;
#X obj 5 2 cnv 15 450 20 empty empty [keygate] 2 11 1 18 -233017 -66577
0;
#X obj 160 257 bng 25 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
@@ -24,6 +24,7 @@ inlet takes the data to be gated.;
#X text 18 89 The "f" key on the any keyboard controls this gate:;
#X text 310 263 <-- key released;
#X text 41 264 key pressed -->;
+#X obj 422 3 pddp;
#X connect 2 0 3 0;
#X connect 3 0 4 0;
#X connect 4 0 14 0;
diff --git a/doc/mouse-help.pd b/doc/mouse-help.pd
index 7084893..53fb843 100644
--- a/doc/mouse-help.pd
+++ b/doc/mouse-help.pd
@@ -1,4 +1,4 @@
-#N canvas 470 274 674 468 10;
+#N canvas 470 274 661 472 10;
#X symbolatom 211 268 6 0 0 1 code - -;
#X obj 130 106 tgl 25 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0
1;
@@ -83,7 +83,7 @@
#X connect 30 0 17 0;
#X connect 31 0 16 0;
#X restore 425 186 pd mouse-noise 1;
-#X obj 425 119 tgl 25 0 empty empty empty 0 -6 0 8 -225271 -1 -1 1
+#X obj 425 119 tgl 25 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0
1;
#X text 308 95 turn this on to make some noise with the mouse;
#X obj 211 241 unpack symbol float;
@@ -106,7 +106,7 @@
;
#X text 228 436 released under the GNU GPL;
#X text 424 436 $Author: eighthave $;
-#X text 424 423 $Revision: 1.8 $;
+#X text 424 423 $Revision: 1.9 $;
#X obj 526 382 all_about_hid;
#X text 417 383 For more info:;
#X obj 601 334 tgl 25 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0
@@ -123,6 +123,7 @@ in each axis to calibrate it.;
#X floatatom 516 165 1 0 0 0 - - -;
#X msg 180 146 refresh;
#X obj 130 171 mouse 0;
+#X obj 619 3 pddp;
#X connect 1 0 38 0;
#X connect 9 0 38 0;
#X connect 10 0 38 0;
diff --git a/hid.c b/hid.c
index 8718299..335f71a 100644
--- a/hid.c
+++ b/hid.c
@@ -32,8 +32,6 @@
#define DEBUG(x)
//#define DEBUG(x) x
-#define DEFAULT_DELAY 5
-
/*------------------------------------------------------------------------------
* FUNCTION PROTOTYPES
*/
@@ -95,7 +93,7 @@ void hid_stop(t_hid* x)
if (x->x_started)
{
clock_unset(x->x_clock);
- post("[hid] polling stopped");
+ DEBUG(post("[hid] polling stopped"););
x->x_started = 0;
}
}
@@ -110,7 +108,7 @@ t_int hid_close(t_hid *x)
if(! hid_close_device(x))
{
- post("[hid] closed device number %d",x->x_device_number);
+ post("[hid] closed device %d",x->x_device_number);
x->x_device_open = 0;
return (0);
}
@@ -119,44 +117,46 @@ t_int hid_close(t_hid *x)
}
-/* closed same device open */
-/* open same device no action */
-/* closed different device open */
-/* open different device close open */
+/* closed / same device open */
+/* open / same device no action */
+/* closed / different device open */
+/* open / different device close open */
t_int hid_open(t_hid *x, t_float f)
{
DEBUG(post("hid_open"););
/* store running state to be restored after the device has been opened */
- t_int started = x->x_started;
-
- if ( (f != x->x_device_number) && (x->x_device_open) ) hid_close(x);
-
- /* set obj device name to parameter otherwise set to default */
- if (f > 0)
- x->x_device_number = f;
+ t_int started = x->x_started;
+
+/* only close the device if its different than the current and open */
+ if ( (f != x->x_device_number) && (x->x_device_open) )
+ hid_close(x);
+
+ if (f > 0)
+ x->x_device_number = f;
+ else
+ x->x_device_number = 0;
+
+/* if device is open still, that means the same device is trying to be opened,
+ * therefore ignore the redundant open request. To reopen the same device,
+ * send a [close( msg, then an [open( msg. */
+ if (! x->x_device_open)
+ if (hid_open_device(x,x->x_device_number))
+ {
+ error("[hid] can not open device %d",x->x_device_number);
+ return (1);
+ }
else
- x->x_device_number = 0;
-
- if (! x->x_device_open)
- if (hid_open_device(x,x->x_device_number))
- {
- error("[hid] can not open device %d",x->x_device_number);
- post("\\=========================== [hid] ===========================/\n");
- return (1);
- }
- else
- {
- x->x_device_open = 1;
- }
+ {
+ x->x_device_open = 1;
+ }
/* restore the polling state so that when I [tgl] is used to start/stop [hid],
* the [tgl]'s state will continue to accurately reflect [hid]'s state */
- hid_set_from_float(x,started);
+ if(started)
+ hid_set_from_float(x,x->x_delay);
-
- post("\\=========================== [hid] ===========================/\n");
return (0);
}
@@ -181,13 +181,16 @@ void hid_start(t_hid* x, t_float f)
DEBUG(post("hid_start"););
/* if the user sets the delay less than one, ignore */
- if ( f >= 1 )
+ if( f >= 1 )
x->x_delay = (t_int)f;
+
+ if(!x->x_device_open)
+ hid_open(x,x->x_device_number);
- if (!x->x_started)
+ if(!x->x_started)
{
clock_delay(x->x_clock, x->x_delay);
- post("[hid]: polling started");
+ DEBUG(post("[hid] polling started"););
x->x_started = 1;
}
}
@@ -205,10 +208,10 @@ static void hid_free(t_hid* x)
DEBUG(post("hid_free"););
hid_close(x);
-
- hid_platform_specific_free(x);
-
clock_free(x->x_clock);
+ hid_instance_count--;
+
+ hid_platform_specific_free(x);
}
/* create a new instance of this class */
@@ -218,9 +221,11 @@ static void *hid_new(t_float f)
DEBUG(post("hid_new"););
- post("/=========================== [hid] ===========================\\");
- post("[hid] %d.%d, written by Hans-Christoph Steiner <hans@eds.org>",
- HID_MAJOR_VERSION, HID_MINOR_VERSION);
+/* only display the version when the first instance is loaded */
+ if(!hid_instance_count)
+ post("[hid] %d.%d, written by Hans-Christoph Steiner <hans@eds.org>",
+ HID_MAJOR_VERSION, HID_MINOR_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!");
@@ -245,7 +250,9 @@ static void *hid_new(t_float f)
* patch. */
if (hid_open(x,f))
error("[hid] device %d did not open",(t_int)f);
-
+
+ hid_instance_count++;
+
return (x);
}
@@ -265,6 +272,7 @@ void hid_setup(void)
/* add inlet message methods */
class_addmethod(hid_class,(t_method) hid_build_device_list,gensym("refresh"),0);
+ class_addmethod(hid_class,(t_method) hid_print,gensym("print"),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"),A_DEFFLOAT,0);
diff --git a/hid.h b/hid.h
index 7db864b..c406e43 100644
--- a/hid.h
+++ b/hid.h
@@ -14,7 +14,7 @@
#define HID_MAJOR_VERSION 0
#define HID_MINOR_VERSION 1
-static char *version = "$Revision: 1.10 $";
+static char *version = "$Revision: 1.11 $";
/*------------------------------------------------------------------------------
* CLASS DEF
@@ -30,18 +30,26 @@ typedef struct _hid
t_int x_delay;
t_int x_started;
t_int x_device_open;
- t_int x_instance_count;
} t_hid;
/*------------------------------------------------------------------------------
- * GLOBALS
+ * GLOBAL DEFINES
*/
-/* TODO: what are these for again? */
-char *deviceList[64];
-char *typeList[256];
-char *codeList[256];
+#define DEFAULT_DELAY 5
+
+
+/*------------------------------------------------------------------------------
+ * GLOBAL VARIABLES
+ */
+
+/*
+ * count the number of instances of this object so that certain free()
+ * functions can be called only after the final instance is detroyed.
+ */
+t_int hid_instance_count;
+
/*------------------------------------------------------------------------------
* FUNCTION PROTOTYPES FOR DIFFERENT PLATFORMS
@@ -56,6 +64,7 @@ t_int hid_open_device(t_hid *x, t_int device_number);
t_int hid_close_device(t_hid *x);
t_int hid_build_device_list(t_hid* x);
t_int hid_get_events(t_hid *x) ;
+void hid_print(t_hid* x);
void hid_platform_specific_free(t_hid *x);
#endif /* #ifndef _HID_H */
diff --git a/hid_darwin.c b/hid_darwin.c
index 6b19be3..729347c 100644
--- a/hid_darwin.c
+++ b/hid_darwin.c
@@ -58,6 +58,7 @@
* GLOBAL VARS
*======================================================================== */
+extern t_int hid_instance_count;
/*==============================================================================
* FUNCTION PROTOTYPES
@@ -162,7 +163,7 @@ void hid_convert_hatswitch_values(IOHIDEventStruct event, char *linux_type, char
pRecDevice hid_get_device_by_number(t_int device_number)
{
- pRecDevice currentDevice;
+ pRecDevice pCurrentHIDDevice;
t_int i, numdevs;
/*
@@ -179,14 +180,21 @@ pRecDevice hid_get_device_by_number(t_int device_number)
* want the oldest to be number 0 rather than the newest, so I use (numdevs -
* device_number - 1).
*/
- currentDevice = HIDGetFirstDevice();
+ pCurrentHIDDevice = HIDGetFirstDevice();
for(i=0; i < numdevs - device_number - 1; ++i)
- currentDevice = HIDGetNextDevice(currentDevice);
+ pCurrentHIDDevice = HIDGetNextDevice(pCurrentHIDDevice);
- return currentDevice;
+ return pCurrentHIDDevice;
}
-t_int hid_build_element_list(t_hid *x)
+
+void hid_build_element_list(t_hid *x)
+{
+
+}
+
+
+t_int hid_print_element_list(t_hid *x)
{
DEBUG(post("hid_build_element_list"););
@@ -200,8 +208,12 @@ t_int hid_build_element_list(t_hid *x)
char usage_name[256];
pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number);
- if(!pCurrentHIDDevice) return (1);
-
+ if ( ! HIDIsValidDevice(pCurrentHIDDevice) )
+ {
+ error("[hid]: device %d is not a valid device\n",x->x_device_number);
+ return(1);
+ }
+
pCurrentHIDElement = HIDGetFirstDeviceElement(pCurrentHIDDevice, kHIDElementTypeInput);
numElements = HIDCountDeviceElements(pCurrentHIDDevice, kHIDElementTypeInput);
@@ -236,6 +248,36 @@ t_int hid_build_element_list(t_hid *x)
}
+void hid_print_device_list(t_hid *x)
+{
+ char cstrDeviceName [256];
+ t_int i,numdevs;
+ UInt32 usagePage, usage;
+ pRecDevice pCurrentHIDDevice;
+
+ if( HIDHaveDeviceList() )
+ {
+ numdevs = (t_int) HIDCountDevices();
+
+ post("");
+ /* display device list in console */
+ for(i=0; i < numdevs; i++)
+ {
+ pCurrentHIDDevice = hid_get_device_by_number(i);
+ post("Device %d: '%s' '%s' version %d",i,pCurrentHIDDevice->manufacturer,
+ pCurrentHIDDevice->product,pCurrentHIDDevice->version);
+ //usage
+ HIDGetUsageName (pCurrentHIDDevice->usagePage,
+ pCurrentHIDDevice->usage,
+ cstrDeviceName);
+ DEBUG(post(" vendorID: %d productID: %d locID: %d",
+ pCurrentHIDDevice->vendorID,
+ pCurrentHIDDevice->productID,
+ pCurrentHIDDevice->locID););
+ }
+ post("");
+ }
+}
/* ============================================================================== */
/* Pd [hid] FUNCTIONS */
@@ -352,8 +394,8 @@ t_int hid_get_events(t_hid *x)
++event_counter;
}
DEBUG(
- if(event_counter)
- post("output %d events",event_counter);
+// if(event_counter)
+// post("output %d events",event_counter);
);
/* /\* get the first element *\/ */
/* pCurrentHIDElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeIO); */
@@ -396,24 +438,40 @@ t_int hid_open_device(t_hid *x, t_int device_number)
{
DEBUG(post("hid_open_device"););
- t_int err,result;
- pRecDevice currentDevice = NULL;
+ t_int result = 0;
+ pRecDevice pCurrentHIDDevice = NULL;
- result = HIDBuildDeviceList (NULL, NULL);
- // returns false if no device found
- if(result) error("[hid]: no HID devices found\n");
+/* rebuild device list to make sure the list is current */
+ if ( ! HIDHaveDeviceList() )
+ {
+ result = (t_int) HIDBuildDeviceList (NULL, NULL);
+ // returns false if no device found
+ if(result)
+ {
+ error("[hid]: no HID devices found\n");
+ return(result);
+ }
+ }
+
+ pCurrentHIDDevice = hid_get_device_by_number(device_number);
+ if ( ! HIDIsValidDevice(pCurrentHIDDevice) )
+ {
+ error("[hid]: device %d is not a valid device\n",device_number);
+ return(1);
+ }
- currentDevice = hid_get_device_by_number(device_number);
+// this doesn't seem to be needed at all
+// result = HIDCreateOpenDeviceInterface(pCurrentHIDDevice);
post("[hid] opened device %d: %s %s",
- device_number, currentDevice->manufacturer, currentDevice->product);
+ device_number, pCurrentHIDDevice->manufacturer, pCurrentHIDDevice->product);
hid_build_element_list(x);
- HIDQueueDevice(currentDevice);
+ HIDQueueDevice(pCurrentHIDDevice);
// TODO: queue all elements except absolute axes, those can just be polled
- return (0);
+ return(result);
}
@@ -421,8 +479,14 @@ t_int hid_close_device(t_hid *x)
{
DEBUG(post("hid_close_device"););
- post("[hid] closing device %d",x->x_device_number);
- return( HIDDequeueDevice( hid_get_device_by_number(x->x_device_number) ) );
+ t_int result = 0;
+ pRecDevice pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number);
+
+ HIDDequeueDevice(pCurrentHIDDevice);
+// this doesn't seem to be needed at all
+// result = HIDCloseReleaseInterface(pCurrentHIDDevice);
+
+ return(result);
}
@@ -430,45 +494,33 @@ t_int hid_build_device_list(t_hid *x)
{
DEBUG(post("hid_build_device_list"););
- int i,err;
- UInt32 usagePage, usage;
- pRecDevice pCurrentHIDDevice;
-
- Boolean result = HIDBuildDeviceList (NULL, NULL);
// returns false if no device found
- if(result) error("[hid]: no HID devices found\n");
+ if(HIDBuildDeviceList (NULL, NULL))
+ error("[hid]: no HID devices found\n");
- int numdevs = HIDCountDevices();
- // exit if no devices found
- if(!numdevs) return (0);
+ return (0);
+}
- char cstrDeviceName [256];
-
- post("");
- /* display device list in console */
- for(i=0; i < numdevs; i++)
- {
- pCurrentHIDDevice = hid_get_device_by_number(i);
- post("Device %d: '%s' '%s' version %d",i,pCurrentHIDDevice->manufacturer,
- pCurrentHIDDevice->product,pCurrentHIDDevice->version);
- //usage
- HIDGetUsageName (pCurrentHIDDevice->usagePage,
- pCurrentHIDDevice->usage,
- cstrDeviceName);
- DEBUG(post(" vendorID: %d productID: %d locID: %d",
- pCurrentHIDDevice->vendorID,
- pCurrentHIDDevice->productID,
- pCurrentHIDDevice->locID););
- }
- post("");
+
+void hid_print(t_hid *x)
+{
+ hid_print_device_list(x);
- return (0);
+ if(x->x_device_open)
+ hid_print_element_list(x);
}
+
void hid_platform_specific_free(t_hid *x)
{
- HIDReleaseAllDeviceQueues();
- HIDReleaseDeviceList();
+ DEBUG(post("hid_platform_specific_free"););
+/* only call this if the last instance is being freed */
+ if (hid_instance_count < 1)
+ {
+ DEBUG(post("RELEASE ALL hid_instance_count: %d", hid_instance_count););
+ HIDReleaseAllDeviceQueues();
+ HIDReleaseDeviceList();
+ }
}
//void HIDGetUsageName (const long valueUsagePage, const long valueUsage, char * cstrName)
diff --git a/hid_linux.c b/hid_linux.c
index 74b80cc..90fb6ad 100644
--- a/hid_linux.c
+++ b/hid_linux.c
@@ -42,7 +42,123 @@
/* LINUX-SPECIFIC SUPPORT FUNCTIONS */
/* ============================================================================== */
-void hid_list_devices(void)
+void hid_print_element_list(t_hid *x)
+{
+ unsigned long bitmask[EV_MAX][NBITS(KEY_MAX)];
+ char devicename[256] = "Unknown";
+ t_int event_type, event_code;
+ char *event_type_name = "";
+ /* counts for various event types */
+ t_int synCount,keyCount,relCount,absCount,mscCount,ledCount,sndCount,repCount,ffCount,pwrCount,ff_statusCount;
+
+ /* get name of device */
+ ioctl(x->x_fd, EVIOCGNAME(sizeof(devicename)), devicename);
+ post ("\nConfiguring device %d as %s (%s)",
+ x->x_device_number,devicename,device_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_type_name = "Synchronization"; break;
+ case EV_KEY: event_type_name = "Keys/Buttons"; break;
+ case EV_REL: event_type_name = "Relative Axis"; break;
+ case EV_ABS: event_type_name = "Absolute Axis"; break;
+ case EV_MSC: event_type_name = "Miscellaneous"; break;
+ case EV_LED: event_type_name = "LEDs"; break;
+ case EV_SND: event_type_name = "System Sounds"; break;
+ case EV_REP: event_type_name = "Autorepeat Values"; break;
+ case EV_FF: event_type_name = "Force Feedback"; break;
+ case EV_PWR: event_type_name = "Power"; break;
+ case EV_FF_STATUS: event_type_name = "Force Feedback Status"; break;
+ }
+// post(" %s (%s) ", event_type_name, 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]);
+
+ post("");
+ post(" TYPE\tCODE\tEVENT NAME");
+ post("-----------------------------------------------------------");
+
+ /* 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]))
+ {
+ if ((event_type == EV_KEY) && (event_code >= BTN_MISC) && (event_code < KEY_OK) )
+ {
+ char hid_code[7];
+ hid_convert_linux_buttons_to_numbers(event_code,hid_code);
+ post(" %s\t%s\t%s",
+ ev[event_type] ? ev[event_type] : "?",
+ hid_code,
+ event_names[event_type] ? (event_names[event_type][event_code] ? event_names[event_type][event_code] : "?") : "?");
+ }
+ else
+ post(" %s\t\t%s\t%s",
+ ev[event_type] ? ev[event_type] : "?",
+ event_names[event_type] ? (event_names[event_type][event_code] ? event_names[event_type][event_code] : "?") : "?",
+ event_type_name);
+/* 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);
+}
+
+
+void hid_print_device_list(void)
{
int i,fd;
char device_output_string[256] = "Unknown";
@@ -138,26 +254,26 @@ t_int hid_get_events(t_hid *x)
DEBUG(++event_counter;);
}
DEBUG(
- if (event_counter > 0)
- post("output %d events",event_counter);
+ //if (event_counter > 0)
+ //post("output %d events",event_counter);
);
return (0);
}
+void hid_print(t_hid* x)
+{
+ hid_print_device_list();
+}
+
+
t_int hid_open_device(t_hid *x, t_int device_number)
{
DEBUG(post("hid_open_device"););
char device_name[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_type_name = "";
- /* counts for various event types */
- t_int synCount,keyCount,relCount,absCount,mscCount,ledCount,sndCount,repCount,ffCount,pwrCount,ff_statusCount;
x->x_fd = -1;
@@ -181,111 +297,6 @@ t_int hid_open_device(t_hid *x, t_int device_number)
* 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,device_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_type_name = "Synchronization"; break;
- case EV_KEY: event_type_name = "Keys/Buttons"; break;
- case EV_REL: event_type_name = "Relative Axis"; break;
- case EV_ABS: event_type_name = "Absolute Axis"; break;
- case EV_MSC: event_type_name = "Miscellaneous"; break;
- case EV_LED: event_type_name = "LEDs"; break;
- case EV_SND: event_type_name = "System Sounds"; break;
- case EV_REP: event_type_name = "Autorepeat Values"; break;
- case EV_FF: event_type_name = "Force Feedback"; break;
- case EV_PWR: event_type_name = "Power"; break;
- case EV_FF_STATUS: event_type_name = "Force Feedback Status"; break;
- }
-// post(" %s (%s) ", event_type_name, 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]);
-
- post("");
- post(" TYPE\tCODE\tEVENT NAME");
- post("-----------------------------------------------------------");
-
- /* 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]))
- {
- if ((event_type == EV_KEY) && (event_code >= BTN_MISC) && (event_code < KEY_OK) )
- {
- char hid_code[7];
- hid_convert_linux_buttons_to_numbers(event_code,hid_code);
- post(" %s\t%s\t%s",
- ev[event_type] ? ev[event_type] : "?",
- hid_code,
- event_names[event_type] ? (event_names[event_type][event_code] ? event_names[event_type][event_code] : "?") : "?");
- }
- else
- post(" %s\t\t%s\t%s",
- ev[event_type] ? ev[event_type] : "?",
- event_names[event_type] ? (event_names[event_type][event_code] ? event_names[event_type][event_code] : "?") : "?",
- event_type_name);
-/* 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);
}
@@ -313,8 +324,6 @@ t_int hid_build_device_list(t_hid *x)
* the current t_float, then this will probably need to be changed.
*/
- hid_list_devices();
-
return (0);
}
diff --git a/joystick.pd b/joystick.pd
index 77e5c83..955a987 100644
--- a/joystick.pd
+++ b/joystick.pd
@@ -1,4 +1,4 @@
-#N canvas 368 109 823 611 10;
+#N canvas 246 181 827 615 10;
#X msg 96 64 start;
#X msg 105 83 stop;
#X obj 77 30 inlet;
@@ -24,30 +24,31 @@
;
#X text 228 566 released under the GNU GPL;
#X text 424 566 $Author: eighthave $;
-#X text 424 553 $Revision: 1.3 $$Date: 2004-11-16 01:35:35 $;
-#X obj 38 489 autoscale -1 1;
-#X obj 103 449 autoscale -1 1;
-#X obj 169 409 autoscale -1 1;
-#X obj 235 368 autoscale -1 1;
+#X text 424 553 $Revision: 1.4 $$Date: 2004-11-28 01:27:47 $;
#X obj 38 264 route abs_x abs_y abs_rz abs_throttle abs_hat0x abs_hat0y
;
#X text 287 388 throttle/slider;
#X text 346 343 hat0x;
#X text 416 319 hat0y;
+#X obj 235 368 autoscale 0 1;
+#X obj 169 409 autoscale 0 1;
+#X obj 103 449 autoscale 0 1;
+#X obj 38 489 autoscale 0 1;
+#X text 8 6 [joystick];
#X connect 0 0 10 0;
#X connect 1 0 10 0;
#X connect 2 0 10 0;
#X connect 10 0 15 0;
-#X connect 15 0 28 0;
+#X connect 15 0 24 0;
#X connect 15 1 9 0;
#X connect 15 2 3 0;
-#X connect 24 0 5 0;
-#X connect 25 0 11 0;
-#X connect 26 0 12 0;
-#X connect 27 0 13 0;
-#X connect 28 0 24 0;
-#X connect 28 1 25 0;
-#X connect 28 2 26 0;
-#X connect 28 3 27 0;
-#X connect 28 4 6 0;
-#X connect 28 5 7 0;
+#X connect 24 0 31 0;
+#X connect 24 1 30 0;
+#X connect 24 2 29 0;
+#X connect 24 3 28 0;
+#X connect 24 4 6 0;
+#X connect 24 5 7 0;
+#X connect 28 0 13 0;
+#X connect 29 0 12 0;
+#X connect 30 0 11 0;
+#X connect 31 0 5 0;