From 0e71af11a27631e45c0160842e4498507420eff0 Mon Sep 17 00:00:00 2001 From: stkhan Date: Fri, 31 Mar 2023 19:42:29 -0500 Subject: bar and blocks --- wm/someblocks/CHANGELOG.md | 6 ++ wm/someblocks/LICENSE | 8 ++ wm/someblocks/Makefile | 20 ++++ wm/someblocks/README.md | 19 ++++ wm/someblocks/blocks.def.h | 11 ++ wm/someblocks/blocks.h | 15 +++ wm/someblocks/dwmblocks-battery | 21 ++++ wm/someblocks/dwmblocks-brightness | 6 ++ wm/someblocks/dwmblocks-du | 5 + wm/someblocks/dwmblocks-forecast | 18 ++++ wm/someblocks/dwmblocks-mpc | 6 ++ wm/someblocks/dwmblocks-volume | 13 +++ wm/someblocks/someblocks | Bin 0 -> 17408 bytes wm/someblocks/someblocks.1 | 22 ++++ wm/someblocks/someblocks.c | 215 +++++++++++++++++++++++++++++++++++++ 15 files changed, 385 insertions(+) create mode 100644 wm/someblocks/CHANGELOG.md create mode 100644 wm/someblocks/LICENSE create mode 100644 wm/someblocks/Makefile create mode 100644 wm/someblocks/README.md create mode 100644 wm/someblocks/blocks.def.h create mode 100644 wm/someblocks/blocks.h create mode 100755 wm/someblocks/dwmblocks-battery create mode 100755 wm/someblocks/dwmblocks-brightness create mode 100755 wm/someblocks/dwmblocks-du create mode 100755 wm/someblocks/dwmblocks-forecast create mode 100755 wm/someblocks/dwmblocks-mpc create mode 100755 wm/someblocks/dwmblocks-volume create mode 100755 wm/someblocks/someblocks create mode 100644 wm/someblocks/someblocks.1 create mode 100644 wm/someblocks/someblocks.c (limited to 'wm/someblocks') diff --git a/wm/someblocks/CHANGELOG.md b/wm/someblocks/CHANGELOG.md new file mode 100644 index 0000000..e4bfdde --- /dev/null +++ b/wm/someblocks/CHANGELOG.md @@ -0,0 +1,6 @@ +## [1.0.1] - 2022-12-11 +### Fixed +- Fixed crashes due to bad signal handling + +## [1.0.0] - 2022-04-20 +Initial release diff --git a/wm/someblocks/LICENSE b/wm/someblocks/LICENSE new file mode 100644 index 0000000..603a997 --- /dev/null +++ b/wm/someblocks/LICENSE @@ -0,0 +1,8 @@ +ISC License (ISC) + +Copyright 2020 torrinfail +Copyright 2021 Raphael Robatsch + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/wm/someblocks/Makefile b/wm/someblocks/Makefile new file mode 100644 index 0000000..f0c027b --- /dev/null +++ b/wm/someblocks/Makefile @@ -0,0 +1,20 @@ +PREFIX ?= /usr/local +MANPREFIX ?= $(PREFIX)/share/man +CC ?= cc + +output: someblocks.c blocks.def.h blocks.h + ${CC} someblocks.c $(LDFLAGS) -o someblocks +blocks.h: + cp blocks.def.h $@ + + +clean: + rm -f *.o *.gch someblocks +install: output + mkdir -p $(DESTDIR)$(PREFIX)/bin + install -m 0755 someblocks $(DESTDIR)$(PREFIX)/bin/someblocks + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + install -m 0644 someblocks.1 $(DESTDIR)$(MANPREFIX)/man1/someblocks.1 +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/someblocks + rm -f $(DESTDIR)$(MANPREFIX)/man1/someblocks.1 diff --git a/wm/someblocks/README.md b/wm/someblocks/README.md new file mode 100644 index 0000000..f96c944 --- /dev/null +++ b/wm/someblocks/README.md @@ -0,0 +1,19 @@ +# someblocks +Modular status bar for [somebar](https://git.sr.ht/~raphi/somebar) written in c. + +This is a fork of [dwmblocks](https://github.com/torrinfail/dwmblocks), modified +to connect to somebar instead of dwm. + +The mailing list for this project is +[~raphi/public-inbox@lists.sr.ht](mailto:~raphi/public-inbox@lists.sr.ht). +# usage +To use someblocks first run 'make' and then install it with 'sudo make install'. +After that you can put someblocks in your startup script to have it start with dwl/somebar. +# modifying blocks +The statusbar is made from text output from commandline programs. +Blocks are added and removed by editing the blocks.h header file. +By default the blocks.h header file is created the first time you run make which copies the default config from blocks.def.h. +This is so you can edit your status bar commands and they will not get overwritten in a future update. +# patches +Here are some patches to someblocks that add features that I either don't want to merge in, or that require a dwl/somebar patch to work. +I do not maintain these but I will take pull requests to update them. diff --git a/wm/someblocks/blocks.def.h b/wm/someblocks/blocks.def.h new file mode 100644 index 0000000..9c22d68 --- /dev/null +++ b/wm/someblocks/blocks.def.h @@ -0,0 +1,11 @@ +//Modify this file to change what commands output to your statusbar, and recompile using the make command. +static const Block blocks[] = { + /*Icon*/ /*Command*/ /*Update Interval*/ /*Update Signal*/ + {"Mem:", "free -h | awk '/^Mem/ { print $3\"/\"$2 }' | sed s/i//g", 30, 0}, + + {"", "date '+%b %d (%a) %I:%M%p'", 5, 0}, +}; + +//sets delimeter between status commands. NULL character ('\0') means no delimeter. +static char delim[] = " | "; +static unsigned int delimLen = 5; diff --git a/wm/someblocks/blocks.h b/wm/someblocks/blocks.h new file mode 100644 index 0000000..2b7566c --- /dev/null +++ b/wm/someblocks/blocks.h @@ -0,0 +1,15 @@ +//Modify this file to change what commands output to your statusbar, and recompile using the make command. +static const Block blocks[] = { + + /*Icon*/ /*Command*/ /*Update Interval*/ /*Update Signal*/ + {"", "dwmblocks-mpc", 2, 2}, + {"", "dwmblocks-du", 60, 0}, + {"", "dwmblocks-volume", 0, 10}, + {"", "dwmblocks-battery", 1, 0}, + {"🕗 ", "date '+%k:%M'", 1, 0}, + {"📅 ", "date '+%A, %B %d %G'", 1, 0}, +}; + +//sets delimeter between status commands. NULL character ('\0') means no delimeter. +static char delim[] = " | "; +static unsigned int delimLen = 5; diff --git a/wm/someblocks/dwmblocks-battery b/wm/someblocks/dwmblocks-battery new file mode 100755 index 0000000..66f1d1f --- /dev/null +++ b/wm/someblocks/dwmblocks-battery @@ -0,0 +1,21 @@ +#!/bin/sh + +BAT_FILE=/sys/class/power_supply/BAT0 + +for battery in $BAT_FILE; do + # If non-first battery, print a space separator. + [ -n "${capacity+x}" ] && printf " " + # Sets up the status and capacity + case "$(cat "$battery/status" 2>&1)" in + "Full") status="🔋" ;; + "Discharging") status="🔋-" ;; + "Charging") status="🔋+" ;; + "Not charging") status="🛑" ;; + *) exit 1 ;; + esac + capacity="$(cat "$battery/capacity" 2>&1)" + # Will make a warn variable if discharging and low + [ "$status" = "🔋" ] && [ "$capacity" -le 25 ] && warn="❗" + # Prints the info + printf "%s%s%d%%" "$status " "$warn" " $capacity"; unset warn +done && printf "\\n" diff --git a/wm/someblocks/dwmblocks-brightness b/wm/someblocks/dwmblocks-brightness new file mode 100755 index 0000000..420518d --- /dev/null +++ b/wm/someblocks/dwmblocks-brightness @@ -0,0 +1,6 @@ +#!/bin/sh + +CMD=$(light | sed 's/...$//') +ICON=💡 + +echo "$ICON $CMD%" diff --git a/wm/someblocks/dwmblocks-du b/wm/someblocks/dwmblocks-du new file mode 100755 index 0000000..ed5f791 --- /dev/null +++ b/wm/someblocks/dwmblocks-du @@ -0,0 +1,5 @@ +#!/bin/sh +icon='💾' +cmd=$(df -h --output='pcent' /home | sed 1g | tr -d '\n ') + +echo $icon $cmd diff --git a/wm/someblocks/dwmblocks-forecast b/wm/someblocks/dwmblocks-forecast new file mode 100755 index 0000000..3c2482e --- /dev/null +++ b/wm/someblocks/dwmblocks-forecast @@ -0,0 +1,18 @@ +#!/bin/sh + +weatherreport="$HOME/.cache/dwmblocks_forecast" +getforecast() { curl -sf "wttr.in/" > "$weatherreport" || exit 1 ;} + +# Some very particular and terse stream manipulation. We get the maximum +# precipitation chance and the daily high and low from the downloaded file and +# display them with coresponding emojis. +showweather() { printf "%s" "$(sed '16q;d' "$weatherreport" | + grep -wo "[0-9]*%" | sort -rn | sed "s/^/☔ /g;1q" | tr -d '\n')" +sed '13q;d' "$weatherreport" | grep -o "m\\([-+]\\)*[0-9]\\+" | sed 's/+//g' | sort -n -t 'm' -k 2n | sed -e 1b -e '$!d' | tr '\n|m' ' ' | awk '{print " 🥶 " $1 "°","🌞 " $2 "°"}' ;} + +# The test if our forcecast is updated to the day. If it isn't download a new +# weather report from wttr.in with the above function. +[ "$(stat -c %y "$weatherreport" 2>/dev/null | cut -d' ' -f1)" = "$(date '+%Y-%m-%d')" ] || + getforecast + +showweather diff --git a/wm/someblocks/dwmblocks-mpc b/wm/someblocks/dwmblocks-mpc new file mode 100755 index 0000000..c468ec8 --- /dev/null +++ b/wm/someblocks/dwmblocks-mpc @@ -0,0 +1,6 @@ +#!/bin/sh + +SONG=$(mpc --format "%title% - %artist%" | mpc --format "%title% - %artist%" | sed "/^volume:/d;s/\\&/&/g;s/\\[paused\\].*/⏸/g;/\\[playing\\].*/d;/^ERROR/Q" | sed 1q;) +ICON="🎵" + +echo "$ICON $SONG" diff --git a/wm/someblocks/dwmblocks-volume b/wm/someblocks/dwmblocks-volume new file mode 100755 index 0000000..048fa04 --- /dev/null +++ b/wm/someblocks/dwmblocks-volume @@ -0,0 +1,13 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 4) pamixer --allow-boost -i 1;; + 5) pamixer --allow-boost -d 1;; +esac +ICON="🔉" +VOL=$(pamixer --get-volume) + +if [ $(pamixer --get-mute) = 'true' ]; then + ICON="🔇" +fi +echo "$ICON $VOL%" diff --git a/wm/someblocks/someblocks b/wm/someblocks/someblocks new file mode 100755 index 0000000..d3fed0f Binary files /dev/null and b/wm/someblocks/someblocks differ diff --git a/wm/someblocks/someblocks.1 b/wm/someblocks/someblocks.1 new file mode 100644 index 0000000..4b5cf6e --- /dev/null +++ b/wm/someblocks/someblocks.1 @@ -0,0 +1,22 @@ +.TH someblocks 1 someblocks\-1.0 +.SH NAME +someblocks \- Modular status bar for somebar +.SH SYNOPSIS +.B someblocks +.RB [ \-d +.IR delimiter ] +.RB [ \-s +.IR path ] +.RB [ \-p ] +.SH DESCRIPTION +Modular status bar for somebar written in c. +.SH OPTIONS +.TP +.B \-d +Sets the delimiter between blocks +.TP +.B \-s +Sets the path to the somebar control FIFO. The default value is +$XDG_RUNTIME_DIR/somebar-0 +.SH BUGS +Send bug reports to ~raphi/public-inbox@lists.sr.ht diff --git a/wm/someblocks/someblocks.c b/wm/someblocks/someblocks.c new file mode 100644 index 0000000..f149896 --- /dev/null +++ b/wm/someblocks/someblocks.c @@ -0,0 +1,215 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include +#include +#include +#ifdef __OpenBSD__ +#define SIGPLUS SIGUSR1+1 +#define SIGMINUS SIGUSR1-1 +#else +#define SIGPLUS SIGRTMIN +#define SIGMINUS SIGRTMIN +#endif +#define LENGTH(X) (sizeof(X) / sizeof (X[0])) +#define CMDLENGTH 50 +#define MIN( a, b ) ( ( a < b) ? a : b ) +#define STATUSLENGTH (LENGTH(blocks) * CMDLENGTH + 1) + +typedef struct { + char* icon; + char* command; + unsigned int interval; + unsigned int signal; +} Block; +#ifndef __OpenBSD__ +void dummysighandler(int num); +#endif +void sighandler(int num); +void getcmds(int time); +void getsigcmds(unsigned int signal); +void setupsignals(); +void sighandler(int signum); +int getstatus(char *str, char *last); +void statusloop(); +void termhandler(); +void pstdout(); +void psomebar(); +static void (*writestatus) () = psomebar; + +#include "blocks.h" + +static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0}; +static char statusstr[2][STATUSLENGTH]; +static int statusContinue = 1; +static int returnStatus = 0; +static char somebarPath[128]; +static int somebarFd = -1; + +//opens process *cmd and stores output in *output +void getcmd(const Block *block, char *output) +{ + strcpy(output, block->icon); + FILE *cmdf = popen(block->command, "r"); + if (!cmdf) + return; + int i = strlen(block->icon); + fgets(output+i, CMDLENGTH-i-delimLen, cmdf); + i = strlen(output); + if (i == 0) { + //return if block and command output are both empty + pclose(cmdf); + return; + } + if (delim[0] != '\0') { + //only chop off newline if one is present at the end + i = output[i-1] == '\n' ? i-1 : i; + strncpy(output+i, delim, delimLen); + } + else + output[i++] = '\0'; + pclose(cmdf); +} + +void getcmds(int time) +{ + const Block* current; + for (unsigned int i = 0; i < LENGTH(blocks); i++) { + current = blocks + i; + if ((current->interval != 0 && time % current->interval == 0) || time == -1) + getcmd(current,statusbar[i]); + } +} + +void getsigcmds(unsigned int signal) +{ + const Block *current; + for (unsigned int i = 0; i < LENGTH(blocks); i++) { + current = blocks + i; + if (current->signal == signal) + getcmd(current,statusbar[i]); + } +} + +void setupsignals() +{ + struct sigaction sa = {0}; +#ifndef __OpenBSD__ + /* initialize all real time signals with dummy handler */ + sa.sa_handler = dummysighandler; + for (int i = SIGRTMIN; i <= SIGRTMAX; i++) + sigaction(i, &sa, NULL); +#endif + + sa.sa_handler = sighandler; + for (unsigned int i = 0; i < LENGTH(blocks); i++) { + if (blocks[i].signal > 0) + sigaction(SIGMINUS+blocks[i].signal, &sa, NULL); + } + +} + +int getstatus(char *str, char *last) +{ + strcpy(last, str); + str[0] = '\0'; + for (unsigned int i = 0; i < LENGTH(blocks); i++) + strcat(str, statusbar[i]); + str[strlen(str)-strlen(delim)] = '\0'; + return strcmp(str, last);//0 if they are the same +} + +void pstdout() +{ + if (!getstatus(statusstr[0], statusstr[1]))//Only write out if text has changed. + return; + printf("%s\n",statusstr[0]); + fflush(stdout); +} + + +void psomebar() +{ + if (!getstatus(statusstr[0], statusstr[1]))//Only write out if text has changed. + return; + if (somebarFd < 0) { + somebarFd = open(somebarPath, O_WRONLY|O_CLOEXEC); + if (somebarFd < 0 && errno == ENOENT) { + // assume somebar is not ready yet + sleep(1); + somebarFd = open(somebarPath, O_WRONLY|O_CLOEXEC); + } + if (somebarFd < 0) { + perror("open"); + return; + } + } + dprintf(somebarFd, "status %s\n", statusstr[0]); +} + + +void statusloop() +{ + setupsignals(); + int i = 0; + getcmds(-1); + while (1) { + getcmds(i++); + writestatus(); + if (!statusContinue) + break; + sleep(1.0); + } +} + +#ifndef __OpenBSD__ +/* this signal handler should do nothing */ +void dummysighandler(int signum) +{ + return; +} +#endif + +void sighandler(int signum) +{ + getsigcmds(signum-SIGPLUS); + writestatus(); +} + +void termhandler() +{ + statusContinue = 0; +} + +void sigpipehandler() +{ + close(somebarFd); + somebarFd = -1; +} + +int main(int argc, char** argv) +{ + for (int i = 0; i < argc; i++) {//Handle command line arguments + if (!strcmp("-d",argv[i])) + strncpy(delim, argv[++i], delimLen); + else if (!strcmp("-p",argv[i])) + writestatus = pstdout; + else if (!strcmp("-s",argv[i])) + strcpy(somebarPath, argv[++i]); + } + + if (!strlen(somebarPath)) { + strcpy(somebarPath, getenv("XDG_RUNTIME_DIR")); + strcat(somebarPath, "/somebar-0"); + } + + delimLen = MIN(delimLen, strlen(delim)); + delim[delimLen++] = '\0'; + signal(SIGTERM, termhandler); + signal(SIGINT, termhandler); + signal(SIGPIPE, sigpipehandler); + statusloop(); + return 0; +} -- cgit v1.2.3