wmbiff: tidy up socket connexions.
[dockapps.git] / wmwlmon / wmwlmon.c
blob795e72a53b3c966ea70b357e1f241049d5dead48
1 /* $Id: wmwlmon.c,v 1.41 2008/05/13 09:26:22 hacki Exp $ */
3 /*
4 * Copyright (c) 2005, 2006 Marcus Glocker <marcus@nazgul.ch>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <ctype.h>
20 #include <err.h>
21 #include <limits.h>
22 #include <math.h>
23 #include <signal.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <X11/X.h>
29 #include <X11/xpm.h>
31 #include "wl.h"
32 #include "xutils.h"
33 #include "bitmaps/wmwlmon_mask.xbm"
34 #include "bitmaps/wmwlmon_master.xpm"
37 * defines
39 #define DELAY 10000
40 #define NWIDLENP 52
41 #define NWIDLENC 8
44 * prototypes
46 int main(int, char **);
47 void usage(int);
48 void signal_handler(const int);
49 void debugloop(char *);
50 void draw_nwid(char *, int);
51 void draw_string(const char *, const int, const int);
52 void draw_signal(const int, const int);
53 int scroll_lcd(const int, const int, const int, const int, const int,
54 const char *);
55 int scroll_bounce(const int, const int, const int, const int, const int,
56 const char *);
57 int scroll_fade(const int, const int, const int, const int, const int,
58 const char *);
61 * global variables for this file
63 static const char *version = "1.0";
64 volatile sig_atomic_t quit = 0;
65 char TimeColor[30] = "#ffff00";
66 char BackgroundColor[30] = "#181818";
68 struct coordinates {
69 int x;
70 int y;
71 int w;
72 int h;
73 } fonts[128] = {
74 { 60, 102, 6, 8 }, /* Dec 0 nul NOTUSED */
75 { 60, 102, 6, 8 }, /* Dec 1 soh NOTUSED */
76 { 60, 102, 6, 8 }, /* Dec 2 stx NOTUSED */
77 { 60, 102, 6, 8 }, /* Dec 3 etx NOTUSED */
78 { 60, 102, 6, 8 }, /* Dec 4 eot NOTUSED */
79 { 60, 102, 6, 8 }, /* Dec 5 enq NOTUSED */
80 { 60, 102, 6, 8 }, /* Dec 6 ack NOTUSED */
81 { 60, 102, 6, 8 }, /* Dec 7 bel NOTUSED */
82 { 60, 102, 6, 8 }, /* Dec 8 bs NOTUSED */
83 { 60, 102, 6, 8 }, /* Dec 9 ht NOTUSED */
84 { 60, 102, 6, 8 }, /* Dec 10 nl NOTUSED */
85 { 60, 102, 6, 8 }, /* Dec 11 vt NOTUSED */
86 { 60, 102, 6, 8 }, /* Dec 12 np NOTUSED */
87 { 60, 102, 6, 8 }, /* Dec 13 cr NOTUSED */
88 { 60, 102, 6, 8 }, /* Dec 14 so NOTUSED */
89 { 60, 102, 6, 8 }, /* Dec 15 si NOTUSED */
90 { 60, 102, 6, 8 }, /* Dec 16 dle NOTUSED */
91 { 60, 102, 6, 8 }, /* Dec 17 dc1 NOTUSED */
92 { 60, 102, 6, 8 }, /* Dec 18 dc2 NOTUSED */
93 { 60, 102, 6, 8 }, /* Dec 19 dc3 NOTUSED */
94 { 60, 102, 6, 8 }, /* Dec 20 dc4 NOTUSED */
95 { 60, 102, 6, 8 }, /* Dec 21 nak NOTUSED */
96 { 60, 102, 6, 8 }, /* Dec 22 syn NOTUSED */
97 { 60, 102, 6, 8 }, /* Dec 23 etb NOTUSED */
98 { 60, 102, 6, 8 }, /* Dec 24 can NOTUSED */
99 { 60, 102, 6, 8 }, /* Dec 25 em NOTUSED */
100 { 60, 102, 6, 8 }, /* Dec 26 sub NOTUSED */
101 { 60, 102, 6, 8 }, /* Dec 27 esc NOTUSED */
102 { 60, 102, 6, 8 }, /* Dec 28 fs NOTUSED */
103 { 60, 102, 6, 8 }, /* Dec 29 gs NOTUSED */
104 { 60, 102, 6, 8 }, /* Dec 30 rs NOTUSED */
105 { 60, 102, 6, 8 }, /* Dec 31 us NOTUSED */
106 { 60, 102, 6, 8 }, /* Dec 32 sp NOTUSED */
107 { 66, 102, 6, 8 }, /* Dec 33 '!' */
108 { 72, 102, 6, 8 }, /* Dec 34 '"' */
109 { 78, 102, 6, 8 }, /* Dec 35 '#' */
110 { 60, 102, 6, 8 }, /* Dec 36 '$' NOTUSED */
111 { 90, 101, 6, 8 }, /* Dec 37 '%' */
112 { 96, 102, 6, 8 }, /* Dec 38 '&' */
113 { 102, 102, 6, 8 }, /* Dec 39 ''' */
114 { 108, 102, 6, 8 }, /* Dec 40 '(' */
115 { 114, 102, 6, 8 }, /* Dec 41 ')' */
116 { 120, 102, 6, 8 }, /* Dec 42 '*' */
117 { 126, 102, 6, 8 }, /* Dec 43 '+' */
118 { 132, 102, 6, 8 }, /* Dec 44 ',' */
119 { 138, 102, 6, 8 }, /* Dec 45 '-' */
120 { 144, 102, 6, 8 }, /* Dec 46 '.' */
121 { 150, 102, 6, 8 }, /* Dec 47 '/' */
122 { 0, 102, 6, 6 }, /* Dec 48 '0' */
123 { 6, 102, 6, 6 }, /* Dec 49 '1' */
124 { 12, 102, 6, 6 }, /* Dec 50 '2' */
125 { 18, 102, 6, 6 }, /* Dec 51 '3' */
126 { 24, 102, 6, 6 }, /* Dec 52 '4' */
127 { 30, 102, 6, 6 }, /* Dec 53 '5' */
128 { 36, 102, 6, 6 }, /* Dec 54 '6' */
129 { 42, 102, 6, 6 }, /* Dec 55 '7' */
130 { 48, 102, 6, 6 }, /* Dec 56 '8' */
131 { 54, 102, 6, 6 }, /* Dec 57 '9' */
132 { 0, 112, 6, 8 }, /* Dec 58 ':' */
133 { 6, 113, 6, 8 }, /* Dec 59 ';' */
134 { 12, 112, 6, 8 }, /* Dec 60 '<'*/
135 { 18, 112, 6, 8 }, /* Dec 61 '='*/
136 { 24, 112, 6, 8 }, /* Dec 62 '>'*/
137 { 30, 112, 6, 8 }, /* Dec 63 '?'*/
138 { 36, 112, 6, 8 }, /* Dec 64 '@'*/
139 { 0, 79, 6, 8 }, /* Dec 65 'A' */
140 { 6, 79, 6, 8 }, /* Dec 66 'B' */
141 { 12, 79, 6, 8 }, /* Dec 67 'C' */
142 { 18, 79, 6, 8 }, /* Dec 68 'D' */
143 { 24, 79, 6, 8 }, /* Dec 69 'E' */
144 { 30, 79, 6, 8 }, /* Dec 70 'F' */
145 { 36, 79, 6, 8 }, /* Dec 71 'G' */
146 { 42, 79, 6, 8 }, /* Dec 72 'H' */
147 { 48, 79, 6, 8 }, /* Dec 73 'I' */
148 { 54, 79, 6, 8 }, /* Dec 74 'J' */
149 { 60, 79, 6, 8 }, /* Dec 75 'K' */
150 { 66, 79, 6, 8 }, /* Dec 76 'L' */
151 { 72, 79, 6, 8 }, /* Dec 77 'M' */
152 { 78, 79, 6, 8 }, /* Dec 78 'N' */
153 { 84, 79, 6, 8 }, /* Dec 79 'O' */
154 { 90, 79, 6, 8 }, /* Dec 80 'P' */
155 { 96, 79, 6, 8 }, /* Dec 81 'Q' */
156 { 102, 79, 6, 8 }, /* Dec 82 'R' */
157 { 108, 79, 6, 8 }, /* Dec 83 'S' */
158 { 114, 79, 6, 8 }, /* Dec 84 'T' */
159 { 120, 79, 6, 8 }, /* Dec 85 'U' */
160 { 126, 79, 6, 8 }, /* Dec 86 'V' */
161 { 132, 79, 6, 8 }, /* Dec 87 'W' */
162 { 138, 79, 6, 8 }, /* Dec 88 'X' */
163 { 144, 79, 6, 8 }, /* Dec 89 'Y' */
164 { 150, 79, 6, 8 }, /* Dec 90 'Z' */
165 { 42, 112, 6, 8 }, /* Dec 91 '[' */
166 { 48, 112, 6, 8 }, /* Dec 92 '\' */
167 { 54, 112, 6, 8 }, /* Dec 93 ']' */
168 { 60, 112, 6, 8 }, /* Dec 94 '^' */
169 { 66, 113, 6, 8 }, /* Dec 95 '_' */
170 { 72, 112, 6, 8 }, /* Dec 96 '`' */
171 { 0, 90, 6, 8 }, /* Dec 97 'a' */
172 { 6, 90, 6, 8 }, /* Dec 98 'b' */
173 { 12, 90, 6, 8 }, /* Dec 99 'c' */
174 { 18, 90, 6, 8 }, /* Dec 100 'd' */
175 { 24, 90, 6, 8 }, /* Dec 101 'e' */
176 { 30, 90, 6, 8 }, /* Dec 102 'f' */
177 { 36, 90, 6, 8 }, /* Dec 103 'g' */
178 { 42, 90, 6, 8 }, /* Dec 104 'h' */
179 { 48, 90, 6, 8 }, /* Dec 105 'i' */
180 { 54, 90, 6, 8 }, /* Dec 106 'j' */
181 { 60, 90, 6, 8 }, /* Dec 107 'k' */
182 { 66, 90, 6, 8 }, /* Dec 108 'l' */
183 { 72, 90, 6, 8 }, /* Dec 109 'm' */
184 { 78, 90, 6, 8 }, /* Dec 110 'n' */
185 { 84, 90, 6, 8 }, /* Dec 111 'o' */
186 { 90, 90, 6, 8 }, /* Dec 112 'p' */
187 { 96, 90, 6, 8 }, /* Dec 113 'q' */
188 { 102, 90, 6, 8 }, /* Dec 114 'r' */
189 { 108, 90, 6, 8 }, /* Dec 115 's' */
190 { 114, 90, 6, 8 }, /* Dec 116 't' */
191 { 120, 90, 6, 8 }, /* Dec 117 'u' */
192 { 126, 90, 6, 8 }, /* Dec 118 'v' */
193 { 132, 90, 6, 8 }, /* Dec 119 'w' */
194 { 138, 90, 6, 8 }, /* Dec 120 'x' */
195 { 144, 90, 6, 8 }, /* Dec 121 'y' */
196 { 150, 90, 6, 8 }, /* Dec 122 'z' */
197 { 78, 112, 6, 8 }, /* Dec 123 '{' */
198 { 84, 112, 6, 8 }, /* Dec 124 '|' */
199 { 90, 112, 6, 8 }, /* Dec 125 '}' */
200 { 60, 112, 6, 8 }, /* Dec 126 '~' */
201 { 60, 102, 6, 8 } /* Dec 127 del NOTUSED */
205 * usage
207 void
208 usage(int mode)
210 extern char *__progname;
212 if (mode) {
213 fprintf(stderr, "%s %s\n", __progname, version);
214 exit(1);
217 fprintf(stderr, "usage: %s ", __progname);
218 fprintf(stderr, "[-Dhvw] [-i interface] [-s scrolling] ");
219 fprintf(stderr, "[-display display]\n\n");
220 fprintf(stderr, "options:\n");
221 fprintf(stderr, " -D\t\t: Debug mode.\n");
222 fprintf(stderr, " -h\t\t: This help.\n");
223 fprintf(stderr, " -v\t\t: Shows version.\n");
224 fprintf(stderr, " -w\t\t: Enable WaveLAN compatibility.\n");
225 fprintf(stderr, " -i\t\t: Set interface.\n");
226 fprintf(stderr, " -s\t\t: Network ID scrolling.\n");
227 fprintf(stderr, " \t\t 0 = Disable 1 = LCD (default) 2 = Bounce ");
228 fprintf(stderr, "3 = Fade\n");
229 fprintf(stderr, " -display\t: Set display name.\n");
231 exit(1);
235 * signal handler
237 void
238 signal_handler(const int sig)
240 switch (sig) {
241 case SIGINT:
242 /* FALLTHROUGH */
243 case SIGTERM:
244 quit = 1;
245 break;
246 case SIGCHLD:
247 /* ignore */
248 break;
249 case SIGHUP:
250 /* ignore */
251 break;
252 case SIGQUIT:
253 /* ignore */
254 break;
255 case SIGALRM:
256 /* ignore */
257 break;
258 case SIGPIPE:
259 /* ignore */
260 break;
261 default:
262 /* ignore */
263 break;
268 * main()
269 * wireless monitor wmdockapp
270 * Return:
274 main(int argc, char *argv[])
276 int i, r, ch, opt_wavelan = 0;
277 int opt_debug = 0, nic_status = 1, opt_scroll = 1;
278 char *opt_interface = NULL, *opt_display = NULL;
279 char *nwid = NULL, *speed = NULL, *status = NULL;
280 char sig[4], chn[4];
281 #ifdef __OpenBSD__
282 const char *errstr;
283 #endif
284 XEvent event;
287 * get command line options
290 /* keep the old good -display tradition */
291 for (i = 0; i < argc; i++) {
292 if (!strcmp(argv[i], "-display"))
293 argv[i] = "-d";
296 while ((ch = getopt(argc, argv, "Dd:hi:s:vw")) != -1) {
297 switch (ch) {
298 case 'D':
299 opt_debug = 1;
300 break;
301 case 'd':
302 opt_display = strdup(optarg);
303 break;
304 case 'i':
305 opt_interface = strdup(optarg);
306 break;
307 case 's':
308 #ifdef __OpenBSD__
309 opt_scroll = strtonum(optarg, 0, 3, &errstr);
310 if (errstr)
311 usage(0);
312 #else
313 opt_scroll = strtol(optarg, 0, 10);
314 #endif
315 break;
316 case 'v':
317 usage(1);
318 break;
319 case 'w':
320 opt_wavelan = 1;
321 break;
322 case 'h':
323 /* FALLTHROUGH */
324 default:
325 usage(0);
326 /* NOTREACHED */
331 * get interface
333 if (opt_interface == NULL) {
334 /* scan for interface */
335 opt_interface = get_first_wnic();
336 if (opt_interface == NULL) {
337 fprintf(stderr, "No wireless interface found\n");
338 exit(1);
340 } else {
341 /* check defined interface */
342 if (!check_nic(opt_interface)) {
343 fprintf(stderr, "%s: no such interface\n",
344 opt_interface);
345 exit(1);
346 } else {
347 if (get_wep(opt_interface) == -1) {
348 fprintf(stderr, "%s: not a wireless ",
349 opt_interface);
350 fprintf(stderr, "interface\n");
351 exit(1);
355 /* is the interface wi? */
356 if ((strncmp(opt_interface, "wi", 2) == 0) && isdigit(opt_interface[2]))
357 opt_wavelan = 1;
360 * install signal handler
362 signal(SIGINT, signal_handler);
363 signal(SIGTERM, signal_handler);
364 signal(SIGCHLD, signal_handler);
365 signal(SIGHUP, signal_handler);
366 signal(SIGQUIT, signal_handler);
367 signal(SIGALRM, signal_handler);
368 signal(SIGPIPE, signal_handler);
371 * run in debug mode
373 if (opt_debug)
374 debugloop(opt_interface); /* does not return */
377 * init X window
379 initXwindow(opt_display);
382 * open X window
384 openXwindow(argc, argv, wmwlmon_master, wmwlmon_mask_bits,
385 wmwlmon_mask_width, wmwlmon_mask_height);
388 * main loop
390 for (i = 100; !quit; i++) {
392 * get wirless network state and draw it
394 if (i == 100) {
395 /* reset all */
396 i = 0;
397 copyXPMArea(65, 0, 64, 64, 0, 0);
399 /* check if interface still exists */
400 nic_status = check_nic(opt_interface);
401 if (!nic_status)
402 continue;
404 /* interface name */
405 draw_string(opt_interface, 6, 7);
407 /* network status */
408 status = get_status(opt_interface);
409 if (!strcmp(status, "active"))
410 copyXPMArea(0, 67, 4, 4, 53, 8);
412 /* network id */
413 nwid = get_nwid(opt_interface);
415 /* speed */
416 speed = get_speed(opt_interface);
417 if (speed != NULL) {
418 copyXPMArea(28, 67, 23, 8, 29, 36);
419 if (strlen(speed) == 1)
420 draw_string(speed, 18, 36);
421 if (strlen(speed) == 2)
422 draw_string(speed, 12, 36);
423 if (strlen(speed) == 3)
424 draw_string(speed, 6, 36);
427 /* signal strength */
428 if (opt_wavelan)
429 r = get_wi_signal(opt_interface);
430 else
431 r = get_signal(opt_interface, nwid);
433 if (r > 0) {
434 copyXPMArea(15, 67, 10, 6, 30, 29);
435 snprintf(sig, sizeof(sig), "%d", r);
436 if (strlen(sig) == 1)
437 draw_string(sig, 18, 29);
438 if (strlen(sig) == 2)
439 draw_string(sig, 12, 29);
440 if (strlen(sig) == 3)
441 draw_string(sig, 6, 29);
442 if (speed != NULL)
443 draw_signal(atoi(speed), r);
446 /* channel */
447 r = get_channel(opt_interface);
448 if (r > 0) {
449 copyXPMArea(61, 67, 10, 6, 30, 44);
450 snprintf(chn, sizeof(sig), "%d", r);
451 if (strlen(chn) == 1)
452 draw_string(chn, 18, 44);
453 if (strlen(chn) == 2)
454 draw_string(chn, 12, 44);
455 if (strlen(chn) == 3)
456 draw_string(chn, 6, 44);
459 /* wep */
460 r = get_wep(opt_interface);
461 if (r > 0)
462 copyXPMArea(54, 67, 4, 6, 48, 44);
465 if (nwid != NULL && i % 2 == 0 && nic_status) {
466 /* reset nwid area */
467 copyXPMArea(70, 50, 54, 9, 5, 50);
468 draw_nwid(nwid, opt_scroll);
472 * process pending X events
474 while (XPending(display)) {
475 XNextEvent(display, &event);
476 switch(event.type) {
477 case Expose:
478 RedrawWindow();
479 break;
484 * redraw
486 RedrawWindow();
487 usleep(DELAY);
490 exit(0);
493 void
494 debugloop(char *interface)
496 char *status, *nwid, *speed;
497 int r;
500 * debug loop
502 while (!quit) {
503 /* check if interface still exists */
504 if (!check_nic(interface)) {
505 printf("NIC gone!\n");
506 sleep(2);
507 continue;
510 /* interface name */
511 printf("NIC:\t %s\n", interface);
513 /* network status */
514 status = get_status(interface);
515 if (status != NULL)
516 printf("Status:\t %s\n", status);
518 /* network id */
519 nwid = get_nwid(interface);
520 if (nwid != NULL)
521 printf("NwID:\t %s\n", nwid);
523 /* speed */
524 speed = get_speed(interface);
525 if (speed != NULL)
526 printf("Speed:\t %s Mbps\n", speed);
528 /* signal strength */
529 r = get_signal(interface, nwid);
530 if (r > 0)
531 printf("Signal:\t %d dB\n", r);
533 /* channel */
534 r = get_channel(interface);
535 if (r > 0)
536 printf("Channel: %d\n", r);
538 /* wep */
539 r = get_wep(interface);
540 if (r > 0)
541 printf("WEP:\t enabled\n");
542 else
543 printf("WEP:\t disabled\n");
545 printf("\n");
546 sleep(2);
549 exit(0);
552 void
553 draw_nwid(char *nwid, int scroll)
555 static int offset = 0;
556 static char *save_nwid;
557 char network_id_cut[NWIDLENC + 1];
559 if (strlen(nwid) > NWIDLENC) {
560 if (save_nwid == NULL || strcmp(nwid, save_nwid)) {
561 free(save_nwid);
562 if ((save_nwid = strdup(nwid)) == NULL)
563 err(1, NULL);
564 offset = 0;
566 switch (scroll) {
567 case 0:
568 /* off */
569 strlcpy(network_id_cut, nwid, sizeof(network_id_cut));
570 draw_string(network_id_cut, 6, 51);
571 break;
572 case 1:
573 /* lcd */
574 offset = scroll_lcd(0, 124, 6, 51, offset, nwid);
575 break;
576 case 2:
577 /* bounce */
578 offset = scroll_bounce(0, 124, 6, 51, offset, nwid);
579 break;
580 case 3:
581 /* fade */
582 offset = scroll_fade(0, 124, 6, 51, offset, nwid);
583 break;
585 } else
586 draw_string(nwid, 6, 51);
590 * draw string
592 void
593 draw_string(const char *string, const int x, const int y)
595 int c, i, offset;
597 for (i = 0, offset = x; string[i] != '\0'; i++) {
598 c = string[i];
600 copyXPMArea(fonts[c].x, fonts[c].y, fonts[c].w, fonts[c].h,
601 offset, y);
602 offset += fonts[c].w;
607 * calculate the signal strength in percents and draw it
609 void
610 draw_signal(const int speed, const int signal)
612 int i, bars, loop, offset;
613 float have, need;
615 bars = 26;
616 need = speed / 1.10;
617 have = (signal * bars) / need;
618 if (have >= bars)
619 loop = bars;
620 else
621 loop = floor(have);
623 for (i = 0, offset = 6; i < loop; i++, offset += 2)
624 copyXPMArea(10, 67, 1, 6, offset, 21);
628 * scroll_lcd()
629 * scrolls a string from left to right separated by a space
630 * Return:
631 * offset = success
634 scroll_lcd(const int src_x, const int src_y, const int dst_x,
635 const int dst_y, const int offset, const char *nwid)
637 int len, pos, frame;
639 /* copy offset */
640 pos = offset;
642 /* draw network id */
643 if (pos == src_x) {
644 copyXPMArea(0, 132, 160, 8, src_x, src_y);
645 draw_string(nwid, src_x, src_y);
648 /* calculate image length */
649 len = (strlen(nwid) + 1) * 6;
651 /* reached end of source, reset */
652 if (pos == len)
653 pos = src_x;
655 /* copy scroll frame to destination */
656 frame = len - pos;
657 if (frame >= NWIDLENP)
658 copyXPMArea(pos, src_y, NWIDLENP, 8, dst_x, dst_y);
659 else {
660 copyXPMArea(pos, src_y, frame, 8, dst_x, dst_y);
661 copyXPMArea(src_x, src_y, NWIDLENP - frame, 8, dst_x + frame,
662 dst_y);
665 /* move to next pixel */
666 pos++;
668 return (pos);
672 * scroll_bounce()
673 * scrolls a string from left to right and bounces back from right to left
674 * Return:
675 * offset = success
678 scroll_bounce(const int src_x, const int src_y, const int dst_x,
679 const int dst_y, const int offset, const char *nwid)
681 int len, pos, frame;
682 static int delay = 0, direction = 0;
684 /* copy offset */
685 pos = offset;
687 /* draw network id */
688 if (pos == src_x) {
689 copyXPMArea(0, 132, 160, 8, src_x, src_y);
690 draw_string(nwid, src_x, src_y);
693 /* calculate image length */
694 len = strlen(nwid) * 6;
696 /* delay */
697 if (delay > 0) {
698 if (direction == 0)
699 copyXPMArea(pos - 1, src_y, NWIDLENP, 8, dst_x, dst_y);
700 if (direction == 1)
701 copyXPMArea(pos + 1, src_y, NWIDLENP, 8, dst_x, dst_y);
702 delay--;
704 return (pos);
707 /* start */
708 if (pos == src_x) {
709 delay = 10;
710 direction = 0;
712 /* end */
713 frame = len - pos;
714 if (frame == NWIDLENP) {
715 delay = 10;
716 direction = 1;
719 /* copy scroll frame to destination */
720 copyXPMArea(pos, src_y, NWIDLENP, 8, dst_x, dst_y);
722 /* move to next pixel */
723 if (direction == 0)
724 pos++;
725 if (direction == 1)
726 pos--;
728 return (pos);
732 * scroll_fade()
733 * scrolls a string from left to right, fading it out and begins again
734 * Return:
735 * offset = success
738 scroll_fade(const int src_x, const int src_y, const int dst_x,
739 const int dst_y, const int offset, const char *nwid)
741 int len, pos, frame;
742 static int delay = 0;
744 /* copy offset */
745 pos = offset;
747 /* draw network id */
748 if (pos == src_x) {
749 copyXPMArea(0, 132, 160, 8, src_x, src_y);
750 draw_string(nwid, src_x, src_y);
753 /* calculate image length */
754 len = (strlen(nwid) + 1) * 6;
756 /* delay */
757 if (delay > 0) {
758 copyXPMArea(pos - 1, src_y, NWIDLENP, 8, dst_x, dst_y);
759 delay--;
761 return (pos);
764 /* end */
765 if (pos == len)
766 pos = src_x;
767 /* start */
768 if (pos == src_x)
769 delay = 10;
771 /* copy scroll frame to destination */
772 frame = len - pos;
773 if (frame >= NWIDLENP)
774 copyXPMArea(pos, src_y, NWIDLENP, 8, dst_x, dst_y);
775 else
776 copyXPMArea(pos, src_y, frame, 8, dst_x, dst_y);
778 /* move to next pixel */
779 pos++;
781 return (pos);