asbeats: Add "install" target to Makefile.
[dockapps.git] / wmfu / wmfu.c
blob9cb6597c03c130960acab323a7fbada0b0653df0
1 /*
2 * Copyright (c) 2007 Daniel Borca All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <ctype.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/stat.h>
25 #include <time.h>
26 #include <unistd.h>
27 #include <X11/Xlib.h>
28 #include <X11/xpm.h>
30 #include "dockapp.h"
31 #include "sensors.h"
32 #include "system.h"
33 #include "util.h"
35 #include "font.h"
36 #include "frame0.xpm"
37 #include "frame1.xpm"
38 #include "frame2.xpm"
39 #include "frame3.xpm"
40 #include "frame4.xpm"
41 #include "frame5.xpm"
44 #define DockApp App.d
46 #define NELEM(tab) (const int)(sizeof(tab) / sizeof((tab)[0]))
48 #define INSIDE(x, y, xmin, ymin, xmax, ymax) ((x) >= (xmin) && (x) <= (xmax) && (y) >= (ymin) && (y) <= (ymax))
50 #define SWITCH_FRAME(a, n) \
51 do { \
52 if ((a)->frames[n].v) { \
53 (a)->page = n; \
54 (a)->millis = (a)->frames[n].u; \
55 (a)->handle = handle_frame##n; \
56 (a)->update = update_frame##n; \
57 (a)->frames[n].p = 0; \
58 (a)->update(a, 1); \
59 } \
60 } while (0)
62 #define SCROLL_START(start, num_items, max_items) \
63 do { \
64 if ((start) > (num_items) - (max_items)) { \
65 (start) = (num_items) - (max_items); \
66 } \
67 if ((start) < 0) { \
68 (start) = 0; \
69 } \
70 } while (0)
72 #define MAX_DISPLAY_CPU 2
73 #define MAX_DISPLAY_NET 2
74 #define MAX_DISPLAY_TEMP 5
77 typedef struct {
78 Pixmap f;
79 Pixmap m;
80 int v;
81 int u;
82 int p;
83 } FRAME;
85 typedef struct {
86 int row;
87 int height;
88 const int *width;
89 const int *offset;
90 } FONT;
92 typedef struct APP {
93 DOCKAPP d;
94 FONT fontx9;
95 FONT fontx8;
96 FONT fontx7;
97 FONT fontx6;
98 FONT meter2;
99 Pixmap font;
100 SENSOR *list;
101 FRAME *frames;
102 void (*handle) (struct APP *a, XEvent *event);
103 void (*update) (const struct APP *a, int full);
104 int page;
105 int millis;
106 } APP;
109 static int
110 draw_text (const APP *a, const FONT *font, const char *str, int dx, int dy)
112 const DOCKAPP *d = (DOCKAPP *)a;
114 int ch;
116 while ((ch = *(unsigned char *)str++)) {
117 int w = font->width[ch];
118 dockapp_copy_area(d, a->font, font->offset[ch], font->row, w, font->height, dx, dy);
119 dx += w;
122 /*printf("dx = %d\n", dx);*/
123 return dx;
127 static void
128 draw_meter (const APP *a, const FONT *meter, int num, int den, int dx, int dy)
130 const DOCKAPP *d = (DOCKAPP *)a;
132 const int w = meter->width[0];
133 const int h = meter->height;
134 int col = 1 * w;
136 if (num) {
137 int ratio = w * num / den;
139 XCopyArea(d->display, a->font, a->font, d->gc,
140 1 * w, meter->row,
141 w, h,
142 2 * w, meter->row);
143 XCopyArea(d->display, a->font, a->font, d->gc,
144 0 * w, meter->row,
145 ratio, h,
146 2 * w, meter->row);
147 col = 2 * w;
149 dockapp_copy_area(d, a->font, col, meter->row, w, h, dx, dy);
153 static void handle_frame0 (APP *a, XEvent *event);
154 #define handle_frame1 handle_frameN
155 #define handle_frame2 handle_frameN
156 #define handle_frame3 handle_frameN
157 #define handle_frame4 handle_frameN
158 #define handle_frame5 handle_frameN
159 static void handle_frameN (APP *a, XEvent *event);
160 static void update_frame0 (const APP *a, int full);
161 static void update_frame1 (const APP *a, int full);
162 static void update_frame2 (const APP *a, int full);
163 static void update_frame3 (const APP *a, int full);
164 static void update_frame4 (const APP *a, int full);
165 static void update_frame5 (const APP *a, int full);
168 static void
169 handle_frame0 (APP *a, XEvent *event)
171 XButtonPressedEvent *bevent;
173 switch (event->type) {
174 case ButtonPress:
175 bevent = (XButtonPressedEvent *)event;
176 switch (bevent->button & 0xFF) {
177 case Button1:
178 /*printf("handle0: b1\n");*/
179 if (INSIDE(bevent->x, bevent->y, 4, 4, 10, 10)) {
180 /*printf("next: %d %d\n", bevent->x, bevent->y);*/
181 break;
183 if (INSIDE(bevent->x, bevent->y, 50, 4, 56, 10)) {
184 /*printf("quit: %d %d\n", bevent->x, bevent->y);*/
185 ((DOCKAPP *)a)->quit = True;
186 break;
188 if (INSIDE(bevent->x, bevent->y, 1, 1, 59, 13)) {
189 /*printf("time: %d %d\n", bevent->x, bevent->y);*/
190 SWITCH_FRAME(a, 1);
191 break;
193 if (INSIDE(bevent->x, bevent->y, 1, 16, 59, 27)) {
194 /*printf("cpu : %d %d\n", bevent->x, bevent->y);*/
195 SWITCH_FRAME(a, 2);
196 break;
198 if (INSIDE(bevent->x, bevent->y, 1, 30, 29, 41)) {
199 /*printf("wifi: %d %d\n", bevent->x, bevent->y);*/
200 SWITCH_FRAME(a, 3);
201 break;
203 if (INSIDE(bevent->x, bevent->y, 32, 30, 59, 41)) {
204 /*printf("temp: %d %d\n", bevent->x, bevent->y);*/
205 SWITCH_FRAME(a, 4);
206 break;
208 if (INSIDE(bevent->x, bevent->y, 1, 44, 59, 59)) {
209 /*printf("batt: %d %d\n", bevent->x, bevent->y);*/
210 SWITCH_FRAME(a, 5);
211 break;
213 break;
214 case Button2:
215 /*printf("handle0: b2\n");*/
216 break;
217 case Button3:
218 /*printf("handle0: b3\n");*/
219 break;
221 break;
226 static void
227 handle_frameN (APP *a, XEvent *event)
229 XButtonPressedEvent *bevent;
231 switch (event->type) {
232 case ButtonPress:
233 bevent = (XButtonPressedEvent *)event;
234 switch (bevent->button & 0xFF) {
235 case Button1:
236 /*printf("handleN: b1\n");*/
237 SWITCH_FRAME(a, 0);
238 break;
239 case Button2:
240 /*printf("handleN: b2\n");*/
241 break;
242 case Button3:
243 /*printf("handleN: b3\n");*/
244 break;
245 case Button4:
246 /*printf("handle0: b4\n");*/
247 a->frames[a->page].p--;
248 a->update(a, 0);
249 break;
250 case Button5:
251 /*printf("handle0: b5\n");*/
252 a->frames[a->page].p++;
253 a->update(a, 0);
254 break;
256 break;
261 static void
262 update_frame0 (const APP *a, int full)
264 const DOCKAPP *d = (DOCKAPP *)a;
265 const FRAME *frame = &a->frames[0];
267 char buf[16];
269 time_t at;
270 struct tm *bt;
272 static CPUSTAT avg;
274 int wifi;
276 int temp;
277 int crit;
279 int on_line;
280 int battery;
281 BATSTAT total;
283 if (full) {
284 if (!d->iswindowed) {
285 dockapp_set_shape(d, frame->m);
288 dockapp_copy_area(d, frame->f, 0, 0, d->width, d->height, 0, 0);
291 at = time(NULL);
292 bt = localtime(&at);
293 sprintf(buf, "%2d:%02d", bt->tm_hour, bt->tm_min);
294 draw_text(a, &a->fontx9, buf, 15, 2);
296 if (system_get_cpu_load(0, &avg, NULL) > 0) {
297 sprintf(buf, "__CPU__%3d%%", avg.used);
298 } else {
299 strcpy(buf, " _____");
301 draw_text(a, &a->fontx8, buf, 1, 17);
303 if (system_get_best_wifi(&wifi)) {
304 sprintf(buf, "%3d\xF7", wifi);
305 } else {
306 strcpy(buf, " \xF7");
308 draw_text(a, &a->fontx8, buf, 0, 31);
310 if (system_get_max_temp(a->list, &temp, &crit)) {
311 sprintf(buf, "%3d\xF8", temp);
312 } else {
313 strcpy(buf, " \xF8");
315 draw_text(a, &a->fontx8, buf, 31, 31);
317 battery = system_get_battery(a->list, 0, &total, NULL);
318 on_line = system_get_ac_adapter(a->list);
319 if (battery) {
320 int ratio = 100 * total.curr_cap / total.full_cap;
321 int ch = 0xB0;
322 if (ratio >= 33) {
323 ch++;
325 if (ratio >= 66) {
326 ch++;
328 if (total.rate) {
329 if (on_line) {
330 /* charging */
331 int estimate = 60 * (total.full_cap - total.curr_cap) / total.rate;
332 int hours = estimate / 60;
333 if (hours > 99) {
334 hours = 99;
336 sprintf(buf, "%c__%2d:%02d\xAE\x98", ch, hours, estimate % 60);
337 } else {
338 /* discharging */
339 int estimate = 60 * total.curr_cap / total.rate;
340 int hours = estimate / 60;
341 if (hours > 99) {
342 hours = 99;
344 sprintf(buf, "%c__%2d:%02d__ ", ch, hours, estimate % 60);
346 } else {
347 if (on_line) {
348 /* bat + AC */
349 sprintf(buf, "%c__%3d%%___\x98", ch, ratio);
350 } else {
351 /* bat */
352 sprintf(buf, "%c__%3d%%___ ", ch, ratio);
355 draw_meter(a, &a->meter2, total.curr_cap, total.full_cap, 3, 55);
356 } else {
357 if (on_line) {
358 /* only AC */
359 strcpy(buf, " _____\x98");
360 } else {
361 /* nada */
362 strcpy(buf, " _____ ");
364 draw_meter(a, &a->meter2, 0, 0, 3, 55);
366 draw_text(a, &a->fontx9, buf, 2, 44);
368 dockapp_update(d);
372 static void
373 update_frame1 (const APP *a, int full)
375 const DOCKAPP *d = (DOCKAPP *)a;
376 const FRAME *frame = &a->frames[1];
378 char buf[16];
380 time_t at;
381 struct tm *bt;
383 int days, hours, mins;
385 static const char *dow[] = {
386 "___SUNDAY___",
387 "___MONDAY___",
388 "__TUESDAY__",
389 "WEDNESDAY",
390 "_THURSDAY_",
391 "___FRIDAY___",
392 "_SATURDAY_"
394 static const char *mon[] = {
395 "JAN", "FEB", "MAR", "APR",
396 "MAY", "JUN", "JUL", "AUG",
397 "SEP", "OCT", "NOV", "DEC"
400 if (full) {
401 if (!d->iswindowed) {
402 dockapp_set_shape(d, frame->m);
405 dockapp_copy_area(d, frame->f, 0, 0, d->width, d->height, 0, 0);
408 at = time(NULL);
409 bt = localtime(&at);
410 draw_text(a, &a->fontx9, dow[bt->tm_wday], 3, 2);
412 sprintf(buf, "%-2d %s", bt->tm_mday, mon[bt->tm_mon]);
413 draw_text(a, &a->fontx9, buf, 10, 13);
415 sprintf(buf, "%d", 1900 + bt->tm_year);
416 draw_text(a, &a->fontx9, buf, 16, 24);
418 draw_text(a, &a->fontx7, "UPTIME", 15, 39);
419 strcpy(buf, " _ _ ");
420 if (system_get_uptime(&days, &hours, &mins)) {
421 if (days > 999) {
422 days = 999;
424 sprintf(buf, "%03d_%02d:%02d", days, hours, mins);
426 draw_text(a, &a->fontx8, buf, 2, 48);
428 dockapp_update(d);
432 static void
433 update_frame2 (const APP *a, int full)
435 const DOCKAPP *d = (DOCKAPP *)a;
436 FRAME *frame = &a->frames[2];
438 char buf[16];
440 int speed[8];
441 static CPUSTAT load[8];
442 int mem_free, mem_total, swp_free, swp_total;
443 int i, j, n, k;
445 if (full) {
446 if (!d->iswindowed) {
447 dockapp_set_shape(d, frame->m);
450 dockapp_copy_area(d, frame->f, 0, 0, d->width, d->height, 0, 0);
453 n = system_get_cpu_speed(NELEM(speed), speed);
454 system_get_cpu_load(NELEM(load), NULL, load);
456 SCROLL_START(frame->p, n, MAX_DISPLAY_CPU);
457 j = frame->p + MAX_DISPLAY_CPU;
458 if (n < MAX_DISPLAY_CPU) {
459 while (j > n) {
460 j--;
461 draw_text(a, &a->fontx7, " ", 2, 2 + j * 20);
462 draw_text(a, &a->fontx7, " ", 2, 10 + j * 20);
466 for (k = 0, i = 0; k < j; i++, k++) {
467 int r;
468 char *gov;
470 if (speed[i] < 0) {
471 k--;
472 continue;
475 r = k - frame->p;
477 if (r < 0) {
478 continue;
481 sprintf(buf, "CPU%d %4d M", i, speed[i]);
482 draw_text(a, &a->fontx7, buf, 2, 2 + r * 20);
484 strcpy(buf, " ");
485 if (load[i].used >= 0) {
486 sprintf(buf, "%3d%%", load[i].used);
488 draw_text(a, &a->fontx7, buf, 2, 10 + r * 20);
490 gov = " ";
491 if (system_get_cpu_gov(i, sizeof(buf), buf)) {
492 if (!strcmp(buf, "performance")) {
493 gov = "PERFRM";
494 } else if (!strcmp(buf, "powersave")) {
495 gov = "PWRSAV";
496 } else if (!strcmp(buf, "userspace")) {
497 gov = "USRSPC";
498 } else if (!strcmp(buf, "ondemand")) {
499 gov = "ONDMND";
500 } else if (!strcmp(buf, "conservative")) {
501 gov = "CONSRV";
504 draw_text(a, &a->fontx7, gov, 27, 10 + r * 20);
507 if (system_get_mem_stat(&mem_free, &mem_total, &swp_free, &swp_total)) {
508 strcpy(buf, " ");
509 if (mem_total) {
510 sprintf(buf, "MEM %3d%%", 100 * (mem_total - mem_free) / mem_total);
512 draw_text(a, &a->fontx7, buf, 7, 42);
513 strcpy(buf, " ");
514 if (swp_total) {
515 sprintf(buf, "SWP %3d%%", 100 * (swp_total - swp_free) / swp_total);
517 draw_text(a, &a->fontx7, buf, 7, 50);
520 dockapp_update(d);
524 static void
525 update_frame3 (const APP *a, int full)
527 const DOCKAPP *d = (DOCKAPP *)a;
528 FRAME *frame = &a->frames[3];
530 char buf[16];
532 IFSTAT ifs[8];
533 int i, j, n;
535 if (full) {
536 if (!d->iswindowed) {
537 dockapp_set_shape(d, frame->m);
540 dockapp_copy_area(d, frame->f, 0, 0, d->width, d->height, 0, 0);
543 n = system_get_netif(NELEM(ifs), ifs);
545 SCROLL_START(frame->p, n, MAX_DISPLAY_NET);
546 j = frame->p + MAX_DISPLAY_NET;
547 if (n < MAX_DISPLAY_NET) {
548 while (j > n) {
549 j--;
550 draw_text(a, &a->fontx7, " ", 2, 2 + j * 30);
551 draw_text(a, &a->fontx7, " ", 2, 2 + j * 30 + 9);
552 draw_text(a, &a->fontx6, " _ _ _ ", 2, 2 + j * 30 + 18);
556 for (i = frame->p; i < j; i++) {
557 int r = i - frame->p;
559 strupr(ifs[i].name, ifs[i].name);
560 ifs[i].name[6] = '\0';
561 if (ifs[i].wlink >= 0) {
562 sprintf(buf, "%-6s_%3d\xF7", ifs[i].name, ifs[i].wlink);
563 draw_text(a, &a->fontx7, buf, 2, 2 + r * 30);
564 strupr(buf, ifs[i].essid);
565 buf[11] = '\0';
566 } else {
567 sprintf(buf, "%-6s_ _", ifs[i].name);
568 draw_text(a, &a->fontx7, buf, 2, 2 + r * 30);
569 strcpy(buf, " ");
571 draw_text(a, &a->fontx7, buf, 2, 2 + r * 30 + 9);
572 if (ifs[i].ipv4 != -1) {
573 int addr = ifs[i].ipv4;
574 sprintf(buf, "%3d.%3d.%3d.%3d", (addr >> 24) & 0xFF, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF, addr & 0xFF);
575 } else {
576 strcpy(buf, " _ _ _ ");
578 draw_text(a, &a->fontx6, buf, 2, 2 + r * 30 + 18);
581 dockapp_update(d);
585 static void
586 update_frame4 (const APP *a, int full)
588 const DOCKAPP *d = (DOCKAPP *)a;
589 FRAME *frame = &a->frames[4];
591 char buf[16];
593 TEMPSTAT temp[16];
594 int i, j, n;
596 if (full) {
597 if (!d->iswindowed) {
598 dockapp_set_shape(d, frame->m);
601 dockapp_copy_area(d, frame->f, 0, 0, d->width, d->height, 0, 0);
604 n = system_get_temperature(a->list, NELEM(temp), temp);
606 SCROLL_START(frame->p, n, MAX_DISPLAY_TEMP);
607 j = frame->p + MAX_DISPLAY_TEMP;
608 if (n < MAX_DISPLAY_TEMP) {
609 while (j > n) {
610 j--;
611 draw_text(a, &a->fontx7, " _ ", 1, 1 + j * 12);
615 for (i = frame->p; i < j; i++) {
616 int r = i - frame->p;
618 if (!strncmp(temp[i].name, "Core ", 5) && isdigit(temp[i].name[5]) && !temp[i].name[6]) {
619 temp[i].name[3] = temp[i].name[5];
621 temp[i].name[4] = '\0';
622 strupr(temp[i].name, temp[i].name);
623 sprintf(buf, "%-4s:%3d\xA7%3d", temp[i].name, temp[i].temp, temp[i].max);
624 if (!temp[i].max) {
625 int l = strlen(buf);
626 buf[--l] = ' ';
627 buf[--l] = ' ';
628 buf[--l] = ' ';
630 draw_text(a, &a->fontx7, buf, 1, 1 + r * 12);
633 dockapp_update(d);
637 static void
638 update_frame5 (const APP *a, int full)
640 const DOCKAPP *d = (DOCKAPP *)a;
641 const FRAME *frame = &a->frames[5];
643 char buf[16];
645 int on_line;
646 int battery;
647 BATSTAT total, batt[2];
649 int i;
651 if (full) {
652 if (!d->iswindowed) {
653 dockapp_set_shape(d, frame->m);
656 dockapp_copy_area(d, frame->f, 0, 0, d->width, d->height, 0, 0);
659 on_line = system_get_ac_adapter(a->list);
660 battery = system_get_battery(a->list, NELEM(batt), &total, batt);
662 for (i = 0; i < battery; i++) {
663 char *state;
664 int ratio = 100 * batt[i].curr_cap / batt[i].full_cap;
665 if (batt[i].rate) {
666 int estimate;
667 int hours;
668 if (on_line) {
669 estimate = 60 * (batt[i].full_cap - batt[i].curr_cap) / batt[i].rate;
670 state = "CHARGING ";
671 } else {
672 estimate = 60 * batt[i].curr_cap / batt[i].rate;
673 state = "DISCHARGING";
675 hours = estimate / 60;
676 if (hours > 99) {
677 hours = 99;
679 sprintf(buf, "%3d%% %2d:%02d", ratio, hours, estimate % 60);
680 } else {
681 sprintf(buf, "%3d%% _ ", ratio);
682 state = "STEADY ";
684 draw_text(a, &a->fontx7, batt[i].name, 2, 1 + i * 30);
685 draw_text(a, &a->fontx7, state, 2, 9 + i * 30);
686 draw_text(a, &a->fontx7, buf, 2, 17 + i * 30);
687 draw_meter(a, &a->meter2, batt[i].curr_cap, batt[i].full_cap, 3, 25 + i * 30);
689 for (; i < 2; i++) {
690 draw_text(a, &a->fontx7, " ", 2, 1 + i * 30);
691 draw_text(a, &a->fontx7, " ", 2, 9 + i * 30);
692 draw_text(a, &a->fontx7, " _ ", 2, 17 + i * 30);
693 draw_text(a, &a->fontx7, " ", 2, 20 + i * 30);
696 dockapp_update(d);
700 static int
701 update_text (SENSOR *list)
703 (void)list;
704 /* XXX cool stuff here */
708 static int
709 run_text (SENSOR *list, unsigned long millis)
711 struct timeval timeout;
712 fd_set rset;
714 struct stat buf;
715 int redir = fstat(STDOUT_FILENO, &buf) == 0 &&
716 (S_ISREG(buf.st_mode) || S_ISFIFO(buf.st_mode));
718 for (;;) {
719 update_text(list);
721 if (redir) {
722 break;
725 printf("not yet implemented -- press Enter to quit\n");
727 timeout.tv_sec = millis / 1000;
728 timeout.tv_usec = (millis % 1000) * 1000;
730 FD_ZERO(&rset);
731 FD_SET(0, &rset);
732 if (select(0 + 1, &rset, NULL, NULL, &timeout) > 0) {
733 break;
737 return 0;
741 static void
742 args (int argc, char **argv, int *iswindowed, const char **display_name, int *textmode)
744 const char *myself = argv[0];
746 *iswindowed = 0;
747 *display_name = NULL;
748 *textmode = 0;
750 while (--argc) {
751 const char *p = *++argv;
752 if (!strcmp(p, "-h") || !strcmp(p, "--help")) {
753 printf("wmfu v1.0 (c) 2007 Daniel Borca\n");
754 printf("wmfu is distributed under GNU GPL v2\n\n");
755 printf("usage: %s [OPTIONS]\n", myself);
756 printf(" -display <name> use specified display\n");
757 printf(" --windowed run in regular window\n");
758 printf(" --textmode run in text mode\n");
759 exit(0);
761 if (!strcmp(p, "-display")) {
762 if (argc < 2) {
763 fprintf(stderr, "%s: argument to `%s' is missing\n", myself, p);
764 exit(1);
766 --argc;
767 *display_name = *++argv;
769 if (!strcmp(p, "--windowed")) {
770 *iswindowed = 1;
772 if (!strcmp(p, "--textmode")) {
773 *textmode = 1;
780 main (int argc, char **argv)
782 int rv;
784 APP App;
785 FRAME frames[6];
787 int iswindowed;
788 const char *display_name;
789 int textmode;
791 args(argc, argv, &iswindowed, &display_name, &textmode);
793 App.list = sensors_init();
794 if (App.list == NULL) {
795 fprintf(stderr, "Error allocating sensor structure\n");
796 return -1;
799 if (textmode) {
800 int rv = run_text(App.list, 1000);
801 sensors_free(App.list);
802 return rv;
805 rv = dockapp_open_window(&DockApp, display_name, "wmfu", iswindowed, argc, argv);
806 if (rv != 0) {
807 fprintf(stderr, "Could not open display `%s'\n", display_name);
808 sensors_free(App.list);
809 return rv;
812 frames[0].v = dockapp_xpm2pixmap(&DockApp, frame0_xpm, &frames[0].f, &frames[0].m, NULL, 0);
813 if (!frames[0].v) {
814 fprintf(stderr, "Error initializing frame\n");
815 sensors_free(App.list);
816 return -1;
819 if (!dockapp_xpm2pixmap(&DockApp, font_xpm, &App.font, NULL, NULL, 0)) {
820 fprintf(stderr, "Error initializing font\n");
821 sensors_free(App.list);
822 return -1;
825 App.fontx9.row = FONTX9_ROW;
826 App.fontx9.height = 9;
827 App.fontx9.width = fontx9_width;
828 App.fontx9.offset = fontx9_offset;
830 App.fontx8.row = FONTX8_ROW;
831 App.fontx8.height = 8;
832 App.fontx8.width = fontx8_width;
833 App.fontx8.offset = fontx8_offset;
835 App.fontx7.row = FONTX7_ROW;
836 App.fontx7.height = 7;
837 App.fontx7.width = fontx7_width;
838 App.fontx7.offset = fontx7_offset;
840 App.fontx6.row = FONTX6_ROW;
841 App.fontx6.height = 6;
842 App.fontx6.width = fontx6_width;
843 App.fontx6.offset = fontx6_offset;
845 App.meter2.row = METER2_ROW;
846 App.meter2.height = 2;
847 App.meter2.width = meter2_width;
848 App.meter2.offset = NULL;
850 frames[1].v = dockapp_xpm2pixmap(&DockApp, frame1_xpm, &frames[1].f, &frames[1].m, NULL, 0);
851 frames[2].v = dockapp_xpm2pixmap(&DockApp, frame2_xpm, &frames[2].f, &frames[2].m, NULL, 0);
852 frames[3].v = dockapp_xpm2pixmap(&DockApp, frame3_xpm, &frames[3].f, &frames[3].m, NULL, 0);
853 frames[4].v = dockapp_xpm2pixmap(&DockApp, frame4_xpm, &frames[4].f, &frames[4].m, NULL, 0);
854 frames[5].v = dockapp_xpm2pixmap(&DockApp, frame5_xpm, &frames[5].f, &frames[5].m, NULL, 0);
856 frames[0].u = 2000;
857 frames[1].u = 10000;
858 frames[2].u = 5000;
859 frames[3].u = 5000;
860 frames[4].u = 5000;
861 frames[5].u = 10000;
863 App.frames = frames;
864 SWITCH_FRAME(&App, 0);
866 dockapp_set_eventmask(&DockApp, ButtonPressMask);
868 #if 1
869 while (!DockApp.quit) {
870 XEvent event;
871 if (dockapp_nextevent_or_timeout(&DockApp, &event, App.millis)) {
872 App.handle(&App, &event);
873 } else {
874 App.update(&App, 0);
877 #else
879 int i;
880 for (i = 0; i < 1000; i++) {
881 App.update(&App, 0);
884 #endif
886 XCloseDisplay(DockApp.display);
888 sensors_free(App.list);
889 return 0;