mirror of
https://github.com/ericonr/sndio.git
synced 2024-02-18 04:45:21 -06:00
allow device to be disconnected
This commit is contained in:
parent
955ec5b4b3
commit
860ecb9d0d
@ -1,6 +1,6 @@
|
|||||||
.\" $OpenBSD$
|
.\" $OpenBSD$
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2010-2012 Alexandre Ratchov <alex@caoua.org>
|
.\" Copyright (c) 2014 Alexandre Ratchov <alex@caoua.org>
|
||||||
.\"
|
.\"
|
||||||
.\" Permission to use, copy, modify, and distribute this software for any
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
.\" purpose with or without fee is hereby granted, provided that the above
|
.\" purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -14,7 +14,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd November 29, 2010
|
.Dd $Mdocdate$
|
||||||
.Dt XVOLKEYS 1
|
.Dt XVOLKEYS 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -54,12 +54,3 @@ Increase log verbosity.
|
|||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr sndiod 1
|
.Xr sndiod 1
|
||||||
.Xr sndio 7
|
.Xr sndio 7
|
||||||
.Sh BUGS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility keeps the audio device open.
|
|
||||||
If the device is disconnected or
|
|
||||||
.Xr sndiod 1
|
|
||||||
is restarted, the
|
|
||||||
.Nm
|
|
||||||
process terminates.
|
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
/* $OpenBSD$ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Alexandre Ratchov <alex@caoua.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -33,6 +49,8 @@
|
|||||||
/*
|
/*
|
||||||
* midi parser state
|
* midi parser state
|
||||||
*/
|
*/
|
||||||
|
char *port;
|
||||||
|
struct pollfd pfds[16];
|
||||||
struct mio_hdl *hdl;
|
struct mio_hdl *hdl;
|
||||||
unsigned int midx;
|
unsigned int midx;
|
||||||
unsigned char mev[MIDI_MSGMAX];
|
unsigned char mev[MIDI_MSGMAX];
|
||||||
@ -41,7 +59,7 @@ int master = MIDI_MAXVOL;
|
|||||||
int verbose;
|
int verbose;
|
||||||
|
|
||||||
unsigned char dumpreq[] = {
|
unsigned char dumpreq[] = {
|
||||||
SYSEX_START,
|
SYSEX_START,
|
||||||
SYSEX_TYPE_EDU,
|
SYSEX_TYPE_EDU,
|
||||||
0,
|
0,
|
||||||
SYSEX_AUCAT,
|
SYSEX_AUCAT,
|
||||||
@ -56,18 +74,44 @@ Display *dpy;
|
|||||||
KeyCode inc_code, dec_code;
|
KeyCode inc_code, dec_code;
|
||||||
KeySym *inc_map, *dec_map;
|
KeySym *inc_map, *dec_map;
|
||||||
|
|
||||||
|
int
|
||||||
|
midi_connect(void)
|
||||||
|
{
|
||||||
|
hdl = mio_open(port, MIO_IN | MIO_OUT, 0);
|
||||||
|
if (hdl == NULL) {
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, "%s: couldn't open MIDI port\n", port);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
midi_disconnect(void)
|
||||||
|
{
|
||||||
|
if (!mio_eof(hdl))
|
||||||
|
return;
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, "%s: MIDI port disconnected\n");
|
||||||
|
mio_close(hdl);
|
||||||
|
hdl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
midi_setvol(int vol)
|
midi_setvol(int vol)
|
||||||
{
|
{
|
||||||
struct sysex msg;
|
struct sysex msg;
|
||||||
|
|
||||||
if (vol > MIDI_MAXVOL)
|
if (vol > MIDI_MAXVOL)
|
||||||
vol = MIDI_MAXVOL;
|
vol = MIDI_MAXVOL;
|
||||||
if (vol < 0)
|
if (vol < 0)
|
||||||
vol = 0;
|
vol = 0;
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stderr, "setvol(%d)\n", vol);
|
fprintf(stderr, "%s: setting volume to %d\n", port, vol);
|
||||||
|
if (!midi_connect())
|
||||||
|
return;
|
||||||
if (master != vol) {
|
if (master != vol) {
|
||||||
|
master = vol;
|
||||||
msg.start = SYSEX_START;
|
msg.start = SYSEX_START;
|
||||||
msg.type = SYSEX_TYPE_RT;
|
msg.type = SYSEX_TYPE_RT;
|
||||||
msg.dev = SYSEX_DEV_ANY;
|
msg.dev = SYSEX_DEV_ANY;
|
||||||
@ -76,11 +120,10 @@ midi_setvol(int vol)
|
|||||||
msg.u.master.fine = 0;
|
msg.u.master.fine = 0;
|
||||||
msg.u.master.coarse = vol;
|
msg.u.master.coarse = vol;
|
||||||
msg.u.master.end = SYSEX_END;
|
msg.u.master.end = SYSEX_END;
|
||||||
if (mio_write(hdl, &msg, SYSEX_SIZE(master)) == 0) {
|
if (hdl) {
|
||||||
fprintf(stderr, "Couldn't write volume message\n");
|
mio_write(hdl, &msg, SYSEX_SIZE(master));
|
||||||
exit(1);
|
midi_disconnect();
|
||||||
}
|
}
|
||||||
master = vol;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +141,10 @@ midi_sysex(unsigned char *msg, unsigned len)
|
|||||||
msg[4] == SYSEX_MASTER) {
|
msg[4] == SYSEX_MASTER) {
|
||||||
if (master != msg[6]) {
|
if (master != msg[6]) {
|
||||||
master = msg[6];
|
master = msg[6];
|
||||||
fprintf(stderr, "master -> %d\n", master);
|
if (verbose) {
|
||||||
|
fprintf(stderr, "%s: volume is %d\n",
|
||||||
|
port, master);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +192,7 @@ grab_keys(void)
|
|||||||
fprintf(stderr, "Couldn't get keymap for '+' key\n");
|
fprintf(stderr, "Couldn't get keymap for '+' key\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
dec_code = XKeysymToKeycode(dpy, KEY_DEC);
|
dec_code = XKeysymToKeycode(dpy, KEY_DEC);
|
||||||
dec_map = XGetKeyboardMapping(dpy, dec_code, 1, &nret);
|
dec_map = XGetKeyboardMapping(dpy, dec_code, 1, &nret);
|
||||||
if (nret <= ShiftMask) {
|
if (nret <= ShiftMask) {
|
||||||
@ -159,7 +205,7 @@ grab_keys(void)
|
|||||||
if ((i & MODMASK) != 0)
|
if ((i & MODMASK) != 0)
|
||||||
continue;
|
continue;
|
||||||
for (scr = 0; scr != nscr; scr++) {
|
for (scr = 0; scr != nscr; scr++) {
|
||||||
|
|
||||||
XGrabKey(dpy, inc_code, i | MODMASK,
|
XGrabKey(dpy, inc_code, i | MODMASK,
|
||||||
RootWindow(dpy, scr), 1,
|
RootWindow(dpy, scr), 1,
|
||||||
GrabModeAsync, GrabModeAsync);
|
GrabModeAsync, GrabModeAsync);
|
||||||
@ -198,8 +244,6 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
#define MIDIBUFSZ 0x100
|
#define MIDIBUFSZ 0x100
|
||||||
unsigned char msg[MIDIBUFSZ];
|
unsigned char msg[MIDIBUFSZ];
|
||||||
char *devname;
|
|
||||||
struct pollfd *pfds;
|
|
||||||
unsigned int i, scr;
|
unsigned int i, scr;
|
||||||
XEvent xev;
|
XEvent xev;
|
||||||
int c, nfds, n;
|
int c, nfds, n;
|
||||||
@ -208,7 +252,7 @@ main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* parse command line options
|
* parse command line options
|
||||||
*/
|
*/
|
||||||
devname = "snd/0";
|
port = "snd/0";
|
||||||
verbose = 0;
|
verbose = 0;
|
||||||
background = 0;
|
background = 0;
|
||||||
while ((c = getopt(argc, argv, "Dq:v")) != -1) {
|
while ((c = getopt(argc, argv, "Dq:v")) != -1) {
|
||||||
@ -220,7 +264,7 @@ main(int argc, char **argv)
|
|||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
devname = optarg;
|
port = optarg;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
@ -231,12 +275,6 @@ main(int argc, char **argv)
|
|||||||
if (argc > 0)
|
if (argc > 0)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
hdl = mio_open("snd/0", MIO_IN | MIO_OUT, 0);
|
|
||||||
if (hdl == NULL) {
|
|
||||||
fprintf(stderr, "Couldn't open MIDI control device\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
dpy = XOpenDisplay(NULL);
|
dpy = XOpenDisplay(NULL);
|
||||||
if (dpy == 0) {
|
if (dpy == 0) {
|
||||||
fprintf(stderr, "Couldn't open display\n");
|
fprintf(stderr, "Couldn't open display\n");
|
||||||
@ -247,22 +285,18 @@ main(int argc, char **argv)
|
|||||||
for (scr = 0; scr != ScreenCount(dpy); scr++)
|
for (scr = 0; scr != ScreenCount(dpy); scr++)
|
||||||
XSelectInput(dpy, RootWindow(dpy, scr), KeyPress);
|
XSelectInput(dpy, RootWindow(dpy, scr), KeyPress);
|
||||||
|
|
||||||
|
(void)midi_connect();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* request initial volume
|
* request initial volume
|
||||||
*/
|
*/
|
||||||
if (mio_write(hdl, dumpreq, sizeof(dumpreq)) != sizeof(dumpreq)) {
|
if (hdl) {
|
||||||
fprintf(stderr, "Failed to request master volume\n");
|
mio_write(hdl, dumpreq, sizeof(dumpreq));
|
||||||
exit(1);
|
midi_disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
grab_keys();
|
grab_keys();
|
||||||
|
|
||||||
pfds = malloc(sizeof(struct pollfd) * (mio_nfds(hdl) + 1));
|
|
||||||
if (pfds == NULL) {
|
|
||||||
fprintf(stderr, "Failed to allocate pollfd structures\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (background) {
|
if (background) {
|
||||||
verbose = 0;
|
verbose = 0;
|
||||||
if (daemon(0, 0) < 0) {
|
if (daemon(0, 0) < 0) {
|
||||||
@ -292,21 +326,22 @@ main(int argc, char **argv)
|
|||||||
midi_setvol(master - 5);
|
midi_setvol(master - 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nfds = mio_pollfd(hdl, pfds, POLLIN);
|
nfds = (hdl != NULL) ? mio_pollfd(hdl, pfds, POLLIN) : 0;
|
||||||
pfds[nfds].fd = ConnectionNumber(dpy);
|
pfds[nfds].fd = ConnectionNumber(dpy);
|
||||||
pfds[nfds].events = POLLIN;
|
pfds[nfds].events = POLLIN;
|
||||||
while (poll(pfds, nfds + 1, -1) < 0 && errno == EINTR)
|
while (poll(pfds, nfds + 1, -1) < 0 && errno == EINTR)
|
||||||
; /* nothing */
|
; /* nothing */
|
||||||
if (mio_revents(hdl, pfds) & POLLIN) {
|
if (hdl) {
|
||||||
n = mio_read(hdl, msg, MIDIBUFSZ);
|
if (mio_revents(hdl, pfds) & POLLIN) {
|
||||||
if (n == 0)
|
n = mio_read(hdl, msg, MIDIBUFSZ);
|
||||||
break;
|
midi_parse(msg, n);
|
||||||
midi_parse(msg, n);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(inc_map);
|
XFree(inc_map);
|
||||||
XFree(dec_map);
|
XFree(dec_map);
|
||||||
XCloseDisplay(dpy);
|
XCloseDisplay(dpy);
|
||||||
mio_close(hdl);
|
if (hdl)
|
||||||
|
mio_close(hdl);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user