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 }