# HG changeset patch # Date 1353796988 -7200 # User Barbu Paul - Gheorghe # Parent 9cace08dcb7e57f76a2206bada6fc3b9557c63dc Control MPD via keybinds diff -r 9cace08dcb7e Makefile --- a/Makefile Sun Nov 18 17:52:42 2012 +0100 +++ b/Makefile Sun Nov 25 00:43:08 2012 +0200 @@ -18,7 +18,7 @@ @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: config.h config.mk +${OBJ}: config.h config.mk mpdcontrol.c config.h: @echo creating $@ from config.def.h diff -r 9cace08dcb7e config.def.h --- a/config.def.h Sun Nov 18 17:52:42 2012 +0100 +++ b/config.def.h Sun Nov 25 00:43:08 2012 +0200 @@ -53,6 +53,8 @@ static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; static const char *termcmd[] = { "uxterm", NULL }; +#include "mpdcontrol.c" + static Key keys[] = { /* modifier key function argument */ { MODKEY, XK_p, spawn, {.v = dmenucmd } }, @@ -88,6 +90,9 @@ TAGKEYS( XK_8, 7) TAGKEYS( XK_9, 8) { MODKEY|ShiftMask, XK_q, quit, {0} }, + { MODKEY, XK_F1, mpdchange, {.i = -1} }, + { MODKEY, XK_F2, mpdchange, {.i = +1} }, + { MODKEY, XK_Escape, mpdcontrol, {0} }, }; /* button definitions */ diff -r 9cace08dcb7e config.mk --- a/config.mk Sun Nov 18 17:52:42 2012 +0100 +++ b/config.mk Sun Nov 25 00:43:08 2012 +0200 @@ -16,7 +16,7 @@ # includes and libs INCS = -I${X11INC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -lmpdclient # flags CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff -r 9cace08dcb7e mpdcontrol.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpdcontrol.c Sun Nov 25 00:43:08 2012 +0200 @@ -0,0 +1,140 @@ +#include +#include +#include +#include + +#include + +#define MPDHOST "localhost" +#define MPDPORT 6600 + +struct mpd_connection *get_conn(){ + struct mpd_connection *conn; + + conn = mpd_connection_new(MPDHOST, MPDPORT, 1000); + + if(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS){ + fprintf(stderr, "Could not connect to mpd: %s\n", mpd_connection_get_error_message(conn)); + + mpd_connection_free(conn); + return NULL; + } + + return conn; +} + +void mpdchange(const Arg *direction){ + struct mpd_connection *conn; + + conn = get_conn(); + + if(conn == NULL){ + return; + } + + if(direction->i > 0){ + mpd_run_next(conn); + } + else{ + mpd_run_previous(conn); + } + + mpd_connection_free(conn); +} + +char *get_regerror(int errcode, regex_t *compiled){ + size_t length = regerror(errcode, compiled, NULL, 0); + char *buffer = malloc(length); + (void) regerror(errcode, compiled, buffer, length); + + return buffer; +} + +void mpdcontrol(){ + struct mpd_connection *conn; + struct mpd_status *status; + struct mpd_song *song; + enum mpd_state state; + + const char *filename; + + regex_t expr; + + conn = get_conn(); + + if(conn == NULL){ + return; + } + + status = mpd_run_status(conn); + + if(status == NULL){ + fprintf(stderr, "Could not get mpd status: %s\n", mpd_status_get_error(status)); + + mpd_status_free(status); + mpd_connection_free(conn); + return; + } + + state = mpd_status_get_state(status); + + if(state == MPD_STATE_STOP || state == MPD_STATE_PAUSE){ + mpd_run_play(conn); + mpd_status_free(status); + mpd_connection_free(conn); + } + else if(state != MPD_STATE_UNKNOWN){ //playing some music + song = mpd_run_current_song(conn); + + if(song == NULL){ + fprintf(stderr, "Error fetching current song!\n"); + + mpd_song_free(song); + mpd_status_free(status); + mpd_connection_free(conn); + return; + } + + filename = mpd_song_get_uri(song); + + int errcode = regcomp(&expr, "^[[:alnum:]]+://", REG_EXTENDED|REG_NOSUB); + if(errcode != 0){ + char *err = get_regerror(errcode, &expr); + fprintf(stderr, "Could not compile regexp: %s\n", err); + + mpd_song_free(song); + mpd_status_free(status); + mpd_connection_free(conn); + free(err); + regfree(&expr); + return; + } + + int matchcode = regexec(&expr, filename, 0, NULL, 0); + + if(matchcode == 0){ + if(strstr(filename, "file://") == filename){ //match just at the start of the filename + //this means that mpd is playing a file outside the music_dir, + //but on disk, so we can safely pause + mpd_run_toggle_pause(conn); + } + else{ + mpd_run_stop(conn); + } + } + else if(matchcode == REG_NOMATCH){ + mpd_run_toggle_pause(conn); + } + else{ + char *err = get_regerror(matchcode, &expr); + fprintf(stderr, "Error while matching regexp: %s\n", err); + + free(err); + } + + regfree(&expr); + mpd_song_free(song); + mpd_status_free(status); + mpd_connection_free(conn); + } +}