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 }