Xinqi Bao's Git

Split into multiple files
[slstatus.git] / slstatus.c
1 /* See LICENSE file for copyright and license details. */
2 #include <err.h>
3 #include <errno.h>
4 #include <locale.h>
5 #include <signal.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <time.h>
10 #include <X11/Xlib.h>
11
12 #include "arg.h"
13 #include "util.h"
14
15 struct arg {
16 const char *(*func)();
17 const char *fmt;
18 const char *args;
19 };
20
21 static const char *battery_perc(const char *bat);
22 static const char *battery_power(const char *bat);
23 static const char *battery_state(const char *bat);
24 static const char *cpu_freq(void);
25 static const char *cpu_perc(void);
26 static const char *cpu_iowait(void);
27 static const char *datetime(const char *fmt);
28 static const char *disk_free(const char *mnt);
29 static const char *disk_perc(const char *mnt);
30 static const char *disk_total(const char *mnt);
31 static const char *disk_used(const char *mnt);
32 static const char *entropy(void);
33 static const char *gid(void);
34 static const char *hostname(void);
35 static const char *ipv4(const char *iface);
36 static const char *ipv6(const char *iface);
37 static const char *kernel_release(void);
38 static const char *keyboard_indicators(void);
39 static const char *load_avg(const char *fmt);
40 static const char *num_files(const char *dir);
41 static const char *ram_free(void);
42 static const char *ram_perc(void);
43 static const char *ram_used(void);
44 static const char *ram_total(void);
45 static const char *run_command(const char *cmd);
46 static const char *swap_free(void);
47 static const char *swap_perc(void);
48 static const char *swap_used(void);
49 static const char *swap_total(void);
50 static const char *temp(const char *file);
51 static const char *uid(void);
52 static const char *uptime(void);
53 static const char *username(void);
54 static const char *vol_perc(const char *card);
55 static const char *wifi_perc(const char *iface);
56 static const char *wifi_essid(const char *iface);
57
58 char *argv0;
59 static unsigned short int done;
60 static Display *dpy;
61
62 #include "config.h"
63
64 static void
65 terminate(const int signo)
66 {
67 done = 1;
68 }
69
70 static void
71 difftimespec(struct timespec *res, struct timespec *a, struct timespec *b)
72 {
73 res->tv_sec = a->tv_sec - b->tv_sec - (a->tv_nsec < b->tv_nsec);
74 res->tv_nsec = a->tv_nsec - b->tv_nsec +
75 (a->tv_nsec < b->tv_nsec) * 1000000000;
76 }
77
78 static void
79 usage(void)
80 {
81 fprintf(stderr, "usage: %s [-s]\n", argv0);
82 exit(1);
83 }
84
85 int
86 main(int argc, char *argv[])
87 {
88 struct sigaction act;
89 struct timespec start, current, diff, intspec, wait;
90 size_t i, len;
91 int sflag = 0;
92 char status[MAXLEN];
93
94 ARGBEGIN {
95 case 's':
96 sflag = 1;
97 break;
98 default:
99 usage();
100 } ARGEND
101
102 if (argc) {
103 usage();
104 }
105
106 setlocale(LC_ALL, "");
107
108 memset(&act, 0, sizeof(act));
109 act.sa_handler = terminate;
110 sigaction(SIGINT, &act, NULL);
111 sigaction(SIGTERM, &act, NULL);
112
113 if (!sflag && !(dpy = XOpenDisplay(NULL))) {
114 fprintf(stderr, "slstatus: cannot open display");
115 return 1;
116 }
117
118 while (!done) {
119 clock_gettime(CLOCK_MONOTONIC, &start);
120
121 status[0] = '\0';
122 for (i = len = 0; i < LEN(args); i++) {
123 len += snprintf(status + len, sizeof(status) - len,
124 args[i].fmt, args[i].func(args[i].args));
125
126 if (len >= sizeof(status)) {
127 status[sizeof(status) - 1] = '\0';
128 }
129 }
130
131 if (sflag) {
132 printf("%s\n", status);
133 } else {
134 XStoreName(dpy, DefaultRootWindow(dpy), status);
135 XSync(dpy, False);
136 }
137
138 if (!done) {
139 clock_gettime(CLOCK_MONOTONIC, &current);
140 difftimespec(&diff, &current, &start);
141
142 intspec.tv_sec = interval / 1000;
143 intspec.tv_nsec = (interval % 1000) * 1000000;
144 difftimespec(&wait, &intspec, &diff);
145
146 if (wait.tv_sec >= 0) {
147 nanosleep(&wait, NULL);
148 }
149 }
150 }
151
152 if (!sflag) {
153 XStoreName(dpy, DefaultRootWindow(dpy), NULL);
154 XCloseDisplay(dpy);
155 }
156
157 return 0;
158 }