sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | 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 +}