[PATCH - amixer] listen to D-Bus for volume-up, volume-down and mute signals.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux