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