dwmblocks

status bar for dwm
git clone https://git.beauhilton.com/dwmblocks.git
Log | Files | Refs | README | LICENSE

dwmblocks.c (3919B)


      1 #include<stdlib.h>
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<unistd.h>
      5 #include<signal.h>
      6 #include<X11/Xlib.h>
      7 #define LENGTH(X)               (sizeof(X) / sizeof (X[0]))
      8 #define CMDLENGTH		50
      9 
     10 typedef struct {
     11 	char* command;
     12 	unsigned int interval;
     13 	unsigned int signal;
     14 } Block;
     15 void sighandler(int num);
     16 void buttonhandler(int sig, siginfo_t *si, void *ucontext);
     17 void replace(char *str, char old, char new);
     18 void getcmds(int time);
     19 #ifndef __OpenBSD__
     20 void getsigcmds(int signal);
     21 void setupsignals();
     22 void sighandler(int signum);
     23 #endif
     24 int getstatus(char *str, char *last);
     25 void setroot();
     26 void statusloop();
     27 void termhandler(int signum);
     28 
     29 
     30 #include "config.h"
     31 
     32 static Display *dpy;
     33 static int screen;
     34 static Window root;
     35 static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
     36 static char statusstr[2][256];
     37 static char exportstring[CMDLENGTH + 22] = "export BLOCK_BUTTON=-;";
     38 static int button = 0;
     39 static int statusContinue = 1;
     40 static void (*writestatus) () = setroot;
     41 
     42 void replace(char *str, char old, char new)
     43 {
     44 	int N = strlen(str);
     45 	for(int i = 0; i < N; i++)
     46 		if(str[i] == old)
     47 			str[i] = new;
     48 }
     49 
     50 //opens process *cmd and stores output in *output
     51 void getcmd(const Block *block, char *output)
     52 {
     53 	if (block->signal)
     54 	{
     55 		output[0] = block->signal;
     56 		output++;
     57 	}
     58 	char* cmd;
     59 	FILE *cmdf;
     60 	if (button)
     61 	{
     62 		cmd = strcat(exportstring, block->command);
     63 		cmd[20] = '0' + button;
     64 		button = 0;
     65 		cmdf = popen(cmd,"r");
     66 		cmd[22] = '\0';
     67 	}
     68 	else
     69 	{
     70 		cmd = block->command;
     71 		cmdf = popen(cmd,"r");
     72 	}
     73 	if (!cmdf)
     74 		return;
     75 	fgets(output, CMDLENGTH, cmdf);
     76 	int i = strlen(output);
     77 	if (delim != '\0' && i)
     78 		output[i++] = delim;
     79 	output[i++] = '\0';
     80 	pclose(cmdf);
     81 }
     82 
     83 void getcmds(int time)
     84 {
     85 	const Block* current;
     86 	for(int i = 0; i < LENGTH(blocks); i++)
     87 	{
     88 		current = blocks + i;
     89 		if ((current->interval != 0 && time % current->interval == 0) || time == -1)
     90 			getcmd(current,statusbar[i]);
     91 	}
     92 }
     93 
     94 #ifndef __OpenBSD__
     95 void getsigcmds(int signal)
     96 {
     97 	const Block *current;
     98 	for (int i = 0; i < LENGTH(blocks); i++)
     99 	{
    100 		current = blocks + i;
    101 		if (current->signal == signal)
    102 			getcmd(current,statusbar[i]);
    103 	}
    104 }
    105 
    106 void setupsignals()
    107 {
    108 	struct sigaction sa;
    109 	for(int i = 0; i < LENGTH(blocks); i++)
    110 	{
    111 		if (blocks[i].signal > 0)
    112 		{
    113 			signal(SIGRTMIN+blocks[i].signal, sighandler);
    114 			sigaddset(&sa.sa_mask, SIGRTMIN+blocks[i].signal);
    115 		}
    116 	}
    117 	sa.sa_sigaction = buttonhandler;
    118 	sa.sa_flags = SA_SIGINFO;
    119 	sigaction(SIGUSR1, &sa, NULL);
    120 
    121 }
    122 #endif
    123 
    124 int getstatus(char *str, char *last)
    125 {
    126 	strcpy(last, str);
    127 	str[0] = '\0';
    128 	for(int i = 0; i < LENGTH(blocks); i++)
    129 		strcat(str, statusbar[i]);
    130 	str[strlen(str)-1] = '\0';
    131 	return strcmp(str, last);//0 if they are the same
    132 }
    133 
    134 void setroot()
    135 {
    136 	if (!getstatus(statusstr[0], statusstr[1]))//Only set root if text has changed.
    137 		return;
    138 	Display *d = XOpenDisplay(NULL);
    139 	if (d) {
    140 		dpy = d;
    141 	}
    142 	screen = DefaultScreen(dpy);
    143 	root = RootWindow(dpy, screen);
    144 	XStoreName(dpy, root, statusstr[0]);
    145 	XCloseDisplay(dpy);
    146 }
    147 
    148 void pstdout()
    149 {
    150 	if (!getstatus(statusstr[0], statusstr[1]))//Only write out if text has changed.
    151 		return;
    152 	printf("%s\n",statusstr[0]);
    153 	fflush(stdout);
    154 }
    155 
    156 
    157 void statusloop()
    158 {
    159 #ifndef __OpenBSD__
    160 	setupsignals();
    161 #endif
    162 	int i = 0;
    163 	getcmds(-1);
    164 	while(statusContinue)
    165 	{
    166 		getcmds(i);
    167 		writestatus();
    168 		sleep(1.0);
    169 		i++;
    170 	}
    171 }
    172 
    173 #ifndef __OpenBSD__
    174 void sighandler(int signum)
    175 {
    176 	getsigcmds(signum-SIGRTMIN);
    177 	writestatus();
    178 }
    179 
    180 void buttonhandler(int sig, siginfo_t *si, void *ucontext)
    181 {
    182 	button = si->si_value.sival_int & 0xff;
    183 	getsigcmds(si->si_value.sival_int >> 8);
    184 	writestatus();
    185 }
    186 
    187 #endif
    188 
    189 void termhandler(int signum)
    190 {
    191 	statusContinue = 0;
    192 	exit(0);
    193 }
    194 
    195 int main(int argc, char** argv)
    196 {
    197 	for(int i = 0; i < argc; i++)
    198 	{
    199 		if (!strcmp("-d",argv[i]))
    200 			delim = argv[++i][0];
    201 		else if(!strcmp("-p",argv[i]))
    202 			writestatus = pstdout;
    203 	}
    204 	signal(SIGTERM, termhandler);
    205 	signal(SIGINT, termhandler);
    206 	statusloop();
    207 }