Blame |
Last modification |
View Log
| RSS feed
/*
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#if defined(USE_NCURSES)
#include <curses.h>
#include <term.h>
#elif defined(USE_CONIO)
#include <conio.h>
/* for usleep() */
#include <unistd.h>
/* for sound(), nosound() */
#include <pc.h>
#else
#error USE_NCURSES or USE_CONIO must be defined
#endif
#include "hconf.h"
/*
*
* CONIO
*
*/
#ifdef USE_CONIO
// with bold
#define DEFAULT_FG CYAN
#define DEFAULT_BG BLUE
#define NORMAL_FG BLACK
#define NORMAL_BG WHITE
// with bold
#define INVERSE_FG WHITE
#define INVERSE_BG BLUE
//with bold
#define BOX_BORDERFGU WHITE
#define BOX_BORDERBGU WHITE
#define BOX_BORDERFGD BLACK
#define BOX_BORDERBGD WHITE
#define BOX_FG BLACK
#define BOX_BG WHITE
#define SHADOW_FG BLACK
#define SHADOW_BG BLACK
#define TITLE_FG YELLOW
#define TITLE_BG WHITE
#define _KEY_OK 0x1b
#define _KEY_OK2 0x4b
#define _KEY_DOWN 0x50
#define _KEY_UP 0x48
#define _KEY_TOGGLE 0x0d
#define _KEY_HELP '?'
/* (U-upper,L-lower) (L-left,R-right) */
#define _UL 'Ú'
#define _LL 'À'
#define _UR '¿'
#define _LR 'Ù'
#define _HH 'Ä'
#define _VV '³'
/* -- */
typedef struct tagWINDOW
{
int str
,stc
,nl
,nc
;
} WINDOW
;
void _defaultcolor
(WINDOW
*w
)
{
textbackground
(DEFAULT_BG
);
textcolor
(DEFAULT_FG
);
}
void _normal
(WINDOW
*w
)
{
textbackground
(NORMAL_BG
);
textcolor
(NORMAL_FG
);
}
void _inverse
(WINDOW
*w
)
{
textbackground
(INVERSE_BG
);
textcolor
(INVERSE_FG
);
}
void _shadow
(WINDOW
*w
)
{
textbackground
(SHADOW_BG
);
textcolor
(SHADOW_FG
);
}
void _boxcolor
(WINDOW
*w
)
{
textbackground
(BOX_BG
);
textcolor
(BOX_FG
);
}
void _titlecolor
(WINDOW
*w
)
{
textbackground
(TITLE_BG
);
textcolor
(TITLE_FG
);
}
void _borderboxucolor
(WINDOW
*w
)
{
textbackground
(BOX_BORDERBGU
);
textcolor
(BOX_BORDERFGU
);
}
void _borderboxdcolor
(WINDOW
*w
)
{
textbackground
(BOX_BORDERBGD
);
textcolor
(BOX_BORDERFGD
);
}
/* -- */
struct text_info info
;
#define _cols() info.screenwidth
#define _rows() info.screenheight
#define _cursor_invisible() _setcursortype(_NOCURSOR)
#define _cursor_visible() _setcursortype(_NORMALCURSOR)
#define _gotorc(w,r,c) gotoxy(w->stc+c+1,w->str+r+1)
#define _printw(w,fmt,args...) cprintf(fmt,##args)
#define _refresh(w)
#define _putch(w,c) putch(c)
#define _getch() getch()
void _clrscr
(WINDOW
*w
)
{
static char buffer
[256];
int r
;
memset(buffer
,' ',sizeof(buffer
));
buffer
[w
->nc
]='\0';
for (r
=0;r
<w
->nl
;r
++) {
gotoxy
(w
->stc
+1,w
->str
+r
+1);
cprintf
("%s",buffer
);
}
}
void _clreol
(WINDOW
*w
)
{
int l
;
l
=w
->stc
+w
->nc
-wherex
();
if (l
>0)
while (l
-->0) putch
(' ');
}
void _bell
(void)
{
sound
(2000);
usleep
(250000l);
nosound
();
}
/* -- */
WINDOW
*_createwin
(int str
, int stc
, int nlines
, int cols
)
{
WINDOW
*wnd
;
wnd
=(WINDOW
*)malloc(sizeof(WINDOW
));
if (wnd
!=NULL
) {
wnd
->str
=str
;
wnd
->stc
=stc
;
wnd
->nl
=nlines
;
wnd
->nc
=cols
;
}
return wnd
;
}
#define _deletewin(w) free(w)
WINDOW
*STDWIN
;
void _initscreen
(void)
{
gppconio_init
();
gettextinfo
(&info
);
STDWIN
=_createwin
(0,0,_rows
(),_cols
());
_defaultcolor
(STDWIN
);
clrscr
();
}
void _endscreen
(void)
{
//clrscr();
}
#endif
/*
*
* NCURSES
*
*/
#ifdef USE_NCURSES
// with bold
#define DEFAULT_FG COLOR_CYAN
#define DEFAULT_BG COLOR_BLUE
#define NORMAL_FG COLOR_BLACK
#define NORMAL_BG COLOR_WHITE
// with bold
#define INVERSE_FG COLOR_WHITE
#define INVERSE_BG COLOR_BLUE
//with bold
#define BOX_BORDERFGU COLOR_WHITE
#define BOX_BORDERBGU COLOR_WHITE
#define BOX_BORDERFGD COLOR_BLACK
#define BOX_BORDERBGD COLOR_WHITE
#define BOX_FG COLOR_BLACK
#define BOX_BG COLOR_WHITE
#define SHADOW_FG COLOR_BLACK
#define SHADOW_BG COLOR_BLACK
#define TITLE_FG COLOR_YELLOW
#define TITLE_BG COLOR_WHITE
#define _KEY_OK 0x1b
#define _KEY_OK2 'q'
#define _KEY_DOWN KEY_DOWN
#define _KEY_UP KEY_UP
#define _KEY_TOGGLE 0x0a
#define _KEY_HELP '?'
/* -- */
#define _BACKGROUND 1
#define _NORMAL 2
#define _INVERSE 3
#define _BORDERBOXU 4
#define _BORDERBOXD 5
#define _BOX 6
#define _SHADOW 7
#define _TITLE 8
#define _DEFAULT 9
#define STDWIN stdscr
/* (U-upper,L-lower) (L-left,R-right) */
#define _UL ACS_BSSB
#define _LL ACS_SSBB
#define _UR ACS_BBSS
#define _LR ACS_SBBS
#define _HH ACS_BSBS
#define _VV ACS_SBSB
void _defaultcolor
(WINDOW
*w
)
{
wattrset
(w
,COLOR_PAIR
(_DEFAULT
)|A_BOLD
);
wbkgdset
(w
,COLOR_PAIR
(_DEFAULT
)|A_BOLD
);
}
void _normal
(WINDOW
*w
)
{
wattrset
(w
,COLOR_PAIR
(_NORMAL
));
wbkgdset
(w
,COLOR_PAIR
(_NORMAL
));
}
void _inverse
(WINDOW
*w
)
{
wattrset
(w
,COLOR_PAIR
(_INVERSE
)|A_BOLD
);
wbkgdset
(w
,COLOR_PAIR
(_INVERSE
)|A_BOLD
);
}
void _shadow
(WINDOW
*w
)
{
wattrset
(w
,COLOR_PAIR
(_SHADOW
));
wbkgdset
(w
,COLOR_PAIR
(_SHADOW
));
}
void _boxcolor
(WINDOW
*w
)
{
wattrset
(w
,COLOR_PAIR
(_BOX
));
wbkgdset
(w
,COLOR_PAIR
(_BOX
));
}
void _titlecolor
(WINDOW
*w
)
{
wattrset
(w
,COLOR_PAIR
(_TITLE
)|A_BOLD
);
wbkgdset
(w
,COLOR_PAIR
(_TITLE
)|A_BOLD
);
}
void _borderboxucolor
(WINDOW
*w
)
{
wattrset
(w
,COLOR_PAIR
(_BORDERBOXU
)|A_BOLD
);
wbkgdset
(w
,COLOR_PAIR
(_BORDERBOXU
)|A_BOLD
);
}
void _borderboxdcolor
(WINDOW
*w
)
{
wattrset
(w
,COLOR_PAIR
(_BORDERBOXD
));
wbkgdset
(w
,COLOR_PAIR
(_BORDERBOXD
));
}
/* -- */
#define _cursor_invisible() putp(cursor_invisible)
#define _cursor_visible() {putp(cursor_visible);putp(cursor_normal);}
#define _cols() COLS
#define _rows() LINES
#define _gotorc(w,r,c) wmove(w,r,c)
#define _printw(w,fmt,args...) wprintw(w,fmt,##args)
#define _refresh(w) wrefresh(w)
#define _putch(w,c) waddch(w,c)
#define _getch() getch()
#define _clreol(w) wclrtoeol(w)
#define _clrscr(w) wclear(w)
#define _bell() addch('\07');
/* -- */
void _initscreen
(void)
{
initscr
();
start_color
();
init_pair
(_BACKGROUND
,DEFAULT_BG
,DEFAULT_BG
);
init_pair
(_DEFAULT
,DEFAULT_FG
,DEFAULT_BG
);
init_pair
(_NORMAL
,NORMAL_FG
,NORMAL_BG
);
init_pair
(_INVERSE
,INVERSE_FG
,INVERSE_BG
);
init_pair
(_BORDERBOXU
,BOX_BORDERFGU
,BOX_BORDERBGU
);
init_pair
(_BORDERBOXD
,BOX_BORDERFGD
,BOX_BORDERBGD
);
init_pair
(_BOX
,BOX_FG
,BOX_BG
);
init_pair
(_SHADOW
,SHADOW_FG
,SHADOW_BG
);
init_pair
(_TITLE
,TITLE_FG
,TITLE_BG
);
bkgdset
(COLOR_PAIR
(_BACKGROUND
));
clear
();
cbreak
(); /* input one char at time (don't wait for \n) */
noecho
();
keypad
(stdscr
,TRUE
);
_normal
(stdscr
);
_cursor_invisible
();
refresh
();
}
void _endscreen
(void)
{
_cursor_visible
();
refresh
();
endwin
();
}
WINDOW
*_createwin
(int str
, int stc
, int nlines
, int cols
)
{
WINDOW
*wnd
;
wnd
=newwin
(nlines
,cols
,str
,stc
);
if (wnd
!=NULL
) {
//wbkgdset(wnd,COLOR_PAIR(_BACKGROUND));
//wclear(wnd);
//_normal(wnd);
}
return wnd
;
}
#define _deletewin(w) delwin(w)
#endif
/*
*
*
*
*/
static void whichcolor
(WINDOW
*wnd
, int up
, int inv
)
{
if (((inv
==1)&&(up
==1))||((inv
==0)&&(up
==0))) _borderboxdcolor
(wnd
);
else _borderboxucolor
(wnd
);
}
void _settitle
(WINDOW
*wnd
,
int sy
, int sx
,
int nlines
, int cols
,
int bordy
, int bordx
,
char *title
,
int shad
, int inv
)
{
int x
;
sx
-=bordx
+1;
sy
-=bordy
+1;
cols
+=2*(bordx
+1);
nlines
+=2*(bordy
+1);
whichcolor
(wnd
,1,inv
);
_gotorc
(wnd
,sy
,sx
+1);
for (x
=0;x
<cols
-2;x
++) _putch
(wnd
,_HH
);
if (title
!=NULL
) {
_titlecolor
(wnd
);
_gotorc
(wnd
,sy
,sx
+(cols
-strlen(title
)-2)/2);
_printw
(wnd
," %s ",title
);
_normal
(wnd
);
_gotorc
(wnd
,sy
+2,sx
+2);
_printw
(wnd
,"use <ESC> to exit, <ENTER> to enter/toggle,");
_gotorc
(wnd
,sy
+3,sx
+2);
_printw
(wnd
,"arrows keys to move");
}
_refresh
(wnd
);
}
void _box
(WINDOW
*wnd
,
int sy
, int sx
,
int nlines
, int cols
,
int bordy
, int bordx
,
char *title
,
int shad
, int inv
)
{
int x
,y
;
sx
-=bordx
+1;
sy
-=bordy
+1;
cols
+=2*(bordx
+1);
nlines
+=2*(bordy
+1);
{
static char blanks
[180];
memset(blanks
,' ',sizeof(blanks
));
blanks
[cols
]='\0';
_boxcolor
(wnd
);
for (y
=0;y
<nlines
;y
++) {
_gotorc
(wnd
,sy
+y
,sx
);
_printw
(wnd
,"%s",blanks
);
}
}
whichcolor
(wnd
,1,inv
);
_gotorc
(wnd
,sy
,sx
);
_putch
(wnd
,_UL
);
for (x
=0;x
<cols
-2;x
++) _putch
(wnd
,_HH
);
whichcolor
(wnd
,0,inv
);
_putch
(wnd
,_UR
);
for (y
=1;y
<nlines
-1;y
++) {
whichcolor
(wnd
,1,inv
);
_gotorc
(wnd
,sy
+y
,sx
);
_putch
(wnd
,_VV
);
whichcolor
(wnd
,0,inv
);
_gotorc
(wnd
,sy
+y
,sx
+cols
-1);
_putch
(wnd
,_VV
);
if (shad
) {
_shadow
(wnd
);
_putch
(wnd
,' ');
_putch
(wnd
,' ');
}
}
whichcolor
(wnd
,1,inv
);
_gotorc
(wnd
,sy
+nlines
-1,sx
);
_putch
(wnd
,_LL
);
whichcolor
(wnd
,0,inv
);
for (x
=0;x
<cols
-2;x
++) _putch
(wnd
,_HH
);
_putch
(wnd
,_LR
);
if (shad
) {
_shadow
(wnd
);
_putch
(wnd
,' ');
_putch
(wnd
,' ');
}
if (shad
) {
_shadow
(wnd
);
_gotorc
(wnd
,sy
+nlines
,sx
+1);
for (x
=0;x
<cols
+1;x
++) _putch
(wnd
,' ');
}
sx
+=bordx
+1;
sy
+=bordy
+1;
cols
-=2*(bordx
+1);
nlines
-=2*(bordy
+1);
_settitle
(wnd
,sy
,sx
,nlines
,cols
,bordy
,bordx
,title
,shad
,inv
);
/* refresh made by _settitle() */
}
void showtitle
(char *s
);
/* -- */
void showbool
(WINDOW
*wnd
, struct menuentry
*ptr
)
{
struct variable
*var
;
char ch
;
var
=ptr
->x.
bool.
var;
if (!strcmp(var
->value
,"y")) ch
='*';
else ch
=' ';
_printw
(wnd
,"[%c] %s",ch
,ptr
->x.
bool.
text);
_normal
(wnd
);
_clreol
(wnd
);
}
void showtristate
(WINDOW
*wnd
, struct menuentry
*ptr
)
{
struct variable
*var
;
char ch
;
var
=ptr
->x.
bool.
var;
if (!strcmp(var
->value
,"y")) ch
='*';
else if (!strcmp(var
->value
,"n")) ch
=' ';
else ch
='M';
_printw
(wnd
,"<%c> %s",ch
,ptr
->x.
bool.
text);
_normal
(wnd
);
_clreol
(wnd
);
}
void showchoice
(WINDOW
*wnd
, struct menuentry
*ptr
)
{
if (strcmp(ptr
->x.
choice.
act->var
->value
,"y")) {
/* well.. sometimes reading an old config.h can cause act pointer */
/* to be bad :-( */
struct choice
*p
;
p
=ptr
->x.
choice.
list;
while (p
!=NULL
) {
if (!strcmp(p
->var
->value
,"y")) {
ptr
->x.
choice.
act=p
;
break;
}
p
=p
->next
;
}
}
_printw
(wnd
," %s (%s)",ptr
->x.
choice.
text,ptr
->x.
choice.
act->text
);
_normal
(wnd
);
_clreol
(wnd
);
}
void showrange
(WINDOW
*wnd
, struct menuentry
*ptr
)
{
_printw
(wnd
," %s (%s)",ptr
->x.
range.
text,ptr
->x.
range.
var->value
);
_normal
(wnd
);
_clreol
(wnd
);
}
void showsubmenu
(WINDOW
*wnd
, struct menuentry
*ptr
)
{
_printw
(wnd
," %s --->",ptr
->x.
submenu.
text);
_normal
(wnd
);
_clreol
(wnd
);
}
void showseparator
(WINDOW
*wnd
, struct menuentry
*ptr
)
{
_printw
(wnd
," *********************** ");
_normal
(wnd
);
_clreol
(wnd
);
}
/* -- */
int nmax
; // numero linee massimo
void showmenuentries
(WINDOW
*wnd
,struct menuentry
*ptr
, int r
, int c
, int rcur
)
{
int i
;
i
=0;
while (ptr
!=NULL
) {
_gotorc
(wnd
,r
,c
);
if (r
==rcur
) _inverse
(wnd
);
else _normal
(wnd
);
r
++;
switch(ptr
->type
) {
case RANGEENTRY
:
showrange
(wnd
,ptr
);
break;
case BOOLENTRY
:
showbool
(wnd
,ptr
);
break;
case TRISTATEENTRY
:
showtristate
(wnd
,ptr
);
break;
case CHOICEENTRY
:
showchoice
(wnd
,ptr
);
break;
case SUBMENUENTRY
:
showsubmenu
(wnd
,ptr
);
break;
case SEPARATORENTRY
:
showseparator
(wnd
,ptr
);
break;
default:
_printw
(wnd
,"@@@");
break;
}
ptr
=ptr
->n
;
i
++;
if (i
==nmax
) return;
}
}
/* --- */
struct menuentry
*expandcase
(struct menuentry
*menuent
);
struct menuentry
*expandmenu
(struct menuentry
*menuent
);
struct menuentry
*expandcase
(struct menuentry
*menuent
)
{
struct _case
*list
;
list
=menuent
->x._case.
list;
while (list
!=NULL
) {
if (!strcmp(list
->value
,menuent
->x._case.
var->value
)) {
return expandmenu
(list
->list
);
}
list
=list
->next
;
}
return NULL
;
}
int nument
;
struct menuentry
*expandmenu
(struct menuentry
*menuent
)
{
struct menuentry
*start
,*ptr
,*ent
,*prev
,*p
;
int ne
;
ne
=0;
ptr
=menuent
;
prev
=NULL
;
start
=NULL
;
while (ptr
!=NULL
) {
switch(ptr
->type
) {
case CASEENTRY
:
ent
=expandcase
(ptr
);
if (ent
==NULL
) {
if (prev
!=NULL
) prev
->n
=ptr
->next
;
ptr
=ptr
->next
;
break;
}
if (start
==NULL
) start
=ent
;
if (prev
!=NULL
) prev
->n
=ent
;
ent
->p
=prev
;
p
=ent
;
while (p
->n
!=NULL
) p
=p
->n
;
p
->n
=ptr
->next
;
prev
=p
;
ptr
=ptr
->next
;
break;
default:
if (start
==NULL
) start
=ptr
;
ne
++;
ptr
->p
=prev
;
ptr
->n
=ptr
->next
;
prev
=ptr
;
ptr
=ptr
->next
;
break;
}
}
nument
+=ne
;
return start
;
}
/* -- */
#define MUSTREDISPLAY 0x01
#define MUSTREBUILD 0x02
int showmenu
(WINDOW
*wnd
, struct menu
*menu
);
int showchoicewnd
(WINDOW
*wnd
, struct menuentry
*menu
);
int showrangewnd
(WINDOW
*wnd
, struct menuentry
*menu
);
int enteron
(WINDOW
*wnd
,struct menuentry
*ptr
)
{
struct variable
*var
;
switch(ptr
->type
) {
case BOOLENTRY
:
var
=ptr
->x.
bool.
var;
if (*var
->value
=='y') *var
->value
='n';
else *var
->value
='y';
if (var
->flags
&FLAG_M
) return MUSTREBUILD
;
break;
case TRISTATEENTRY
:
var
=ptr
->x.
tristate.
var;
if (*var
->value
=='y') *var
->value
='n';
else if (*var
->value
=='n') *var
->value
='m';
else *var
->value
='y';
if (var
->flags
&FLAG_M
) return MUSTREBUILD
;
break;
case RANGEENTRY
:
return showrangewnd
(wnd
,ptr
)|MUSTREDISPLAY
;
case CHOICEENTRY
:
return showchoicewnd
(wnd
,ptr
)|MUSTREDISPLAY
;
case SUBMENUENTRY
:
return showmenu
(wnd
,ptr
->x.
submenu.
menu)|MUSTREDISPLAY
;
default:
_bell
();
break;
}
return 0;
}
/* --- */
int SC
=9;
int SR
=9;
int NL
=36;
int NC
=61;
int BR
=0;
int BC
=4;
/* --- */
/* sigh :-( */
static struct choice
*findprev
(struct choice
*list
, struct choice
*cur
)
{
struct choice
*c
,*p
;
c
=list
;
p
=NULL
;
while (c
!=NULL
) {
if (c
==cur
) return p
;
p
=c
;
c
=c
->next
;
}
return NULL
;
}
int showchoicewnd
(WINDOW
*oldwnd
, struct menuentry
*ent
)
{
WINDOW
*wnd
;
struct choice
*first
; // first menuentry of the list
struct choice
*cur
; // selected menuentry
struct choice
*fline
; // menuentry to show on the first line
struct choice
*p
;
int ch
;
int rcur
;
int i
,r
,c
;
int ret
;
int numcho
;
ret
=MUSTREDISPLAY
;
numcho
=ent
->x.
choice.
numchoices;
_box
(oldwnd
,(NL
-2-numcho
)/2,5,numcho
,NC
-10,1,1,NULL
,0,0);
wnd
=_createwin
(SR
+(NL
-2-numcho
)/2,SC
+5,numcho
,NC
-10);
_normal
(wnd
);
_clrscr
(wnd
);
first
=fline
=cur
=ent
->x.
choice.
list;
rcur
=0;
//showtitle(ent->x.choice.text);
_clrscr
(wnd
);
for (;;) {
r
=c
=0;
p
=fline
;
i
=0;
while (p
!=NULL
) {
_gotorc
(wnd
,r
,c
);
if (r
==rcur
) _inverse
(wnd
);
else _normal
(wnd
);
r
++;
_printw
(wnd
,"(%c) %s",p
==ent
->x.
choice.
act?'X':' ',p
->text
);
_clreol
(wnd
);
p
=p
->next
;
i
++;
if (i
==nmax
) break;
}
_refresh
(wnd
);
ch
=getch();
switch (ch
) {
case _KEY_OK
:
case _KEY_OK2
:
return ret
;
case _KEY_DOWN
:
if (cur
->next
==NULL
) break;
cur
=cur
->next
;
if (rcur
<NL
-1) {
rcur
++;
break;
}
fline
=fline
->next
;
break;
case _KEY_UP
:
p
=findprev
(ent
->x.
choice.
list,cur
);
if (p
==NULL
) break;
cur
=p
;
if (rcur
!=0) {
rcur
=rcur
--;
break;
}
fline
=findprev
(ent
->x.
choice.
list,fline
);
break;
case _KEY_TOGGLE
:
if ((ent
->x.
choice.
act->var
->flags
&FLAG_M
)||(cur
->var
->flags
&FLAG_M
))
ret
|=MUSTREBUILD
;
*(ent
->x.
choice.
act->var
->value
)='n';
ent
->x.
choice.
act=cur
;
*(ent
->x.
choice.
act->var
->value
)='y';
break;
}
}
}
int showrangewnd
(WINDOW
*wnd
, struct menuentry
*ent
)
{
WINDOW
*nw
;
int ret
;
int ch
;
int val
;
ret
=MUSTREDISPLAY
;
_box
(wnd
,(NL
-3)/2,5,1,NC
-10,1,1,NULL
,0,0);
nw
=_createwin
(SR
+(NL
-3)/2,SC
+5,1,NC
-10);
_normal
(nw
);
_clrscr
(nw
);
val
=atoi(ent
->x.
range.
var->value
);
for (;;) {
_normal
(nw
);
_gotorc
(nw
,0,0);
_printw
(nw
," %s : %8i",ent
->x.
range.
text,val
);
_clreol
(nw
);
_refresh
(nw
);
ch
=getch();
switch (ch
) {
case _KEY_OK
:
case _KEY_OK2
:
case _KEY_TOGGLE
:
{
char buffer
[256];
sprintf(buffer
,"%i",val
);
copystring
(&ent
->x.
range.
var->value
,buffer
);
}
_deletewin
(nw
);
return ret
;
case _KEY_DOWN
:
if (val
>ent
->x.
range.
minval) val
--;
break;
case _KEY_UP
:
if (val
<ent
->x.
range.
maxval) val
++;
break;
}
}
}
int showhelpwin
(WINDOW
*wnd
, struct menuentry
*ent
)
{
struct variable
*var
;
FILE
*fin
;
char buffer
[256];
WINDOW
*nw
;
int ret
;
int ch
;
int flag
;
ret
=MUSTREDISPLAY
;
_box
(wnd
,(NL
-3)/2,5,1,NC
-10,1,1,NULL
,0,0);
nw
=_createwin
(SR
+(NL
-3)/2,SC
+5,1,NC
-10);
_normal
(nw
);
_clrscr
(nw
);
_normal
(nw
);
_gotorc
(nw
,0,0);
switch(ent
->type
) {
case BOOLENTRY
: var
=ent
->x.
bool.
var; break;
case SUBMENUENTRY
: var
=NULL
; break;
case TRISTATEENTRY
: var
=ent
->x.
tristate.
var; break;
case CHOICEENTRY
: var
=ent
->x.
choice.
act->var
; break;
case CASEENTRY
: var
=NULL
; break;
case RANGEENTRY
: var
=ent
->x.
range.
var; break;
case SEPARATORENTRY
: var
=NULL
; break;
default: var
=NULL
;
}
if (var
==NULL
) goto END
;
fin
=fopen(helpfilename
,"rt");
if (fin
!=NULL
) {
if (varhelp
[findvarindex
(var
)]==0) goto END
;
fseek(fin
,varhelp
[findvarindex
(var
)],SEEK_SET
);
flag
=0;
while (fgets(buffer
,sizeof(buffer
),fin
)!=NULL
) {
if (*buffer
=='#') continue;
if (*buffer
=='@') {
if (flag
) break;
continue;
}
_gotorc
(nw
,flag
,0);
_printw
(nw
,"%s",buffer
);
flag
++;
}
fclose(fin
);
}
_clreol
(nw
);
_refresh
(nw
);
ch
=getch();
END
:
_deletewin
(nw
);
return ret
;
}
int showmenu
(WINDOW
*wnd
, struct menu
*menu
)
{
struct menuentry
*first
; /* first menuentry of the list */
struct menuentry
*cur
; /* selected menuentry */
struct menuentry
*fline
; /* menuentry to show on the first line */
int redo
;
int ch
;
int rcur
;
int ret
;
first
=fline
=cur
=NULL
;
rcur
=0;
redo
=1;
ret
=MUSTREDISPLAY
;
for (;;) {
if (redo
&MUSTREBUILD
) redo
|=MUSTREDISPLAY
;
ret
|=redo
;
if (redo
&MUSTREBUILD
) {
fline
=NULL
;
}
if (redo
&MUSTREDISPLAY
) {
nument
=0;
first
=expandmenu
(menu
->entries
);
if (fline
==NULL
) {
fline
=first
;
if (cur
==NULL
) {
cur
=fline
;
rcur
=0;
}
}
nmax
=NL
;
showtitle
(menu
->title
);
_normal
(wnd
);
_clrscr
(wnd
);
redo
=0;
}
showmenuentries
(wnd
,fline
,0,0,rcur
);
_refresh
(wnd
);
ch
=getch();
switch (ch
) {
case _KEY_OK
:
case _KEY_OK2
:
return ret
;
case _KEY_DOWN
:
if (cur
->n
==NULL
) break;
cur
=cur
->n
;
if (rcur
<NL
-1) {
rcur
++;
break;
}
fline
=fline
->n
;
break;
case _KEY_UP
:
if (cur
->p
==NULL
) break;
cur
=cur
->p
;
if (rcur
!=0) {
rcur
=rcur
--;
break;
}
fline
=fline
->p
;
break;
case _KEY_TOGGLE
:
redo
=enteron
(wnd
,cur
);
break;
case _KEY_HELP
:
redo
=showhelpwin
(wnd
,cur
);
break;
default:
/*
_normal(STDWIN);
_gotorc(STDWIN,0,0);
_printw(STDWIN,"%04x",ch);
_refresh(STDWIN);
*/
}
}
}
void showtitle
(char *s
)
{
_settitle
(STDWIN
,SR
-6,SC
-2,NL
+8,NC
+4,BR
,BC
,s
,1,0);
}
/*
*
*/
int show
(void)
{
WINDOW
*wnd
;
int i
;
_initscreen
();
_cursor_invisible
();
SC
=9;
SR
=9;
NL
=_rows
()-5-SR
-BR
*2;
NC
=_cols
()-2-SC
-BC
*2;
BR
=0;
BC
=4;
_defaultcolor
(STDWIN
);
_gotorc
(STDWIN
,0,0);
if (caption
!=NULL
) _printw
(STDWIN
," %s",caption
);
_gotorc
(STDWIN
,1,1);
for (i
=0;i
<_cols
()-2;i
++) _putch
(STDWIN
,_HH
);
_box
(STDWIN
,SR
-6,SC
-2,NL
+8,NC
+4,BR
,BC
,NULL
,1,0);
_box
(STDWIN
,SR
,SC
,NL
,NC
,BR
,BC
,NULL
,0,1);
wnd
=_createwin
(SR
,SC
,NL
,NC
);
showmenu
(wnd
,mainmenu
);
_cursor_visible
();
_refresh
(STDWIN
);
_endscreen
();
return 0;
}