dwm-r1615-mpdcontrol.diff (5560B)
1 # HG changeset patch 2 # Date 1353796988 -7200 3 # User Barbu Paul - Gheorghe <barbu.paul.gheorghe@gmail.com> 4 # Parent 9cace08dcb7e57f76a2206bada6fc3b9557c63dc 5 Control MPD via keybinds 6 7 diff -r 9cace08dcb7e Makefile 8 --- a/Makefile Sun Nov 18 17:52:42 2012 +0100 9 +++ b/Makefile Sun Nov 25 00:43:08 2012 +0200 10 @@ -18,7 +18,7 @@ 11 @echo CC $< 12 @${CC} -c ${CFLAGS} $< 13 14 -${OBJ}: config.h config.mk 15 +${OBJ}: config.h config.mk mpdcontrol.c 16 17 config.h: 18 @echo creating $@ from config.def.h 19 diff -r 9cace08dcb7e config.def.h 20 --- a/config.def.h Sun Nov 18 17:52:42 2012 +0100 21 +++ b/config.def.h Sun Nov 25 00:43:08 2012 +0200 22 @@ -53,6 +53,8 @@ 23 static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; 24 static const char *termcmd[] = { "uxterm", NULL }; 25 26 +#include "mpdcontrol.c" 27 + 28 static Key keys[] = { 29 /* modifier key function argument */ 30 { MODKEY, XK_p, spawn, {.v = dmenucmd } }, 31 @@ -88,6 +90,9 @@ 32 TAGKEYS( XK_8, 7) 33 TAGKEYS( XK_9, 8) 34 { MODKEY|ShiftMask, XK_q, quit, {0} }, 35 + { MODKEY, XK_F1, mpdchange, {.i = -1} }, 36 + { MODKEY, XK_F2, mpdchange, {.i = +1} }, 37 + { MODKEY, XK_Escape, mpdcontrol, {0} }, 38 }; 39 40 /* button definitions */ 41 diff -r 9cace08dcb7e config.mk 42 --- a/config.mk Sun Nov 18 17:52:42 2012 +0100 43 +++ b/config.mk Sun Nov 25 00:43:08 2012 +0200 44 @@ -16,7 +16,7 @@ 45 46 # includes and libs 47 INCS = -I${X11INC} 48 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} 49 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -lmpdclient 50 51 # flags 52 CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} 53 diff -r 9cace08dcb7e mpdcontrol.c 54 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55 +++ b/mpdcontrol.c Sun Nov 25 00:43:08 2012 +0200 56 @@ -0,0 +1,140 @@ 57 +#include <stdlib.h> 58 +#include <string.h> 59 +#include <stdio.h> 60 +#include <regex.h> 61 + 62 +#include <mpd/client.h> 63 + 64 +#define MPDHOST "localhost" 65 +#define MPDPORT 6600 66 + 67 +struct mpd_connection *get_conn(){ 68 + struct mpd_connection *conn; 69 + 70 + conn = mpd_connection_new(MPDHOST, MPDPORT, 1000); 71 + 72 + if(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS){ 73 + fprintf(stderr, "Could not connect to mpd: %s\n", mpd_connection_get_error_message(conn)); 74 + 75 + mpd_connection_free(conn); 76 + return NULL; 77 + } 78 + 79 + return conn; 80 +} 81 + 82 +void mpdchange(const Arg *direction){ 83 + struct mpd_connection *conn; 84 + 85 + conn = get_conn(); 86 + 87 + if(conn == NULL){ 88 + return; 89 + } 90 + 91 + if(direction->i > 0){ 92 + mpd_run_next(conn); 93 + } 94 + else{ 95 + mpd_run_previous(conn); 96 + } 97 + 98 + mpd_connection_free(conn); 99 +} 100 + 101 +char *get_regerror(int errcode, regex_t *compiled){ 102 + size_t length = regerror(errcode, compiled, NULL, 0); 103 + char *buffer = malloc(length); 104 + (void) regerror(errcode, compiled, buffer, length); 105 + 106 + return buffer; 107 +} 108 + 109 +void mpdcontrol(){ 110 + struct mpd_connection *conn; 111 + struct mpd_status *status; 112 + struct mpd_song *song; 113 + enum mpd_state state; 114 + 115 + const char *filename; 116 + 117 + regex_t expr; 118 + 119 + conn = get_conn(); 120 + 121 + if(conn == NULL){ 122 + return; 123 + } 124 + 125 + status = mpd_run_status(conn); 126 + 127 + if(status == NULL){ 128 + fprintf(stderr, "Could not get mpd status: %s\n", mpd_status_get_error(status)); 129 + 130 + mpd_status_free(status); 131 + mpd_connection_free(conn); 132 + return; 133 + } 134 + 135 + state = mpd_status_get_state(status); 136 + 137 + if(state == MPD_STATE_STOP || state == MPD_STATE_PAUSE){ 138 + mpd_run_play(conn); 139 + mpd_status_free(status); 140 + mpd_connection_free(conn); 141 + } 142 + else if(state != MPD_STATE_UNKNOWN){ //playing some music 143 + song = mpd_run_current_song(conn); 144 + 145 + if(song == NULL){ 146 + fprintf(stderr, "Error fetching current song!\n"); 147 + 148 + mpd_song_free(song); 149 + mpd_status_free(status); 150 + mpd_connection_free(conn); 151 + return; 152 + } 153 + 154 + filename = mpd_song_get_uri(song); 155 + 156 + int errcode = regcomp(&expr, "^[[:alnum:]]+://", REG_EXTENDED|REG_NOSUB); 157 + if(errcode != 0){ 158 + char *err = get_regerror(errcode, &expr); 159 + fprintf(stderr, "Could not compile regexp: %s\n", err); 160 + 161 + mpd_song_free(song); 162 + mpd_status_free(status); 163 + mpd_connection_free(conn); 164 + free(err); 165 + regfree(&expr); 166 + return; 167 + } 168 + 169 + int matchcode = regexec(&expr, filename, 0, NULL, 0); 170 + 171 + if(matchcode == 0){ 172 + if(strstr(filename, "file://") == filename){ //match just at the start of the filename 173 + //this means that mpd is playing a file outside the music_dir, 174 + //but on disk, so we can safely pause 175 + mpd_run_toggle_pause(conn); 176 + } 177 + else{ 178 + mpd_run_stop(conn); 179 + } 180 + } 181 + else if(matchcode == REG_NOMATCH){ 182 + mpd_run_toggle_pause(conn); 183 + } 184 + else{ 185 + char *err = get_regerror(matchcode, &expr); 186 + fprintf(stderr, "Error while matching regexp: %s\n", err); 187 + 188 + free(err); 189 + } 190 + 191 + regfree(&expr); 192 + mpd_song_free(song); 193 + mpd_status_free(status); 194 + mpd_connection_free(conn); 195 + } 196 +}