diff --git a/Makefile b/Makefile index d8f3ff0..51e63b3 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ -PROG = dwmst -PREFIX ?= /usr/local +PROG = dwmst +CC = gcc +PREFIX ?= /usr/local +BINPREFIX = ${PREFIX}/bin # MPD, comment if you don't want it #MPDLIB = -lmpdclient @@ -9,24 +11,26 @@ PREFIX ?= /usr/local AUDLIB = `pkg-config --cflags --libs glib-2.0 dbus-glib-1 audclient` AUDFLAG = -DAUD -# Clock, comment if you don't want it -#CLKFLAG = -DCLK - LIBS = -liw -lasound -lX11 -lcanberra ${MPDLIB} ${AUDLIB} CPPFLAGS = ${MPDFLAG} ${AUDFLAG} ${CLKFLAG} -CFLAGS = -Os -Wall -Wextra -pedantic -Wno-format-zero-length -Wno-unused-parameter -Wno-unused-result ${CPPFLAGS} +CFLAGS = -Os -Wall -Wextra ${CPPFLAGS} ${PROG}: ${PROG}.c ${PROG}.h @${CC} ${CFLAGS} ${LIBS} -o ${PROG} ${PROG}.c @strip ${PROG} -clean: - rm -f ${PROG} +debug: CFLAGS += -O0 -g -pedantic +debug: ${PROG} install: - install -Dm755 ${PROG} ${DESTDIR}${PREFIX}/bin/${PROG} + install -Dm755 ${PROG} ${DESTDIR}${BINPREFIX}/${PROG} install -Dm644 ${PROG}.service ${DESTDIR}/usr/lib/systemd/system/${PROG}.service uninstall: - rm -f ${PREFIX}/bin/${PROG} + rm -f ${BINPREFIX}/${PROG} rm -f /usr/lib/systemd/system/${PROG}.service + +clean: + rm -f ${PROG} + +.PHONY: all debug clean install uninstall diff --git a/README.md b/README.md index 64ba6fe..69be587 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,6 @@ ToDo ---- * See if there's a better way to implement wired connection checks * Re-check event sounds +* Code left to clean up: + * MPD; + * Alsa; diff --git a/dwmst.c b/dwmst.c index 874f6ce..b43c694 100644 --- a/dwmst.c +++ b/dwmst.c @@ -7,14 +7,18 @@ int main() { exit(1); } root = XRootWindow(dpy, DefaultScreen(dpy)); - winfo = (struct wireless_info *) calloc(1, sizeof(struct wireless_info)); ca_context_create(&sound); -#ifdef CLK - setlocale(LC_ALL, ""); +#ifdef MPD + conn = mpd_connection_new(NULL, 0, 30000); #endif #ifdef AUD g_type_init(); + connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + session = dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE, AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE); #endif + winfo = (struct wireless_info *) calloc(1, sizeof(struct wireless_info)); + memset(winfo, 0, sizeof(struct wireless_info)); + skfd = iw_sockets_open(); /* MAIN LOOP STARTS HERE */ for (;;) { status[0]='\0'; @@ -22,46 +26,45 @@ int main() { #ifdef MPD if (++musicloops > 10) { musicloops = 0; - struct mpd_connection *conn = mpd_connection_new(NULL, 0, 30000); if (mpd_connection_get_error(conn)) sprintf(musicstring, NO_MPD_STR); mpd_command_list_begin(conn, true); mpd_send_status(conn); mpd_send_current_song(conn); mpd_command_list_end(conn); - struct mpd_status* theStatus = mpd_recv_status(conn); - if (!theStatus) - sprintf(musicstring, NO_MPD_STR); - else { - if (mpd_status_get_state(theStatus) == MPD_STATE_PLAY) { - mpd_response_next(conn); - song = mpd_recv_song(conn); - title = mpd_song_get_tag(song, MPD_TAG_TITLE, 0); - artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0); - sprintf(musicstring, MPD_STR, title, artist); - mpd_song_free(song); - } else if (mpd_status_get_state(theStatus) == MPD_STATE_PAUSE) { - mpd_response_next(conn); - song = mpd_recv_song(conn); - title = mpd_song_get_tag(song, MPD_TAG_TITLE, 0); - artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0); - sprintf(musicstring, MPD_P_STR, title, artist); - mpd_song_free(song); - } else if (mpd_status_get_state(theStatus) == MPD_STATE_STOP) - sprintf(musicstring, MPD_S_STR); - } + mpd_status = mpd_recv_status(conn); + if (!mpd_status) + sprintf(musicstring, NO_MPD_STR); + else { + if (mpd_status_get_state(mpd_status) == MPD_STATE_PLAY) { + mpd_response_next(conn); + song = mpd_recv_song(conn); + title = mpd_song_get_tag(song, MPD_TAG_TITLE, 0); + artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0); + sprintf(musicstring, MPD_STR, title, artist); + mpd_song_free(song); + free(title); + free(artist); + } else if (mpd_status_get_state(mpd_status) == MPD_STATE_PAUSE) { + mpd_response_next(conn); + song = mpd_recv_song(conn); + title = mpd_song_get_tag(song, MPD_TAG_TITLE, 0); + artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0); + sprintf(musicstring, MPD_P_STR, title, artist); + mpd_song_free(song); + free(title); + free(artist); + } else if (mpd_status_get_state(mpd_status) == MPD_STATE_STOP) + sprintf(musicstring, MPD_S_STR); + } mpd_response_finish(conn); - mpd_connection_free(conn); } strcat(status, musicstring); #endif #ifdef AUD if (++musicloops > 10) { musicloops = 0; - connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - session = dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE, AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE); - playpos = audacious_remote_get_playlist_pos(session); - psong = audacious_remote_get_playlist_title(session, playpos); + psong = audacious_remote_get_playlist_title(session, audacious_remote_get_playlist_pos(session)); if (psong) { if (audacious_remote_is_paused(session)) { sprintf(musicstring, MUSIC_P_STR, psong); @@ -69,11 +72,8 @@ int main() { } else if (audacious_remote_is_playing(session)) { sprintf(musicstring, MUSIC_STR, psong); free(psong); - } else - sprintf(musicstring, MUSIC_S_STR); - } else - sprintf(musicstring, MUSIC_S_STR); - g_object_unref(session); + } + } } strcat(status, musicstring); #endif @@ -82,17 +82,15 @@ int main() { if (infile) { sprintf(statnext, SKYPE_STR); fclose(infile); - } else - sprintf(statnext, NO_SKYPE_STR); - strcat(status, statnext); + strcat(status, statnext); + } /* NET */ if (++netloops > 60) { netloops = 0; - if(fopen(NET_FILE, "r")) { + if (fopen(NET_FILE, "r")) { fclose(infile); sprintf(netstring, LAN_STR); } else { - skfd = iw_sockets_open(); if (iw_get_basic_config(skfd, WLAN, &(winfo->b)) > -1) { if (iw_get_stats(skfd, WLAN, &(winfo->stats), &winfo->range, winfo->has_range) >= 0) winfo->has_stats = 1; @@ -102,11 +100,9 @@ int main() { if (winfo->b.essid_on) sprintf(netstring, WLAN_STR, winfo->b.essid, (winfo->stats.qual.qual * 100) / winfo->range.max_qual.qual); else - sprintf(netstring, NO_WLAN_STR); + sprintf(netstring, NO_CON_STR); } } - iw_sockets_close(skfd); - memset(winfo, 0, sizeof(struct wireless_info)); } } strcat(status, netstring); @@ -116,24 +112,24 @@ int main() { snd_mixer_selem_register(handle, NULL, NULL); snd_mixer_load(handle); snd_mixer_selem_id_malloc(&vol_info); - snd_mixer_selem_id_set_name(vol_info, VOL_CH); - pcm_mixer = snd_mixer_find_selem(handle, vol_info); - snd_mixer_selem_get_playback_volume_range(pcm_mixer, &min, &max); /* get volume */ - snd_mixer_selem_get_playback_volume(pcm_mixer, SND_MIXER_SCHN_MONO, &vol); snd_mixer_selem_id_malloc(&mute_info); + snd_mixer_selem_id_set_name(vol_info, VOL_CH); snd_mixer_selem_id_set_name(mute_info, VOL_CH); + pcm_mixer = snd_mixer_find_selem(handle, vol_info); mas_mixer = snd_mixer_find_selem(handle, mute_info); - snd_mixer_selem_get_playback_switch(mas_mixer, SND_MIXER_SCHN_MONO, &mute); /* get mute state */ - if(mute == 0) + snd_mixer_selem_get_playback_volume_range(pcm_mixer, &min, &max); + snd_mixer_selem_get_playback_volume(pcm_mixer, SND_MIXER_SCHN_MONO, &vol); + snd_mixer_selem_get_playback_switch(mas_mixer, SND_MIXER_SCHN_MONO, &mute); + if (!mute) sprintf(statnext, VOL_MUTE_STR); else { realvol = (vol * 100) / max; sprintf(statnext, VOL_STR, realvol); - if(oldvol > 0 && oldvol != realvol) + if (oldvol > 0 && oldvol != realvol) ca_context_play(sound, 0, CA_PROP_APPLICATION_NAME, "Dwmst", CA_PROP_EVENT_ID, "audio-volume-change", CA_PROP_CANBERRA_CACHE_CONTROL, "never", NULL); oldvol = realvol; } - if(vol_info) + if (vol_info) snd_mixer_selem_id_free(vol_info); if (mute_info) snd_mixer_selem_id_free(mute_info); @@ -141,56 +137,45 @@ int main() { snd_mixer_close(handle); strcat(status,statnext); /* Power / Battery */ - infile = fopen(BATT_NOW, "r"); - fscanf(infile, "%ld\n", &now); fclose(infile); - infile = fopen(BATT_FULL, "r"); - fscanf(infile, "%ld\n", &full); fclose(infile); - infile = fopen(BATT_STAT, "r"); - fscanf(infile, "%s\n", state); fclose(infile); - infile = fopen(BATT_VOLT, "r"); - fscanf(infile, "%ld\n", &voltage); fclose(infile); - infile = fopen(BATT_CNOW, "r"); - fscanf(infile, "%ld\n", &rate); fclose(infile); - now = ((float)voltage / 1000) * ((float)now / 1000); - full = ((float)voltage / 1000) * ((float)full / 1000); - rate = ((float)voltage / 1000) * ((float)rate / 1000); + infile = fopen(BATT_NOW, "r"); fscanf(infile, "%ld\n", &now); fclose(infile); + infile = fopen(BATT_FULL, "r"); fscanf(infile, "%ld\n", &full); fclose(infile); + infile = fopen(BATT_STAT, "r"); fscanf(infile, "%s\n", state); fclose(infile); + infile = fopen(BATT_VOLT, "r"); fscanf(infile, "%ld\n", &voltage); fclose(infile); + infile = fopen(BATT_CNOW, "r"); fscanf(infile, "%ld\n", &rate); fclose(infile); + now = ((float)voltage * (float)now); + full = ((float)voltage * (float)full); + rate = ((float)voltage * (float)rate); perc = (now * 100) / full; if (strncmp(state, "Full", 8) == 0) - sprintf(statnext, BAT_FULL_STR, perc); - else if(strncmp(state, "Unknown", 8) == 0) + sprintf(statnext, BAT_FULL_STR); + else if (strncmp(state, "Unknown", 8) == 0) sprintf(statnext, BAT_UNK_STR); - else if (strncmp(state, "Charging", 8) == 0) { - seconds = 3600 * (((float)full - (float)now) / (float)rate); - hours = seconds / 3600; - seconds -= 3600 * hours; - minutes = seconds / 60; - seconds -= 60 * minutes; - sprintf(statnext, BAT_CHRG_STR, perc, hours, minutes); - warning = 0; - } else { - seconds = 3600 * ((float)now / (float)rate); + else { + if (strncmp(state, "Charging", 8) == 0) + seconds = 3600 * (((float)full - (float)now) / (float)rate); + else + seconds = 3600 * ((float)now / (float)rate); hours = seconds / 3600; seconds -= 3600 * hours; minutes = seconds / 60; seconds -= 60 * minutes; - if (perc < BAT_LOW_P || minutes < BAT_LOW_T) { - sprintf(statnext, BAT_LOW_STR, perc, hours, minutes); - if(!warning) { - ca_context_play(sound, 0, CA_PROP_APPLICATION_NAME, "Dwmst", CA_PROP_EVENT_ID, "suspend-error", CA_PROP_CANBERRA_CACHE_CONTROL, "never", NULL); - warning = 1; - } - } else { - sprintf(statnext, BAT_STR, perc, hours, minutes); + if (strncmp(state, "Charging", 8) == 0) { + sprintf(statnext, BAT_CHRG_STR, perc, hours, minutes); warning = 0; + } else { + if (perc < BAT_LOW_P || minutes < BAT_LOW_T) { + sprintf(statnext, BAT_LOW_STR, perc, hours, minutes); + if (!warning) { + ca_context_play(sound, 0, CA_PROP_APPLICATION_NAME, "Dwmst", CA_PROP_EVENT_ID, "suspend-error", CA_PROP_CANBERRA_CACHE_CONTROL, "never", NULL); + warning = 1; + } + } else { + sprintf(statnext, BAT_STR, perc, hours, minutes); + warning = 0; + } } } - hours = minutes = seconds = 0; strcat(status, statnext); -#ifdef CLK - time(¤t); - strftime(statnext, 38, DATE_TIME_STR, localtime(¤t)); - strcat(status, statnext); -#endif /* Set root name */ XStoreName(dpy, root, status); XFlush(dpy); @@ -199,5 +184,13 @@ int main() { /* NEXT LINES SHOULD NEVER EXECUTE, only here to satisfy Trilby's O.C.D. ;) */ XCloseDisplay(dpy); ca_context_destroy(sound); +#ifdef MPD + mpd_connection_free(conn); +#endif +#ifdef AUD + dbus_g_connection_unref(connection); + g_object_unref(session); +#endif + iw_sockets_close(skfd); return 0; } diff --git a/dwmst.h b/dwmst.h index 4f293ed..7093610 100644 --- a/dwmst.h +++ b/dwmst.h @@ -2,14 +2,10 @@ #include #include #include -#include #include #include #include #include -#ifdef CLK -#include -#endif #ifdef MPD #include #endif @@ -20,18 +16,18 @@ #define LAN "enp3s0" /* Wired interface */ #define WLAN "wlp5s0" /* Wireless interface */ -#define BAT_LOW_P 11 /* Below BATT_LOW percentage left on battery, the battery display turns red */ +#define BAT_LOW_P 11 /* Below BAT_LOW percentage left on battery, the battery display turns red */ #define BAT_LOW_T 3 /* Same as above, but now minutes instead of percentage */ #define INTERVAL 1 /* Sleeps for INTERVAL seconds between updates */ #define VOL_CH "Master" /* Channel to watch for volume */ /* Files read for system info: */ #define SKYPE_FILE "/home/jente/.Skype/jente_etnej/main.lock" +#define NET_FILE "/sys/class/net/LAN/carrier" #define BATT_NOW "/sys/class/power_supply/BAT0/charge_now" #define BATT_FULL "/sys/class/power_supply/BAT0/charge_full" #define BATT_STAT "/sys/class/power_supply/BAT0/status" #define BATT_VOLT "/sys/class/power_supply/BAT0/voltage_now" #define BATT_CNOW "/sys/class/power_supply/BAT0/current_now" -#define NET_FILE "/sys/class/net/LAN/carrier" /* Display format strings. Defaults make extensive use of escape characters for colors which require colorstatus patch. */ #ifdef MPD #define MPD_STR "\x02%s \x01 - \x02 %s " /* MPD, playing */ @@ -45,41 +41,35 @@ #define MUSIC_S_STR "" /* Music, stopped */ #endif #define SKYPE_STR "\x02Skype \x01" /* Skype is running */ -#define NO_SKYPE_STR "" /* Skype is not running */ #define LAN_STR "Verbonden \x01" /* LAN */ #define WLAN_STR "%s \x02%d%% \x01" /* WLAN */ -#define NO_WLAN_STR "Geen verbinding \x01" /* WLAN, no connection */ +#define NO_CON_STR "Geen verbinding \x01" /* WLAN, no connection */ #define VOL_STR "Volume \x02%d%% \x01" /* Volume */ #define VOL_MUTE_STR "Volume \x02M \x01" /* Volume, muted */ -#define BAT_FULL_STR "Batterij\x02 F %d%% " /* Battery, full */ +#define BAT_FULL_STR "Batterij\x02 F " /* Battery, full */ #define BAT_STR "Batterij\x02 D %d%%\x01, \x02%02d:%02d resterend " /* Battery, discharging, above BATT_LOW percentage */ #define BAT_LOW_STR "Batterij\x02 D %d%%\x01, \x02%02d:%02d resterend " /* Battery, discharging, below BATT_LOW percentage */ #define BAT_CHRG_STR "Batterij\x02 C %d%%\x01, \x02%02d:%02d tot opgeladen " /* Battery, AC */ #define BAT_UNK_STR "Batterij\x02 U " /* Battery, unknown */ -#ifdef CLK -#define DATE_TIME_STR "\x01 %a \x02%d \x01%b,\x02 %H:%M" /* This is a strftime format string which is passed localtime */ -#endif Display *dpy; Window root; FILE *infile; ca_context *sound; -int warning, perc, hours, minutes, seconds = -1, skfd, mute = 0, oldvol = -1, realvol = 0, netloops = 60, musicloops = 10; -long now = -1, full = -1, voltage = -1, rate = -1, vol = 0, max = 0, min = 0; char state[8], statnext[100], status[200], netstring[30], musicstring[100]; +long now = -1, full = -1, voltage = -1, rate = -1, vol = 0, max = 0, min = 0; +int warning, perc, hours, minutes, seconds = -1, skfd, mute = 0, oldvol = -1, realvol = 0, netloops = 60, musicloops = 10; struct wireless_info *winfo; snd_mixer_t *handle; snd_mixer_elem_t *pcm_mixer, *mas_mixer; snd_mixer_selem_id_t *vol_info, *mute_info; -#ifdef CLK -time_t current; -#endif #ifdef MPD struct mpd_song *song = NULL; +struct mpd_connection *conn = NULL; +struct mpd_status *mpd_status = NULL; const char *title = NULL, *artist = NULL; #endif #ifdef AUD -int playpos; char *psong = NULL; DBusGProxy *session = NULL; DBusGConnection *connection = NULL;