]> git.armaanb.net Git - dwmblocks.git/blob - dwmblocks.c
Removed call to redundant call to exit()
[dwmblocks.git] / dwmblocks.c
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 #ifdef __OpenBSD__
8 #define SIGPLUS                 SIGUSR1+1
9 #define SIGMINUS                SIGUSR1-1
10 #else
11 #define SIGPLUS                 SIGRTMIN
12 #define SIGMINUS                SIGRTMIN
13 #endif
14 #define LENGTH(X)               (sizeof(X) / sizeof (X[0]))
15 #define CMDLENGTH               50
16 #define STATUSLENGTH (LENGTH(blocks) * CMDLENGTH + 1)
17
18 typedef struct {
19         char* icon;
20         char* command;
21         unsigned int interval;
22         unsigned int signal;
23 } Block;
24 #ifndef __OpenBSD__
25 void dummysighandler(int num);
26 #endif
27 void sighandler(int num);
28 void getcmds(int time);
29 void getsigcmds(int signal);
30 void setupsignals();
31 void sighandler(int signum);
32 int getstatus(char *str, char *last);
33 void setroot();
34 void statusloop();
35 void termhandler(int signum);
36
37
38 #include "blocks.h"
39
40 static Display *dpy;
41 static int screen;
42 static Window root;
43 static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
44 static char statusstr[2][STATUSLENGTH];
45 static int statusContinue = 1;
46 static void (*writestatus) () = setroot;
47
48 //opens process *cmd and stores output in *output
49 void getcmd(const Block *block, char *output)
50 {
51         strcpy(output, block->icon);
52         char *cmd = block->command;
53         FILE *cmdf = popen(cmd,"r");
54         if (!cmdf)
55                 return;
56         char c;
57         int i = strlen(block->icon);
58         fgets(output+i, CMDLENGTH-i, cmdf);
59         i = strlen(output);
60         if (delim != '\0' && --i)
61                 output[i++] = delim;
62         output[i++] = '\0';
63         pclose(cmdf);
64 }
65
66 void getcmds(int time)
67 {
68         const Block* current;
69         for(int i = 0; i < LENGTH(blocks); i++)
70         {
71                 current = blocks + i;
72                 if ((current->interval != 0 && time % current->interval == 0) || time == -1)
73                         getcmd(current,statusbar[i]);
74         }
75 }
76
77 void getsigcmds(int signal)
78 {
79         const Block *current;
80         for (int i = 0; i < LENGTH(blocks); i++)
81         {
82                 current = blocks + i;
83                 if (current->signal == signal)
84                         getcmd(current,statusbar[i]);
85         }
86 }
87
88 void setupsignals()
89 {
90 #ifndef __OpenBSD__
91             /* initialize all real time signals with dummy handler */
92     for(int i = SIGRTMIN; i <= SIGRTMAX; i++)
93         signal(i, dummysighandler);
94 #endif
95
96         for(int i = 0; i < LENGTH(blocks); i++)
97         {
98                 if (blocks[i].signal > 0)
99                         signal(SIGMINUS+blocks[i].signal, sighandler);
100         }
101
102 }
103
104 int getstatus(char *str, char *last)
105 {
106         strcpy(last, str);
107         str[0] = '\0';
108         for(int i = 0; i < LENGTH(blocks); i++)
109                 strcat(str, statusbar[i]);
110         str[strlen(str)-1] = '\0';
111         return strcmp(str, last);//0 if they are the same
112 }
113
114 void setroot()
115 {
116         if (!getstatus(statusstr[0], statusstr[1]))//Only set root if text has changed.
117                 return;
118         Display *d = XOpenDisplay(NULL);
119         if (d) {
120                 dpy = d;
121         }
122         screen = DefaultScreen(dpy);
123         root = RootWindow(dpy, screen);
124         XStoreName(dpy, root, statusstr[0]);
125         XCloseDisplay(dpy);
126 }
127
128 void pstdout()
129 {
130         if (!getstatus(statusstr[0], statusstr[1]))//Only write out if text has changed.
131                 return;
132         printf("%s\n",statusstr[0]);
133         fflush(stdout);
134 }
135
136
137 void statusloop()
138 {
139         setupsignals();
140         int i = 0;
141         getcmds(-1);
142         while(statusContinue)
143         {
144                 getcmds(i);
145                 writestatus();
146                 sleep(1.0);
147                 i++;
148         }
149 }
150
151 #ifndef __OpenBSD__
152 /* this signal handler should do nothing */
153 void dummysighandler(int signum)
154 {
155     return;
156 }
157 #endif
158
159 void sighandler(int signum)
160 {
161         getsigcmds(signum-SIGPLUS);
162         writestatus();
163 }
164
165 void termhandler(int signum)
166 {
167         statusContinue = 0;
168 }
169
170 int main(int argc, char** argv)
171 {
172         for(int i = 0; i < argc; i++)
173         {
174                 if (!strcmp("-d",argv[i]))
175                         delim = argv[++i][0];
176                 else if(!strcmp("-p",argv[i]))
177                         writestatus = pstdout;
178         }
179         signal(SIGTERM, termhandler);
180         signal(SIGINT, termhandler);
181         statusloop();
182 }