2001-09-24 16:30:31 +00:00
/*
* ncurses driver
*
* Display LCD display at top left of terminal screen
* using ncurses.
*
*/
1999-12-16 09:20:22 +00:00
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
1999-12-09 23:15:14 +00:00
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
1999-12-16 09:20:22 +00:00
#ifdef HAVE_NCURSES_H
1999-12-09 23:15:14 +00:00
#include <ncurses.h>
#else
#include <curses.h>
#endif
2001-05-25 03:14:27 +00:00
#include "shared/str.h"
1999-12-09 23:15:14 +00:00
#include "lcd.h"
#include "curses_drv.h"
#include "drv_base.h"
lcd_logical_driver * curses_drv ;
2001-09-25 05:10:19 +00:00
// Character used for title bars...
#define PAD '#'
// #define PAD ACS_BLOCK
2000-03-30 20:20:41 +00:00
int ELLIPSIS = 7 ;
1999-12-09 23:15:14 +00:00
//////////////////////////////////////////////////////////////////////////
////////////////////// For Curses Terminal Output ////////////////////////
//////////////////////////////////////////////////////////////////////////
static char icon_char = '@' ;
2001-09-25 05:10:19 +00:00
static WINDOW * lcd_win ;
1999-12-09 23:15:14 +00:00
2001-09-25 22:10:30 +00:00
chtype get_color ( char * colorstr ) {
if ( strcasecmp ( colorstr , "red" ) == 0 )
return COLOR_RED ;
else if ( strcasecmp ( colorstr , "black" ) == 0 )
return COLOR_BLACK ;
else if ( strcasecmp ( colorstr , "green" ) == 0 )
return COLOR_GREEN ;
else if ( strcasecmp ( colorstr , "yellow" ) == 0 )
return COLOR_YELLOW ;
else if ( strcasecmp ( colorstr , "blue" ) == 0 )
return COLOR_BLUE ;
else if ( strcasecmp ( colorstr , "magenta" ) == 0 )
return COLOR_MAGENTA ;
else if ( strcasecmp ( colorstr , "cyan" ) == 0 )
return COLOR_CYAN ;
else if ( strcasecmp ( colorstr , "white" ) == 0 )
return COLOR_WHITE ;
else
return - 1 ;
}
/*
* A few different nice pairs of colors to use...
*
*/
#define DEFAULT_FOREGROUND_COLOR COLOR_CYAN
#define DEFAULT_BACKGROUND_COLOR COLOR_BLUE
// #define DEFAULT_FOREGROUND_COLOR COLOR_WHITE
// #define DEFAULT_BACKGROUND_COLOR COLOR_BLUE
// #define DEFAULT_FOREGROUND_COLOR COLOR_WHITE
// #define DEFAULT_BACKGROUND_COLOR COLOR_RED
2001-09-25 22:55:56 +00:00
chtype
2001-09-25 22:10:30 +00:00
set_foreground_color ( char * buf ) {
2001-09-25 22:55:56 +00:00
chtype color ;
if (( color = get_color ( buf )) < 0 )
color = DEFAULT_FOREGROUND_COLOR ;
return color ;
2001-09-25 22:10:30 +00:00
}
2001-09-25 22:55:56 +00:00
chtype
2001-09-25 22:10:30 +00:00
set_background_color ( char * buf ) {
2001-09-25 22:55:56 +00:00
chtype color ;
if (( color = get_color ( buf )) < 0 )
color = DEFAULT_BACKGROUND_COLOR ;
return color ;
2001-09-25 22:10:30 +00:00
}
/*
* What position (X,Y) to start the left top corner at...
*
*/
#define TOP_LEFT_X 7
#define TOP_LEFT_Y 7
2000-03-30 20:20:41 +00:00
int
curses_drv_init ( struct lcd_logical_driver * driver , char * args )
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
char * argv [ 64 ];
int argc ;
2001-05-15 01:55:59 +00:00
int i ;
2001-09-25 22:10:30 +00:00
char buf [ 64 ];
1999-12-09 23:15:14 +00:00
2001-09-25 05:10:19 +00:00
// Colors....
2001-09-25 22:10:30 +00:00
chtype back_color = DEFAULT_BACKGROUND_COLOR ,
fore_color = DEFAULT_FOREGROUND_COLOR ;
2001-09-25 05:10:19 +00:00
// Screen position (top left)
2001-09-25 22:10:30 +00:00
int screen_begx = TOP_LEFT_X ,
screen_begy = TOP_LEFT_Y ;
2001-09-25 05:10:19 +00:00
2001-09-25 22:10:30 +00:00
memset ( & argv , '\0' , sizeof ( argv ));
2000-04-03 22:13:57 +00:00
argc = get_args ( argv , args , 64 );
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
for ( i = 0 ; i < argc ; i ++ ) {
if ( 0 == strcmp ( argv [ i ], "-f" ) || 0 == strcmp ( argv [ i ], "--forecolor" )) {
2001-09-25 22:10:30 +00:00
if ( i + 1 >= argc ) {
2000-04-03 22:13:57 +00:00
fprintf ( stderr , "curses_init: %s requires an argument \n " , argv [ i ]);
return - 1 ;
}
2001-09-25 22:10:30 +00:00
strncpy ( buf , argv [ ++ i ], sizeof ( buf ));
2001-09-25 22:59:52 +00:00
fore_color = set_foreground_color ( buf );
2000-04-03 22:13:57 +00:00
} else if ( 0 == strcmp ( argv [ i ], "-b" ) || 0 == strcmp ( argv [ i ], "--backcolor" )) {
2001-09-25 22:10:30 +00:00
if ( i + 1 >= argc ) {
2000-04-03 22:13:57 +00:00
fprintf ( stderr , "curses_init: %s requires an argument \n " , argv [ i ]);
return - 1 ;
}
2001-09-25 22:10:30 +00:00
strncpy ( buf , argv [ ++ i ], sizeof ( buf ));
2001-09-25 22:59:52 +00:00
back_color = set_background_color ( buf );
2000-04-03 22:13:57 +00:00
} else if ( 0 == strcmp ( argv [ i ], "-B" ) || 0 == strcmp ( argv [ i ], "--backlight" )) {
2001-09-25 22:10:30 +00:00
if ( i + 1 >= argc ) {
2000-04-03 22:13:57 +00:00
fprintf ( stderr , "curses_init: %s requires an argument \n " , argv [ i ]);
return - 1 ;
}
2001-09-25 22:10:30 +00:00
// TODO: Backlight... backlight? where?
printf ( "Sorry, backlight not yet implemented... \n " );
2000-04-03 22:13:57 +00:00
} else if ( 0 == strcmp ( argv [ i ], "-h" ) || 0 == strcmp ( argv [ i ], "--help" )) {
printf ( "LCDproc [n]curses driver \n " " \t -f \t --forecolor \t Change the foreground color \n " " \t -b \t --backcolor \t Change the backlight's \" off \" color \n " " \t -B \t --backlight \t Change the backlight's \" on \" color \n " " \t -h \t --help \t\t Show this help information \n " );
return - 1 ;
} else {
printf ( "Invalid parameter: %s \n " , argv [ i ]);
}
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
}
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
curses_drv = driver ;
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
// Init curses...
initscr ();
cbreak ();
noecho ();
nodelay ( stdscr , TRUE );
nonl ();
intrflush ( stdscr , FALSE );
keypad ( stdscr , TRUE );
2001-09-25 22:10:30 +00:00
lcd_win = newwin ( curses_drv -> hgt + 2 ,
curses_drv -> wid + 2 ,
screen_begy ,
screen_begx );
2001-09-25 05:10:19 +00:00
curs_set ( 0 );
if ( has_colors ()) {
start_color ();
init_pair ( 1 , fore_color , back_color );
init_pair ( 2 , back_color , fore_color );
init_pair ( 3 , COLOR_WHITE , back_color );
}
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
curses_drv_clear ();
1999-12-09 23:15:14 +00:00
2001-09-26 20:06:42 +00:00
driver -> daemonize = 0 ; // don't daemonize...
2000-04-03 22:13:57 +00:00
// Override output functions...
driver -> clear = curses_drv_clear ;
driver -> string = curses_drv_string ;
driver -> chr = curses_drv_chr ;
driver -> vbar = curses_drv_vbar ;
2001-09-24 23:28:05 +00:00
//driver->init_vbar = NULL;
2000-04-03 22:13:57 +00:00
driver -> hbar = curses_drv_hbar ;
2001-09-24 23:28:05 +00:00
//driver->init_hbar = NULL;
2000-04-03 22:13:57 +00:00
driver -> num = curses_drv_num ;
driver -> init_num = curses_drv_init_num ;
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
driver -> init = curses_drv_init ;
driver -> close = curses_drv_close ;
driver -> flush = curses_drv_flush ;
driver -> flush_box = curses_drv_flush_box ;
2001-09-24 23:28:05 +00:00
//driver->contrast = NULL;
//driver->backlight = NULL;
//driver->set_char = NULL;
2000-04-03 22:13:57 +00:00
driver -> icon = curses_drv_icon ;
driver -> draw_frame = curses_drv_draw_frame ;
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
driver -> getkey = curses_drv_getkey ;
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
// Change the character used for "..."
ELLIPSIS = '~' ;
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
return 200 ; // 200 is arbitrary. (must be 1 or more)
1999-12-09 23:15:14 +00:00
}
2001-09-25 05:10:19 +00:00
static void
curses_drv_wborder ( WINDOW * win ) {
int x , y ;
char buf [ 128 ];
if ( has_colors ()) {
wcolor_set ( win , 3 , NULL );
wattron ( win , COLOR_PAIR ( 3 ) | A_BOLD );
}
box ( win , 0 , 0 );
if ( has_colors ()) {
wcolor_set ( win , 1 , NULL );
wattron ( win , COLOR_PAIR ( 1 ));
wattroff ( win , A_BOLD );
}
}
2000-03-30 20:20:41 +00:00
void
curses_drv_close ()
1999-12-09 23:15:14 +00:00
{
2001-09-25 05:24:00 +00:00
// Note that the program leaves a screen on
// the display to be left behind after closing;
// so don't clear...
//
2000-04-03 22:13:57 +00:00
// Close curses
2001-09-25 05:10:19 +00:00
wrefresh ( lcd_win );
delwin ( lcd_win );
2000-04-03 22:13:57 +00:00
move ( 0 , 0 );
endwin ();
2000-03-30 20:20:41 +00:00
2001-09-25 01:01:55 +00:00
if ( curses_drv -> framebuf != NULL )
free ( curses_drv -> framebuf );
curses_drv -> framebuf = NULL ;
1999-12-09 23:15:14 +00:00
}
/////////////////////////////////////////////////////////////////
// Clears the LCD screen
//
2000-03-30 20:20:41 +00:00
void
curses_drv_clear ()
1999-12-09 23:15:14 +00:00
{
2001-09-25 05:24:00 +00:00
wbkgdset ( lcd_win , COLOR_PAIR ( 1 ) | ' ' );
2001-09-25 05:10:19 +00:00
curses_drv_wborder ( lcd_win );
werase ( lcd_win );
1999-12-09 23:15:14 +00:00
}
2001-09-25 05:10:19 +00:00
#define ValidX(a) { if (x > curses_drv->wid) { x = curses_drv->wid; } else x < 1 ? 1 : x; }
#define ValidY(a) { if (y > curses_drv->hgt) { y = curses_drv->hgt; } else y < 1 ? 1 : y; }
1999-12-09 23:15:14 +00:00
/////////////////////////////////////////////////////////////////
// Prints a string on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
2000-03-30 20:20:41 +00:00
void
2001-09-25 05:10:19 +00:00
curses_drv_string ( int x , int y , char * string )
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
int i ;
2001-09-25 05:10:19 +00:00
unsigned char * p ;
1999-12-09 23:15:14 +00:00
2001-09-25 05:10:19 +00:00
ValidX ( x );
ValidY ( y );
p = string ;
// Convert NULLs and 0xFF in string to
// valid printables...
while ( * p ) {
switch ( * p ) {
//case 0: -- can never happen?
// *p = icon_char;
// break;
case 255 :
* p = PAD ;
break ;
2000-04-03 22:13:57 +00:00
}
2001-09-25 05:10:19 +00:00
p ++ ;
2000-04-03 22:13:57 +00:00
}
2001-09-25 05:10:19 +00:00
mvwaddstr ( lcd_win , y , x , string );
1999-12-09 23:15:14 +00:00
}
/////////////////////////////////////////////////////////////////
// Prints a character on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
2000-03-30 20:20:41 +00:00
void
curses_drv_chr ( int x , int y , char c )
1999-12-09 23:15:14 +00:00
{
2001-09-25 05:10:19 +00:00
ValidX ( x );
ValidY ( y );
2000-04-03 22:13:57 +00:00
switch ( c ) {
2001-09-25 05:10:19 +00:00
case 0 :
c = icon_char ;
break ;
case - 1 : // translates to 255 (ouch!)
c = PAD ;
break ;
//default:
// normal character...
2000-04-03 22:13:57 +00:00
}
1999-12-09 23:15:14 +00:00
2001-09-25 05:10:19 +00:00
mvwaddch ( lcd_win , y , x , c );
1999-12-09 23:15:14 +00:00
}
/////////////////////////////////////////////////////////////////
// Sets up for big numbers.
//
2000-03-30 20:20:41 +00:00
void
curses_drv_init_num ()
1999-12-09 23:15:14 +00:00
{
2001-09-25 05:10:19 +00:00
;
1999-12-09 23:15:14 +00:00
}
/////////////////////////////////////////////////////////////////
// Writes a big number.
//
2000-03-30 20:20:41 +00:00
void
curses_drv_num ( int x , int num )
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
char c ;
int y , dx ;
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
c = '0' + num ;
1999-12-09 23:15:14 +00:00
// printf(&c,"%1d",num);
2000-04-03 22:13:57 +00:00
for ( y = 1 ; y < 5 ; y ++ )
for ( dx = 0 ; dx < 3 ; dx ++ )
curses_drv_chr ( x + dx , y , c );
1999-12-09 23:15:14 +00:00
}
/////////////////////////////////////////////////////////////////
// Draws a vertical bar; erases entire column onscreen.
//
2000-03-30 20:20:41 +00:00
void
curses_drv_vbar ( int x , int len )
1999-12-09 23:15:14 +00:00
{
2001-09-25 05:10:19 +00:00
//char map[] = "_.,,ooO8";
char map [] = { ACS_S9 , ACS_S9 , ACS_S7 , ACS_S7 , ACS_S3 , ACS_S3 , ACS_S1 , ACS_S1 };
2000-04-03 22:13:57 +00:00
int y ;
2000-03-30 20:20:41 +00:00
2001-09-25 05:10:19 +00:00
ValidX ( x );
#define MAX_LINES (curses_drv->cellhgt * curses_drv->hgt)
len = len > ( MAX_LINES - 1 ) ? ( MAX_LINES - 1 ) : len ;
len = len < 0 ? 0 : len ;
// len is the length of the bar (in pixels/scanlines)
// y is one character line (cellhgt pixels/scanlines)
for ( y = curses_drv -> hgt ; y > 0 && len > 0 ; y -- ) {
if ( len >= curses_drv -> cellhgt ) {
// write a "full" block to the screen...
//curses_drv_chr (x, y, '8');
curses_drv_chr ( x , y , ACS_BLOCK );
len -= curses_drv -> cellhgt ;
}
else {
// write a partial block...
curses_drv_chr ( x , y , map [ len - 1 ]);
break ;
}
2000-04-03 22:13:57 +00:00
}
1999-12-09 23:15:14 +00:00
// move(4-len/lcd.cellhgt, x-1);
// vline(0, len/lcd.cellhgt);
2000-03-30 20:20:41 +00:00
1999-12-09 23:15:14 +00:00
}
/////////////////////////////////////////////////////////////////
// Draws a horizontal bar to the right.
//
2000-03-30 20:20:41 +00:00
void
curses_drv_hbar ( int x , int y , int len )
1999-12-09 23:15:14 +00:00
{
2001-09-25 01:01:55 +00:00
for (; x <= curses_drv -> wid && len > 0 ; x ++ ) {
if ( len >= curses_drv -> cellwid )
2000-04-03 22:13:57 +00:00
curses_drv_chr ( x , y , '=' );
else
curses_drv_chr ( x , y , '-' );
2000-03-30 20:20:41 +00:00
2001-09-25 01:01:55 +00:00
len -= curses_drv -> cellwid ;
2000-04-03 22:13:57 +00:00
}
1999-12-09 23:15:14 +00:00
// move(y-1, x-1);
// hline(0, len/lcd.cellwid);
}
/////////////////////////////////////////////////////////////////
// Sets character 0 to an icon...
//
2000-03-30 20:20:41 +00:00
void
curses_drv_icon ( int which , char dest )
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
if ( dest == 0 )
switch ( which ) {
2001-09-25 05:10:19 +00:00
case 0 :
icon_char = '+' ;
break ;
case 1 :
icon_char = '*' ;
break ;
default :
icon_char = PAD ;
break ;
2000-04-03 22:13:57 +00:00
}
2000-03-30 20:20:41 +00:00
1999-12-09 23:15:14 +00:00
}
//////////////////////////////////////////////////////////////////
// Flushes all output to the lcd...
//
2000-03-30 20:20:41 +00:00
void
curses_drv_flush ()
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
curses_drv_draw_frame ( curses_drv -> framebuf );
1999-12-09 23:15:14 +00:00
}
2000-03-30 20:20:41 +00:00
void
curses_drv_flush_box ( int lft , int top , int rgt , int bot )
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
curses_drv_flush ();
1999-12-09 23:15:14 +00:00
}
2000-03-30 20:20:41 +00:00
void
curses_drv_draw_frame ( char * dat )
1999-12-09 23:15:14 +00:00
{
2001-09-25 05:10:19 +00:00
curses_drv_wborder ( lcd_win );
wrefresh ( lcd_win );
1999-12-09 23:15:14 +00:00
}
2000-03-30 20:20:41 +00:00
char
curses_drv_getkey ()
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
int i ;
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
i = getch ();
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
if ( i == KEY_LEFT )
return 'D' ;
if ( i == KEY_UP )
return 'B' ;
if ( i == KEY_DOWN )
return 'C' ;
if ( i == KEY_RIGHT )
return 'A' ;
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
if ( i != ERR )
return i ;
else
return 0 ;
2000-03-30 20:20:41 +00:00
1999-12-09 23:15:14 +00:00
}