Sync usage with man page.
[netbsd-mini2440.git] / usr.sbin / isdn / isdnmonitor / curses.c
blob10862423283e4e475e7a1569988b501db45db9ef
1 /*
2 * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
25 *---------------------------------------------------------------------------
27 * i4b daemon - curses fullscreen output
28 * -------------------------------------
30 * $Id: curses.c,v 1.7 2009/04/16 05:56:33 lukem Exp $
32 * $FreeBSD$
34 * last edit-date: [Mon Dec 13 21:51:47 1999]
36 *---------------------------------------------------------------------------*/
38 #include "monprivate.h"
40 #ifndef WIN32
42 static void display_bell(void);
43 static void display_chans(void);
45 /*---------------------------------------------------------------------------*
46 * program exit
47 *---------------------------------------------------------------------------*/
48 void
49 do_exit(int exitval)
51 if (curses_ready)
52 endwin();
53 exit(exitval);
56 /*---------------------------------------------------------------------------*
57 * init curses fullscreen display
58 *---------------------------------------------------------------------------*/
59 void
60 init_screen(void)
62 char buffer[512];
63 int uheight, lheight;
64 int i, j;
66 initscr(); /* curses init */
68 if ((COLS < 80) || (LINES < 24))
70 endwin();
71 fprintf(stderr, "ERROR, minimal screensize must be 80x24, is %dx%d, terminating!",COLS, LINES);
72 exit(1);
75 noecho();
76 raw();
78 uheight = nctrl * 2; /* cards * b-channels */
79 lheight = LINES - uheight - 6 + 1; /* rest of display */
81 if ((upper_w = newwin(uheight, COLS, UPPER_B, 0)) == NULL)
83 endwin();
84 fprintf(stderr, "ERROR, curses init upper window, terminating!");
85 exit(1);
88 if ((mid_w = newwin(1, COLS, UPPER_B+uheight+1, 0)) == NULL)
90 endwin();
91 fprintf(stderr, "ERROR, curses init mid window, terminating!");
92 exit(1);
95 if ((lower_w = newwin(lheight, COLS, UPPER_B+uheight+3, 0)) == NULL)
97 endwin();
98 fprintf(stderr, "ERROR, curses init lower window, LINES = %d, lheight = %d, uheight = %d, terminating!", LINES, lheight, uheight);
99 exit(1);
102 scrollok(lower_w, 1);
104 snprintf(buffer, sizeof(buffer), "----- isdn controller channel state ------------- isdnmonitor %02d.%02d.%d -", VERSION, REL, STEP);
106 while((int)strlen(buffer) < COLS)
107 strlcat(buffer, "-", sizeof(buffer));
109 move(0, 0);
110 standout();
111 addstr(buffer);
112 standend();
114 move(1, 0);
115 /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789 */
116 addstr("# tei b remote iface dir outbytes obps inbytes ibps units");
118 if (hostname)
119 snprintf(buffer, sizeof(buffer), "----- isdn userland interface state ------------- %s:%d -", hostname, portno);
120 else
121 snprintf(buffer, sizeof(buffer), "----- isdn userland interface state ------------- %s -", sockpath);
123 while((int)strlen(buffer) < COLS)
124 strlcat(buffer, "-", sizeof(buffer));
126 move(uheight+2, 0);
127 standout();
128 addstr(buffer);
129 standend();
131 snprintf(buffer, sizeof(buffer), "----- isdnd logfile display --------------------------------------------------");
132 while((int)strlen(buffer) < COLS)
133 strlcat(buffer, "-", sizeof(buffer));
135 move(uheight+4, 0);
136 standout();
137 addstr(buffer);
138 standend();
140 refresh();
142 for (i=0, j=0; i <= nctrl; i++, j+=2)
144 mvwprintw(upper_w, j, H_CNTL, "%d --- 1 ", i); /*TEI*/
145 mvwprintw(upper_w, j+1, H_CNTL, " L12 2 ");
147 wrefresh(upper_w);
149 #ifdef NOTDEF
150 for (i=0, j=0; i < nentries; i++) /* walk thru all entries */
152 p = &cfg_entry_tab[i]; /* get ptr to enry */
154 mvwprintw(mid_w, 0, j, "%s%d ", bdrivername(p->usrdevicename), p->usrdeviceunit);
156 p->fs_position = j;
158 j += ((strlen(bdrivername(p->usrdevicename)) + (p->usrdeviceunit > 9 ? 2 : 1) + 1));
160 #else
161 mvwprintw(mid_w, 0, 0, "%s", devbuf);
162 #endif
163 wrefresh(mid_w);
165 wmove(lower_w, 0, 0);
166 wrefresh(lower_w);
168 curses_ready = 1;
171 /*---------------------------------------------------------------------------*
172 * display the charge in units
173 *---------------------------------------------------------------------------*/
174 void
175 display_charge(int pos, int charge)
177 mvwprintw(upper_w, pos, H_UNITS, "%d", charge);
178 wclrtoeol(upper_w);
179 wrefresh(upper_w);
182 /*---------------------------------------------------------------------------*
183 * display the calculated charge in units
184 *---------------------------------------------------------------------------*/
185 void
186 display_ccharge(int pos, int units)
188 mvwprintw(upper_w, pos, H_UNITS, "(%d)", units);
189 wclrtoeol(upper_w);
190 wrefresh(upper_w);
193 /*---------------------------------------------------------------------------*
194 * display accounting information
195 *---------------------------------------------------------------------------*/
196 void
197 display_acct(int pos, int obyte, int obps, int ibyte, int ibps)
199 mvwprintw(upper_w, pos, H_OUT, "%-10d", obyte);
200 mvwprintw(upper_w, pos, H_OUTBPS, "%-4d", obps);
201 mvwprintw(upper_w, pos, H_IN, "%-10d", ibyte);
202 mvwprintw(upper_w, pos, H_INBPS, "%-4d", ibps);
203 wrefresh(upper_w);
206 /*---------------------------------------------------------------------------*
207 * erase line at disconnect time
208 *---------------------------------------------------------------------------*/
209 void
210 display_disconnect(int pos)
212 wmove(upper_w, pos, H_TELN);
213 wclrtoeol(upper_w);
214 wrefresh(upper_w);
216 if (do_bell)
217 display_bell();
220 /*---------------------------------------------------------------------------*
221 * display interface up/down information
222 *---------------------------------------------------------------------------*/
223 void
224 display_updown(int pos, int updown, char *device)
226 if (updown)
227 wstandend(mid_w);
228 else
229 wstandout(mid_w);
231 mvwprintw(mid_w, 0, pos, "%s ", device);
233 wstandend(mid_w);
234 wrefresh(mid_w);
237 /*---------------------------------------------------------------------------*
238 * display interface up/down information
239 *---------------------------------------------------------------------------*/
240 void
241 display_l12stat(int controller, int layer, int state)
243 if (controller > nctrl)
244 return;
246 if (!(layer == 1 || layer == 2))
247 return;
249 if (state)
250 wstandout(upper_w);
251 else
252 wstandend(upper_w);
254 if (layer == 1)
256 mvwprintw(upper_w, (controller*2)+1, H_TEI+1, "1");
258 if (!state)
259 mvwprintw(upper_w, (controller*2)+1, H_TEI+2, "2");
261 else if (layer == 2)
263 mvwprintw(upper_w, (controller*2)+1, H_TEI+2, "2");
264 if (state)
265 mvwprintw(upper_w, (controller*2)+1, H_TEI+1, "1");
268 wstandend(upper_w);
269 wrefresh(upper_w);
272 /*---------------------------------------------------------------------------*
273 * display TEI
274 *---------------------------------------------------------------------------*/
275 void
276 display_tei(int controller, int tei)
278 if (controller > nctrl)
279 return;
281 if (tei == -1)
282 mvwprintw(upper_w, controller*2, H_TEI, "---");
283 else
284 mvwprintw(upper_w, controller*2, H_TEI, "%3d", tei);
286 wrefresh(upper_w);
289 /*---------------------------------------------------------------------------*
290 * display bell :-)
291 *---------------------------------------------------------------------------*/
292 static void
293 display_bell(void)
295 static char bell[1] = { 0x07 };
296 write(STDOUT_FILENO, &bell[0], 1);
299 /*---------------------------------------------------------------------------*
300 * curses menu for fullscreen command mode
301 *---------------------------------------------------------------------------*/
302 void
303 do_menu(void)
305 static const char *menu[WMITEMS] =
307 "1 - (D)isplay refresh",
308 "2 - (H)angup (choose a channel)",
309 "3 - (R)eread config file",
310 "4 - (Q)uit the program",
313 WINDOW *menu_w;
314 int c;
315 int mpos;
316 struct pollfd set[1];
318 /* create a new window in the lower screen area */
320 if ((menu_w = newwin(WMENU_HGT, WMENU_LEN, WMENU_POSLN, WMENU_POSCO )) == NULL)
322 return;
325 /* create a border around the window */
327 box(menu_w, '|', '-');
329 /* add a title */
331 wstandout(menu_w);
332 mvwaddstr(menu_w, 0, (WMENU_LEN / 2) - (strlen(WMENU_TITLE) / 2), WMENU_TITLE);
333 wstandend(menu_w);
335 /* fill the window with the menu options */
337 for (mpos=0; mpos <= (WMITEMS-1); mpos++)
338 mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
340 /* highlight the first menu option */
342 mpos = 0;
343 wstandout(menu_w);
344 mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
345 wstandend(menu_w);
347 /* input loop */
349 set[0].fd = STDIN_FILENO;
350 set[0].events = POLLIN;
351 for (;;)
353 wrefresh(menu_w);
355 /* if no char is available within timeout, exit menu*/
357 if ((poll(set, 1, WMTIMEOUT * 1000)) <= 0)
358 goto mexit;
360 c = wgetch(menu_w);
362 switch (c)
364 case ' ':
365 case '\t': /* hilite next option */
366 mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
367 mpos++;
368 if (mpos >= WMITEMS)
369 mpos = 0;
370 wstandout(menu_w);
371 mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
372 wstandend(menu_w);
373 break;
375 case ('0'+WREFRESH+1): /* display refresh */
376 case 'D':
377 case 'd':
378 wrefresh(curscr);
379 goto mexit;
381 case ('0'+WQUIT+1): /* quit program */
382 case 'Q':
383 case 'q':
384 do_exit(0);
385 goto mexit;
388 case ('0'+WHANGUP+1): /* hangup connection */
389 case 'H':
390 case 'h':
391 display_chans();
392 goto mexit;
394 case ('0'+WREREAD+1): /* reread config file */
395 case 'R':
396 case 'r':
397 reread();
398 goto mexit;
400 case '\n':
401 case '\r': /* exec highlighted option */
402 switch (mpos)
404 case WREFRESH:
405 wrefresh(curscr);
406 break;
408 case WQUIT:
409 do_exit(0);
410 break;
412 case WHANGUP:
413 display_chans();
414 break;
416 case WREREAD:
417 reread();
418 break;
420 goto mexit;
421 break;
423 default:
424 goto mexit;
425 break;
429 mexit:
430 /* delete the menu window */
432 delwin(menu_w);
434 /* re-display the original lower window contents */
436 touchwin(lower_w);
437 wrefresh(lower_w);
440 /*---------------------------------------------------------------------------*
441 * display connect information
442 *---------------------------------------------------------------------------*/
443 void
444 display_connect(int pos, int dir, char *name, char *remtel, char *dev)
446 char buffer[256];
448 /* remote telephone number */
450 snprintf(buffer, sizeof(buffer), "%s/%s", name, remtel);
452 buffer[H_IFN - H_TELN - 1] = '\0';
454 mvwprintw(upper_w, pos, H_TELN, "%s", buffer);
456 /* interface */
458 mvwprintw(upper_w, pos, H_IFN, "%s ", dev);
460 mvwprintw(upper_w, pos, H_IO, dir ? "out" : "in");
462 mvwprintw(upper_w, pos, H_OUT, "-");
463 mvwprintw(upper_w, pos, H_OUTBPS, "-");
464 mvwprintw(upper_w, pos, H_IN, "-");
465 mvwprintw(upper_w, pos, H_INBPS, "-");
467 if (do_bell)
468 display_bell();
470 wrefresh(upper_w);
473 /*---------------------------------------------------------------------------*
474 * display channel information for shutdown
475 *---------------------------------------------------------------------------*/
476 static void
477 display_chans(void)
479 char buffer[80];
480 int i;
481 int cnt = 0;
482 WINDOW *chan_w;
483 int nlines, ncols, pos_x, pos_y;
484 struct pollfd set[1];
486 /* need this later to close the connection */
487 struct ctlr_chan {
488 int cntl;
489 int chn;
490 } *cc = NULL;
492 for (i = 0; i < nctrl; i++)
494 if (remstate[i].ch1state)
495 cnt++;
496 if (remstate[i].ch2state)
497 cnt++;
500 if (cnt > 0)
502 if ((cc = (struct ctlr_chan *)malloc (cnt *
503 sizeof (struct ctlr_chan))) == NULL)
505 return;
507 nlines = cnt + 4;
508 ncols = 60;
510 else
512 nlines = 5;
513 ncols = 22;
516 pos_y = WMENU_POSLN + 4;
517 pos_x = WMENU_POSCO + 10;
519 /* create a new window in the lower screen area */
521 if ((chan_w = newwin(nlines, ncols, pos_y, pos_x )) == NULL)
523 if (cnt > 0)
524 free(cc);
525 return;
528 /* create a border around the window */
530 box(chan_w, '|', '-');
532 /* add a title */
534 wstandout(chan_w);
535 mvwaddstr(chan_w, 0, (ncols / 2) - (strlen("Channels") / 2), "Channels");
536 wstandend(chan_w);
538 /* no active channels */
539 if (cnt == 0)
541 mvwaddstr(chan_w, 2, 2, "No active channels");
542 wrefresh(chan_w);
543 sleep(1);
545 /* delete the channels window */
547 delwin(chan_w);
548 return;
551 nlines = 2;
552 ncols = 1;
554 for (i = 0; i < nctrl; i++)
556 if (remstate[i].ch1state)
558 snprintf(buffer, sizeof(buffer),
559 "%d - Controller %d channel %s", ncols, i, "B1");
560 mvwaddstr(chan_w, nlines, 2, buffer);
561 cc[ncols - 1].cntl = i;
562 cc[ncols - 1].chn = CHAN_B1;
563 nlines++;
564 ncols++;
566 if (remstate[i].ch2state)
568 snprintf(buffer, sizeof(buffer),
569 "%d - Controller %d channel %s", ncols, i, "B2");
570 mvwaddstr(chan_w, nlines, 2, buffer);
571 cc[ncols - 1].cntl = i;
572 cc[ncols - 1].chn = CHAN_B2;
573 nlines++;
574 ncols++;
578 set[0].fd = STDIN_FILENO;
579 set[0].events = POLLIN;
580 for (;;)
582 wrefresh(chan_w);
584 /* if no char is available within timeout, exit menu*/
586 if ((poll(set, 1, WMTIMEOUT * 1000)) <= 0)
587 break;
589 ncols = wgetch(chan_w);
591 if (!(isdigit(ncols)))
593 display_bell();
594 continue;
597 nlines = ncols - '0';
599 if ((nlines == 0) || (nlines > cnt))
601 display_bell();
602 continue;
605 hangup(cc[nlines-1].cntl, cc[nlines-1].chn);
606 break;
609 free(cc);
611 /* delete the channels window */
613 delwin(chan_w);
616 #endif /* !WIN32*/
618 /* EOF */