From ad1aca0634cb3b00f0d6a83bba16a63d8bddf0f1 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Thu, 8 Jun 2006 17:23:37 +0000 Subject: [PATCH] - separated curses.c out into separate source files to optimise library use later on - some small mods to existing functions --- src/hci/mucurses/alert.c | 12 +++ src/hci/mucurses/clear.c | 51 ++++++++++ src/hci/mucurses/colour.c | 50 ++++++++++ src/hci/mucurses/core.c | 95 +++++++++++++++++++ src/hci/mucurses/core.h | 39 ++++++++ src/hci/mucurses/cursor.c | 25 +++++ src/hci/mucurses/cursor.h | 11 +++ src/hci/mucurses/edging.c | 105 +++++++++++++++++++++ src/hci/mucurses/print.c | 52 +++++++++++ src/hci/mucurses/slk.c | 179 ++++++++++++++++++++++++++++++++++++ src/hci/mucurses/winattrs.c | 115 +++++++++++++++++++++++ src/hci/mucurses/wininit.c | 20 ++++ 12 files changed, 754 insertions(+) create mode 100644 src/hci/mucurses/alert.c create mode 100644 src/hci/mucurses/clear.c create mode 100644 src/hci/mucurses/colour.c create mode 100644 src/hci/mucurses/core.c create mode 100644 src/hci/mucurses/core.h create mode 100644 src/hci/mucurses/cursor.c create mode 100644 src/hci/mucurses/cursor.h create mode 100644 src/hci/mucurses/edging.c create mode 100644 src/hci/mucurses/print.c create mode 100644 src/hci/mucurses/slk.c create mode 100644 src/hci/mucurses/winattrs.c create mode 100644 src/hci/mucurses/wininit.c diff --git a/src/hci/mucurses/alert.c b/src/hci/mucurses/alert.c new file mode 100644 index 00000000..dedc3ba5 --- /dev/null +++ b/src/hci/mucurses/alert.c @@ -0,0 +1,12 @@ +#include +#include + +/** + * Audible signal + * + * @ret rc return status code + */ +int beep ( void ) { + printf("\a"); + return OK; +} diff --git a/src/hci/mucurses/clear.c b/src/hci/mucurses/clear.c new file mode 100644 index 00000000..7e124c1d --- /dev/null +++ b/src/hci/mucurses/clear.c @@ -0,0 +1,51 @@ +#include +#include "core.h" +#include "cursor.h" + +/** + * Clear a window to the bottom from current cursor position + * + * @v *win subject window + * @ret rc return status code + */ +int wclrtobot ( WINDOW *win ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + do { + _wputch( win, (unsigned)' ', WRAP ); + } while ( win->curs_y + win->curs_x ); + _restore_curs_pos( win, &pos ); + + return OK; +} + +/** + * Clear a window to the end of the current line + * + * @v *win subject window + * @ret rc return status code + */ +int wclrtoeol ( WINDOW *win ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + while ( ( win->curs_y - pos.y ) == 0 ) { + _wputch( win, (unsigned)' ', WRAP ); + } + _restore_curs_pos( win, &pos ); + + return OK; +} + +/** + * Completely clear a window + * + * @v *win subject window + * @ret rc return status code + */ +int werase ( WINDOW *win ) { + wmove( win, 0, 0 ); + wclrtobot( win ); + return OK; +} diff --git a/src/hci/mucurses/colour.c b/src/hci/mucurses/colour.c new file mode 100644 index 00000000..dca255c7 --- /dev/null +++ b/src/hci/mucurses/colour.c @@ -0,0 +1,50 @@ +#include + +/** + * Indicates whether the underlying terminal device is capable of + * having colours redefined + * + * @ret bool returns boolean + */ +bool can_change_colour ( void ) { + return (bool)TRUE; +} + +/** + * Identify the RGB components of a given colour value + * + * @v colour colour value + * @v *red address to store red component + * @v *green address to store green component + * @v *blue address to store blue component + * @ret rc return status code + */ +int colour_content ( short colour, short *red, short *green, short *blue ) { + /* we do not have a particularly large range of colours (3 + primary, 3 secondary and black), so let's just put in a + basic switch... */ + switch(colour) { + case COLOUR_BLACK: + *red = 0; *green = 0; *blue = 0; + break; + case COLOUR_BLUE: + *red = 0; *green = 0; *blue = 1000; + break; + case COLOUR_GREEN: + *red = 0; *green = 1000; *blue = 0; + break; + case COLOUR_CYAN: + *red = 0; *green = 1000; *blue = 1000; + break; + case COLOUR_RED: + *red = 1000; *green = 0; *blue = 0; + break; + case COLOUR_MAGENTA: + *red = 1000; *green = 0; *blue = 1000; + break; + case COLOUR_YELLOW: + *red = 1000; *green = 1000; *blue = 0; + break; + } + return OK; +} diff --git a/src/hci/mucurses/core.c b/src/hci/mucurses/core.c new file mode 100644 index 00000000..a29f79fa --- /dev/null +++ b/src/hci/mucurses/core.c @@ -0,0 +1,95 @@ +#include +#include "core.h" + +WINDOW _stdscr = { + .attrs = A_DEFAULT, + .ori_y = 0, + .ori_x = 0, + .curs_y = 0, + .curs_x = 0, + .scr = curscr, +}; + +struct _softlabelkeys *slks; + +/* + * Primitives + */ + +/** + * Write a single character rendition to a window + * + * @v *win window in which to write + * @v ch character rendition to write + * @v wrap wrap "switch" + */ +void _wputch ( WINDOW *win, chtype ch, int wrap ) { + /* make sure we set the screen cursor to the right position + first! */ + win->scr->movetoyx( win->scr, win->ori_y + win->curs_y, + win->ori_x + win->curs_x ); + win->scr->putc(win->scr, ch); + if ( ++(win->curs_x) == win->width ) { + if ( wrap == WRAP ) { + win->curs_x = 0; + /* specification says we should really scroll, + but we have no buffer to scroll with, so we + can only overwrite back at the beginning of + the window */ + if ( ++(win->curs_y) == win->height ) + win->curs_y = 0; + } else { + (win->curs_x)--; + } + } +} + +/** + * Write a chtype string to a window + * + * @v *win window in which to write + * @v *chstr chtype string + * @v wrap wrap "switch" + * @v n write at most n chtypes + */ +void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) { + for ( ; *chstr && n-- ; chstr++ ) { + _wputch(win,*chstr,wrap); + } +} + +/** + * Write a standard c-style string to a window + * + * @v *win window in which to write + * @v *str string + * @v wrap wrap "switch" + * @v n write at most n chars from *str + */ +void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) { + for ( ; *str && n-- ; str++ ) { + _wputch( win, *str | win->attrs, wrap ); + } +} + +/** + * Move a window's cursor to the specified position + * + * @v *win window to be operated on + * @v y Y position + * @v x X position + * @ret rc return status code + */ +int wmove ( WINDOW *win, int y, int x ) { + /* chech for out-of-bounds errors */ + if ( ( ( (unsigned)x - win->ori_x ) > win->width ) || + ( ( (unsigned)y - win->ori_y ) > win->height ) ) { + return ERR; + } + + win->curs_y = y; + win->curs_x = x; + win->scr->movetoyx( win->scr, win->ori_y + win->curs_y, + win->ori_x + win->curs_x ); + return OK; +} diff --git a/src/hci/mucurses/core.h b/src/hci/mucurses/core.h new file mode 100644 index 00000000..37351dc3 --- /dev/null +++ b/src/hci/mucurses/core.h @@ -0,0 +1,39 @@ +#ifndef CORE_H +#define CORE_H + +#define WRAP 0 +#define NOWRAP 1 + +unsigned short _COLS; +unsigned short _LINES; +unsigned short _COLOURS; +unsigned int *_COLOUR_PAIRS; /* basically this is an array, but as its + length is determined only when initscr + is run, I can only think to make it a + pointer and malloc the array into being + ... */ + +struct _softlabel { + // label string + char *label; + /* Format of soft label + 0: left justify + 1: centre justify + 2: right justify + */ + unsigned short fmt; +}; + +struct _softlabelkeys { + struct _softlabel fkeys[12]; + attr_t attrs; + unsigned short fmt; + unsigned short maxlablen; +}; + +void _wputch ( WINDOW *win, chtype ch, int wrap ); +void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ); +void _wputstr ( WINDOW *win, const char *str, int wrap, int n ); +int wmove ( WINDOW *win, int y, int x ); + +#endif /* CURSES_H */ diff --git a/src/hci/mucurses/cursor.c b/src/hci/mucurses/cursor.c new file mode 100644 index 00000000..0d1a175a --- /dev/null +++ b/src/hci/mucurses/cursor.c @@ -0,0 +1,25 @@ +#include +#include "cursor.h" + +/** + * Restore cursor position from encoded backup variable + * + * @v *win window on which to operate + * @v *pos pointer to struct in which original cursor position is stored + */ +void _restore_curs_pos ( WINDOW *win, struct cursor_pos *pos ) { + win->curs_y = pos->y; + win->curs_x = pos->x; + win->scr->movetoyx ( win->scr, win->curs_y, win->curs_x ); +} + +/** + * Store cursor position for later restoration + * + * @v *win window on which to operate + * @v *pos pointer to struct in which to store cursor position + */ +void _store_curs_pos ( WINDOW *win, struct cursor_pos *pos ) { + pos->y = win->curs_y; + pos->x = win->curs_x; +} diff --git a/src/hci/mucurses/cursor.h b/src/hci/mucurses/cursor.h new file mode 100644 index 00000000..acc68ec5 --- /dev/null +++ b/src/hci/mucurses/cursor.h @@ -0,0 +1,11 @@ +#ifndef CURSOR_H +#define CURSOR_H + +struct cursor_pos { + unsigned int y, x; +}; + +void _restore_curs_pos ( WINDOW *win, struct cursor_pos *pos ); +void _store_curs_pos ( WINDOW *win, struct cursor_pos *pos ); + +#endif /* CURSOR_H */ diff --git a/src/hci/mucurses/edging.c b/src/hci/mucurses/edging.c new file mode 100644 index 00000000..5948232f --- /dev/null +++ b/src/hci/mucurses/edging.c @@ -0,0 +1,105 @@ +#include +#include "core.h" +#include "cursor.h" + +/** + * Draw borders from single-byte characters and renditions around a + * window + * + * @v *win window to be bordered + * @v verch vertical chtype + * @v horch horizontal chtype + * @ret rc return status code + */ +int box ( WINDOW *win, chtype verch, chtype horch ) { + chtype corner = '+' | win->attrs; /* default corner character */ + return wborder( win, verch, verch, horch, horch, + corner, corner, corner, corner ); +} + +/** + * Draw borders from single-byte characters and renditions around a + * window + * + * @v *win window to be bordered + * @v ls left side + * @v rs right side + * @v ts top + * @v bs bottom + * @v tl top left corner + * @v tr top right corner + * @v bl bottom left corner + * @v br bottom right corner + * @ret rc return status code + */ +int wborder ( WINDOW *win, chtype ls, chtype rs, + chtype ts, chtype bs, chtype tl, + chtype tr, chtype bl, chtype br ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + wmove(win,0,0); + + _wputch(win,tl,WRAP); + while ( ( win->width - 1 ) - win->curs_x ) { + _wputch(win,ts,WRAP); + } + _wputch(win,tr,WRAP); + + while ( ( win->height - 1 ) - win->curs_y ) { + _wputch(win,ls,WRAP); + wmove(win,win->curs_y,(win->width)-1); + _wputch(win,rs,WRAP); + } + + _wputch(win,bl,WRAP); + while ( ( win->width -1 ) - win->curs_x ) { + _wputch(win,bs,WRAP); + } + _wputch(win,br,NOWRAP); /* do not wrap last char to leave + cursor in last position */ + _restore_curs_pos( win, &pos ); + + return OK; +} + +/** + * Create a horizontal line in a window + * + * @v *win subject window + * @v ch rendition and character + * @v n max number of chars (wide) to render + * @ret rc return status code + */ +int whline ( WINDOW *win, chtype ch, int n ) { + struct cursor_pos pos; + + _store_curs_pos ( win, &pos ); + while ( ( win->curs_x - win->width ) && n-- ) { + _wputch ( win, ch, NOWRAP ); + } + _restore_curs_pos ( win, &pos ); + + return OK; +} + +/** + * Create a vertical line in a window + * + * @v *win subject window + * @v ch rendition and character + * @v n max number of lines to render + * @ret rc return status code + */ +int wvline ( WINDOW *win, chtype ch, int n ) { + struct cursor_pos pos; + + _store_curs_pos ( win, &pos ); + while ( ( win->curs_y - win->height ) && n-- ) { + _wputch ( win, ch, NOWRAP ); + wmove( win, ++(win->curs_y), pos.x); + } + _restore_curs_pos ( win, &pos ); + + return OK; +} diff --git a/src/hci/mucurses/print.c b/src/hci/mucurses/print.c new file mode 100644 index 00000000..c5b70282 --- /dev/null +++ b/src/hci/mucurses/print.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include "core.h" + +static printw_context { + struct printf_context ctx; + WINDOW *win; +}; + +static void _printw_handler ( struct printf_context *ctx, unsigned int c ) { + struct printw_context *wctx = + container_of ( ctx, struct printw_context, ctx ); + + _wputch( wctx->win, c | wctx->win->attrs, WRAP ); +} + +/** + * Print formatted output in a window + * + * @v *win subject window + * @v *fmt formatted string + * @v varglist argument list + * @ret rc return status code + */ +int vw_printw ( WINDOW *win, const char *fmt, va_list varglist ) { + struct printw_context wctx = { + .win = win, + .ctx = { .handler = _printw_handler, }, + }; + + vcprintf ( &(wctx.ctx), fmt, varglist ); + return OK; +} + +/** + * Print formatted output to a window + * + * @v *win subject window + * @v *fmt formatted string + * @v ... string arguments + * @ret rc return status code + */ +int wprintw ( WINDOW *win, const char *fmt, ... ) { + va_list args; + int i; + + va_start ( args, fmt ); + i = vw_printw ( win, fmt, args ); + va_end ( args ); + return i; +} diff --git a/src/hci/mucurses/slk.c b/src/hci/mucurses/slk.c new file mode 100644 index 00000000..6833eade --- /dev/null +++ b/src/hci/mucurses/slk.c @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include "core.h" + +extern struct _softlabelkeys *slks; + +/** + * Return the attribute used for the soft function keys + * + * @ret attrs the current attributes of the soft function keys + */ +attr_t slk_attr ( void ) { + return ( slks == NULL ? 0 : slks->attrs ); +} + +/** + * Turn off soft function key attributes + * + * @v attrs attribute bit mask + * @ret rc return status code + */ +int slk_attroff ( const chtype attrs ) { + if ( slks == NULL ) + return ERR; + slks->attrs &= ~( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Turn on soft function key attributes + * + * @v attrs attribute bit mask + * @ret rc return status code + */ +int slk_attron ( const chtype attrs ) { + if ( slks == NULL ) + return ERR; + slks->attrs |= ( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Set soft function key attributes + * + * @v attrs attribute bit mask + * @ret rc return status code + */ +int slk_attrset ( const chtype attrs ) { + if ( slks == NULL ) + return ERR; + slks->attrs = ( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Turn off soft function key attributes + * + * @v attrs attribute bit mask + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int slk_attr_off ( const attr_t attrs, void *opts __unused ) { + return slk_attroff( attrs ); +} + +/** + * Turn on soft function key attributes + * + * @v attrs attribute bit mask + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int slk_attr_on ( attr_t attrs, void *opts __unused ) { + return slk_attron( attrs ); +} + +/** + * Set soft function key attributes + * + * @v attrs attribute bit mask + * @v colour_pair_number colour pair integer + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int slk_attr_set ( const attr_t attrs, short colour_pair_number, + void *opts __unused ) { + if ( slks == NULL ) + return ERR; + + if ( ( unsigned short )colour_pair_number > COLORS ) + return ERR; + + slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) | + ( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Clear the soft function key labels from the screen + * + * @ret rc return status code + */ +int slk_clear ( void ) { + if ( slks == NULL ) + return ERR; + + wmove(stdscr,stdscr->height-1,0); + wclrtoeol(stdscr); + return 0; +} + +/** + * Initialise the soft function keys + * + * @v fmt format of keys + * @ret rc return status code + */ +int slk_init ( int fmt ) { + if ( (unsigned)fmt > 3 ) { + return ERR; + } + + slks = malloc(sizeof(struct _softlabelkeys)); + slks->attrs = A_DEFAULT; + slks->fmt = (unsigned short)fmt; + slks->maxlablen = 5; + return OK; +} + +/** + * Return the label for the specified soft key + * + * @v labnum soft key identifier + * @ret label return label + */ +char* slk_label ( int labnum ) { + if ( slks == NULL ) + return NULL; + + return slks->fkeys[labnum].label; +} + +/** + * Restore soft function key labels to the screen + * + * @ret rc return status code + */ +int slk_restore ( void ) { + if ( slks == NULL ) + return ERR; + + return OK; +} + +/** + * Configure specified soft key + * + * @v labnum soft label position to configure + * @v *label string to use as soft key label + * @v fmt justification format of label + * @ret rc return status code + */ +int slk_set ( int labnum, const char *label, int fmt ) { + if ( slks == NULL ) + return ERR; + if ( (unsigned short)labnum > 12 ) + return ERR; + if ( (unsigned short)fmt >= 3 ) + return ERR; + if ( strlen(label) > slks->maxlablen ) + return ERR; + + strcpy( slks->fkeys[labnum].label, label ); + slks->fkeys[labnum].fmt = fmt; + + return OK; +} diff --git a/src/hci/mucurses/winattrs.c b/src/hci/mucurses/winattrs.c new file mode 100644 index 00000000..f31fdac5 --- /dev/null +++ b/src/hci/mucurses/winattrs.c @@ -0,0 +1,115 @@ +#include + +/** + * Turn off attributes in a window + * + * @v win subject window + * @v attrs attributes to enable + * @ret rc return status code + */ +int wattroff ( WINDOW *win, int attrs ) { + win->attrs &= ~attrs; + return OK; +} + +/** + * Turn on attributes in a window + * + * @v win subject window + * @v attrs attributes to enable + * @ret rc return status code + */ +int wattron ( WINDOW *win, int attrs ) { + win->attrs |= attrs; + return OK; +} + +/** + * Set attributes in a window + * + * @v win subject window + * @v attrs attributes to enable + * @ret rc return status code + */ +int wattrset ( WINDOW *win, int attrs ) { + win->attrs = ( attrs | ( win->attrs & A_COLOR ) ); + return OK; +} + +/** + * Get attributes and colour pair information + * + * @v *win window to obtain information from + * @v *attrs address in which to store attributes + * @v *pair address in which to store colour pair + * @v *opts undefined (for future implementation) + * @ret rc return status cude + */ +int wattr_get ( WINDOW *win, attr_t *attrs, short *pair, + void *opts __unused ) { + *attrs = win->attrs & A_ATTRIBUTES; + *pair = (short)(( win->attrs & A_COLOR ) >> CPAIR_SHIFT); + return OK; +} + +/** + * Turn off attributes in a window + * + * @v *win subject window + * @v attrs attributes to toggle + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wattr_off ( WINDOW *win, attr_t attrs, + void *opts __unused ) { + wattroff( win, attrs ); + return OK; +} + +/** + * Turn on attributes in a window + * + * @v *win subject window + * @v attrs attributes to toggle + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wattr_on ( WINDOW *win, attr_t attrs, + void *opts __unused ) { + wattron( win, attrs ); + return OK; +} + +/** + * Set attributes and colour pair information in a window + * + * @v *win subject window + * @v attrs attributes to set + * @v cpair colour pair to set + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wattr_set ( WINDOW *win, attr_t attrs, short cpair, + void *opts __unused ) { + wattrset( win, attrs | ( ( (unsigned short)cpair ) << CPAIR_SHIFT ) ); + return OK; +} + +/** + * Set colour pair for a window + * + * @v *win subject window + * @v colour_pair_number colour pair integer + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wcolour_set ( WINDOW *win, short colour_pair_number, + void *opts __unused ) { + if ( ( unsigned short )colour_pair_number > COLORS ) + return ERR; + + win->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) | + ( win->attrs & A_ATTRIBUTES ); + return OK; +} + diff --git a/src/hci/mucurses/wininit.c b/src/hci/mucurses/wininit.c new file mode 100644 index 00000000..48f3b15a --- /dev/null +++ b/src/hci/mucurses/wininit.c @@ -0,0 +1,20 @@ +#include +#include +#include "core.h" + +extern struct _softlabelkeys *slks; + +/** + * Initialise console environment + * + * @ret *win return pointer to stdscr + */ +WINDOW *initscr ( void ) { + /* determine console size */ + /* initialise screen */ + stdscr->width = 80; + stdscr->height = ( slks == NULL ? 25 : 24 ); + /* set previously unknown window attributes */ + /* refresh screen */ + return stdscr; +}