#include #include "mucurses.h" /** @file * * MuCurses core functions * */ FILE_LICENCE ( GPL2_OR_LATER ); static void _wupdcurs ( WINDOW *win ) __nonnull; void _wputch ( WINDOW *win, chtype ch, int wrap ) __nonnull; void _wputc ( WINDOW *win, char c, int wrap ) __nonnull; void _wcursback ( WINDOW *win ) __nonnull; void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) __nonnull; void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) __nonnull; int wmove ( WINDOW *win, int y, int x ) __nonnull; WINDOW _stdscr = { .attrs = A_DEFAULT, .ori_y = 0, .ori_x = 0, .curs_y = 0, .curs_x = 0, .scr = &_ansi_screen, }; /* * Primitives */ /** * Update cursor position * * @v *win window in which to update position */ static void _wupdcurs ( WINDOW *win ) { win->scr->movetoyx ( win->scr, win->ori_y + win->curs_y, win->ori_x + win->curs_x ); } /** * 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! */ _wupdcurs(win); win->scr->putc(win->scr, ch); if ( ++(win->curs_x) - win->width == 0 ) { 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 == 0 ) win->curs_y = 0; } else { (win->curs_x)--; } } } /** * Write a single character to a window * * @v *win window in which to write * @v c character rendition to write * @v wrap wrap "switch" */ void _wputc ( WINDOW *win, char c, int wrap ) { _wputch ( win, ( ( ( unsigned char ) c ) | win->attrs ), wrap ); } /** * Retreat the cursor back one position (useful for a whole host of * ops) * * @v *win window in which to retreat */ void _wcursback ( WINDOW *win ) { if ( win->curs_x == 0 ) { if ( win->curs_y == 0 ) win->curs_y = win->height - 1; win->curs_x = win->width = 1; } else { win->curs_x--; } _wupdcurs(win); } /** * 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++ ) { _wputc ( win, *str, 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)y >= win->height ) || ( (unsigned)x >= win->width ) ) { return ERR; } win->curs_y = y; win->curs_x = x; _wupdcurs(win); return OK; } /** * Set cursor visibility * * @v visibility cursor visibility */ int curs_set ( int visibility ) { stdscr->scr->cursor ( stdscr->scr, visibility ); return OK; }