dwm-r1615-mpdcontrol.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       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 +}