2 * wmupmon - A dockapp to monitor system uptime
3 * Copyright (C) 2003 Justin Spadea <jzs@mail.rit.edu>
5 * Based on work by Seiichi SATO <ssato@sh.rim.or.jp>
6 * Copyright (C) 2001,2002 Seiichi SATO <ssato@sh.rim.or.jp>
7 * AND by Mark Staggs <me@markstaggs.net>
8 * Copyright (C) 2002 Mark Staggs <me@markstaggs.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "display_link.xpm"
29 #include "display_stats.xpm"
35 #define WINDOWED_BG " \tc #AEAAAE"
36 #define MAX_HISTORY 16
37 #define CPUNUM_NONE -1
39 typedef enum { LIGHTON
, LIGHTOFF
} light
;
40 typedef enum { STANDARD
, EXTENDED
} interface
;
46 Pixmap backdrop_on_stats
;
50 static char *display_name
= "";
51 static char *light_color
= NULL
; /* back-light color */
52 static unsigned update_interval
= 1;
53 static light backlight
= LIGHTOFF
;
54 static interface gui
= STANDARD
;
55 static interface lgui
= STANDARD
;
68 time_t last_update
= 0;
73 static void update(struct wifi
*wfi
);
74 static void switch_interface(struct wifi
*wfi
);
75 static void do_theme(struct theme thm
);
76 static void draw_junk(struct wifi
*wfi
);
77 static void draw_ext(struct wifi
*wfi
);
78 static void draw_text(char *text
, int dx
, int dy
, Bool digit
);
79 static void parse_arguments(int argc
, char **argv
);
80 static void print_help(char *prog
);
81 static void copy_wifi(struct wifi
*lwfi
, struct wifi
*wfi
);
82 static void clear_wifi(struct wifi
*wfi
);
83 static void refresh(struct theme thm
);
85 int main(int argc
, char **argv
)
88 XButtonPressedEvent
*bevent
;
94 /* Parse CommandLine */
95 parse_arguments(argc
, argv
);
97 /* Initialize Application */
98 dockapp_open_window(display_name
, PACKAGE
, SIZE
, SIZE
, argc
, argv
);
99 dockapp_set_eventmask(ButtonPressMask
);
101 if (backlight
== LIGHTON
) {
108 if (!dockapp_iswindowed
)
109 dockapp_setshape(mask
, 0, 0);
111 XFreePixmap(display
, mask
);
113 /* pixmap : draw area */
114 pixmap
= dockapp_XCreatePixmap(SIZE
, SIZE
);
116 /* Initialize pixmap */
119 dockapp_copyarea(display_link
, pixmap
, 0, 0, SIZE
, SIZE
, 0, 0);
121 dockapp_copyarea(display_stats
, pixmap
, 0, 0, SIZE
, SIZE
, 0, 0);
123 dockapp_set_background(pixmap
);
125 draw_text("link", 32, 47, False
);
129 if (time(NULL
) != last_update
)
132 while (XPending(display
)) {
133 XNextEvent(display
, &event
);
135 switch (event
.type
) {
137 bevent
= (XButtonPressedEvent
*) & event
;
138 switch (bevent
->button
& 0xff) {
140 scroll
= (scroll
) ? False
: True
;
147 switch_interface(&wfi
);
151 default: /* make gcc happy */
155 usleep(update_interval
*1000000L);
160 static void do_theme(struct theme thm
)
162 XpmColorSymbol colors
[4] =
163 { {"Back0", NULL
, 0}, {"Fore0", NULL
, 0}, {"High0", NULL
, 0},
169 colors
[0].pixel
= dockapp_getcolor(thm
.bg
);
170 colors
[1].pixel
= dockapp_getcolor(thm
.fg
);
171 colors
[2].pixel
= dockapp_getcolor(thm
.hi
);
172 colors
[3].pixel
= dockapp_getcolor(thm
.mt
);
174 /* change raw xpm data to pixmap */
175 if (dockapp_iswindowed
)
176 display_link_xpm
[1] = WINDOWED_BG
;
178 if (!dockapp_xpm2pixmap
179 (display_link_xpm
, &display_link
, &mask
, colors
, ncolor
)) {
180 fprintf(stderr
, "Error initializing background image.\n");
183 if (!dockapp_xpm2pixmap
184 (display_stats_xpm
, &display_stats
, &mask
, colors
, ncolor
)) {
185 fprintf(stderr
, "Error initializing background image.\n");
188 if (!dockapp_xpm2pixmap(parts_xpm
, &parts
, NULL
, colors
, ncolor
)) {
189 fprintf(stderr
, "Error initializing parts image.\n");
192 if (!dockapp_xpm2pixmap(font_xpm
, &fonts
, NULL
, colors
, ncolor
)) {
193 fprintf(stderr
, "Error initializing fonts image.\n");
198 /* called by timer */
199 static void update(struct wifi
*wfi
)
203 //char *str = calloc(1, sizeof(wfi->ifname) + sizeof(wfi->essid) + 3);
208 /* get current link level from /proc/net/wireless */
209 copy_wifi(&lwfi
, wfi
);
212 if (wfi
->max_qual
== -1) {
213 tcur
.bg
= "rgb:ff/0/0";
214 tcur
.fg
= "rgb:0/0/0";
215 tcur
.mt
= "rgb:00/00/00";
217 dockapp_copyarea(display_link
, pixmap
, 0, 0, 58, 58, 0, 0);
218 draw_text("ERROR", (56 / 2) - 5 * 2.5, 4, False
);
222 /* If percent == 0, show backlight */
223 percent
= wfi
->link
/ (wfi
->max_qual
/ 100);
225 if (backlight
== LIGHTON
) {
228 backlight
= LIGHTOFF
;
230 if (backlight
== LIGHTOFF
) {
236 if (gui
== STANDARD
) {
238 if (backlight
== LIGHTOFF
)
248 if (backlight
== LIGHTOFF
)
258 dockapp_copyarea(display_link
, pixmap
, 0, 0, 58, 12, 0, 0);
259 snprintf(str
, strlen(wfi
->ifname
) + strlen(wfi
->essid
) + 4,
260 "%s - %s", wfi
->ifname
, wfi
->essid
);
261 draw_text(str
, 52 - (count
* 3), 4, False
);
262 dockapp_copyarea(display_link
, pixmap
, 0, 0, 4, 12, 0, 0);
263 dockapp_copyarea(display_link
, pixmap
, 55, 0, 3, 12, 55, 0);
264 if (count
> (strlen(str
) * 3))
267 int diff
= now
- last_swap
;
268 /* swap between ifname and essid every 2 seconds */
271 else if ((diff
> 2) && (diff
<= 4))
278 dockapp_copyarea(display_link
, pixmap
, 0, 0, 58, 12, 0, 0);
279 draw_text(wfi
->ifname
,
280 ((56 / 2) - (strlen(wfi
->ifname
) * 2)), 4,
282 dockapp_copyarea(display_link
, pixmap
, 0, 0, 4, 12, 0, 0);
283 dockapp_copyarea(display_link
, pixmap
, 55, 0, 3, 12, 55,
287 dockapp_copyarea(display_link
, pixmap
, 0, 0, 58, 12, 0, 0);
288 draw_text(wfi
->essid
,
289 ((56 / 2) - (strlen(wfi
->essid
) * 2)), 4, False
);
290 dockapp_copyarea(display_link
, pixmap
, 0, 0, 4, 12, 0, 0);
291 dockapp_copyarea(display_link
, pixmap
, 55, 0, 3, 12, 55,
298 dockapp_copy2window(pixmap
);
301 static void refresh(struct theme thm
)
306 dockapp_copyarea(display_link
, pixmap
, 0, 0, 58, 58, 0, 0);
308 draw_text("link", 32, 47, False
);
311 dockapp_copyarea(display_stats
, pixmap
, 0, 0, 58, 58, 0, 0);
313 draw_text("lnk", 37, 45, False
);
314 draw_text("lvl", 37, 36, False
);
315 draw_text("nse", 37, 27, False
);
316 draw_text("rte", 37, 18, False
);
321 static void switch_interface(struct wifi
*wfi
)
327 dockapp_copyarea(display_link
, pixmap
, 0, 0, 58, 58, 0, 0);
328 draw_text("lnk", 37, 45, False
);
329 draw_text("lvl", 37, 36, False
);
330 draw_text("nse", 37, 27, False
);
331 draw_text("rte", 37, 18, False
);
336 dockapp_copyarea(display_stats
, pixmap
, 0, 0, 58, 58, 0, 0);
337 draw_text("link", 32, 47, False
);
340 dockapp_copy2window(pixmap
);
343 /* called when mouse button pressed */
344 static void draw_ext(struct wifi
*wfi
)
347 double rate
= wfi
->bitrate
.value
;
349 if (lwfi
.link
!= wfi
->link
) {
350 sprintf(buffer
, "%.f", wfi
->link
);
351 draw_text(buffer
, 15, 45, True
);
354 if (lwfi
.level
!= wfi
->level
) {
355 sprintf(buffer
, "%d", wfi
->level
- 0x100);
356 draw_text(buffer
, 15, 36, True
);
359 if ((lwfi
.noise
- 0x100) != (wfi
->noise
- 0x100)) {
360 sprintf(buffer
, "%d", wfi
->noise
- 0x100);
361 draw_text(buffer
, 15, 27, True
);
364 if (lwfi
.bitrate
.value
!= wfi
->bitrate
.value
) {
366 sprintf(buffer
, "%.fgb", rate
/ GIGA
);
367 draw_text(buffer
, 9, 18, False
);
370 sprintf(buffer
, "%.fmb", (rate
/ MEGA
));
371 draw_text(buffer
, 9, 18, False
);
373 sprintf(buffer
, "%.fkb", rate
/ KILO
);
374 draw_text(buffer
, 3, 18, False
);
380 static void draw_text(char *text
, int dx
, int dy
, Bool digit
)
382 int ax
, ay
= 1, bx
, len
, i
;
383 char tmptext
[255] = "";
389 for (i = 0; i < len; i++) {
390 digit = (!isalpha(text[i])) ? True : False;
397 strcat(tmptext
, text
);
399 strcat(tmptext
, text
);
402 tmptext
[1] = text
[0];
403 tmptext
[2] = text
[1];
409 tmptext
[2] = text
[0];
413 strcpy(tmptext
, text
);
416 for (i
= 0; i
< len
; i
++) {
417 if (isalpha(tmptext
[i
])) {
418 ax
= ((tolower(tmptext
[i
]) - 97) * 6) + 1;
421 ax
= ((tmptext
[i
] - 33) * 6) + 1;
425 if (tmptext
[i
] == 0x20)
428 dockapp_copyarea(fonts
, pixmap
, ax
, ay
, 6, 8, dx
, dy
);
434 static void draw_junk(struct wifi
*wfi
)
441 if (lwfi
.link
!= wfi
->link
) {
443 if (wfi
->max_qual
> -1) {
447 /* Calculate Link percentage */
448 percent
= num
/ (wfi
->max_qual
/ 100);
453 sprintf(tmp
, "%d", num
);
454 draw_text(tmp
, 6, 47, True
);
456 dockapp_copyarea(display_link
, pixmap
, 10, 21, 15, 24, 10, 21);
457 dockapp_copyarea(display_link
, pixmap
, 37, 16, 18, 30, 37, 16);
460 /* Level bar 1 ( > 1 - 20%) */
461 dockapp_copyarea(parts
, pixmap
, 70, 27, 2, 2, 37, 44);
464 /* Level bar 2 (18.4 - 40%) */
465 dockapp_copyarea(parts
, pixmap
, 70, 27, 2, 2, 41, 44);
466 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 41, 37);
468 dockapp_copyarea(parts
, pixmap
, 2, y1
, 15, 24, 10, 21);
471 /* Level bar 3 (36.8 - 60%) */
472 dockapp_copyarea(parts
, pixmap
, 70, 27, 2, 2, 45, 44);
473 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 45, 37);
474 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 45, 30);
476 dockapp_copyarea(parts
, pixmap
, 18, y1
, 15, 24, 10, 21);
479 dockapp_copyarea(parts
, pixmap
, 70, 27, 2, 2, 49, 44);
480 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 49, 37);
481 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 49, 30);
482 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 49, 23);
484 dockapp_copyarea(parts
, pixmap
, 34, y1
, 15, 24, 10, 21);
487 /* Level bar 5 (73.6 - 100%) */
488 dockapp_copyarea(parts
, pixmap
, 70, 27, 2, 2, 53, 44);
489 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 53, 37);
490 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 53, 30);
491 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 53, 23);
492 dockapp_copyarea(parts
, pixmap
, 74, 22, 2, 7, 53, 16);
494 dockapp_copyarea(parts
, pixmap
, 50, y1
, 15, 24, 10, 21);
500 static void copy_wifi(struct wifi
*lwfi
, struct wifi
*wfi
)
502 memcpy(lwfi
->ifname
, wfi
->ifname
, 255);
503 memcpy(lwfi
->essid
, wfi
->essid
, IW_ESSID_MAX_SIZE
+ 1);
504 lwfi
->ifnum
= wfi
->ifnum
;
505 lwfi
->link
= wfi
->link
;
506 lwfi
->level
= wfi
->level
;
507 lwfi
->noise
= wfi
->noise
;
508 lwfi
->bitrate
.value
= wfi
->bitrate
.value
;
510 static void clear_wifi(struct wifi
*wfi
)
512 //memcpy(wfi->ifname, 0, 255);
513 //memcpy(wfi->essid, 0, IW_ESSID_MAX_SIZE + 1);
515 wfi
->link
= (float) 0;
517 wfi
->noise
= 0 - 0x100;
518 wfi
->bitrate
.value
= 0;
520 static void parse_arguments(int argc
, char **argv
)
524 //dockapp_isbrokenwm = True;
526 /* Default to Classic Theme */
527 tcur
.bg
= "rgb:8e/96/8a";
528 tcur
.hi
= "rgb:76/7c/6f";
529 tcur
.mt
= "rgb:44/44/44";
530 tcur
.fg
= "rgb:00/00/00";
531 blgt
.bg
= "rgb:6E/C6/3B";
532 blgt
.fg
= "rgb:00/00/00";
533 blgt
.mt
= "rgb:00/00/00";
534 blgt
.hi
= "rgb:6c/b2/37";
537 for (i
= 1; i
< argc
; i
++) {
538 if (!strcmp(argv
[i
], "--help") || !strcmp(argv
[i
], "-h"))
539 print_help(argv
[0]), exit(0);
540 else if (!strcmp(argv
[i
], "--version") || !strcmp(argv
[i
], "-v"))
541 printf("%s version %s\n", PACKAGE
, VERSION
), exit(0);
542 else if (!strcmp(argv
[i
], "--display") || !strcmp(argv
[i
], "-d")) {
543 display_name
= argv
[i
+ 1];
545 } else if (!strcmp(argv
[i
], "--backlight")
546 || !strcmp(argv
[i
], "-bl")) {
548 } else if (!strcmp(argv
[i
], "--light-color")
549 || !strcmp(argv
[i
], "-lc")) {
550 light_color
= argv
[i
+ 1];
551 blgt
.bg
= argv
[i
+ 1];
553 } else if (!strcmp(argv
[i
], "--interval")
554 || !strcmp(argv
[i
], "-i")) {
557 "%s: error parsing argument for option %s\n",
558 argv
[0], argv
[i
]), exit(1);
559 if (sscanf(argv
[i
+ 1], "%i", &integer
) != 1)
561 "%s: error parsing argument for option %s\n",
562 argv
[0], argv
[i
]), exit(1);
564 fprintf(stderr
, "%s: argument %s must be >=1\n",
565 argv
[0], argv
[i
]), exit(1);
566 update_interval
= integer
;
568 } else if (!strcmp(argv
[i
], "--learn")
569 || !strcmp(argv
[i
], "-l")) {
571 } else if (!strcmp(argv
[i
], "--scroll-on")
572 || !strcmp(argv
[i
], "+s")) {
574 } else if (!strcmp(argv
[i
], "--scroll-off")
575 || !strcmp(argv
[i
], "-s")) {
577 } else if (!strcmp(argv
[i
], "--windowed")
578 || !strcmp(argv
[i
], "-w")) {
579 dockapp_iswindowed
= True
;
580 } else if (!strcmp(argv
[i
], "--theme-classic")
581 || !strcmp(argv
[i
], "-tc")) {
582 tcur
.bg
= "rgb:8e/96/8a";
583 tcur
.hi
= "rgb:76/7c/6f";
584 tcur
.mt
= "rgb:44/44/44";
585 tcur
.fg
= "rgb:00/00/00";
586 } else if (!strcmp(argv
[i
], "--theme-snow")
587 || !strcmp(argv
[i
], "-ts")) {
588 tcur
.hi
= "rgb:cc/cc/cc";
589 tcur
.mt
= "rgb:aa/aa/aa";
590 tcur
.bg
= "rgb:ff/ff/ff";
591 tcur
.fg
= "rgb:00/00/00";
592 } else if (!strcmp(argv
[i
], "--theme-new")
593 || !strcmp(argv
[i
], "-tn")) {
594 tcur
.hi
= "rgb:00/49/41";
595 tcur
.mt
= "rgb:02/7e/72";
596 tcur
.bg
= "rgb:20/20/20";
597 tcur
.fg
= "rgb:20/b2/ae";
598 } else if (!strcmp(argv
[i
], "--hilight-color")
599 || !strcmp(argv
[i
], "-hi")) {
600 tcur
.hi
= argv
[i
+ 1];
602 } else if (!strcmp(argv
[i
], "--midtone-color")
603 || !strcmp(argv
[i
], "-mt")) {
604 tcur
.mt
= argv
[i
+ 1];
606 } else if (!strcmp(argv
[i
], "--background-color")
607 || !strcmp(argv
[i
], "-bg")) {
608 tcur
.bg
= argv
[i
+ 1];
610 } else if (!strcmp(argv
[i
], "--foreground-color")
611 || !strcmp(argv
[i
], "-fg")) {
612 tcur
.fg
= argv
[i
+ 1];
614 } else if (!strcmp(argv
[i
], "--broken-wm")
615 || !strcmp(argv
[i
], "-bw"))
616 dockapp_isbrokenwm
= True
;
618 fprintf(stderr
, "%s: unrecognized option '%s'\n", argv
[0],
620 print_help(argv
[0]), exit(1);
625 static void print_help(char *prog
)
627 printf("Usage : %s [OPTIONS]\n", prog
);
628 printf("wmwifi - Wireless signal strength monitor dockapp\n");
629 printf(" -d, --display <string> display to use\n");
630 printf(" -bl, --backlight turn on back-light\n");
632 (" -lc, --light-color <string> back-light color(rgb:6E/C6/3B is default)\n");
634 (" -fg, --foreground-color <string> foreground color(rgb:00/00/00 is default)\n");
636 (" -bg, --background-color <string> background color(rgb:8e/96/8a is default)\n");
638 (" -hc, --hilight-color <string> background highlight color(rgb:76/7c/6f is default)\n");
640 (" -mt, --midtone-color <string> midtone highlight color(rgb:44/44/44 is default)\n");
642 (" -i, --interval <number> number of secs between updates (1 is default)\n");
644 (" -h, --help show this help text and exit\n");
646 (" -v, --version show program version and exit\n");
648 (" -w, --windowed run the application in windowed mode\n");
650 (" -bw, --broken-wm activate broken window manager fix\n");
652 (" -l, --learn enter learning mode (may break quality)\n");
654 (" +s, --scroll-on scroll interface name and essid\n");
656 (" -s, --scroll-off use <= 0.5 style interface and essid\n");
658 (" -tc, --theme-classic Theme: use <= 0.5 style interface theme\n");
659 printf(" -ts, --theme-snow Theme: Snow\n");
660 printf(" -tn, --theme-new Theme: New\n");