From 94fdf25843e6eb23c2265efd5c8280fa39f4bfde Mon Sep 17 00:00:00 2001 From: Gustaf Rydholm Date: Thu, 8 Jul 2021 15:51:38 +0200 Subject: Latest update --- Makefile | 22 +++--- blocks.def.h | 11 --- config.h | 14 ++++ dwmblocks.c | 216 +++++++++++++++++++++++++++++++++-------------------------- 4 files changed, 148 insertions(+), 115 deletions(-) delete mode 100644 blocks.def.h create mode 100644 config.h diff --git a/Makefile b/Makefile index ef43ef4..5cfbb5a 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,19 @@ -PREFIX ?= /usr/local -CC ?= cc -LDFLAGS = -lX11 - -output: dwmblocks.c blocks.def.h blocks.h - ${CC} dwmblocks.c $(LDFLAGS) -o dwmblocks -blocks.h: - cp blocks.def.h $@ +.POSIX: +PREFIX = /usr/local +CC = gcc +dwmblocks: dwmblocks.o + $(CC) dwmblocks.o -lX11 -o dwmblocks +dwmblocks.o: dwmblocks.c config.h + $(CC) -c dwmblocks.c clean: rm -f *.o *.gch dwmblocks -install: output +install: dwmblocks mkdir -p $(DESTDIR)$(PREFIX)/bin - install -m 0755 dwmblocks $(DESTDIR)$(PREFIX)/bin/dwmblocks + cp -f dwmblocks $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/dwmblocks uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/dwmblocks + +.PHONY: clean install uninstall diff --git a/blocks.def.h b/blocks.def.h deleted file mode 100644 index 9c22d68..0000000 --- a/blocks.def.h +++ /dev/null @@ -1,11 +0,0 @@ -//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/config.h b/config.h new file mode 100644 index 0000000..2c92c4e --- /dev/null +++ b/config.h @@ -0,0 +1,14 @@ +//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*/ + {"", "sb-pacpackages", 0, 8}, + {"", "sb-cpubars", 10, 18}, + {"", "sb-memory", 5, 4}, + {"", "sb-nettraf", 1, 16}, + {"", "sb-internet", 5, 4}, + {"", "sb-volume", 0, 10}, + {"", "sb-clock", 60, 1}, +}; + +//Sets delimiter between status commands. NULL character ('\0') means no delimiter. +static char *delim = " "; diff --git a/dwmblocks.c b/dwmblocks.c index ded717c..563a07e 100644 --- a/dwmblocks.c +++ b/dwmblocks.c @@ -3,20 +3,9 @@ #include #include #include -#ifndef NO_X #include -#endif -#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; @@ -24,76 +13,95 @@ typedef struct { unsigned int interval; unsigned int signal; } Block; -#ifndef __OpenBSD__ -void dummysighandler(int num); -#endif void sighandler(int num); +void buttonhandler(int sig, siginfo_t *si, void *ucontext); +void replace(char *str, char old, char new); +void remove_all(char *str, char to_remove); void getcmds(int time); -void getsigcmds(unsigned int signal); +#ifndef __OpenBSD__ +void getsigcmds(int signal); void setupsignals(); void sighandler(int signum); +#endif int getstatus(char *str, char *last); -void statusloop(); -void termhandler(); -void pstdout(); -#ifndef NO_X void setroot(); -static void (*writestatus) () = setroot; -static int setupX(); -static Display *dpy; -static int screen; -static Window root; -#else -static void (*writestatus) () = pstdout; -#endif +void statusloop(); +void termhandler(int signum); -#include "blocks.h" +#include "config.h" +static Display *dpy; +static int screen; +static Window root; static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0}; -static char statusstr[2][STATUSLENGTH]; +static char statusstr[2][256]; static int statusContinue = 1; -static int returnStatus = 0; +static void (*writestatus) () = setroot; + +void replace(char *str, char old, char new) +{ + int N = strlen(str); + for(int i = 0; i < N; i++) + if(str[i] == old) + str[i] = new; +} + +void remove_all(char *str, char to_remove) { + char *read = str; + char *write = str; + while (*read) { + if (*read != to_remove) { + *write = *read; + ++write; + } + ++read; + } + *write = '\0'; +} //opens process *cmd and stores output in *output void getcmd(const Block *block, char *output) { + if (block->signal) + { + output[0] = block->signal; + output++; + } strcpy(output, block->icon); - FILE *cmdf = popen(block->command, "r"); + char *cmd = block->command; + FILE *cmdf = popen(cmd,"r"); if (!cmdf) return; + char c; int i = strlen(block->icon); - fgets(output+i, CMDLENGTH-i-delimLen, cmdf); + fgets(output+i, CMDLENGTH-(strlen(delim)+1), cmdf); + remove_all(output, '\n'); 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'; + if ((i > 0 && block != &blocks[LENGTH(blocks) - 1])) + strcat(output, delim); + i+=strlen(delim); + output[i++] = '\0'; pclose(cmdf); } void getcmds(int time) { const Block* current; - for (unsigned int i = 0; i < LENGTH(blocks); i++) { + for(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) +#ifndef __OpenBSD__ +void getsigcmds(int signal) { const Block *current; - for (unsigned int i = 0; i < LENGTH(blocks); i++) { + for (int i = 0; i < LENGTH(blocks); i++) + { current = blocks + i; if (current->signal == signal) getcmd(current,statusbar[i]); @@ -102,50 +110,57 @@ void getsigcmds(unsigned int signal) void setupsignals() { -#ifndef __OpenBSD__ - /* initialize all real time signals with dummy handler */ - for (int i = SIGRTMIN; i <= SIGRTMAX; i++) - signal(i, dummysighandler); -#endif + struct sigaction sa; - for (unsigned int i = 0; i < LENGTH(blocks); i++) { + for(int i = SIGRTMIN; i <= SIGRTMAX; i++) + signal(i, SIG_IGN); + + for(int i = 0; i < LENGTH(blocks); i++) + { if (blocks[i].signal > 0) - signal(SIGMINUS+blocks[i].signal, sighandler); + { + signal(SIGRTMIN+blocks[i].signal, sighandler); + sigaddset(&sa.sa_mask, SIGRTMIN+blocks[i].signal); + } } + sa.sa_sigaction = buttonhandler; + sa.sa_flags = SA_SIGINFO; + sigaction(SIGUSR1, &sa, NULL); + struct sigaction sigchld_action = { + .sa_handler = SIG_DFL, + .sa_flags = SA_NOCLDWAIT + }; + sigaction(SIGCHLD, &sigchld_action, NULL); } +#endif int getstatus(char *str, char *last) { strcpy(last, str); str[0] = '\0'; - for (unsigned int i = 0; i < LENGTH(blocks); i++) + for(int i = 0; i < LENGTH(blocks); i++) { strcat(str, statusbar[i]); - str[strlen(str)-strlen(delim)] = '\0'; + if (i == LENGTH(blocks) - 1) + strcat(str, " "); + } + str[strlen(str)-1] = '\0'; return strcmp(str, last);//0 if they are the same } -#ifndef NO_X void setroot() { if (!getstatus(statusstr[0], statusstr[1]))//Only set root if text has changed. return; - XStoreName(dpy, root, statusstr[0]); - XFlush(dpy); -} - -int setupX() -{ - dpy = XOpenDisplay(NULL); - if (!dpy) { - fprintf(stderr, "dwmblocks: Failed to open display\n"); - return 0; + Display *d = XOpenDisplay(NULL); + if (d) { + dpy = d; } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - return 1; + XStoreName(dpy, root, statusstr[0]); + XCloseDisplay(dpy); } -#endif void pstdout() { @@ -158,56 +173,69 @@ void pstdout() void statusloop() { +#ifndef __OpenBSD__ setupsignals(); +#endif int i = 0; getcmds(-1); - while (1) { - getcmds(i++); + while(statusContinue) + { + getcmds(i); writestatus(); - if (!statusContinue) - break; sleep(1.0); + i++; } } #ifndef __OpenBSD__ -/* this signal handler should do nothing */ -void dummysighandler(int signum) +void sighandler(int signum) { - return; + getsigcmds(signum-SIGRTMIN); + writestatus(); } -#endif -void sighandler(int signum) +void buttonhandler(int sig, siginfo_t *si, void *ucontext) { - getsigcmds(signum-SIGPLUS); - writestatus(); + char button[2] = {'0' + si->si_value.sival_int & 0xff, '\0'}; + pid_t process_id = getpid(); + sig = si->si_value.sival_int >> 8; + if (fork() == 0) + { + const Block *current; + for (int i = 0; i < LENGTH(blocks); i++) + { + current = blocks + i; + if (current->signal == sig) + break; + } + char shcmd[1024]; + sprintf(shcmd,"%s && kill -%d %d",current->command, current->signal+34,process_id); + char *command[] = { "/bin/sh", "-c", shcmd, NULL }; + setenv("BLOCK_BUTTON", button, 1); + setsid(); + execvp(command[0], command); + exit(EXIT_SUCCESS); + } } -void termhandler() +#endif + +void termhandler(int signum) { statusContinue = 0; + exit(0); } int main(int argc, char** argv) { - for (int i = 0; i < argc; i++) {//Handle command line arguments + for(int i = 0; i < argc; i++) + { if (!strcmp("-d",argv[i])) - strncpy(delim, argv[++i], delimLen); - else if (!strcmp("-p",argv[i])) + delim = argv[++i]; + else if(!strcmp("-p",argv[i])) writestatus = pstdout; } -#ifndef NO_X - if (!setupX()) - return 1; -#endif - delimLen = MIN(delimLen, strlen(delim)); - delim[delimLen++] = '\0'; signal(SIGTERM, termhandler); signal(SIGINT, termhandler); statusloop(); -#ifndef NO_X - XCloseDisplay(dpy); -#endif - return 0; } -- cgit v1.2.3-70-g09d2