Created
April 9, 2010 23:54
-
-
Save oneman/361712 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
xmms2-gnome-mediakeys-listener.c | |
this xmms2 client connects to the gnome settings daemon | |
which broadcast out a dbus signal when those prev, play/pause, next keys are hit on your keyboard | |
this listens for those signals and tells xmms2 to do something via simple command line | |
2010 rawdod / oneman / drr | |
to compile do it like this: | |
gcc -Wall -g -ldbus-1 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -o xmms2-gnome-mediakeys-listener xmms2-gnome-mediakeys-listener.c | |
*/ | |
#include <dbus/dbus.h> | |
#include <stdbool.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
void handle_signal(char *command) { | |
/* printf("%s\n", command); */ | |
if (strcmp("Next", command) == 0) { | |
system("xmms2 next"); | |
} | |
if (strcmp("Previous", command) == 0) { | |
system("xmms2 prev"); | |
} | |
if (strcmp("Play", command) == 0) { | |
system("xmms2 toggleplay"); | |
} | |
} | |
/** | |
* Listens for signals on the bus | |
*/ | |
void receive() | |
{ | |
DBusMessage* msg; | |
DBusMessageIter args; | |
DBusConnection* conn; | |
DBusError err; | |
int ret; | |
char* sigvalue; | |
printf("Listening for signals from gnome settings daemon :D \n"); | |
// initialise the errors | |
dbus_error_init(&err); | |
// connect to the bus and check for errors | |
conn = dbus_bus_get(DBUS_BUS_SESSION, &err); | |
if (dbus_error_is_set(&err)) { | |
fprintf(stderr, "Connection Error (%s)\n", err.message); | |
dbus_error_free(&err); | |
} | |
if (NULL == conn) { | |
exit(1); | |
} | |
// request our name on the bus and check for errors | |
ret = dbus_bus_request_name(conn, "test.signal.sink", DBUS_NAME_FLAG_REPLACE_EXISTING , &err); | |
if (dbus_error_is_set(&err)) { | |
fprintf(stderr, "Name Error (%s)\n", err.message); | |
dbus_error_free(&err); | |
} | |
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { | |
exit(1); | |
} | |
// add a rule for which messages we want to see | |
dbus_bus_add_match(conn, "type='signal',interface='org.gnome.SettingsDaemon.MediaKeys'", &err); // see signals from the given interface | |
dbus_connection_flush(conn); | |
if (dbus_error_is_set(&err)) { | |
fprintf(stderr, "Match Error (%s)\n", err.message); | |
exit(1); | |
} | |
//printf("Match rule sent\n"); | |
// loop listening for signals being emmitted | |
while (true) { | |
// non blocking read of the next available message | |
dbus_connection_read_write(conn, 0); | |
msg = dbus_connection_pop_message(conn); | |
// loop again if we haven't read a message | |
if (NULL == msg) { | |
usleep(250000); | |
continue; | |
} | |
// check if the message is a signal from the correct interface and with the correct name | |
if (dbus_message_is_signal(msg, "org.gnome.SettingsDaemon.MediaKeys", "MediaPlayerKeyPressed")) { | |
// read the parameters | |
if (!dbus_message_iter_init(msg, &args)) | |
fprintf(stderr, "Message Has No Parameters\n"); | |
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) | |
fprintf(stderr, "Argument is not string!\n"); | |
else | |
/* gnome sends out two strings banshee-1 and then the command for whatever reason */ | |
dbus_message_iter_get_basic(&args, &sigvalue); | |
handle_signal(sigvalue); | |
dbus_message_iter_next(&args); | |
dbus_message_iter_get_basic(&args, &sigvalue); | |
handle_signal(sigvalue); | |
} | |
// free the message | |
dbus_message_unref(msg); | |
} | |
} | |
int main(int argc, char** argv) | |
{ | |
receive(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment