mirror of https://github.com/ericonr/sndio.git
Merge branch 'master' of ssh://moule/~alex/git/sndio
This commit is contained in:
commit
5b1c87e324
|
@ -1,12 +1,9 @@
|
|||
XVOLKEYS = @xvolkeys@
|
||||
|
||||
all:
|
||||
cd libsndio && ${MAKE}
|
||||
cd sndiod && ${MAKE}
|
||||
cd sndioctl && ${MAKE}
|
||||
cd aucat && ${MAKE}
|
||||
cd midicat && ${MAKE}
|
||||
if [ ${XVOLKEYS} = yes ]; then cd xvolkeys && ${MAKE}; fi
|
||||
|
||||
install:
|
||||
cd libsndio && ${MAKE} install
|
||||
|
@ -14,10 +11,8 @@ install:
|
|||
cd sndioctl && ${MAKE} install
|
||||
cd aucat && ${MAKE} install
|
||||
cd midicat && ${MAKE} install
|
||||
if [ ${XVOLKEYS} = yes ]; then cd xvolkeys && ${MAKE} install; fi
|
||||
|
||||
uninstall:
|
||||
cd xvolkeys && ${MAKE} uninstall
|
||||
cd midicat && ${MAKE} uninstall
|
||||
cd aucat && ${MAKE} uninstall
|
||||
cd sndioctl && ${MAKE} uninstall
|
||||
|
@ -31,14 +26,12 @@ clean:
|
|||
cd sndiod && ${MAKE} clean
|
||||
cd libsndio && ${MAKE} clean
|
||||
cd examples && ${MAKE} clean
|
||||
cd xvolkeys && ${MAKE} clean
|
||||
|
||||
distclean: clean
|
||||
rm -f \
|
||||
Makefile aucat/Makefile midicat/Makefile sndiod/Makefile \
|
||||
libsndio/Makefile \
|
||||
sndioctl/Makefile \
|
||||
xvolkeys/Makefile \
|
||||
examples/Makefile \
|
||||
contrib/init.d.sndiod \
|
||||
contrib/sndiod.service
|
||||
|
|
|
@ -22,8 +22,6 @@ Usage: configure [options]
|
|||
--disable-rmidi disable character device midi backend
|
||||
--enable-umidi enable usb-midi backend [$umidi]
|
||||
--disable-umidi disable usb-midi backend
|
||||
--enable-xvolkeys build xvolkeys utility (requires X) [$xvolkeys]
|
||||
--disable-xvolkeys don't build xvolkeys
|
||||
--with-libbsd use the libbsd rather than bsd-compat/*
|
||||
--without-libbsd don't use libbsd
|
||||
END
|
||||
|
@ -41,7 +39,6 @@ rmidi=no # do we want support for raw char dev ?
|
|||
umidi=no # do we want support for umidi ?
|
||||
precision=16 # aucat/sndiod arithmetic precision
|
||||
user=_sndio # non-privileged user for sndio daemon
|
||||
xvolkeys=yes # build xvolkeys ?
|
||||
libbsd=no # use libbsd?
|
||||
so_ldflags= # extra linker flags for shared libs
|
||||
unset vars # variables passed as arguments
|
||||
|
@ -160,12 +157,6 @@ for i; do
|
|||
--privsep-user=*)
|
||||
user="${i#--privsep-user=}"
|
||||
shift;;
|
||||
--enable-xvolkeys)
|
||||
xvolkeys=yes
|
||||
shift;;
|
||||
--disable-xvolkeys)
|
||||
xvolkeys=no
|
||||
shift;;
|
||||
--precision=*)
|
||||
precision="${i#--precision=}"
|
||||
if [ "$precision" != 16 -a "$precision" != 24 ]; then
|
||||
|
@ -253,7 +244,6 @@ fi
|
|||
for f in Makefile aucat/Makefile midicat/Makefile sndiod/Makefile \
|
||||
libsndio/Makefile \
|
||||
sndioctl/Makefile \
|
||||
xvolkeys/Makefile \
|
||||
examples/Makefile \
|
||||
contrib/init.d.sndiod \
|
||||
contrib/sndiod.service
|
||||
|
@ -272,7 +262,6 @@ do
|
|||
-e "s:@vars@:${vars}:" \
|
||||
-e "s:@precision@:$precision:" \
|
||||
-e "s:@user@:$user:" \
|
||||
-e "s:@xvolkeys@:$xvolkeys:" \
|
||||
< $f.in > $f
|
||||
done
|
||||
|
||||
|
@ -293,7 +282,6 @@ oss...................... $oss
|
|||
sun...................... $sun
|
||||
rmidi.................... $rmidi
|
||||
umidi.................... $umidi
|
||||
xvolkeys................. $xvolkeys
|
||||
|
||||
Do "make && make install" to compile and install sndio
|
||||
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
# extra includes paths (-I options)
|
||||
INCLUDE = -I/usr/X11R6/include -I../libsndio -I../bsd-compat
|
||||
|
||||
# extra libraries paths (-L options)
|
||||
LIB = -L/usr/X11R6/lib -L../libsndio
|
||||
|
||||
# extra defines (-D options)
|
||||
DEFS = -DDEBUG @defs@
|
||||
|
||||
# extra libraries (-l options)
|
||||
LDADD = -lX11 -lsndio @ldadd@
|
||||
|
||||
# variables defined on configure script command line (if any)
|
||||
@vars@
|
||||
|
||||
#
|
||||
# binaries, documentation, man pages and examples will be installed in
|
||||
# ${BIN_DIR}, ${MAN1_DIR}
|
||||
#
|
||||
BIN_DIR = @bindir@
|
||||
MAN1_DIR = @mandir@/man1
|
||||
|
||||
#
|
||||
# programs to build
|
||||
#
|
||||
PROG = xvolkeys
|
||||
|
||||
all: ${PROG}
|
||||
|
||||
install:
|
||||
mkdir -p ${DESTDIR}${BIN_DIR} ${DESTDIR}${MAN1_DIR}
|
||||
cp ${PROG} ${DESTDIR}${BIN_DIR}
|
||||
cp ${PROG:=.1} ${DESTDIR}${MAN1_DIR}
|
||||
|
||||
uninstall:
|
||||
cd ${DESTDIR}${BIN_DIR} && rm -f ${PROG}
|
||||
cd ${DESTDIR}${MAN1_DIR} && rm -f ${PROG:=.1}
|
||||
|
||||
clean:
|
||||
rm -f -- *.o xvolkeys
|
||||
|
||||
# ---------------------------------------------------------- dependencies ---
|
||||
|
||||
OBJS = xvolkeys.o
|
||||
|
||||
xvolkeys: ${OBJS}
|
||||
${CC} ${LDFLAGS} ${LIB} -o xvolkeys ${OBJS} ${LDADD}
|
||||
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} ${INCLUDE} ${DEFS} -c $<
|
||||
|
||||
xvolkeys.o: xvolkeys.c
|
|
@ -1,54 +0,0 @@
|
|||
.\" $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.
|
||||
.\"
|
||||
.Dd $Mdocdate$
|
||||
.Dt XVOLKEYS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm xvolkeys
|
||||
.Nd hot-keys in X to control sndiod master volume
|
||||
.Sh SYNOPSIS
|
||||
.Nm xvolkeys
|
||||
.Op Fl D
|
||||
.Op Fl v
|
||||
.Op Fl f Ar device
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
increments or
|
||||
decrements the
|
||||
.Xr sndiod 1
|
||||
master volume whenever the "+" and "-" keys
|
||||
are pressed while the Control and Alt keys are held down.
|
||||
It is meant to be started as background process by
|
||||
.Xr xinit 1
|
||||
or
|
||||
.Xr xdm 1
|
||||
session startup scripts.
|
||||
It exits when X session terminates.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl D
|
||||
Daemonize.
|
||||
.It Fl f Ar device
|
||||
Audio device to control volume of.
|
||||
.It Fl v
|
||||
Increase log verbosity.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sndiod 1
|
||||
.Xr sndio 7
|
|
@ -1,321 +0,0 @@
|
|||
/* $OpenBSD$ */
|
||||
/*
|
||||
* Copyright (c) 2014-2020 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 <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sndio.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
/*
|
||||
* X keysyms to increment / decrement volume: + and -
|
||||
*/
|
||||
#define KEY_INC XK_plus
|
||||
#define KEY_DEC XK_minus
|
||||
|
||||
/*
|
||||
* modifiers: Alt + Ctrl
|
||||
*/
|
||||
#define MODMASK (Mod1Mask | ControlMask)
|
||||
|
||||
/*
|
||||
* volume increment
|
||||
*/
|
||||
#define VOL_INC 9
|
||||
|
||||
char *dev_name;
|
||||
struct pollfd pfds[16];
|
||||
struct sioctl_hdl *hdl;
|
||||
unsigned int output_addr;
|
||||
int output_val, output_maxval;
|
||||
int output_found = 0;
|
||||
int verbose;
|
||||
|
||||
/*
|
||||
* X bits
|
||||
*/
|
||||
Display *dpy;
|
||||
KeyCode inc_code, dec_code;
|
||||
KeySym *inc_map, *dec_map;
|
||||
|
||||
/*
|
||||
* new control
|
||||
*/
|
||||
static void
|
||||
dev_ondesc(void *unused, struct sioctl_desc *desc, int val)
|
||||
{
|
||||
if (desc == NULL)
|
||||
return;
|
||||
if (output_found)
|
||||
return;
|
||||
if (desc->group[0] == 0 &&
|
||||
strcmp(desc->node0.name, "output") == 0 &&
|
||||
strcmp(desc->func, "level") == 0) {
|
||||
output_found = 1;
|
||||
output_addr = desc->addr;
|
||||
output_maxval = desc->maxval;
|
||||
output_val = val;
|
||||
if (verbose)
|
||||
fprintf(stderr, "%s: output at addr %u, value = %u\n",
|
||||
dev_name, output_addr, output_val);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* control value changed
|
||||
*/
|
||||
static void
|
||||
dev_onval(void *unused, unsigned int addr, unsigned int val)
|
||||
{
|
||||
if (addr == output_addr) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "output changed %u -> %u\n", output_val, val);
|
||||
output_val = val;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if there's an error, close connection to sndiod
|
||||
*/
|
||||
static void
|
||||
dev_disconnect(void)
|
||||
{
|
||||
if (!sioctl_eof(hdl))
|
||||
return;
|
||||
if (verbose)
|
||||
fprintf(stderr, "%s: dev device disconnected\n", dev_name);
|
||||
sioctl_close(hdl);
|
||||
hdl = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* connect to sndiod
|
||||
*/
|
||||
static int
|
||||
dev_connect(void)
|
||||
{
|
||||
if (hdl != NULL)
|
||||
return 1;
|
||||
hdl = sioctl_open(dev_name, SIOCTL_READ | SIOCTL_WRITE, 0);
|
||||
if (hdl == NULL) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "%s: couldn't open dev device\n",
|
||||
dev_name);
|
||||
return 0;
|
||||
}
|
||||
output_found = 0;
|
||||
sioctl_ondesc(hdl, dev_ondesc, NULL);
|
||||
sioctl_onval(hdl, dev_onval, NULL);
|
||||
if (!output_found)
|
||||
fprintf(stderr, "%s: warning, couldn't find output control\n",
|
||||
dev_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* send output volume message and to the server
|
||||
*/
|
||||
static void
|
||||
dev_incrvol(int incr)
|
||||
{
|
||||
int vol;
|
||||
|
||||
if (!dev_connect())
|
||||
return;
|
||||
vol = output_val + incr;
|
||||
if (vol > output_maxval)
|
||||
vol = output_maxval;
|
||||
if (vol < 0)
|
||||
vol = 0;
|
||||
if (output_val != (unsigned int)vol) {
|
||||
output_val = vol;
|
||||
if (hdl && output_found) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "%s: setting volume to %d\n",
|
||||
dev_name, vol);
|
||||
}
|
||||
sioctl_setval(hdl, output_addr, output_val);
|
||||
dev_disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* register hot-keys in X
|
||||
*/
|
||||
static void
|
||||
grab_keys(void)
|
||||
{
|
||||
unsigned int i, scr, nscr;
|
||||
int nret;
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "grabbing keys\n");
|
||||
inc_code = XKeysymToKeycode(dpy, KEY_INC);
|
||||
inc_map = XGetKeyboardMapping(dpy, inc_code, 1, &nret);
|
||||
if (nret <= ShiftMask) {
|
||||
fprintf(stderr, "couldn't get keymap for '+' key\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dec_code = XKeysymToKeycode(dpy, KEY_DEC);
|
||||
dec_map = XGetKeyboardMapping(dpy, dec_code, 1, &nret);
|
||||
if (nret <= ShiftMask) {
|
||||
fprintf(stderr, "couldn't get keymap for '-' key\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nscr = ScreenCount(dpy);
|
||||
for (i = 0; i <= 0xff; i++) {
|
||||
if ((i & MODMASK) != 0)
|
||||
continue;
|
||||
for (scr = 0; scr != nscr; scr++) {
|
||||
|
||||
XGrabKey(dpy, inc_code, i | MODMASK,
|
||||
RootWindow(dpy, scr), 1,
|
||||
GrabModeAsync, GrabModeAsync);
|
||||
XGrabKey(dpy, dec_code, i | MODMASK,
|
||||
RootWindow(dpy, scr), 1,
|
||||
GrabModeAsync, GrabModeAsync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* unregister hot-keys
|
||||
*/
|
||||
static void
|
||||
ungrab_keys(void)
|
||||
{
|
||||
unsigned int scr, nscr;
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "ungrabbing keys\n");
|
||||
|
||||
XFree(inc_map);
|
||||
XFree(dec_map);
|
||||
|
||||
nscr = ScreenCount(dpy);
|
||||
for (scr = 0; scr != nscr; scr++)
|
||||
XUngrabKey(dpy, AnyKey, AnyModifier, RootWindow(dpy, scr));
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int scr;
|
||||
XEvent xev;
|
||||
int c, nfds;
|
||||
int background, revents;
|
||||
|
||||
/*
|
||||
* parse command line options
|
||||
*/
|
||||
dev_name = SIO_DEVANY;
|
||||
verbose = 0;
|
||||
background = 0;
|
||||
while ((c = getopt(argc, argv, "Df:q:v")) != -1) {
|
||||
switch (c) {
|
||||
case 'D':
|
||||
background = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'q': /* compat */
|
||||
case 'f':
|
||||
dev_name = optarg;
|
||||
break;
|
||||
default:
|
||||
goto bad_usage;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc > 0) {
|
||||
bad_usage:
|
||||
fprintf(stderr, "usage: xvolkeys [-Dv] [-f device]\n");
|
||||
}
|
||||
|
||||
dpy = XOpenDisplay(NULL);
|
||||
if (dpy == 0) {
|
||||
fprintf(stderr, "Couldn't open display\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* mask non-key events for each screan */
|
||||
for (scr = 0; scr != ScreenCount(dpy); scr++)
|
||||
XSelectInput(dpy, RootWindow(dpy, scr), KeyPress);
|
||||
|
||||
(void)dev_connect();
|
||||
|
||||
grab_keys();
|
||||
|
||||
if (background) {
|
||||
verbose = 0;
|
||||
if (daemon(0, 0) < 0) {
|
||||
perror("daemon");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
while (XPending(dpy)) {
|
||||
XNextEvent(dpy, &xev);
|
||||
if (xev.type == MappingNotify) {
|
||||
if (xev.xmapping.request != MappingKeyboard)
|
||||
continue;
|
||||
if (verbose)
|
||||
fprintf(stderr, "keyboard remapped\n");
|
||||
ungrab_keys();
|
||||
grab_keys();
|
||||
}
|
||||
if (xev.type != KeyPress)
|
||||
continue;
|
||||
if (xev.xkey.keycode == inc_code &&
|
||||
inc_map[xev.xkey.state & ShiftMask] == KEY_INC) {
|
||||
dev_incrvol(VOL_INC);
|
||||
} else if (xev.xkey.keycode == dec_code &&
|
||||
dec_map[xev.xkey.state & ShiftMask] == KEY_DEC) {
|
||||
dev_incrvol(-VOL_INC);
|
||||
}
|
||||
}
|
||||
nfds = (hdl != NULL) ? sioctl_pollfd(hdl, pfds, 0) : 0;
|
||||
pfds[nfds].fd = ConnectionNumber(dpy);
|
||||
pfds[nfds].events = POLLIN;
|
||||
while (poll(pfds, nfds + 1, -1) < 0 && errno == EINTR)
|
||||
; /* nothing */
|
||||
if (hdl) {
|
||||
revents = sioctl_revents(hdl, pfds);
|
||||
if (revents & POLLHUP)
|
||||
dev_disconnect();
|
||||
else if (revents & POLLIN) {
|
||||
/* what */
|
||||
}
|
||||
}
|
||||
}
|
||||
XFree(inc_map);
|
||||
XFree(dec_map);
|
||||
XCloseDisplay(dpy);
|
||||
if (hdl)
|
||||
sioctl_close(hdl);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue