Initial dockapps git repo
[dockapps.git] / wmwifi-0.6 / src / wmwifi.c
blob6123c32fa10c88160b4360ab32bf4700012be854
1 /*
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., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "dockapp.h"
27 #include <dockapp.h>
28 #include "display_link.xpm"
29 #include "display_stats.xpm"
30 #include "parts.xpm"
31 #include "font.xpm"
32 #include "wmwifi.h"
34 #define SIZE 58
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;
41 Pixmap pixmap;
42 Pixmap fonts;
43 Pixmap backdrop_on;
44 Pixmap display_link;
45 Pixmap display_stats;
46 Pixmap backdrop_on_stats;
47 Pixmap display_error;
48 Pixmap parts;
49 Pixmap mask;
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;
56 Bool wmwifi_learn;
57 Bool scroll = True;
58 int count;
59 struct theme {
60 char *bg;
61 char *fg;
62 char *hi;
63 char *mt;
65 struct theme tcur;
66 struct theme blgt;
67 struct wifi lwfi;
69 /* prototypes */
70 static void update(struct wifi *wfi);
71 static void switch_interface(struct wifi *wfi);
72 static void do_theme(struct theme thm);
73 static void draw_junk(struct wifi *wfi);
74 static void draw_ext(struct wifi *wfi);
75 static void draw_text(char *text, int dx, int dy, Bool digit);
76 static void parse_arguments(int argc, char **argv);
77 static void print_help(char *prog);
78 static void copy_wifi(struct wifi *lwfi, struct wifi *wfi);
79 static void clear_wifi(struct wifi *wfi);
80 static void refresh(struct theme thm);
82 int main(int argc, char **argv)
84 XEvent event;
85 XButtonPressedEvent *bevent;
86 int i;
87 struct wifi wfi;
89 wfi.ifnum = 0;
91 /* Parse CommandLine */
92 parse_arguments(argc, argv);
94 /* Initialize Application */
95 dockapp_open_window(display_name, PACKAGE, SIZE, SIZE, argc, argv);
96 dockapp_set_eventmask(ButtonPressMask);
98 if (backlight == LIGHTON) {
99 do_theme(blgt);
100 } else {
101 do_theme(tcur);
104 /* shape window */
105 if (!dockapp_iswindowed)
106 dockapp_setshape(mask, 0, 0);
107 if (mask)
108 XFreePixmap(display, mask);
110 /* pixmap : draw area */
111 pixmap = dockapp_XCreatePixmap(SIZE, SIZE);
113 /* Initialize pixmap */
115 if (gui == STANDARD)
116 dockapp_copyarea(display_link, pixmap, 0, 0, SIZE, SIZE, 0, 0);
117 else
118 dockapp_copyarea(display_stats, pixmap, 0, 0, SIZE, SIZE, 0, 0);
120 dockapp_set_background(pixmap);
121 dockapp_show();
122 draw_text("link", 32, 47, False);
124 /* Main loop */
125 for (i = 0;; i++) {
126 /* CHANGED */
127 if (dockapp_nextevent_or_timeout(&event, update_interval * 100)) {
128 /* Next Event */
129 switch (event.type) {
130 case ButtonPress:
131 bevent = (XButtonPressedEvent *) & event;
132 switch (bevent->button & 0xff) {
133 case Button1:
134 scroll = (scroll) ? False : True;
135 count = 0;
136 break;
137 case Button2:
138 next_if(&wfi);
139 break;
140 case Button3:
141 switch_interface(&wfi);
142 break;
144 break;
145 default: /* make gcc happy */
146 break;
148 } else {
149 /* Time Out */
150 update(&wfi);
154 return 0;
157 static void do_theme(struct theme thm)
159 XpmColorSymbol colors[4] =
160 { {"Back0", NULL, 0}, {"Fore0", NULL, 0}, {"High0", NULL, 0},
161 {"Mid0", NULL, 0}
163 int ncolor = 0;
164 int i;
166 colors[0].pixel = dockapp_getcolor(thm.bg);
167 colors[1].pixel = dockapp_getcolor(thm.fg);
168 colors[2].pixel = dockapp_getcolor(thm.hi);
169 colors[3].pixel = dockapp_getcolor(thm.mt);
170 ncolor = 4;
171 /* change raw xpm data to pixmap */
172 if (dockapp_iswindowed)
173 display_link_xpm[1] = WINDOWED_BG;
175 if (!dockapp_xpm2pixmap
176 (display_link_xpm, &display_link, &mask, colors, ncolor)) {
177 fprintf(stderr, "Error initializing background image.\n");
178 exit(1);
180 if (!dockapp_xpm2pixmap
181 (display_stats_xpm, &display_stats, &mask, colors, ncolor)) {
182 fprintf(stderr, "Error initializing background image.\n");
183 exit(1);
185 if (!dockapp_xpm2pixmap(parts_xpm, &parts, NULL, colors, ncolor)) {
186 fprintf(stderr, "Error initializing parts image.\n");
187 exit(1);
189 if (!dockapp_xpm2pixmap(font_xpm, &fonts, NULL, colors, ncolor)) {
190 fprintf(stderr, "Error initializing fonts image.\n");
191 exit(1);
195 /* called by timer */
196 static void update(struct wifi *wfi)
198 int sw, percent;
199 extern int count;
200 //char *str = calloc(1, sizeof(wfi->ifname) + sizeof(wfi->essid) + 3);
201 char str[512];
203 /* get current link level from /proc/net/wireless */
204 copy_wifi(&lwfi, wfi);
205 get_wifi_info(wfi);
207 if (wfi->max_qual == -1) {
208 tcur.bg = "rgb:ff/0/0";
209 tcur.fg = "rgb:0/0/0";
210 tcur.mt = "rgb:00/00/00";
211 do_theme(tcur);
212 dockapp_copyarea(display_link, pixmap, 0, 0, 58, 58, 0, 0);
213 draw_text("ERROR", (56 / 2) - 5 * 2.5, 4, False);
214 } else {
215 /* all clear */
217 /* If percent == 0, show backlight */
218 percent = wfi->link / (wfi->max_qual / 100);
219 if (percent > 0) {
220 if (backlight == LIGHTON) {
221 refresh(tcur);
223 backlight = LIGHTOFF;
224 } else {
225 if (backlight == LIGHTOFF) {
226 refresh(blgt);
228 backlight = LIGHTON;
231 if (gui == STANDARD) {
232 if (gui != lgui) {
233 if (backlight == LIGHTOFF)
234 refresh(tcur);
235 else
236 refresh(blgt);
237 lgui = gui;
239 /* draw junk */
240 draw_junk(wfi);
241 } else {
242 if (gui != lgui) {
243 if (backlight == LIGHTOFF)
244 refresh(tcur);
245 else
246 refresh(blgt);
247 lgui = gui;
249 draw_ext(wfi);
251 count++;
252 if (scroll) {
253 dockapp_copyarea(display_link, pixmap, 0, 0, 58, 12, 0, 0);
254 snprintf(str, strlen(wfi->ifname) + strlen(wfi->essid) + 4,
255 "%s - %s", wfi->ifname, wfi->essid);
256 draw_text(str, 52 - (count * 3), 4, False);
257 dockapp_copyarea(display_link, pixmap, 0, 0, 4, 12, 0, 0);
258 dockapp_copyarea(display_link, pixmap, 55, 0, 3, 12, 55, 0);
259 if (count > (strlen(str) * 3))
260 count = 1;
261 } else {
262 if (count < 50)
263 sw = 1;
264 if (count >= 50)
265 sw = 2;
266 if (count == 100)
267 count = -1;
268 switch (sw) {
269 case 1:
270 dockapp_copyarea(display_link, pixmap, 0, 0, 58, 12, 0, 0);
271 draw_text(wfi->ifname,
272 ((56 / 2) - (strlen(wfi->ifname) * 2)), 4,
273 False);
274 dockapp_copyarea(display_link, pixmap, 0, 0, 4, 12, 0, 0);
275 dockapp_copyarea(display_link, pixmap, 55, 0, 3, 12, 55,
277 break;
278 case 2:
279 dockapp_copyarea(display_link, pixmap, 0, 0, 58, 12, 0, 0);
280 draw_text(wfi->essid,
281 ((56 / 2) - (strlen(wfi->essid) * 2)), 4, False);
282 dockapp_copyarea(display_link, pixmap, 0, 0, 4, 12, 0, 0);
283 dockapp_copyarea(display_link, pixmap, 55, 0, 3, 12, 55,
285 break;
288 /* show */
290 dockapp_copy2window(pixmap);
292 static void refresh(struct theme thm)
294 do_theme(thm);
295 switch (gui) {
296 case STANDARD:
297 dockapp_copyarea(display_link, pixmap, 0, 0, 58, 58, 0, 0);
298 clear_wifi(&lwfi);
299 draw_text("link", 32, 47, False);
300 break;
301 case EXTENDED:
302 dockapp_copyarea(display_stats, pixmap, 0, 0, 58, 58, 0, 0);
303 clear_wifi(&lwfi);
304 draw_text("lnk", 37, 45, False);
305 draw_text("lvl", 37, 36, False);
306 draw_text("nse", 37, 27, False);
307 draw_text("rte", 37, 18, False);
308 break;
312 static void switch_interface(struct wifi *wfi)
314 switch (gui) {
315 case STANDARD:
316 lgui = gui;
317 gui = EXTENDED;
318 dockapp_copyarea(display_link, pixmap, 0, 0, 58, 58, 0, 0);
319 draw_text("lnk", 37, 45, False);
320 draw_text("lvl", 37, 36, False);
321 draw_text("nse", 37, 27, False);
322 draw_text("rte", 37, 18, False);
323 break;
324 case EXTENDED:
325 lgui = gui;
326 gui = STANDARD;
327 dockapp_copyarea(display_stats, pixmap, 0, 0, 58, 58, 0, 0);
328 draw_text("link", 32, 47, False);
329 break;
331 dockapp_copy2window(pixmap);
334 /* called when mouse button pressed */
335 static void draw_ext(struct wifi *wfi)
337 char buffer[25];
338 double rate = wfi->bitrate.value;
340 if (lwfi.link != wfi->link) {
341 sprintf(buffer, "%.f", wfi->link);
342 draw_text(buffer, 15, 45, True);
345 if (lwfi.level != wfi->level) {
346 sprintf(buffer, "%d", wfi->level - 0x100);
347 draw_text(buffer, 15, 36, True);
350 if ((lwfi.noise - 0x100) != (wfi->noise - 0x100)) {
351 sprintf(buffer, "%d", wfi->noise - 0x100);
352 draw_text(buffer, 15, 27, True);
355 if (lwfi.bitrate.value != wfi->bitrate.value) {
356 if (rate >= GIGA) {
357 sprintf(buffer, "%.fgb", rate / GIGA);
358 draw_text(buffer, 9, 18, False);
359 } else {
360 if (rate >= MEGA) {
361 sprintf(buffer, "%.fmb", (rate / MEGA));
362 draw_text(buffer, 9, 18, False);
363 } else {
364 sprintf(buffer, "%.fkb", rate / KILO);
365 draw_text(buffer, 3, 18, False);
371 static void draw_text(char *text, int dx, int dy, Bool digit)
373 int ax, ay = 1, bx, len, i;
374 char tmptext[255] = "";
376 len = strlen(text);
377 bx = 4;
380 for (i = 0; i < len; i++) {
381 digit = (!isalpha(text[i])) ? True : False;
385 if (digit) {
386 if (len == 4)
387 dx -= 6;
388 strcat(tmptext, text);
389 if (len == 3)
390 strcat(tmptext, text);
391 if (len == 2) {
392 tmptext[0] = 0x20;
393 tmptext[1] = text[0];
394 tmptext[2] = text[1];
395 len++;
397 if (len == 1) {
398 tmptext[0] = ' ';
399 tmptext[1] = ' ';
400 tmptext[2] = text[0];
401 len += 2;
403 } else {
404 strcpy(tmptext, text);
407 for (i = 0; i < len; i++) {
408 if (isalpha(tmptext[i])) {
409 ax = ((tolower(tmptext[i]) - 97) * 6) + 1;
410 ay = 1;
411 } else {
412 ax = ((tmptext[i] - 33) * 6) + 1;
413 ay = 10;
415 /* Space */
416 if (tmptext[i] == 0x20)
417 ax = 79;
418 /* Draw Text */
419 dockapp_copyarea(fonts, pixmap, ax, ay, 6, 8, dx, dy);
420 dx += 6;
425 static void draw_junk(struct wifi *wfi)
427 int num = wfi->link;
428 int percent;
429 int y1 = 5;
430 char tmp[255];
432 if (lwfi.link != wfi->link) {
434 if (wfi->max_qual > -1) {
435 if (num < 0)
436 num = 0;
438 /* Calculate Link percentage */
439 percent = num / (wfi->max_qual / 100);
440 num = percent;
442 /* draw digits */
444 sprintf(tmp, "%d", num);
445 draw_text(tmp, 6, 47, True);
447 dockapp_copyarea(display_link, pixmap, 10, 21, 15, 24, 10, 21);
448 dockapp_copyarea(display_link, pixmap, 37, 16, 18, 30, 37, 16);
450 if (num > 0) {
451 /* Level bar 1 ( > 1 - 20%) */
452 dockapp_copyarea(parts, pixmap, 70, 27, 2, 2, 37, 44);
454 if (num > 20) {
455 /* Level bar 2 (18.4 - 40%) */
456 dockapp_copyarea(parts, pixmap, 70, 27, 2, 2, 41, 44);
457 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 41, 37);
458 /* Antenna */
459 dockapp_copyarea(parts, pixmap, 2, y1, 15, 24, 10, 21);
461 if (num > 40) {
462 /* Level bar 3 (36.8 - 60%) */
463 dockapp_copyarea(parts, pixmap, 70, 27, 2, 2, 45, 44);
464 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 45, 37);
465 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 45, 30);
466 /* Antenna */
467 dockapp_copyarea(parts, pixmap, 18, y1, 15, 24, 10, 21);
469 if (num > 60) {
470 dockapp_copyarea(parts, pixmap, 70, 27, 2, 2, 49, 44);
471 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 49, 37);
472 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 49, 30);
473 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 49, 23);
474 /* Antenna */
475 dockapp_copyarea(parts, pixmap, 34, y1, 15, 24, 10, 21);
477 if (num > 80) {
478 /* Level bar 5 (73.6 - 100%) */
479 dockapp_copyarea(parts, pixmap, 70, 27, 2, 2, 53, 44);
480 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 53, 37);
481 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 53, 30);
482 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 53, 23);
483 dockapp_copyarea(parts, pixmap, 74, 22, 2, 7, 53, 16);
484 /* Antenna */
485 dockapp_copyarea(parts, pixmap, 50, y1, 15, 24, 10, 21);
491 static void copy_wifi(struct wifi *lwfi, struct wifi *wfi)
493 memcpy(lwfi->ifname, wfi->ifname, 255);
494 memcpy(lwfi->essid, wfi->essid, IW_ESSID_MAX_SIZE + 1);
495 lwfi->ifnum = wfi->ifnum;
496 lwfi->link = wfi->link;
497 lwfi->level = wfi->level;
498 lwfi->noise = wfi->noise;
499 lwfi->bitrate.value = wfi->bitrate.value;
501 static void clear_wifi(struct wifi *wfi)
503 //memcpy(wfi->ifname, 0, 255);
504 //memcpy(wfi->essid, 0, IW_ESSID_MAX_SIZE + 1);
505 wfi->ifnum = 0;
506 wfi->link = (float) 0;
507 wfi->level = 0;
508 wfi->noise = 0 - 0x100;
509 wfi->bitrate.value = 0;
511 static void parse_arguments(int argc, char **argv)
513 int i;
514 int integer;
515 //dockapp_isbrokenwm = True;
517 /* Default to Classic Theme */
518 tcur.bg = "rgb:8e/96/8a";
519 tcur.hi = "rgb:76/7c/6f";
520 tcur.mt = "rgb:44/44/44";
521 tcur.fg = "rgb:00/00/00";
522 blgt.bg = "rgb:6E/C6/3B";
523 blgt.fg = "rgb:00/00/00";
524 blgt.mt = "rgb:00/00/00";
525 blgt.hi = "rgb:6c/b2/37";
528 for (i = 1; i < argc; i++) {
529 if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
530 print_help(argv[0]), exit(0);
531 else if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-v"))
532 printf("%s version %s\n", PACKAGE, VERSION), exit(0);
533 else if (!strcmp(argv[i], "--display") || !strcmp(argv[i], "-d")) {
534 display_name = argv[i + 1];
535 i++;
536 } else if (!strcmp(argv[i], "--backlight")
537 || !strcmp(argv[i], "-bl")) {
538 backlight = LIGHTON;
539 } else if (!strcmp(argv[i], "--light-color")
540 || !strcmp(argv[i], "-lc")) {
541 light_color = argv[i + 1];
542 blgt.bg = argv[i + 1];
543 i++;
544 } else if (!strcmp(argv[i], "--interval")
545 || !strcmp(argv[i], "-i")) {
546 if (argc == i + 1)
547 fprintf(stderr,
548 "%s: error parsing argument for option %s\n",
549 argv[0], argv[i]), exit(1);
550 if (sscanf(argv[i + 1], "%i", &integer) != 1)
551 fprintf(stderr,
552 "%s: error parsing argument for option %s\n",
553 argv[0], argv[i]), exit(1);
554 if (integer < 1)
555 fprintf(stderr, "%s: argument %s must be >=1\n",
556 argv[0], argv[i]), exit(1);
557 update_interval = integer;
558 i++;
559 } else if (!strcmp(argv[i], "--learn")
560 || !strcmp(argv[i], "-l")) {
561 wmwifi_learn = True;
562 } else if (!strcmp(argv[i], "--scroll-on")
563 || !strcmp(argv[i], "+s")) {
564 scroll = True;
565 } else if (!strcmp(argv[i], "--scroll-off")
566 || !strcmp(argv[i], "-s")) {
567 scroll = False;
568 } else if (!strcmp(argv[i], "--windowed")
569 || !strcmp(argv[i], "-w")) {
570 dockapp_iswindowed = True;
571 } else if (!strcmp(argv[i], "--theme-classic")
572 || !strcmp(argv[i], "-tc")) {
573 tcur.bg = "rgb:8e/96/8a";
574 tcur.hi = "rgb:76/7c/6f";
575 tcur.mt = "rgb:44/44/44";
576 tcur.fg = "rgb:00/00/00";
577 } else if (!strcmp(argv[i], "--theme-snow")
578 || !strcmp(argv[i], "-ts")) {
579 tcur.hi = "rgb:cc/cc/cc";
580 tcur.mt = "rgb:aa/aa/aa";
581 tcur.bg = "rgb:ff/ff/ff";
582 tcur.fg = "rgb:00/00/00";
583 } else if (!strcmp(argv[i], "--theme-new")
584 || !strcmp(argv[i], "-tn")) {
585 tcur.hi = "rgb:00/49/41";
586 tcur.mt = "rgb:02/7e/72";
587 tcur.bg = "rgb:20/20/20";
588 tcur.fg = "rgb:20/b2/ae";
589 } else if (!strcmp(argv[i], "--hilight-color")
590 || !strcmp(argv[i], "-hi")) {
591 tcur.hi = argv[i + 1];
592 i++;
593 } else if (!strcmp(argv[i], "--midtone-color")
594 || !strcmp(argv[i], "-mt")) {
595 tcur.mt = argv[i + 1];
596 i++;
597 } else if (!strcmp(argv[i], "--background-color")
598 || !strcmp(argv[i], "-bg")) {
599 tcur.bg = argv[i + 1];
600 i++;
601 } else if (!strcmp(argv[i], "--foreground-color")
602 || !strcmp(argv[i], "-fg")) {
603 tcur.fg = argv[i + 1];
604 i++;
605 } else if (!strcmp(argv[i], "--broken-wm")
606 || !strcmp(argv[i], "-bw"))
607 dockapp_isbrokenwm = True;
608 else {
609 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0],
610 argv[i]);
611 print_help(argv[0]), exit(1);
616 static void print_help(char *prog)
618 printf("Usage : %s [OPTIONS]\n", prog);
619 printf("wmwifi - Wireless signal strength monitor dockapp\n");
620 printf(" -d, --display <string> display to use\n");
621 printf(" -bl, --backlight turn on back-light\n");
622 printf
623 (" -lc, --light-color <string> back-light color(rgb:6E/C6/3B is default)\n");
624 printf
625 (" -fg, --foreground-color <string> foreground color(rgb:00/00/00 is default)\n");
626 printf
627 (" -bg, --background-color <string> background color(rgb:8e/96/8a is default)\n");
628 printf
629 (" -hc, --hilight-color <string> background highlight color(rgb:76/7c/6f is default)\n");
630 printf
631 (" -mt, --midtone-color <string> midtone highlight color(rgb:44/44/44 is default)\n");
632 printf
633 (" -i, --interval <number> number of secs between updates (1 is default)\n");
634 printf
635 (" -h, --help show this help text and exit\n");
636 printf
637 (" -v, --version show program version and exit\n");
638 printf
639 (" -w, --windowed run the application in windowed mode\n");
640 printf
641 (" -bw, --broken-wm activate broken window manager fix\n");
642 printf
643 (" -l, --learn enter learning mode (may break quality)\n");
644 printf
645 (" +s, --scroll-on scroll interface name and essid\n");
646 printf
647 (" -s, --scroll-off use <= 0.5 style interface and essid\n");
648 printf
649 (" -tc, --theme-classic Theme: use <= 0.5 style interface theme\n");
650 printf(" -ts, --theme-snow Theme: Snow\n");
651 printf(" -tn, --theme-new Theme: New\n");