Blame |
Last modification |
View Log
| RSS feed
/*
*
*
*/
#include <stdio.h>
#include <stdlib.h>
/* per sleep() */
#include <unistd.h>
#if defined(USE_NCURSES)
#include <curses.h>
#elif defined(USE_CONIO)
#include <conio.o>
#else
#error USE_NCURSES or USE_CONIO must be defined
#endif
#include "hconf.h"
/*
*
* CONIO
*
*/
#ifdef USE_CONIO
#define DEFAULT_BG BLUE
#define NORMAL_FG WHITE
#define NORMAL_BG BLUE
#define INVERSE_FG BLACK
#define INVERSE_BG RED
/* -- */
struct text_info info
;
void _initscreen
(void)
{
textbackground
(DEFAULT_BG
);
clrscr
();
gettextinfo
(&info
);
}
void _endscreen
(void)
{
clrscr
();
}
static __inline__
int _cols
(void)
{
return info.
screenwidth;
}
static __inline__
int _rows
(void)
{
return info.
screenheight;
}
int _gotorc
(int r
, int c
)
{
/* zero based */
gotoxy
(c
,r
);
}
#define _printw(fmt,args...) cprintf(fmt,##args)
#define _refresh()
void _normal
(void)
{
textbackground
(NORMAL_BG
);
textcolor
(NORMAL_FG
);
}
#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_DOWN KEY_DOWN
#define _KEY_UP KEY_UP
#define _KEY_TOGGLE 0x0a
/* -- */
#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
));
}
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
);
refresh
();
}
void _endscreen
(void)
{
endwin
();
}
static __inline__
int _cols
(void)
{
return COLS
;
}
static __inline__
int _rows
(void)
{
return LINES
;
}
static __inline__
void _gotorc
(WINDOW
*w
,int r
, int c
)
{
/* zero based */
wmove
(w
,r
,c
);
}
#define _printw(w,fmt,args...) wprintw(w,fmt,##args)
void _refresh
(WINDOW
*w
)
{
wrefresh
(w
);
}
WINDOW
*_createwin
(int str
, int stc
, int lines
, int cols
)
{
WINDOW
*wnd
;
wnd
=newwin
(lines
,cols
,str
,stc
);
if (wnd
!=NULL
) {
//wbkgdset(wnd,COLOR_PAIR(_BACKGROUND));
//wclear(wnd);
//_normal(wnd);
}
return wnd
;
}
#define _deletewin(w) delwin(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');
#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 lines
, int cols
,
int bordy
, int bordx
,
char *title
,
int shad
, int inv
)
{
int x
;
sx
-=bordx
+1;
sy
-=bordy
+1;
cols
+=2*(bordx
+1);
lines
+=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 lines
, 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);
lines
+=2*(bordy
+1);
{
char blanks
[180];
memset(blanks
,' ',sizeof(blanks
));
blanks
[cols
]='\0';
_boxcolor
(wnd
);
for (y
=0;y
<lines
;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
<lines
-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
+lines
-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
+lines
,sx
+1);
for (x
=0;x
<cols
+1;x
++) _putch
(wnd
,' ');
}
sx
+=bordx
+1;
sy
+=bordy
+1;
cols
-=2*(bordx
+1);
lines
-=2*(bordy
+1);
_settitle
(wnd
,sy
,sx
,lines
,cols
,bordy
,bordx
,title
,shad
,inv
);
/* refresh made by _settitle() */
}
void showtitle
(char *s
);
/* -- */
void showbol
(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
)
{
_printw
(wnd
," %s (%s)",ptr
->x.
choice.
text,ptr
->x.
choice.
act->text
);
_normal
(wnd
);
_clreol
(wnd
);
}
void showsubmenu
(WINDOW
*wnd
, struct menuentry
*ptr
)
{
_printw
(wnd
," %s --->",ptr
->x.
submenu.
text);
_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 BOOLENTRY
:
showbol
(wnd
,ptr
);
break;
case TRISTATEENTRY
:
showtristate
(wnd
,ptr
);
break;
case CHOICEENTRY
:
showchoice
(wnd
,ptr
);
break;
case SUBMENUENTRY
:
showsubmenu
(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 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 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
*wnd
, struct menuentry
*ent
)
{
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
;
ret
=MUSTREDISPLAY
;
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
:
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 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
:
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;
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
();
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);
_printw
(STDWIN
," Hartik4 (Lego) version 4.0pre1 - Configuration");
_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);
_endscreen
();
return 0;
}