diff options
author | mdodd <mdodd@FreeBSD.org> | 2003-04-09 23:19:50 +0000 |
---|---|---|
committer | mdodd <mdodd@FreeBSD.org> | 2003-04-09 23:19:50 +0000 |
commit | d32093d636ee42726dd34adf6e30a23c1f060036 (patch) | |
tree | 5930add24db0626d56070cdbaf1081b88d9b30b4 /usr.bin/usbhidaction | |
parent | bab509397bb4af795629110fcb65b09f43b0271c (diff) | |
download | FreeBSD-src-d32093d636ee42726dd34adf6e30a23c1f060036.zip FreeBSD-src-d32093d636ee42726dd34adf6e30a23c1f060036.tar.gz |
- Implement debounce support.
- Clean up examples.
- Call deamon(3) after we open the PID file.
Submitted by: Mathew Kanner <mat@cnd.mcgill.ca>
Diffstat (limited to 'usr.bin/usbhidaction')
-rw-r--r-- | usr.bin/usbhidaction/usbhidaction.1 | 53 | ||||
-rw-r--r-- | usr.bin/usbhidaction/usbhidaction.c | 64 |
2 files changed, 86 insertions, 31 deletions
diff --git a/usr.bin/usbhidaction/usbhidaction.1 b/usr.bin/usbhidaction/usbhidaction.1 index b0b491e..b83eb40 100644 --- a/usr.bin/usbhidaction/usbhidaction.1 +++ b/usr.bin/usbhidaction/usbhidaction.1 @@ -43,12 +43,10 @@ .Nd perform actions according to USB HID controls .Sh SYNOPSIS .Nm +.Op Fl diev .Fl c Ar config-file -.Op Fl d -.Op Fl i .Fl f Ar device .Op Fl p Ar pidfile -.Op Fl v .Ar arg ... .Sh DESCRIPTION .Nm @@ -60,12 +58,19 @@ die when the USB device is unplugged. .Pp The options are as follows: .Bl -tag -width Ds -.It Fl c Ar config-file -Specify a path name for the config file. .It Fl d Toggle the daemon flag. +.It Fl e +Instruct +.Nm +to die early. Useful when specified with multiple +verbose options to see how files are parsed. .It Fl i Ignore HID items in the config file that does not exist in the device. +.It Fl v +Be verbose, and do not become a daemon. +.It Fl c Ar config-file +Specify a path name for the config file. .It Fl f Ar device Specify a path name for the device to operate on. If @@ -77,8 +82,6 @@ path, it is taken to be the name of the device under An absolute path is taken to be the literal device pathname. .It Fl p Ar pidfile Specify an alternate file in which to store the process ID. -.It Fl v -Be verbose, and do not become a daemon. .El .Pp The config file will be re-read if the process gets a HUP signal. @@ -89,8 +92,8 @@ action; if a line begins with a whitespace it is considered a continuation of the previous line. Lines beginning with `#' are considered as comments. .Pp -Each line has three parts: a name of a USB HID item, a value for that item, -and an action. +Each line has four parts: a name of a USB HID item, a value for that item, +a debounce value, and an action. There must be whitespace between the parts. .Pp The item names are similar to those used by @@ -102,6 +105,12 @@ When the item reports this value the action will be performed. If the value is `*' it will match any value. .Pp +The debouce value is an integer not less than 0. The value of 0 +indicates that no debouncing should occur. A value of 1 will only +execute the action when the state changes. Values greater than one +specify that an action should be performed only when the value +changes by that amount. +.Pp The action is a normal command that is executed with .Xr system 3 . Before it is executed some substitution will occur: @@ -111,7 +120,7 @@ of the HID item, `$N' will be replaced by the name of the control, and `$H' will be replaced by the name of the HID device. .Sh FILES -.Bl -tag -indent +.Bl -tag -width indent .It Pa /usr/share/misc/usb_hid_usages The HID usage table. .It Pa /var/run/usbaction.pid @@ -122,22 +131,26 @@ The following configuration file can be used to control a pair of Philips USB speakers with the HID controls on the speakers. .Bd -literal -offset indent # Configuration for various Philips USB speakers -Consumer:Consumer_Control.Consumer:Volume_Up 1 - mixerctl -f $1 -n -w fea8-i7-master++ -Consumer:Consumer_Control.Consumer:Volume_Down 1 - mixerctl -f $1 -n -w fea8-i7-master-- -Consumer:Consumer_Control.Consumer:Mute 1 - mixerctl -f $1 -n -w fea8-i7-mute++ -Consumer:Consumer_Control.Consumer:Channel_Top.Microsoft:Base_Up 1 - mixerctl -f $1 -n -w fea8-i7-bass++ -Consumer:Consumer_Control.Consumer:Channel_Top.Microsoft:Base_Down 1 - mixerctl -f $1 -n -w fea8-i7-bass-- +Consumer:Volume_Up 1 0 mixer -f $1 vol +1 +Consumer:Volume_Down 1 0 mixer -f $1 vol -1 +# mute not supported +#Consumer:Mute 1 0 mixer -f $1 mute +Consumer:Channel_Top.Microsoft:Base_Up 1 0 mixer -f $1 bass +1 +Consumer:Channel_Top.Microsoft:Base_Down 1 0 mixer -f $1 bass -1 .Ed .Pp A sample invocation using this configuration would be .Bd -literal -offset indent usbhidaction -f /dev/uhid1 -c conf /dev/mixer1 .Ed +.Pp +The following example controls the mixer volume using a Logitech Wingman. +Notice the debouce of 1 for buttons and 5 for the slider. +.Bd -literal -offset indent +Button:Button_1 1 1 mixer vol +10 +Button:Button_2 1 1 mixer vol -10 +Generic_Desktop:Z * 5 mixer vol `echo $V | awk '{print int($$1/255*100)}'` +.Ed .Sh SEE ALSO .Xr usbhidctl 1 , .Xr usbhid 3 , diff --git a/usr.bin/usbhidaction/usbhidaction.c b/usr.bin/usbhidaction/usbhidaction.c index 22868b1..b05de5b 100644 --- a/usr.bin/usbhidaction/usbhidaction.c +++ b/usr.bin/usbhidaction/usbhidaction.c @@ -66,6 +66,9 @@ struct command { struct hid_item item; int value; + int lastseen; + int lastused; + int debounce; char anyvalue; char *name; char *action; @@ -91,7 +94,7 @@ main(int argc, char **argv) const char *conf = NULL; const char *dev = NULL; int fd, fp, ch, sz, n, val, i; - int demon, ignore; + int demon, ignore, dieearly; report_desc_t repd; char buf[100]; char devnamebuf[PATH_MAX]; @@ -100,7 +103,8 @@ main(int argc, char **argv) demon = 1; ignore = 0; - while ((ch = getopt(argc, argv, "c:df:ip:v")) != -1) { + dieearly = 0; + while ((ch = getopt(argc, argv, "c:def:ip:v")) != -1) { switch(ch) { case 'c': conf = optarg; @@ -108,6 +112,9 @@ main(int argc, char **argv) case 'd': demon ^= 1; break; + case 'e': + dieearly = 1; + break; case 'i': ignore++; break; @@ -161,8 +168,6 @@ main(int argc, char **argv) (void)signal(SIGHUP, sighup); if (demon) { - if (daemon(0, 0) < 0) - err(1, "daemon()"); fp = open(pidfile, O_WRONLY|O_CREAT, S_IRUSR|S_IRGRP|S_IROTH); if (fp >= 0) { sz=snprintf(buf,100, "%d\n", getpid()); @@ -170,6 +175,8 @@ main(int argc, char **argv) close(fp); } else err(1, "%s", pidfile); + if (daemon(0, 0) < 0) + err(1, "daemon()"); isdemon = 1; } @@ -194,9 +201,28 @@ main(int argc, char **argv) #endif for (cmd = commands; cmd; cmd = cmd->next) { val = hid_get_data(buf, &cmd->item); - if (cmd->value == val || cmd->anyvalue) + if (cmd->value != val && cmd->anyvalue == 0) + goto next; + if ((cmd->debounce == 0) || + (cmd->debounce && ((cmd->lastseen == -1) || + (cmd->lastseen != val)))) { docmd(cmd, val, dev, argc, argv); + goto next; + } + if ((cmd->debounce > 1) && + ((cmd->lastused == -1) || + (abs(cmd->lastused - val) >= cmd->debounce))) { + docmd(cmd, val, dev, argc, argv); + cmd->lastused = val; + goto next; + } +next: + cmd->lastseen = val; } + + if (dieearly) + exit(0); + if (reparse) { struct command *cmds = parse_conf(conf, repd, reportid, ignore); @@ -215,8 +241,8 @@ void usage(void) { - fprintf(stderr, "Usage: %s -c config_file [-d] -f hid_dev " - "[-i] [-p pidfile] [-v]\n", getprogname()); + fprintf(stderr, "Usage: %s [-deiv] -c config_file -f hid_dev " + "[-p pidfile]\n", getprogname()); exit(1); } @@ -237,7 +263,7 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) FILE *f; char *p; int line; - char buf[SIZE], name[SIZE], value[SIZE], action[SIZE]; + char buf[SIZE], name[SIZE], value[SIZE], debounce[SIZE], action[SIZE]; char usage[SIZE], coll[SIZE]; struct command *cmd, *cmds; struct hid_data *d; @@ -263,7 +289,8 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) } if (p) *p = 0; - if (sscanf(buf, "%s %s %[^\n]", name, value, action) != 3) { + if (sscanf(buf, "%s %s %s %[^\n]", + name, value, debounce, action) != 4) { if (isdemon) { syslog(LOG_WARNING, "config file `%s', line %d" ", syntax error: %s", conf, line, buf); @@ -290,18 +317,33 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) if (isdemon) { syslog(LOG_WARNING, "config file `%s', line %d, " - "bad value: %s\n", + "bad value: %s (should be * or a number)\n", conf, line, value); freecommands(cmds); return (NULL); } else { errx(1, "config file `%s', line %d, " - "bad value: %s\n", + "bad value: %s (should be * or a number)\n", conf, line, value); } } } + if (sscanf(debounce, "%d", &cmd->debounce) != 1) { + if (isdemon) { + syslog(LOG_WARNING, + "config file `%s', line %d, " + "bad value: %s (should be a number >= 0)\n", + conf, line, debounce); + freecommands(cmds); + return (NULL); + } else { + errx(1, "config file `%s', line %d, " + "bad value: %s (should be a number >= 0)\n", + conf, line, debounce); + } + } + coll[0] = 0; for (d = hid_start_parse(repd, 1 << hid_input, reportid); hid_get_item(d, &h); ) { |