The patch introduces D-Bus support in amixer. With --dbus option given amixerworks continiously (like with the --stdin) waiting fororg.freedesktop.Hal.Device.Condition with the first argument "ButtonPressed"and the second being one of: "volume-up", "volume-down" and "mute". Theseare emmited by the HAL input helper. A single amixer process can controllone mixer item. There are options to choose a specific item to controll,an input device to listen and a single adjustment step size. Signed-off-by: Łukasz Stelmach <stlman@xxxxxxxxx>--- amixer/Makefile.am | 3 +- amixer/amixer.1 | 18 ++++++ amixer/amixer.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.in | 12 ++++ 4 files changed, 203 insertions(+), 1 deletions(-) diff --git a/amixer/Makefile.am b/amixer/Makefile.amindex fcd0e81..fa951a6 100644--- a/amixer/Makefile.am+++ b/amixer/Makefile.am@@ -1,5 +1,6 @@ INCLUDES = -I$(top_srcdir)/include-LDADD = -lm+LDADD = -lm @DBUS_LIBS@+CFLAGS += @DBUS_CFLAGS@ # LDFLAGS = -static # CFLAGS += -g -Wall diff --git a/amixer/amixer.1 b/amixer/amixer.1index b1ac323..bc160be 100644--- a/amixer/amixer.1+++ b/amixer/amixer.1@@ -88,6 +88,24 @@ Select the card number to control. The device name created from this parameter has syntax 'hw:N' where N is specified card number. .TP+\fI\-\-dbus[=\fISCONTROL\fP]++Connect to system D-Bus and wait for \fIorg.freedesktop.Hal.Device.Condition\fP+signals with ButtonPressed as the first argument and one of: \fIvolume-up\fP,+\fIvolume-down\fP or \fImute\fP as the second one. Control the selected+\fISCONTROL\fP item. The default item is 'Master,0'.++.TP+\fI\-\-dbus-path=<\fIUDI\fP>++Choose a particular input device that emits control events.++.TP+\fI\-\-dbus-step=<\fIN\fP>++Set an amount by wich to increase or decrease volume upon event.++.TP \fI\-D\fP device Select the device name to control. The default control name is 'default'.diff --git a/amixer/amixer.c b/amixer/amixer.cindex 9620721..31de674 100644--- a/amixer/amixer.c+++ b/amixer/amixer.c@@ -18,6 +18,8 @@ * */ +#include "aconfig.h"+ #include <stdio.h> #include <stdlib.h> #include <string.h>@@ -31,6 +33,10 @@ #include <sys/poll.h> #include "amixer.h" +#ifdef HAVE_DBUS+#include <dbus/dbus.h>+#endif /* HAVE_DBUS */+ #define LEVEL_BASIC (1<<0) #define LEVEL_INACTIVE (1<<1) #define LEVEL_ID (1<<2)@@ -43,6 +49,12 @@ static int ignore_error = 0; static struct snd_mixer_selem_regopt smixer_options; static char card[64] = "default"; +#ifdef HAVE_DBUS+static char dbus_sctl[64] = "Master,0";+static char *dbus_path = NULL;+static char dbus_step[8] = "1";+#endif /* HAVE_DBUS */+ static void error(const char *fmt,...) { va_list va;@@ -60,6 +72,11 @@ static int help(void) printf("\nAvailable options:\n"); printf(" -h,--help this help\n"); printf(" -c,--card N select the card\n");+#ifdef HAVE_DBUS+ printf(" --dbus[=sID] Connect to the system D-Bus and wait for volume messages\n");+ printf(" --dbus-path UDI Choose a particular input device (udi)\n");+ printf(" --dbus-step N Set the step size (default: 1)\n");+#endif /* HAVE_DBUS */ printf(" -D,--device N select the device, default '%s'\n", card); printf(" -d,--debug debug mode\n"); printf(" -n,--nocheck do not perform range checking\n");@@ -1887,15 +1904,147 @@ static int exec_stdin(void) return 0; } +#ifdef HAVE_DBUS++#define OPT_DBUS 0x81+#define OPT_DBUS_PATH 0x82+#define OPT_DBUS_STEP 0x83++void* get_dbus_arg(DBusMessageIter* args, int type, void** out) {+ if (type != dbus_message_iter_get_arg_type(args))+ return NULL;+ dbus_message_iter_get_basic(args, out);+ dbus_message_iter_next(args);+ return *out;+}++int exec_dbus(void)+{+ char *sargv[MAX_ARGS];+ int sargc;+ const char* s;+ int stepl;+ DBusError error;+ DBusMessage* msg;+ DBusConnection *conn;+ DBusMessageIter args;++ stepl = strlen(dbus_step);+ dbus_step[stepl+1] = '\0';++ dbus_error_init (&error);+ conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error);++ if(!conn) {+ fprintf(stderr, "dbus:%s: %s\n",+ error.name, error.message);+ return 1;+ }++ dbus_bus_add_match(conn,+ "type='signal',"+ "interface='org.freedesktop.Hal.Device',"+ "member='Condition'",+ &error);+ /* The first message is a NameOwnerChanged signal, ignore it. */+ msg = dbus_connection_pop_message(conn);+ dbus_message_unref(msg);++ if(dbus_error_is_set(&error)) {+ fprintf(stderr, "dbus:match error:%s\n",+ error.message);+ return 1;+ }++ while (1) {+ sargv[0] = dbus_sctl; sargc = 1;++ if (!(msg = dbus_connection_pop_message(conn))) {+ dbus_connection_read_write(conn, -1);+ continue;+ }++ s = dbus_message_get_interface(msg);+ if(strncmp("org.freedesktop.Hal.Device", s, 26)) {+ if(debugflag)+ fprintf(stderr, "dbus:unsupported interface:%s\n", s);+ goto badmessage;+ }++ if(dbus_path &&+ (s=dbus_message_get_path(msg)) &&+ strncmp(dbus_path, s, strlen(s))) {+ if(debugflag)+ fprintf(stderr, "dbus:not the selected udi:%s\n", s);+ goto badmessage;+ }++ if(!dbus_message_iter_init(msg, &args)) {+ if(debugflag)+ fprintf(stderr, "dbus:message has no arguments\n");+ goto badmessage;+ }++ if (strncmp(get_dbus_arg(&args, DBUS_TYPE_STRING, (void*)&s), "ButtonPressed", 13)) {+ if(debugflag)+ fprintf(stderr, "dbus:not a ButtonPressed event\n");+ goto badmessage;+ }++ if (!get_dbus_arg(&args, DBUS_TYPE_STRING, (void*)&s)) {+ if(debugflag)+ fprintf(stderr, "dbus:invalid argument type\n");+ goto badmessage;+ }++ /* static int sset(unsigned int argc, char *argv[], int roflag, int keep_handle) */+ if (!strncmp(s, "volume-up", 9)) {+ if(debugflag)+ fprintf(stderr, "dbus:volume-up\n");+ dbus_step[stepl]='+';+ sargv[1] = dbus_step;+ } else if (!strncmp(s, "volume-down", 11)) {+ if(debugflag)+ fprintf(stderr, "dbus:volume-down\n");+ dbus_step[stepl]='-';+ sargv[1] = dbus_step;+ } else if (!strncmp(s, "mute", 4)) {+ if(debugflag)+ fprintf(stderr, "dbus:mute (toggle)\n");+ sargv[1] = "toggle";+ } else {+ if(debugflag)+ fprintf(stderr, "dbus:invalid argument value\n");+ goto badmessage;+ }+ sset(++sargc, sargv, 0, 1);+badmessage:+ dbus_message_unref(msg);+ }++ if(conn)+ dbus_connection_unref(conn);+ return 0;+}+#endif /* HAVE_DBUS */ int main(int argc, char *argv[]) { int morehelp, level = 0; int read_stdin = 0;+#ifdef HAVE_DBUS+ int read_dbus = 0;+ int t;+#endif /* HAVE_DBUS */ static const struct option long_option[] = { {"help", 0, NULL, 'h'}, {"card", 1, NULL, 'c'},+#ifdef HAVE_DBUS+ {"dbus", optional_argument, NULL, OPT_DBUS},+ {"dbus-path", 1, NULL, OPT_DBUS_PATH},+ {"dbus-step", 1, NULL, OPT_DBUS_STEP},+#endif /* HAVE_DBUS */ {"device", 1, NULL, 'D'}, {"quiet", 0, NULL, 'q'}, {"inactive", 0, NULL, 'i'},@@ -1964,6 +2113,24 @@ int main(int argc, char *argv[]) case 's': read_stdin = 1; break;+#ifdef HAVE_DBUS+ case OPT_DBUS:+ if(optarg) {+ strncpy(dbus_sctl, optarg, sizeof(dbus_sctl)-1);+ dbus_sctl[sizeof(dbus_sctl)-1] = '\0';+ }+ read_dbus = 1;+ break;+ case OPT_DBUS_PATH:+ dbus_path=optarg;+ break;+ case OPT_DBUS_STEP:+ t=atoi(optarg);+ if(t > 0 && t <= 999999) {+ snprintf(dbus_step, sizeof(dbus_step), "%d", atoi(optarg));+ }+ break;+#endif /* HAVE_DBUS */ default: fprintf(stderr, "Invalid switch or option needs an argument.\n"); morehelp++;@@ -1978,6 +2145,10 @@ int main(int argc, char *argv[]) if (read_stdin) return exec_stdin(); +#ifdef HAVE_DBUS+ if(read_dbus)+ return exec_dbus();+#endif /* HAVE_DBUS */ if (argc - optind <= 0) { return selems(LEVEL_BASIC | level) ? 1 : 0; }diff --git a/configure.in b/configure.inindex 1349ff3..717d6c5 100644--- a/configure.in+++ b/configure.in@@ -7,6 +7,9 @@ AM_INIT_AUTOMAKE(alsa-utils, 1.0.20) AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.15]) +dnl required versions of other packages+m4_define([dbus_required_version], [1.2.0])+ dnl Checks for programs. dnl try to gues cross-compiler if not set@@ -74,6 +77,15 @@ AC_ARG_ENABLE(alsamixer, no) alsamixer=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-alsamixer) ;; esac],[alsamixer=true])+AC_ARG_WITH(dbus, [ --with-dbus Enable D-Bus support in amixer])+ if test "x$with_dbus" != xno; then+ PKG_CHECK_MODULES(DBUS, dbus-1 >= dbus_required_version,+ have_dbus=yes,+ have_dbus=no)+ fi+ if test "x$have_dbus" = xyes; then+ AC_DEFINE(HAVE_DBUS, 1, [Define to 1 if amixer is to support D-Bus])+ fi fi AM_CONDITIONAL(ALSAMIXER, test x$alsamixer = xtrue) -- 1.6.3.3 ----------------------------------------------------------------------Zostan Dziewczyna lub Chlopakiem lata!Wygraj skuter >> http://link.interia.pl/f22a7 _______________________________________________Alsa-devel mailing listAlsa-devel@xxxxxxxxxxxxxxxxxxxx://mailman.alsa-project.org/mailman/listinfo/alsa-devel