dwmblocks

my build of dwmblocks
git clone git://giovanniamaral.com/dwmblocks
Log | Files | Refs | README | LICENSE

dwmblocks.c (4423B)


      1 #include<stdlib.h>
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<unistd.h>
      5 #include<signal.h>
      6 #ifndef NO_X
      7 #include<X11/Xlib.h>
      8 #endif
      9 #ifdef __OpenBSD__
     10 #define SIGPLUS			SIGUSR1+1
     11 #define SIGMINUS		SIGUSR1-1
     12 #else
     13 #define SIGPLUS			SIGRTMIN
     14 #define SIGMINUS		SIGRTMIN
     15 #endif
     16 #define LENGTH(X)               (sizeof(X) / sizeof (X[0]))
     17 #define CMDLENGTH		50
     18 #define MIN( a, b ) ( ( a < b) ? a : b )
     19 #define STATUSLENGTH (LENGTH(blocks) * CMDLENGTH + 1)
     20 
     21 typedef struct {
     22 	char* icon;
     23 	char* command;
     24 	unsigned int interval;
     25 	unsigned int signal;
     26 } Block;
     27 #ifndef __OpenBSD__
     28 void dummysighandler(int num);
     29 #endif
     30 void sighandler(int num);
     31 void getcmds(int time);
     32 void getsigcmds(unsigned int signal);
     33 void setupsignals();
     34 void sighandler(int signum);
     35 int getstatus(char *str, char *last);
     36 void statusloop();
     37 void termhandler(int signum);
     38 void pstdout();
     39 #ifndef NO_X
     40 void setroot();
     41 static void (*writestatus) () = setroot;
     42 static int setupX();
     43 static Display *dpy;
     44 static int screen;
     45 static Window root;
     46 #else
     47 static void (*writestatus) () = pstdout;
     48 #endif
     49 
     50 
     51 #include "blocks.h"
     52 
     53 static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
     54 static char statusstr[2][STATUSLENGTH];
     55 static int statusContinue = 1;
     56 static int returnStatus = 0;
     57 
     58 //opens process *cmd and stores output in *output
     59 void getcmd(const Block *block, char *output)
     60 {
     61 	//make sure status is same until output is ready
     62 	char tempstatus[CMDLENGTH] = {0};
     63 	strcpy(tempstatus, block->icon);
     64 	FILE *cmdf = popen(block->command, "r");
     65 	if (!cmdf)
     66 		return;
     67 	int i = strlen(block->icon);
     68 	fgets(tempstatus+i, CMDLENGTH-i-delimLen, cmdf);
     69 	i = strlen(tempstatus);
     70 	//if block and command output are both not empty
     71 	if (i != 0) {
     72 		//only chop off newline if one is present at the end
     73 		i = tempstatus[i-1] == '\n' ? i-1 : i;
     74 		if (delim[0] != '\0') {
     75 			strncpy(tempstatus+i, delim, delimLen);
     76 		}
     77 		else
     78 			tempstatus[i++] = '\0';
     79 	}
     80 	strcpy(output, tempstatus);
     81 	pclose(cmdf);
     82 }
     83 
     84 void getcmds(int time)
     85 {
     86 	const Block* current;
     87 	for (unsigned int i = 0; i < LENGTH(blocks); i++) {
     88 		current = blocks + i;
     89 		if ((current->interval != 0 && time % current->interval == 0) || time == -1)
     90 			getcmd(current,statusbar[i]);
     91 	}
     92 }
     93 
     94 void getsigcmds(unsigned int signal)
     95 {
     96 	const Block *current;
     97 	for (unsigned int i = 0; i < LENGTH(blocks); i++) {
     98 		current = blocks + i;
     99 		if (current->signal == signal)
    100 			getcmd(current,statusbar[i]);
    101 	}
    102 }
    103 
    104 void setupsignals()
    105 {
    106 #ifndef __OpenBSD__
    107 	    /* initialize all real time signals with dummy handler */
    108     for (int i = SIGRTMIN; i <= SIGRTMAX; i++)
    109         signal(i, dummysighandler);
    110 #endif
    111 
    112 	for (unsigned int i = 0; i < LENGTH(blocks); i++) {
    113 		if (blocks[i].signal > 0)
    114 			signal(SIGMINUS+blocks[i].signal, sighandler);
    115 	}
    116 
    117 }
    118 
    119 int getstatus(char *str, char *last)
    120 {
    121 	strcpy(last, str);
    122 	str[0] = '\0';
    123 	for (unsigned int i = 0; i < LENGTH(blocks); i++)
    124 		strcat(str, statusbar[i]);
    125 	str[strlen(str)-strlen(delim)] = '\0';
    126 	return strcmp(str, last);//0 if they are the same
    127 }
    128 
    129 #ifndef NO_X
    130 void setroot()
    131 {
    132 	if (!getstatus(statusstr[0], statusstr[1]))//Only set root if text has changed.
    133 		return;
    134 	XStoreName(dpy, root, statusstr[0]);
    135 	XFlush(dpy);
    136 }
    137 
    138 int setupX()
    139 {
    140 	dpy = XOpenDisplay(NULL);
    141 	if (!dpy) {
    142 		fprintf(stderr, "dwmblocks: Failed to open display\n");
    143 		return 0;
    144 	}
    145 	screen = DefaultScreen(dpy);
    146 	root = RootWindow(dpy, screen);
    147 	return 1;
    148 }
    149 #endif
    150 
    151 void pstdout()
    152 {
    153 	if (!getstatus(statusstr[0], statusstr[1]))//Only write out if text has changed.
    154 		return;
    155 	printf("%s\n",statusstr[0]);
    156 	fflush(stdout);
    157 }
    158 
    159 
    160 void statusloop()
    161 {
    162 	setupsignals();
    163 	int i = 0;
    164 	getcmds(-1);
    165 	while (1) {
    166 		getcmds(i++);
    167 		writestatus();
    168 		if (!statusContinue)
    169 			break;
    170 		sleep(1.0);
    171 	}
    172 }
    173 
    174 #ifndef __OpenBSD__
    175 /* this signal handler should do nothing */
    176 void dummysighandler(int signum)
    177 {
    178     return;
    179 }
    180 #endif
    181 
    182 void sighandler(int signum)
    183 {
    184 	getsigcmds(signum-SIGPLUS);
    185 	writestatus();
    186 }
    187 
    188 void termhandler(int signum)
    189 {
    190 	statusContinue = 0;
    191 }
    192 
    193 int main(int argc, char** argv)
    194 {
    195 	for (int i = 0; i < argc; i++) {//Handle command line arguments
    196 		if (!strcmp("-d",argv[i]))
    197 			strncpy(delim, argv[++i], delimLen);
    198 		else if (!strcmp("-p",argv[i]))
    199 			writestatus = pstdout;
    200 	}
    201 #ifndef NO_X
    202 	if (!setupX())
    203 		return 1;
    204 #endif
    205 	delimLen = MIN(delimLen, strlen(delim));
    206 	delim[delimLen++] = '\0';
    207 	signal(SIGTERM, termhandler);
    208 	signal(SIGINT, termhandler);
    209 	statusloop();
    210 #ifndef NO_X
    211 	XCloseDisplay(dpy);
    212 #endif
    213 	return 0;
    214 }