Subversion Repositories shark

Rev

Rev 2 | Details | Compare with Previous | 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
 
10
/* per sleep() */
11
#include <unistd.h>
12
 
13
 
14
#if defined(USE_NCURSES)
15
#include <curses.h>
16
#elif defined(USE_CONIO)
17
#include <conio.o>
18
#else
19
#error USE_NCURSES or USE_CONIO must be defined
20
#endif
21
 
22
#include "hconf.h"
23
 
24
/*
25
 *
26
 * CONIO
27
 *
28
 */
29
 
30
#ifdef USE_CONIO
31
 
32
#define DEFAULT_BG BLUE
33
 
34
#define NORMAL_FG WHITE
35
#define NORMAL_BG BLUE
36
 
37
#define INVERSE_FG BLACK
38
#define INVERSE_BG RED
39
 
40
/* -- */
41
 
42
struct text_info info;
43
 
44
void _initscreen(void)
45
{
46
  textbackground(DEFAULT_BG);
47
  clrscr();
48
  gettextinfo(&info);
49
}
50
 
51
void _endscreen(void)
52
{
53
  clrscr();
54
}
55
 
56
static __inline__ int _cols(void)
57
{
58
  return info.screenwidth;
59
}
60
 
61
static __inline__ int _rows(void)
62
{
63
  return info.screenheight;
64
}
65
 
66
int _gotorc(int r, int c)
67
{
68
  /* zero based */
69
  gotoxy(c,r);
70
}
71
 
72
#define _printw(fmt,args...) cprintf(fmt,##args)
73
#define _refresh()
74
 
75
void _normal(void)
76
{
77
  textbackground(NORMAL_BG);
78
  textcolor(NORMAL_FG);
79
}
80
 
81
#endif
82
 
83
/*
84
 *
85
 * NCURSES
86
 *
87
 */
88
 
89
#ifdef USE_NCURSES
90
 
91
// with bold
92
#define DEFAULT_FG COLOR_CYAN
93
#define DEFAULT_BG COLOR_BLUE
94
 
95
#define NORMAL_FG COLOR_BLACK
96
#define NORMAL_BG COLOR_WHITE
97
 
98
// with bold
99
#define INVERSE_FG COLOR_WHITE
100
#define INVERSE_BG COLOR_BLUE
101
 
102
//with bold
103
#define BOX_BORDERFGU COLOR_WHITE
104
#define BOX_BORDERBGU COLOR_WHITE
105
 
106
#define BOX_BORDERFGD COLOR_BLACK
107
#define BOX_BORDERBGD COLOR_WHITE
108
 
109
#define BOX_FG COLOR_BLACK
110
#define BOX_BG COLOR_WHITE
111
 
112
#define SHADOW_FG COLOR_BLACK
113
#define SHADOW_BG COLOR_BLACK
114
 
115
#define TITLE_FG COLOR_YELLOW
116
#define TITLE_BG COLOR_WHITE
117
 
118
#define _KEY_OK     0x1b
119
#define _KEY_DOWN   KEY_DOWN
120
#define _KEY_UP     KEY_UP
121
#define _KEY_TOGGLE 0x0a
122
 
123
/* -- */
124
 
125
#define _BACKGROUND 1
126
#define _NORMAL     2
127
#define _INVERSE    3
128
#define _BORDERBOXU 4
129
#define _BORDERBOXD 5
130
#define _BOX        6
131
#define _SHADOW     7
132
#define _TITLE      8
133
#define _DEFAULT    9
134
 
135
#define STDWIN stdscr
136
 
137
/* (U-upper,L-lower) (L-left,R-right) */
138
#define _UL ACS_BSSB
139
#define _LL ACS_SSBB        
140
#define _UR ACS_BBSS
141
#define _LR ACS_SBBS
142
#define _HH ACS_BSBS
143
#define _VV ACS_SBSB
144
 
145
void _defaultcolor(WINDOW *w)
146
{
147
  wattrset(w,COLOR_PAIR(_DEFAULT)|A_BOLD);
148
  wbkgdset(w,COLOR_PAIR(_DEFAULT)|A_BOLD);
149
}
150
 
151
void _normal(WINDOW *w)
152
{
153
  wattrset(w,COLOR_PAIR(_NORMAL));
154
  wbkgdset(w,COLOR_PAIR(_NORMAL));
155
}
156
 
157
void _inverse(WINDOW *w)
158
{
159
  wattrset(w,COLOR_PAIR(_INVERSE)|A_BOLD);
160
  wbkgdset(w,COLOR_PAIR(_INVERSE)|A_BOLD);
161
}
162
 
163
void _shadow(WINDOW *w)
164
{
165
  wattrset(w,COLOR_PAIR(_SHADOW));
166
  wbkgdset(w,COLOR_PAIR(_SHADOW));
167
}
168
 
169
void _boxcolor(WINDOW *w)
170
{
171
  wattrset(w,COLOR_PAIR(_BOX));
172
  wbkgdset(w,COLOR_PAIR(_BOX));
173
}
174
 
175
void _titlecolor(WINDOW *w)
176
{
177
  wattrset(w,COLOR_PAIR(_TITLE)|A_BOLD);
178
  wbkgdset(w,COLOR_PAIR(_TITLE)|A_BOLD);
179
}
180
 
181
void _borderboxucolor(WINDOW *w)
182
{
183
  wattrset(w,COLOR_PAIR(_BORDERBOXU)|A_BOLD);
184
  wbkgdset(w,COLOR_PAIR(_BORDERBOXU)|A_BOLD);
185
}
186
 
187
void _borderboxdcolor(WINDOW *w)
188
{
189
  wattrset(w,COLOR_PAIR(_BORDERBOXD));
190
  wbkgdset(w,COLOR_PAIR(_BORDERBOXD));
191
}
192
 
193
void _initscreen(void)
194
{
195
  initscr();
196
  start_color();
197
  init_pair(_BACKGROUND,DEFAULT_BG,DEFAULT_BG);
198
  init_pair(_DEFAULT,DEFAULT_FG,DEFAULT_BG);
199
  init_pair(_NORMAL,NORMAL_FG,NORMAL_BG);
200
  init_pair(_INVERSE,INVERSE_FG,INVERSE_BG);
201
  init_pair(_BORDERBOXU,BOX_BORDERFGU,BOX_BORDERBGU);
202
  init_pair(_BORDERBOXD,BOX_BORDERFGD,BOX_BORDERBGD);
203
  init_pair(_BOX,BOX_FG,BOX_BG);
204
  init_pair(_SHADOW,SHADOW_FG,SHADOW_BG);
205
  init_pair(_TITLE,TITLE_FG,TITLE_BG);
206
  bkgdset(COLOR_PAIR(_BACKGROUND));
207
  clear();
208
  cbreak(); /* input one char at time (don't wait for \n) */
209
  noecho();
210
  keypad(stdscr,TRUE);
211
  _normal(stdscr);
212
  refresh();
213
}
214
 
215
void _endscreen(void)
216
{
217
  endwin();
218
}
219
 
220
static __inline__ int _cols(void)
221
{
222
  return COLS;
223
}
224
 
225
static __inline__ int _rows(void)
226
{
227
  return LINES;
228
}
229
 
230
static __inline__ void _gotorc(WINDOW *w,int r, int c)
231
{
232
  /* zero based */
233
  wmove(w,r,c);
234
}
235
 
236
#define _printw(w,fmt,args...) wprintw(w,fmt,##args)
237
 
238
void _refresh(WINDOW *w)
239
{
240
  wrefresh(w);
241
}
242
 
243
WINDOW *_createwin(int str, int stc, int lines, int cols)
244
{
245
  WINDOW *wnd;
246
  wnd=newwin(lines,cols,str,stc);
247
  if (wnd!=NULL) {
248
    //wbkgdset(wnd,COLOR_PAIR(_BACKGROUND));
249
    //wclear(wnd);
250
    //_normal(wnd);
251
  }
252
  return wnd;
253
}
254
 
255
#define _deletewin(w) delwin(w)
256
 
257
#define _putch(w,c) waddch(w,c)
258
#define _getch() getch()
259
#define _clreol(w) wclrtoeol(w)
260
#define _clrscr(w) wclear(w)
261
 
262
#define _bell() addch('\07');
263
 
264
#endif
265
 
266
/*
267
 *
268
 *
269
 *
270
 */
271
 
272
static void whichcolor(WINDOW *wnd, int up, int inv)
273
{
274
  if (((inv==1)&&(up==1))||((inv==0)&&(up==0))) _borderboxdcolor(wnd);
275
  else _borderboxucolor(wnd);
276
}
277
 
278
void _settitle(WINDOW *wnd,
279
               int sy, int sx,
280
               int lines, int cols,
281
               int bordy, int bordx,
282
               char *title,
283
               int shad, int inv)
284
{
285
  int x;
286
 
287
  sx-=bordx+1;
288
  sy-=bordy+1;
289
  cols+=2*(bordx+1);
290
  lines+=2*(bordy+1);
291
 
292
  whichcolor(wnd,1,inv);
293
  _gotorc(wnd,sy,sx+1);
294
  for (x=0;x<cols-2;x++) _putch(wnd,_HH);
295
 
296
  if (title!=NULL) {
297
    _titlecolor(wnd);
298
    _gotorc(wnd,sy,sx+(cols-strlen(title)-2)/2);
299
    _printw(wnd," %s ",title);
300
 
301
    _normal(wnd);
302
    _gotorc(wnd,sy+2,sx+2);
303
    _printw(wnd,"use <ESC> to exit, <ENTER> to enter/toggle,");
304
    _gotorc(wnd,sy+3,sx+2);
305
    _printw(wnd,"arrows keys to move");
306
  }
307
 
308
 
309
  _refresh(wnd);
310
}
311
 
312
void _box(WINDOW *wnd,
313
          int sy, int sx,
314
          int lines, int cols,
315
          int bordy, int bordx,
316
          char *title,
317
          int shad, int inv)
318
{
319
  int x,y;
320
 
321
  sx-=bordx+1;
322
  sy-=bordy+1;
323
  cols+=2*(bordx+1);
324
  lines+=2*(bordy+1);
325
 
326
  {
327
    char blanks[180];
328
    memset(blanks,' ',sizeof(blanks));
329
    blanks[cols]='\0';
330
    _boxcolor(wnd);
331
    for (y=0;y<lines;y++) {
332
      _gotorc(wnd,sy+y,sx);
333
      _printw(wnd,"%s",blanks);
334
    }
335
  }
336
 
337
  whichcolor(wnd,1,inv);
338
  _gotorc(wnd,sy,sx);
339
  _putch(wnd,_UL);
340
  for (x=0;x<cols-2;x++) _putch(wnd,_HH);
341
  whichcolor(wnd,0,inv);
342
  _putch(wnd,_UR);
343
 
344
  for (y=1;y<lines-1;y++) {
345
    whichcolor(wnd,1,inv);
346
    _gotorc(wnd,sy+y,sx);
347
    _putch(wnd,_VV);
348
    whichcolor(wnd,0,inv);
349
    _gotorc(wnd,sy+y,sx+cols-1);
350
    _putch(wnd,_VV);
351
    if (shad) {
352
      _shadow(wnd);
353
      _putch(wnd,' ');
354
      _putch(wnd,' ');
355
    }
356
  }
357
 
358
  whichcolor(wnd,1,inv);
359
  _gotorc(wnd,sy+lines-1,sx);
360
  _putch(wnd,_LL);
361
  whichcolor(wnd,0,inv);
362
  for (x=0;x<cols-2;x++) _putch(wnd,_HH);
363
  _putch(wnd,_LR);
364
  if (shad) {
365
    _shadow(wnd);
366
    _putch(wnd,' ');
367
    _putch(wnd,' ');
368
  }
369
 
370
  if (shad) {
371
    _shadow(wnd);
372
    _gotorc(wnd,sy+lines,sx+1);
373
    for (x=0;x<cols+1;x++) _putch(wnd,' ');
374
  }
375
 
376
  sx+=bordx+1;
377
  sy+=bordy+1;
378
  cols-=2*(bordx+1);
379
  lines-=2*(bordy+1);
380
 
381
  _settitle(wnd,sy,sx,lines,cols,bordy,bordx,title,shad,inv);
382
 
383
  /* refresh made by _settitle() */
384
}
385
 
386
void showtitle(char *s);
387
 
388
/* -- */
389
 
390
 
391
void showbol(WINDOW *wnd, struct menuentry *ptr)
392
{
393
  struct variable *var;
394
  char ch;
395
  var=ptr->x.bool.var;  
396
  if (!strcmp(var->value,"y")) ch='*';
397
  else ch=' ';
398
  _printw(wnd,"[%c] %s",ch,ptr->x.bool.text);
399
  _normal(wnd);
400
  _clreol(wnd);
401
}
402
 
403
void showtristate(WINDOW *wnd, struct menuentry *ptr)
404
{
405
  struct variable *var;
406
  char ch;
407
  var=ptr->x.bool.var;  
408
  if (!strcmp(var->value,"y")) ch='*';
409
  else if (!strcmp(var->value,"n")) ch=' ';
410
  else ch='M';
411
  _printw(wnd,"<%c> %s",ch,ptr->x.bool.text);
412
  _normal(wnd);
413
  _clreol(wnd);
414
}
415
 
416
void showchoice(WINDOW *wnd, struct menuentry *ptr)
417
{
418
  _printw(wnd,"   %s (%s)",ptr->x.choice.text,ptr->x.choice.act->text);
419
  _normal(wnd);
420
  _clreol(wnd);
421
}
422
 
423
void showsubmenu(WINDOW *wnd, struct menuentry *ptr)
424
{
425
  _printw(wnd,"    %s --->",ptr->x.submenu.text);
426
  _normal(wnd);
427
  _clreol(wnd);
428
}
429
 
430
/* -- */
431
 
432
int nmax; // numero linee massimo
433
 
434
void showmenuentries(WINDOW *wnd,struct menuentry *ptr, int r, int c, int rcur)
435
{
436
  int i;
437
 
438
  i=0;
439
  while (ptr!=NULL) {
440
    _gotorc(wnd,r,c);
441
    if (r==rcur) _inverse(wnd);
442
    else _normal(wnd);
443
    r++;
444
    switch(ptr->type) {
445
    case BOOLENTRY:
446
      showbol(wnd,ptr);
447
      break;
448
    case TRISTATEENTRY:
449
      showtristate(wnd,ptr);
450
      break;
451
    case CHOICEENTRY:
452
      showchoice(wnd,ptr);
453
      break;
454
    case SUBMENUENTRY:
455
      showsubmenu(wnd,ptr);
456
      break;
457
    default:
458
      _printw(wnd,"@@@");
459
      break;
460
    }
461
    ptr=ptr->n;
462
    i++;
463
    if (i==nmax) return;
464
  }
465
}
466
 
467
/* --- */
468
 
469
struct menuentry *expandcase(struct menuentry *menuent);
470
struct menuentry *expandmenu(struct menuentry *menuent);
471
 
472
struct menuentry *expandcase(struct menuentry *menuent)
473
{
474
  struct _case *list;
475
  list=menuent->x._case.list;
476
  while (list!=NULL) {
477
    if (!strcmp(list->value,menuent->x._case.var->value)) {      
478
      return expandmenu(list->list);
479
    }
480
    list=list->next;
481
  }
482
  return NULL;
483
}
484
 
485
int nument;
486
 
487
struct menuentry *expandmenu(struct menuentry *menuent)
488
{
489
  struct menuentry *start,*ptr,*ent,*prev,*p;
490
  int ne;
491
 
492
  ne=0;
493
  ptr=menuent;
494
  prev=NULL;
495
  start=NULL;
496
  while (ptr!=NULL) {
497
    switch(ptr->type) {
498
 
499
    case CASEENTRY:
500
      ent=expandcase(ptr);
501
      if (ent==NULL) {
502
        if (prev!=NULL) prev->n=ptr->next;
503
        ptr=ptr->next;
504
        break;
505
      }
506
      if (start==NULL) start=ent;
507
 
508
      if (prev!=NULL) prev->n=ent;
509
      ent->p=prev;
510
      p=ent;
511
      while (p->n!=NULL) p=p->n;
512
      p->n=ptr->next;
513
 
514
      prev=p;
515
      ptr=ptr->next;
516
      break;
517
 
518
    default:
519
      if (start==NULL) start=ptr;
520
      ne++;
521
 
522
      ptr->p=prev;
523
      ptr->n=ptr->next;
524
 
525
      prev=ptr;
526
      ptr=ptr->next;
527
      break;
528
    }
529
  }
530
 
531
  nument+=ne;
532
  return start;
533
}
534
 
535
/* -- */
536
 
537
#define MUSTREDISPLAY 0x01
538
#define MUSTREBUILD   0x02
539
 
540
int showmenu(WINDOW *wnd, struct menu *menu);
541
int showchoicewnd(WINDOW *wnd, struct menuentry *menu);
542
 
543
int enteron(WINDOW *wnd,struct menuentry *ptr)
544
{
545
  struct variable *var;
546
 
547
  switch(ptr->type) {
548
 
549
  case BOOLENTRY:
550
    var=ptr->x.bool.var;
551
    if (*var->value=='y') *var->value='n';
552
    else *var->value='y';
553
    if (var->flags&FLAG_M) return MUSTREBUILD;
554
    break;
555
 
556
  case TRISTATEENTRY:
557
    var=ptr->x.tristate.var;
558
    if (*var->value=='y') *var->value='n';
559
    else if (*var->value=='n') *var->value='m';
560
    else *var->value='y';
561
    if (var->flags&FLAG_M) return MUSTREBUILD;
562
    break;
563
 
564
  case CHOICEENTRY:
565
    return showchoicewnd(wnd,ptr)|MUSTREDISPLAY;
566
 
567
  case SUBMENUENTRY:
568
    return showmenu(wnd,ptr->x.submenu.menu)|MUSTREDISPLAY;
569
 
570
  default:
571
    _bell();
572
    break;
573
  }
574
 
575
  return 0;
576
}
577
 
578
/* --- */
579
 
580
int SC=9;
581
int SR=9;
582
int NL=36;
583
int NC=61;
584
int BR=0;
585
int BC=4;
586
 
587
/* --- */
588
 
589
/* sigh :-( */
590
static struct choice *findprev(struct choice *list, struct choice *cur)
591
{
592
  struct choice *c,*p;
593
  c=list;
594
  p=NULL;
595
  while (c!=NULL) {
596
    if (c==cur) return p;
597
    p=c;
598
    c=c->next;
599
  }
600
  return NULL;
601
}
602
 
603
int showchoicewnd(WINDOW *wnd, struct menuentry *ent)
604
{
605
  struct choice *first; // first menuentry of the list
606
  struct choice *cur;   // selected menuentry
607
  struct choice *fline; // menuentry to show on the first line
608
  struct choice *p;
609
  int ch;
610
  int rcur;
611
  int i,r,c;
612
  int ret;
613
 
614
  ret=MUSTREDISPLAY;
615
 
616
  first=fline=cur=ent->x.choice.list;
617
  rcur=0;
618
 
619
  showtitle(ent->x.choice.text);
620
  _clrscr(wnd);
621
 
622
  for (;;) {
623
 
624
    r=c=0;
625
 
626
    p=fline;
627
    i=0;
628
    while (p!=NULL) {
629
      _gotorc(wnd,r,c);
630
      if (r==rcur) _inverse(wnd);
631
      else _normal(wnd);
632
      r++;
633
 
634
      _printw(wnd,"(%c) %s",p==ent->x.choice.act?'X':' ',p->text);
635
      _clreol(wnd);
636
 
637
      p=p->next;
638
      i++;
639
      if (i==nmax) break;
640
    }
641
 
642
    _refresh(wnd);
643
 
644
    ch=getch();
645
    switch (ch) {
646
 
647
    case _KEY_OK:
648
      return ret;
649
 
650
    case _KEY_DOWN:
651
      if (cur->next==NULL) break;
652
      cur=cur->next;
653
      if (rcur<NL-1) {
654
        rcur++;
655
        break;
656
      }
657
      fline=fline->next;
658
      break;
659
 
660
    case _KEY_UP:
661
      p=findprev(ent->x.choice.list,cur);
662
      if (p==NULL) break;
663
      cur=p;
664
      if (rcur!=0) {
665
        rcur=rcur--;
666
        break;
667
      }
668
      fline=findprev(ent->x.choice.list,fline);
669
      break;
670
 
671
    case _KEY_TOGGLE:
672
      if ((ent->x.choice.act->var->flags&FLAG_M)||(cur->var->flags&FLAG_M))
673
        ret|=MUSTREBUILD;
674
      *(ent->x.choice.act->var->value)='n';
675
      ent->x.choice.act=cur;
676
      *(ent->x.choice.act->var->value)='y';
677
      break;         
678
    }    
679
  }
680
}
681
 
682
int showmenu(WINDOW *wnd, struct menu *menu)
683
{
684
  struct menuentry *first; // first menuentry of the list
685
  struct menuentry *cur;   // selected menuentry
686
  struct menuentry *fline; // menuentry to show on the first line
687
  int redo;
688
  int ch;
689
  int rcur;
690
  int ret;
691
 
692
  first=fline=cur=NULL;
693
  rcur=0;
694
  redo=1;
695
  ret=MUSTREDISPLAY;
696
 
697
  for (;;) {
698
    if (redo&MUSTREBUILD) redo|=MUSTREDISPLAY;
699
    ret|=redo;
700
    if (redo&MUSTREBUILD) {
701
      fline=NULL;
702
 
703
    }
704
    if (redo&MUSTREDISPLAY) {
705
      nument=0;
706
      first=expandmenu(menu->entries);
707
      if (fline==NULL) {
708
        fline=first;
709
        if (cur==NULL) {
710
          cur=fline;
711
          rcur=0;
712
        }
713
      }
714
      nmax=NL;
715
      showtitle(menu->title);
716
      _normal(wnd);
717
      _clrscr(wnd);
718
      redo=0;
719
    }
720
    showmenuentries(wnd,fline,0,0,rcur);
721
    _refresh(wnd);
722
 
723
    ch=getch();
724
    switch (ch) {
725
 
726
    case _KEY_OK:
727
      return ret;
728
 
729
    case _KEY_DOWN:
730
      if (cur->n==NULL) break;
731
      cur=cur->n;
732
      if (rcur<NL-1) {
733
        rcur++;
734
        break;
735
      }
736
      fline=fline->n;
737
      break;
738
 
739
    case _KEY_UP:
740
      if (cur->p==NULL) break;
741
      cur=cur->p;
742
      if (rcur!=0) {
743
        rcur=rcur--;
744
        break;
745
      }
746
      fline=fline->p;
747
      break;
748
 
749
    case _KEY_TOGGLE:
750
      redo=enteron(wnd,cur);      
751
      break;         
752
 
753
    default:
754
      /*
755
      _normal(STDWIN);
756
      _gotorc(STDWIN,0,0);
757
      _printw(STDWIN,"%04x",ch);
758
      _refresh(STDWIN);
759
      */
760
    }    
761
 
762
  }
763
 
764
}
765
 
766
void showtitle(char *s)
767
{
768
  _settitle(STDWIN,SR-6,SC-2,NL+8,NC+4,BR,BC,s,1,0);
769
}
770
 
771
/*
772
 *
773
 */
774
 
775
int show(void)
776
{
777
  WINDOW *wnd;
778
  int i;
779
 
780
  _initscreen();
781
 
782
  SC=9;
783
  SR=9;
784
  NL=_rows()-5-SR-BR*2;
785
  NC=_cols()-2-SC-BC*2;
786
  BR=0;
787
  BC=4;
788
 
789
  _defaultcolor(STDWIN);
790
  _gotorc(STDWIN,0,0);
791
  _printw(STDWIN," Hartik4 (Lego) version 4.0pre1 - Configuration");
792
  _gotorc(STDWIN,1,1);
793
  for (i=0;i<_cols()-2;i++) _putch(STDWIN,_HH);
794
 
795
  _box(STDWIN,SR-6,SC-2,NL+8,NC+4,BR,BC,NULL,1,0);
796
  _box(STDWIN,SR,SC,NL,NC,BR,BC,NULL,0,1);
797
  wnd=_createwin(SR,SC,NL,NC);
798
 
799
 
800
 
801
 
802
 
803
 
804
 
805
  //showmenu(wnd,mainmenu);
806
 
807
 
808
 
809
 
810
 
811
  _endscreen();
812
 
813
  return 0;
814
}
815
 
816
 
817