Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | /* |
2 | * |
||
3 | * |
||
4 | */ |
||
5 | |||
6 | #include <stdio.h> |
||
7 | #include <stdlib.h> |
||
8 | |||
9 | #if defined(USE_NCURSES) |
||
10 | |||
11 | #include <curses.h> |
||
12 | #include <term.h> |
||
13 | |||
14 | #elif defined(USE_CONIO) |
||
15 | |||
16 | #include <conio.h> |
||
17 | |||
18 | /* for usleep() */ |
||
19 | #include <unistd.h> |
||
20 | /* for sound(), nosound() */ |
||
21 | #include <pc.h> |
||
22 | |||
23 | #else |
||
24 | |||
25 | #error USE_NCURSES or USE_CONIO must be defined |
||
26 | |||
27 | #endif |
||
28 | |||
29 | #include "hconf.h" |
||
30 | |||
31 | /* |
||
32 | * |
||
33 | * CONIO |
||
34 | * |
||
35 | */ |
||
36 | |||
37 | #ifdef USE_CONIO |
||
38 | |||
39 | // with bold |
||
40 | #define DEFAULT_FG CYAN |
||
41 | #define DEFAULT_BG BLUE |
||
42 | |||
43 | #define NORMAL_FG BLACK |
||
44 | #define NORMAL_BG WHITE |
||
45 | |||
46 | // with bold |
||
47 | #define INVERSE_FG WHITE |
||
48 | #define INVERSE_BG BLUE |
||
49 | |||
50 | //with bold |
||
51 | #define BOX_BORDERFGU WHITE |
||
52 | #define BOX_BORDERBGU WHITE |
||
53 | |||
54 | #define BOX_BORDERFGD BLACK |
||
55 | #define BOX_BORDERBGD WHITE |
||
56 | |||
57 | #define BOX_FG BLACK |
||
58 | #define BOX_BG WHITE |
||
59 | |||
60 | #define SHADOW_FG BLACK |
||
61 | #define SHADOW_BG BLACK |
||
62 | |||
63 | #define TITLE_FG YELLOW |
||
64 | #define TITLE_BG WHITE |
||
65 | |||
66 | #define _KEY_OK 0x1b |
||
67 | #define _KEY_OK2 0x4b |
||
68 | #define _KEY_DOWN 0x50 |
||
69 | #define _KEY_UP 0x48 |
||
70 | #define _KEY_TOGGLE 0x0d |
||
71 | #define _KEY_HELP '?' |
||
72 | |||
73 | /* (U-upper,L-lower) (L-left,R-right) */ |
||
74 | #define _UL 'Ú' |
||
75 | #define _LL 'À' |
||
76 | #define _UR '¿' |
||
77 | #define _LR 'Ù' |
||
78 | #define _HH 'Ä' |
||
79 | #define _VV '³' |
||
80 | |||
81 | /* -- */ |
||
82 | |||
83 | typedef struct tagWINDOW { |
||
84 | int str,stc,nl,nc; |
||
85 | } WINDOW; |
||
86 | |||
87 | void _defaultcolor(WINDOW *w) |
||
88 | { |
||
89 | textbackground(DEFAULT_BG); |
||
90 | textcolor(DEFAULT_FG); |
||
91 | } |
||
92 | |||
93 | void _normal(WINDOW *w) |
||
94 | { |
||
95 | textbackground(NORMAL_BG); |
||
96 | textcolor(NORMAL_FG); |
||
97 | } |
||
98 | |||
99 | void _inverse(WINDOW *w) |
||
100 | { |
||
101 | textbackground(INVERSE_BG); |
||
102 | textcolor(INVERSE_FG); |
||
103 | } |
||
104 | |||
105 | void _shadow(WINDOW *w) |
||
106 | { |
||
107 | textbackground(SHADOW_BG); |
||
108 | textcolor(SHADOW_FG); |
||
109 | } |
||
110 | |||
111 | void _boxcolor(WINDOW *w) |
||
112 | { |
||
113 | textbackground(BOX_BG); |
||
114 | textcolor(BOX_FG); |
||
115 | } |
||
116 | |||
117 | void _titlecolor(WINDOW *w) |
||
118 | { |
||
119 | textbackground(TITLE_BG); |
||
120 | textcolor(TITLE_FG); |
||
121 | } |
||
122 | |||
123 | void _borderboxucolor(WINDOW *w) |
||
124 | { |
||
125 | textbackground(BOX_BORDERBGU); |
||
126 | textcolor(BOX_BORDERFGU); |
||
127 | } |
||
128 | |||
129 | void _borderboxdcolor(WINDOW *w) |
||
130 | { |
||
131 | textbackground(BOX_BORDERBGD); |
||
132 | textcolor(BOX_BORDERFGD); |
||
133 | } |
||
134 | |||
135 | /* -- */ |
||
136 | |||
137 | struct text_info info; |
||
138 | |||
139 | #define _cols() info.screenwidth |
||
140 | #define _rows() info.screenheight |
||
141 | |||
142 | #define _cursor_invisible() _setcursortype(_NOCURSOR) |
||
143 | #define _cursor_visible() _setcursortype(_NORMALCURSOR) |
||
144 | |||
145 | |||
146 | #define _gotorc(w,r,c) gotoxy(w->stc+c+1,w->str+r+1) |
||
147 | #define _printw(w,fmt,args...) cprintf(fmt,##args) |
||
148 | #define _refresh(w) |
||
149 | |||
150 | #define _putch(w,c) putch(c) |
||
151 | #define _getch() getch() |
||
152 | |||
153 | void _clrscr(WINDOW *w) |
||
154 | { |
||
155 | static char buffer[256]; |
||
156 | int r; |
||
157 | |||
158 | memset(buffer,' ',sizeof(buffer)); |
||
159 | buffer[w->nc]='\0'; |
||
160 | for (r=0;r<w->nl;r++) { |
||
161 | gotoxy(w->stc+1,w->str+r+1); |
||
162 | cprintf("%s",buffer); |
||
163 | } |
||
164 | } |
||
165 | |||
166 | void _clreol(WINDOW *w) |
||
167 | { |
||
168 | int l; |
||
169 | l=w->stc+w->nc-wherex(); |
||
170 | if (l>0) |
||
171 | while (l-->0) putch(' '); |
||
172 | } |
||
173 | |||
174 | void _bell(void) |
||
175 | { |
||
176 | sound(2000); |
||
177 | usleep(250000l); |
||
178 | nosound(); |
||
179 | } |
||
180 | |||
181 | /* -- */ |
||
182 | |||
183 | WINDOW *_createwin(int str, int stc, int nlines, int cols) |
||
184 | { |
||
185 | WINDOW *wnd; |
||
186 | wnd=(WINDOW*)malloc(sizeof(WINDOW)); |
||
187 | if (wnd!=NULL) { |
||
188 | wnd->str=str; |
||
189 | wnd->stc=stc; |
||
190 | wnd->nl=nlines; |
||
191 | wnd->nc=cols; |
||
192 | } |
||
193 | return wnd; |
||
194 | } |
||
195 | |||
196 | #define _deletewin(w) free(w) |
||
197 | |||
198 | WINDOW *STDWIN; |
||
199 | |||
200 | void _initscreen(void) |
||
201 | { |
||
202 | gppconio_init(); |
||
203 | gettextinfo(&info); |
||
204 | STDWIN=_createwin(0,0,_rows(),_cols()); |
||
205 | _defaultcolor(STDWIN); |
||
206 | clrscr(); |
||
207 | } |
||
208 | |||
209 | void _endscreen(void) |
||
210 | { |
||
211 | //clrscr(); |
||
212 | } |
||
213 | |||
214 | #endif |
||
215 | |||
216 | /* |
||
217 | * |
||
218 | * NCURSES |
||
219 | * |
||
220 | */ |
||
221 | |||
222 | #ifdef USE_NCURSES |
||
223 | |||
224 | // with bold |
||
225 | #define DEFAULT_FG COLOR_CYAN |
||
226 | #define DEFAULT_BG COLOR_BLUE |
||
227 | |||
228 | #define NORMAL_FG COLOR_BLACK |
||
229 | #define NORMAL_BG COLOR_WHITE |
||
230 | |||
231 | // with bold |
||
232 | #define INVERSE_FG COLOR_WHITE |
||
233 | #define INVERSE_BG COLOR_BLUE |
||
234 | |||
235 | //with bold |
||
236 | #define BOX_BORDERFGU COLOR_WHITE |
||
237 | #define BOX_BORDERBGU COLOR_WHITE |
||
238 | |||
239 | #define BOX_BORDERFGD COLOR_BLACK |
||
240 | #define BOX_BORDERBGD COLOR_WHITE |
||
241 | |||
242 | #define BOX_FG COLOR_BLACK |
||
243 | #define BOX_BG COLOR_WHITE |
||
244 | |||
245 | #define SHADOW_FG COLOR_BLACK |
||
246 | #define SHADOW_BG COLOR_BLACK |
||
247 | |||
248 | #define TITLE_FG COLOR_YELLOW |
||
249 | #define TITLE_BG COLOR_WHITE |
||
250 | |||
251 | #define _KEY_OK 0x1b |
||
252 | #define _KEY_OK2 'q' |
||
253 | #define _KEY_DOWN KEY_DOWN |
||
254 | #define _KEY_UP KEY_UP |
||
255 | #define _KEY_TOGGLE 0x0a |
||
256 | #define _KEY_HELP '?' |
||
257 | |||
258 | /* -- */ |
||
259 | |||
260 | #define _BACKGROUND 1 |
||
261 | #define _NORMAL 2 |
||
262 | #define _INVERSE 3 |
||
263 | #define _BORDERBOXU 4 |
||
264 | #define _BORDERBOXD 5 |
||
265 | #define _BOX 6 |
||
266 | #define _SHADOW 7 |
||
267 | #define _TITLE 8 |
||
268 | #define _DEFAULT 9 |
||
269 | |||
270 | #define STDWIN stdscr |
||
271 | |||
272 | /* (U-upper,L-lower) (L-left,R-right) */ |
||
273 | #define _UL ACS_BSSB |
||
274 | #define _LL ACS_SSBB |
||
275 | #define _UR ACS_BBSS |
||
276 | #define _LR ACS_SBBS |
||
277 | #define _HH ACS_BSBS |
||
278 | #define _VV ACS_SBSB |
||
279 | |||
280 | void _defaultcolor(WINDOW *w) |
||
281 | { |
||
282 | wattrset(w,COLOR_PAIR(_DEFAULT)|A_BOLD); |
||
283 | wbkgdset(w,COLOR_PAIR(_DEFAULT)|A_BOLD); |
||
284 | } |
||
285 | |||
286 | void _normal(WINDOW *w) |
||
287 | { |
||
288 | wattrset(w,COLOR_PAIR(_NORMAL)); |
||
289 | wbkgdset(w,COLOR_PAIR(_NORMAL)); |
||
290 | } |
||
291 | |||
292 | void _inverse(WINDOW *w) |
||
293 | { |
||
294 | wattrset(w,COLOR_PAIR(_INVERSE)|A_BOLD); |
||
295 | wbkgdset(w,COLOR_PAIR(_INVERSE)|A_BOLD); |
||
296 | } |
||
297 | |||
298 | void _shadow(WINDOW *w) |
||
299 | { |
||
300 | wattrset(w,COLOR_PAIR(_SHADOW)); |
||
301 | wbkgdset(w,COLOR_PAIR(_SHADOW)); |
||
302 | } |
||
303 | |||
304 | void _boxcolor(WINDOW *w) |
||
305 | { |
||
306 | wattrset(w,COLOR_PAIR(_BOX)); |
||
307 | wbkgdset(w,COLOR_PAIR(_BOX)); |
||
308 | } |
||
309 | |||
310 | void _titlecolor(WINDOW *w) |
||
311 | { |
||
312 | wattrset(w,COLOR_PAIR(_TITLE)|A_BOLD); |
||
313 | wbkgdset(w,COLOR_PAIR(_TITLE)|A_BOLD); |
||
314 | } |
||
315 | |||
316 | void _borderboxucolor(WINDOW *w) |
||
317 | { |
||
318 | wattrset(w,COLOR_PAIR(_BORDERBOXU)|A_BOLD); |
||
319 | wbkgdset(w,COLOR_PAIR(_BORDERBOXU)|A_BOLD); |
||
320 | } |
||
321 | |||
322 | void _borderboxdcolor(WINDOW *w) |
||
323 | { |
||
324 | wattrset(w,COLOR_PAIR(_BORDERBOXD)); |
||
325 | wbkgdset(w,COLOR_PAIR(_BORDERBOXD)); |
||
326 | } |
||
327 | |||
328 | /* -- */ |
||
329 | |||
330 | #define _cursor_invisible() putp(cursor_invisible) |
||
331 | #define _cursor_visible() {putp(cursor_visible);putp(cursor_normal);} |
||
332 | |||
333 | #define _cols() COLS |
||
334 | #define _rows() LINES |
||
335 | #define _gotorc(w,r,c) wmove(w,r,c) |
||
336 | |||
337 | #define _printw(w,fmt,args...) wprintw(w,fmt,##args) |
||
338 | #define _refresh(w) wrefresh(w) |
||
339 | |||
340 | #define _putch(w,c) waddch(w,c) |
||
341 | #define _getch() getch() |
||
342 | #define _clreol(w) wclrtoeol(w) |
||
343 | #define _clrscr(w) wclear(w) |
||
344 | |||
345 | #define _bell() addch('\07'); |
||
346 | |||
347 | /* -- */ |
||
348 | |||
349 | void _initscreen(void) |
||
350 | { |
||
351 | initscr(); |
||
352 | start_color(); |
||
353 | init_pair(_BACKGROUND,DEFAULT_BG,DEFAULT_BG); |
||
354 | init_pair(_DEFAULT,DEFAULT_FG,DEFAULT_BG); |
||
355 | init_pair(_NORMAL,NORMAL_FG,NORMAL_BG); |
||
356 | init_pair(_INVERSE,INVERSE_FG,INVERSE_BG); |
||
357 | init_pair(_BORDERBOXU,BOX_BORDERFGU,BOX_BORDERBGU); |
||
358 | init_pair(_BORDERBOXD,BOX_BORDERFGD,BOX_BORDERBGD); |
||
359 | init_pair(_BOX,BOX_FG,BOX_BG); |
||
360 | init_pair(_SHADOW,SHADOW_FG,SHADOW_BG); |
||
361 | init_pair(_TITLE,TITLE_FG,TITLE_BG); |
||
362 | bkgdset(COLOR_PAIR(_BACKGROUND)); |
||
363 | clear(); |
||
364 | cbreak(); /* input one char at time (don't wait for \n) */ |
||
365 | noecho(); |
||
366 | keypad(stdscr,TRUE); |
||
367 | _normal(stdscr); |
||
368 | _cursor_invisible(); |
||
369 | refresh(); |
||
370 | } |
||
371 | |||
372 | void _endscreen(void) |
||
373 | { |
||
374 | _cursor_visible(); |
||
375 | refresh(); |
||
376 | endwin(); |
||
377 | } |
||
378 | |||
379 | WINDOW *_createwin(int str, int stc, int nlines, int cols) |
||
380 | { |
||
381 | WINDOW *wnd; |
||
382 | wnd=newwin(nlines,cols,str,stc); |
||
383 | if (wnd!=NULL) { |
||
384 | //wbkgdset(wnd,COLOR_PAIR(_BACKGROUND)); |
||
385 | //wclear(wnd); |
||
386 | //_normal(wnd); |
||
387 | } |
||
388 | return wnd; |
||
389 | } |
||
390 | |||
391 | #define _deletewin(w) delwin(w) |
||
392 | |||
393 | #endif |
||
394 | |||
395 | /* |
||
396 | * |
||
397 | * |
||
398 | * |
||
399 | */ |
||
400 | |||
401 | static void whichcolor(WINDOW *wnd, int up, int inv) |
||
402 | { |
||
403 | if (((inv==1)&&(up==1))||((inv==0)&&(up==0))) _borderboxdcolor(wnd); |
||
404 | else _borderboxucolor(wnd); |
||
405 | } |
||
406 | |||
407 | void _settitle(WINDOW *wnd, |
||
408 | int sy, int sx, |
||
409 | int nlines, int cols, |
||
410 | int bordy, int bordx, |
||
411 | char *title, |
||
412 | int shad, int inv) |
||
413 | { |
||
414 | int x; |
||
415 | |||
416 | sx-=bordx+1; |
||
417 | sy-=bordy+1; |
||
418 | cols+=2*(bordx+1); |
||
419 | nlines+=2*(bordy+1); |
||
420 | |||
421 | whichcolor(wnd,1,inv); |
||
422 | _gotorc(wnd,sy,sx+1); |
||
423 | for (x=0;x<cols-2;x++) _putch(wnd,_HH); |
||
424 | |||
425 | if (title!=NULL) { |
||
426 | _titlecolor(wnd); |
||
427 | _gotorc(wnd,sy,sx+(cols-strlen(title)-2)/2); |
||
428 | _printw(wnd," %s ",title); |
||
429 | |||
430 | _normal(wnd); |
||
431 | _gotorc(wnd,sy+2,sx+2); |
||
432 | _printw(wnd,"use <ESC> to exit, <ENTER> to enter/toggle,"); |
||
433 | _gotorc(wnd,sy+3,sx+2); |
||
434 | _printw(wnd,"arrows keys to move"); |
||
435 | } |
||
436 | |||
437 | |||
438 | _refresh(wnd); |
||
439 | } |
||
440 | |||
441 | void _box(WINDOW *wnd, |
||
442 | int sy, int sx, |
||
443 | int nlines, int cols, |
||
444 | int bordy, int bordx, |
||
445 | char *title, |
||
446 | int shad, int inv) |
||
447 | { |
||
448 | int x,y; |
||
449 | |||
450 | sx-=bordx+1; |
||
451 | sy-=bordy+1; |
||
452 | cols+=2*(bordx+1); |
||
453 | nlines+=2*(bordy+1); |
||
454 | |||
455 | { |
||
456 | static char blanks[180]; |
||
457 | memset(blanks,' ',sizeof(blanks)); |
||
458 | blanks[cols]='\0'; |
||
459 | _boxcolor(wnd); |
||
460 | for (y=0;y<nlines;y++) { |
||
461 | _gotorc(wnd,sy+y,sx); |
||
462 | _printw(wnd,"%s",blanks); |
||
463 | } |
||
464 | } |
||
465 | |||
466 | whichcolor(wnd,1,inv); |
||
467 | _gotorc(wnd,sy,sx); |
||
468 | _putch(wnd,_UL); |
||
469 | for (x=0;x<cols-2;x++) _putch(wnd,_HH); |
||
470 | whichcolor(wnd,0,inv); |
||
471 | _putch(wnd,_UR); |
||
472 | |||
473 | for (y=1;y<nlines-1;y++) { |
||
474 | whichcolor(wnd,1,inv); |
||
475 | _gotorc(wnd,sy+y,sx); |
||
476 | _putch(wnd,_VV); |
||
477 | whichcolor(wnd,0,inv); |
||
478 | _gotorc(wnd,sy+y,sx+cols-1); |
||
479 | _putch(wnd,_VV); |
||
480 | if (shad) { |
||
481 | _shadow(wnd); |
||
482 | _putch(wnd,' '); |
||
483 | _putch(wnd,' '); |
||
484 | } |
||
485 | } |
||
486 | |||
487 | whichcolor(wnd,1,inv); |
||
488 | _gotorc(wnd,sy+nlines-1,sx); |
||
489 | _putch(wnd,_LL); |
||
490 | whichcolor(wnd,0,inv); |
||
491 | for (x=0;x<cols-2;x++) _putch(wnd,_HH); |
||
492 | _putch(wnd,_LR); |
||
493 | if (shad) { |
||
494 | _shadow(wnd); |
||
495 | _putch(wnd,' '); |
||
496 | _putch(wnd,' '); |
||
497 | } |
||
498 | |||
499 | if (shad) { |
||
500 | _shadow(wnd); |
||
501 | _gotorc(wnd,sy+nlines,sx+1); |
||
502 | for (x=0;x<cols+1;x++) _putch(wnd,' '); |
||
503 | } |
||
504 | |||
505 | sx+=bordx+1; |
||
506 | sy+=bordy+1; |
||
507 | cols-=2*(bordx+1); |
||
508 | nlines-=2*(bordy+1); |
||
509 | |||
510 | _settitle(wnd,sy,sx,nlines,cols,bordy,bordx,title,shad,inv); |
||
511 | |||
512 | /* refresh made by _settitle() */ |
||
513 | } |
||
514 | |||
515 | void showtitle(char *s); |
||
516 | |||
517 | /* -- */ |
||
518 | |||
519 | |||
520 | void showbool(WINDOW *wnd, struct menuentry *ptr) |
||
521 | { |
||
522 | struct variable *var; |
||
523 | char ch; |
||
524 | var=ptr->x.bool.var; |
||
525 | if (!strcmp(var->value,"y")) ch='*'; |
||
526 | else ch=' '; |
||
527 | _printw(wnd,"[%c] %s",ch,ptr->x.bool.text); |
||
528 | _normal(wnd); |
||
529 | _clreol(wnd); |
||
530 | } |
||
531 | |||
532 | void showtristate(WINDOW *wnd, struct menuentry *ptr) |
||
533 | { |
||
534 | struct variable *var; |
||
535 | char ch; |
||
536 | var=ptr->x.bool.var; |
||
537 | if (!strcmp(var->value,"y")) ch='*'; |
||
538 | else if (!strcmp(var->value,"n")) ch=' '; |
||
539 | else ch='M'; |
||
540 | _printw(wnd,"<%c> %s",ch,ptr->x.bool.text); |
||
541 | _normal(wnd); |
||
542 | _clreol(wnd); |
||
543 | } |
||
544 | |||
545 | void showchoice(WINDOW *wnd, struct menuentry *ptr) |
||
546 | { |
||
547 | if (strcmp(ptr->x.choice.act->var->value,"y")) { |
||
548 | /* well.. sometimes reading an old config.h can cause act pointer */ |
||
549 | /* to be bad :-( */ |
||
550 | struct choice *p; |
||
551 | p=ptr->x.choice.list; |
||
552 | while (p!=NULL) { |
||
553 | if (!strcmp(p->var->value,"y")) { |
||
554 | ptr->x.choice.act=p; |
||
555 | break; |
||
556 | } |
||
557 | p=p->next; |
||
558 | } |
||
559 | } |
||
560 | |||
561 | _printw(wnd," %s (%s)",ptr->x.choice.text,ptr->x.choice.act->text); |
||
562 | _normal(wnd); |
||
563 | _clreol(wnd); |
||
564 | } |
||
565 | |||
566 | void showrange(WINDOW *wnd, struct menuentry *ptr) |
||
567 | { |
||
568 | _printw(wnd," %s (%s)",ptr->x.range.text,ptr->x.range.var->value); |
||
569 | _normal(wnd); |
||
570 | _clreol(wnd); |
||
571 | } |
||
572 | |||
573 | void showsubmenu(WINDOW *wnd, struct menuentry *ptr) |
||
574 | { |
||
575 | _printw(wnd," %s --->",ptr->x.submenu.text); |
||
576 | _normal(wnd); |
||
577 | _clreol(wnd); |
||
578 | } |
||
579 | |||
580 | void showseparator(WINDOW *wnd, struct menuentry *ptr) |
||
581 | { |
||
582 | _printw(wnd," *********************** "); |
||
583 | _normal(wnd); |
||
584 | _clreol(wnd); |
||
585 | } |
||
586 | |||
587 | /* -- */ |
||
588 | |||
589 | int nmax; // numero linee massimo |
||
590 | |||
591 | void showmenuentries(WINDOW *wnd,struct menuentry *ptr, int r, int c, int rcur) |
||
592 | { |
||
593 | int i; |
||
594 | |||
595 | i=0; |
||
596 | while (ptr!=NULL) { |
||
597 | _gotorc(wnd,r,c); |
||
598 | if (r==rcur) _inverse(wnd); |
||
599 | else _normal(wnd); |
||
600 | r++; |
||
601 | switch(ptr->type) { |
||
602 | case RANGEENTRY: |
||
603 | showrange(wnd,ptr); |
||
604 | break; |
||
605 | case BOOLENTRY: |
||
606 | showbool(wnd,ptr); |
||
607 | break; |
||
608 | case TRISTATEENTRY: |
||
609 | showtristate(wnd,ptr); |
||
610 | break; |
||
611 | case CHOICEENTRY: |
||
612 | showchoice(wnd,ptr); |
||
613 | break; |
||
614 | case SUBMENUENTRY: |
||
615 | showsubmenu(wnd,ptr); |
||
616 | break; |
||
617 | case SEPARATORENTRY: |
||
618 | showseparator(wnd,ptr); |
||
619 | break; |
||
620 | default: |
||
621 | _printw(wnd,"@@@"); |
||
622 | break; |
||
623 | } |
||
624 | ptr=ptr->n; |
||
625 | i++; |
||
626 | if (i==nmax) return; |
||
627 | } |
||
628 | } |
||
629 | |||
630 | /* --- */ |
||
631 | |||
632 | struct menuentry *expandcase(struct menuentry *menuent); |
||
633 | struct menuentry *expandmenu(struct menuentry *menuent); |
||
634 | |||
635 | struct menuentry *expandcase(struct menuentry *menuent) |
||
636 | { |
||
637 | struct _case *list; |
||
638 | list=menuent->x._case.list; |
||
639 | while (list!=NULL) { |
||
640 | if (!strcmp(list->value,menuent->x._case.var->value)) { |
||
641 | return expandmenu(list->list); |
||
642 | } |
||
643 | list=list->next; |
||
644 | } |
||
645 | return NULL; |
||
646 | } |
||
647 | |||
648 | int nument; |
||
649 | |||
650 | struct menuentry *expandmenu(struct menuentry *menuent) |
||
651 | { |
||
652 | struct menuentry *start,*ptr,*ent,*prev,*p; |
||
653 | int ne; |
||
654 | |||
655 | ne=0; |
||
656 | ptr=menuent; |
||
657 | prev=NULL; |
||
658 | start=NULL; |
||
659 | while (ptr!=NULL) { |
||
660 | switch(ptr->type) { |
||
661 | |||
662 | case CASEENTRY: |
||
663 | ent=expandcase(ptr); |
||
664 | if (ent==NULL) { |
||
665 | if (prev!=NULL) prev->n=ptr->next; |
||
666 | ptr=ptr->next; |
||
667 | break; |
||
668 | } |
||
669 | if (start==NULL) start=ent; |
||
670 | |||
671 | if (prev!=NULL) prev->n=ent; |
||
672 | ent->p=prev; |
||
673 | p=ent; |
||
674 | while (p->n!=NULL) p=p->n; |
||
675 | p->n=ptr->next; |
||
676 | |||
677 | prev=p; |
||
678 | ptr=ptr->next; |
||
679 | break; |
||
680 | |||
681 | default: |
||
682 | if (start==NULL) start=ptr; |
||
683 | ne++; |
||
684 | |||
685 | ptr->p=prev; |
||
686 | ptr->n=ptr->next; |
||
687 | |||
688 | prev=ptr; |
||
689 | ptr=ptr->next; |
||
690 | break; |
||
691 | } |
||
692 | } |
||
693 | |||
694 | nument+=ne; |
||
695 | return start; |
||
696 | } |
||
697 | |||
698 | /* -- */ |
||
699 | |||
700 | #define MUSTREDISPLAY 0x01 |
||
701 | #define MUSTREBUILD 0x02 |
||
702 | |||
703 | int showmenu(WINDOW *wnd, struct menu *menu); |
||
704 | int showchoicewnd(WINDOW *wnd, struct menuentry *menu); |
||
705 | int showrangewnd(WINDOW *wnd, struct menuentry *menu); |
||
706 | |||
707 | int enteron(WINDOW *wnd,struct menuentry *ptr) |
||
708 | { |
||
709 | struct variable *var; |
||
710 | |||
711 | switch(ptr->type) { |
||
712 | |||
713 | case BOOLENTRY: |
||
714 | var=ptr->x.bool.var; |
||
715 | if (*var->value=='y') *var->value='n'; |
||
716 | else *var->value='y'; |
||
717 | if (var->flags&FLAG_M) return MUSTREBUILD; |
||
718 | break; |
||
719 | |||
720 | case TRISTATEENTRY: |
||
721 | var=ptr->x.tristate.var; |
||
722 | if (*var->value=='y') *var->value='n'; |
||
723 | else if (*var->value=='n') *var->value='m'; |
||
724 | else *var->value='y'; |
||
725 | if (var->flags&FLAG_M) return MUSTREBUILD; |
||
726 | break; |
||
727 | |||
728 | case RANGEENTRY: |
||
729 | return showrangewnd(wnd,ptr)|MUSTREDISPLAY; |
||
730 | |||
731 | case CHOICEENTRY: |
||
732 | return showchoicewnd(wnd,ptr)|MUSTREDISPLAY; |
||
733 | |||
734 | case SUBMENUENTRY: |
||
735 | return showmenu(wnd,ptr->x.submenu.menu)|MUSTREDISPLAY; |
||
736 | |||
737 | default: |
||
738 | _bell(); |
||
739 | break; |
||
740 | } |
||
741 | |||
742 | return 0; |
||
743 | } |
||
744 | |||
745 | /* --- */ |
||
746 | |||
747 | int SC=9; |
||
748 | int SR=9; |
||
749 | int NL=36; |
||
750 | int NC=61; |
||
751 | int BR=0; |
||
752 | int BC=4; |
||
753 | |||
754 | /* --- */ |
||
755 | |||
756 | /* sigh :-( */ |
||
757 | static struct choice *findprev(struct choice *list, struct choice *cur) |
||
758 | { |
||
759 | struct choice *c,*p; |
||
760 | c=list; |
||
761 | p=NULL; |
||
762 | while (c!=NULL) { |
||
763 | if (c==cur) return p; |
||
764 | p=c; |
||
765 | c=c->next; |
||
766 | } |
||
767 | return NULL; |
||
768 | } |
||
769 | |||
770 | int showchoicewnd(WINDOW *oldwnd, struct menuentry *ent) |
||
771 | { |
||
772 | WINDOW *wnd; |
||
773 | struct choice *first; // first menuentry of the list |
||
774 | struct choice *cur; // selected menuentry |
||
775 | struct choice *fline; // menuentry to show on the first line |
||
776 | struct choice *p; |
||
777 | int ch; |
||
778 | int rcur; |
||
779 | int i,r,c; |
||
780 | int ret; |
||
781 | int numcho; |
||
782 | |||
783 | ret=MUSTREDISPLAY; |
||
784 | |||
785 | numcho=ent->x.choice.numchoices; |
||
786 | _box(oldwnd,(NL-2-numcho)/2,5,numcho,NC-10,1,1,NULL,0,0); |
||
787 | wnd=_createwin(SR+(NL-2-numcho)/2,SC+5,numcho,NC-10); |
||
788 | _normal(wnd); |
||
789 | _clrscr(wnd); |
||
790 | |||
791 | first=fline=cur=ent->x.choice.list; |
||
792 | rcur=0; |
||
793 | |||
794 | //showtitle(ent->x.choice.text); |
||
795 | _clrscr(wnd); |
||
796 | |||
797 | for (;;) { |
||
798 | |||
799 | r=c=0; |
||
800 | |||
801 | p=fline; |
||
802 | i=0; |
||
803 | while (p!=NULL) { |
||
804 | _gotorc(wnd,r,c); |
||
805 | if (r==rcur) _inverse(wnd); |
||
806 | else _normal(wnd); |
||
807 | r++; |
||
808 | |||
809 | _printw(wnd,"(%c) %s",p==ent->x.choice.act?'X':' ',p->text); |
||
810 | _clreol(wnd); |
||
811 | |||
812 | p=p->next; |
||
813 | i++; |
||
814 | if (i==nmax) break; |
||
815 | } |
||
816 | |||
817 | _refresh(wnd); |
||
818 | |||
819 | ch=getch(); |
||
820 | switch (ch) { |
||
821 | |||
822 | case _KEY_OK: |
||
823 | case _KEY_OK2: |
||
824 | return ret; |
||
825 | |||
826 | case _KEY_DOWN: |
||
827 | if (cur->next==NULL) break; |
||
828 | cur=cur->next; |
||
829 | if (rcur<NL-1) { |
||
830 | rcur++; |
||
831 | break; |
||
832 | } |
||
833 | fline=fline->next; |
||
834 | break; |
||
835 | |||
836 | case _KEY_UP: |
||
837 | p=findprev(ent->x.choice.list,cur); |
||
838 | if (p==NULL) break; |
||
839 | cur=p; |
||
840 | if (rcur!=0) { |
||
841 | rcur=rcur--; |
||
842 | break; |
||
843 | } |
||
844 | fline=findprev(ent->x.choice.list,fline); |
||
845 | break; |
||
846 | |||
847 | case _KEY_TOGGLE: |
||
848 | if ((ent->x.choice.act->var->flags&FLAG_M)||(cur->var->flags&FLAG_M)) |
||
849 | ret|=MUSTREBUILD; |
||
850 | *(ent->x.choice.act->var->value)='n'; |
||
851 | ent->x.choice.act=cur; |
||
852 | *(ent->x.choice.act->var->value)='y'; |
||
853 | break; |
||
854 | } |
||
855 | } |
||
856 | } |
||
857 | |||
858 | int showrangewnd(WINDOW *wnd, struct menuentry *ent) |
||
859 | { |
||
860 | WINDOW *nw; |
||
861 | int ret; |
||
862 | int ch; |
||
863 | int val; |
||
864 | |||
865 | ret=MUSTREDISPLAY; |
||
866 | |||
867 | _box(wnd,(NL-3)/2,5,1,NC-10,1,1,NULL,0,0); |
||
868 | nw=_createwin(SR+(NL-3)/2,SC+5,1,NC-10); |
||
869 | _normal(nw); |
||
870 | _clrscr(nw); |
||
871 | |||
872 | val=atoi(ent->x.range.var->value); |
||
873 | for (;;) { |
||
874 | |||
875 | _normal(nw); |
||
876 | _gotorc(nw,0,0); |
||
877 | _printw(nw," %s : %8i",ent->x.range.text,val); |
||
878 | _clreol(nw); |
||
879 | _refresh(nw); |
||
880 | |||
881 | ch=getch(); |
||
882 | switch (ch) { |
||
883 | |||
884 | case _KEY_OK: |
||
885 | case _KEY_OK2: |
||
886 | case _KEY_TOGGLE: |
||
887 | { |
||
888 | char buffer[256]; |
||
889 | sprintf(buffer,"%i",val); |
||
890 | copystring(&ent->x.range.var->value,buffer); |
||
891 | } |
||
892 | _deletewin(nw); |
||
893 | return ret; |
||
894 | |||
895 | case _KEY_DOWN: |
||
896 | if (val>ent->x.range.minval) val--; |
||
897 | break; |
||
898 | |||
899 | case _KEY_UP: |
||
900 | if (val<ent->x.range.maxval) val++; |
||
901 | break; |
||
902 | |||
903 | } |
||
904 | } |
||
905 | } |
||
906 | |||
907 | |||
908 | |||
909 | |||
910 | |||
911 | |||
912 | int showhelpwin(WINDOW *wnd, struct menuentry *ent) |
||
913 | { |
||
914 | struct variable *var; |
||
915 | FILE *fin; |
||
916 | char buffer[256]; |
||
917 | WINDOW *nw; |
||
918 | int ret; |
||
919 | int ch; |
||
920 | int flag; |
||
921 | |||
922 | ret=MUSTREDISPLAY; |
||
923 | |||
924 | _box(wnd,(NL-3)/2,5,1,NC-10,1,1,NULL,0,0); |
||
925 | nw=_createwin(SR+(NL-3)/2,SC+5,1,NC-10); |
||
926 | _normal(nw); |
||
927 | _clrscr(nw); |
||
928 | |||
929 | _normal(nw); |
||
930 | _gotorc(nw,0,0); |
||
931 | |||
932 | switch(ent->type) { |
||
933 | case BOOLENTRY: var=ent->x.bool.var; break; |
||
934 | case SUBMENUENTRY: var=NULL; break; |
||
935 | case TRISTATEENTRY: var=ent->x.tristate.var; break; |
||
936 | case CHOICEENTRY: var=ent->x.choice.act->var; break; |
||
937 | case CASEENTRY: var=NULL; break; |
||
938 | case RANGEENTRY: var=ent->x.range.var; break; |
||
939 | case SEPARATORENTRY: var=NULL; break; |
||
940 | default: var=NULL; |
||
941 | } |
||
942 | |||
943 | if (var==NULL) goto END; |
||
944 | |||
945 | fin=fopen(helpfilename,"rt"); |
||
946 | if (fin!=NULL) { |
||
947 | |||
948 | if (varhelp[findvarindex(var)]==0) goto END; |
||
949 | fseek(fin,varhelp[findvarindex(var)],SEEK_SET); |
||
950 | |||
951 | flag=0; |
||
952 | while (fgets(buffer,sizeof(buffer),fin)!=NULL) { |
||
953 | if (*buffer=='#') continue; |
||
954 | if (*buffer=='@') { |
||
955 | if (flag) break; |
||
956 | continue; |
||
957 | } |
||
958 | _gotorc(nw,flag,0); |
||
959 | _printw(nw,"%s",buffer); |
||
960 | flag++; |
||
961 | } |
||
962 | fclose(fin); |
||
963 | } |
||
964 | |||
965 | _clreol(nw); |
||
966 | _refresh(nw); |
||
967 | |||
968 | ch=getch(); |
||
969 | |||
970 | END: |
||
971 | _deletewin(nw); |
||
972 | return ret; |
||
973 | } |
||
974 | |||
975 | |||
976 | |||
977 | |||
978 | |||
979 | |||
980 | |||
981 | int showmenu(WINDOW *wnd, struct menu *menu) |
||
982 | { |
||
983 | struct menuentry *first; /* first menuentry of the list */ |
||
984 | struct menuentry *cur; /* selected menuentry */ |
||
985 | struct menuentry *fline; /* menuentry to show on the first line */ |
||
986 | int redo; |
||
987 | int ch; |
||
988 | int rcur; |
||
989 | int ret; |
||
990 | |||
991 | first=fline=cur=NULL; |
||
992 | rcur=0; |
||
993 | redo=1; |
||
994 | ret=MUSTREDISPLAY; |
||
995 | |||
996 | for (;;) { |
||
997 | if (redo&MUSTREBUILD) redo|=MUSTREDISPLAY; |
||
998 | ret|=redo; |
||
999 | if (redo&MUSTREBUILD) { |
||
1000 | fline=NULL; |
||
1001 | |||
1002 | } |
||
1003 | if (redo&MUSTREDISPLAY) { |
||
1004 | nument=0; |
||
1005 | first=expandmenu(menu->entries); |
||
1006 | if (fline==NULL) { |
||
1007 | fline=first; |
||
1008 | if (cur==NULL) { |
||
1009 | cur=fline; |
||
1010 | rcur=0; |
||
1011 | } |
||
1012 | } |
||
1013 | nmax=NL; |
||
1014 | showtitle(menu->title); |
||
1015 | _normal(wnd); |
||
1016 | _clrscr(wnd); |
||
1017 | redo=0; |
||
1018 | } |
||
1019 | showmenuentries(wnd,fline,0,0,rcur); |
||
1020 | _refresh(wnd); |
||
1021 | |||
1022 | ch=getch(); |
||
1023 | switch (ch) { |
||
1024 | |||
1025 | case _KEY_OK: |
||
1026 | case _KEY_OK2: |
||
1027 | return ret; |
||
1028 | |||
1029 | case _KEY_DOWN: |
||
1030 | if (cur->n==NULL) break; |
||
1031 | cur=cur->n; |
||
1032 | if (rcur<NL-1) { |
||
1033 | rcur++; |
||
1034 | break; |
||
1035 | } |
||
1036 | fline=fline->n; |
||
1037 | break; |
||
1038 | |||
1039 | case _KEY_UP: |
||
1040 | if (cur->p==NULL) break; |
||
1041 | cur=cur->p; |
||
1042 | if (rcur!=0) { |
||
1043 | rcur=rcur--; |
||
1044 | break; |
||
1045 | } |
||
1046 | fline=fline->p; |
||
1047 | break; |
||
1048 | |||
1049 | case _KEY_TOGGLE: |
||
1050 | redo=enteron(wnd,cur); |
||
1051 | break; |
||
1052 | |||
1053 | case _KEY_HELP: |
||
1054 | redo=showhelpwin(wnd,cur); |
||
1055 | break; |
||
1056 | |||
1057 | default: |
||
1058 | /* |
||
1059 | _normal(STDWIN); |
||
1060 | _gotorc(STDWIN,0,0); |
||
1061 | _printw(STDWIN,"%04x",ch); |
||
1062 | _refresh(STDWIN); |
||
1063 | */ |
||
1064 | } |
||
1065 | |||
1066 | } |
||
1067 | |||
1068 | } |
||
1069 | |||
1070 | void showtitle(char *s) |
||
1071 | { |
||
1072 | _settitle(STDWIN,SR-6,SC-2,NL+8,NC+4,BR,BC,s,1,0); |
||
1073 | } |
||
1074 | |||
1075 | /* |
||
1076 | * |
||
1077 | */ |
||
1078 | |||
1079 | int show(void) |
||
1080 | { |
||
1081 | WINDOW *wnd; |
||
1082 | int i; |
||
1083 | |||
1084 | _initscreen(); |
||
1085 | _cursor_invisible(); |
||
1086 | |||
1087 | SC=9; |
||
1088 | SR=9; |
||
1089 | NL=_rows()-5-SR-BR*2; |
||
1090 | NC=_cols()-2-SC-BC*2; |
||
1091 | BR=0; |
||
1092 | BC=4; |
||
1093 | |||
1094 | _defaultcolor(STDWIN); |
||
1095 | _gotorc(STDWIN,0,0); |
||
1096 | if (caption!=NULL) _printw(STDWIN," %s",caption); |
||
1097 | _gotorc(STDWIN,1,1); |
||
1098 | for (i=0;i<_cols()-2;i++) _putch(STDWIN,_HH); |
||
1099 | |||
1100 | _box(STDWIN,SR-6,SC-2,NL+8,NC+4,BR,BC,NULL,1,0); |
||
1101 | _box(STDWIN,SR,SC,NL,NC,BR,BC,NULL,0,1); |
||
1102 | wnd=_createwin(SR,SC,NL,NC); |
||
1103 | |||
1104 | showmenu(wnd,mainmenu); |
||
1105 | |||
1106 | _cursor_visible(); |
||
1107 | _refresh(STDWIN); |
||
1108 | _endscreen(); |
||
1109 | |||
1110 | return 0; |
||
1111 | } |
||
1112 | |||
1113 | |||
1114 |