Subversion Repositories shark

Rev

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