blob: 98a8a2c59011cd9bdfebf4f8b16b87c6efe8fa32 [file] [log] [blame]
#include <curses.h>
#include "mucurses.h"
/** @file
*
* MuCurses core functions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
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;
}