176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <curses.h>
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stddef.h>
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h>
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "mucurses.h"
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** @file
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * MuCurses windows instance functions
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Delete a window
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v *win	pointer to window being deleted
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc	return status code
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint delwin ( WINDOW *win ) {
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( win == NULL )
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return ERR;
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* I think we should blank the region covered by the window -
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	   ncurses doesn't do this, but they have a buffer, so they
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	   may just be deleting from an offscreen context whereas we
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	   are guaranteed to be deleting something onscreen */
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	wmove( win, 0, 0 );
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	chtype killch = (chtype)' ';
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	do {
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		_wputch( win, killch, WRAP );
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} while ( win->curs_x + win->curs_y );
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	free( win );
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	wmove ( stdscr, 0, 0 );
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return OK;
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Create a new derived window
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v parent	parent window
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v nlines	window height
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v ncols	window width
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v begin_y	window y origin (relative to parent)
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v begin_x	window x origin (relative to parent)
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret ptr	return pointer to child window
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
4976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanWINDOW *derwin ( WINDOW *parent, int nlines, int ncols,
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     		  	 int begin_y, int begin_x ) {
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	WINDOW *child;
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( parent == NULL )
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL )
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( (unsigned)ncols > parent->width ) ||
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     ( (unsigned)nlines > parent->height ) )
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	child->ori_y = parent->ori_y + begin_y;
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	child->ori_x = parent->ori_x + begin_x;
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	child->height = nlines;
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	child->width = ncols;
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	child->parent = parent;
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	child->scr = parent->scr;
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return child;
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Create a duplicate of the specified window
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v orig	original window
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret ptr	pointer to duplicate window
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
7476d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanWINDOW *dupwin ( WINDOW *orig ) {
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	WINDOW *copy;
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( orig == NULL )
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( copy = malloc( sizeof( WINDOW ) ) ) == NULL )
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	copy->scr = orig->scr;
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	copy->attrs = orig->attrs;
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	copy->ori_y = orig->ori_y;
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	copy->ori_x = orig->ori_x;
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	copy->curs_y = orig->curs_y;
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	copy->curs_x = orig->curs_x;
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	copy->height = orig->height;
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	copy->width = orig->width;
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return copy;
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Move window origin to specified coordinates
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v *win	window to move
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v y		Y position
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v x		X position
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc	return status code
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint mvwin ( WINDOW *win, int y, int x ) {
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( win == NULL )
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return ERR;
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( ( (unsigned)y + win->height ) > LINES ) ||
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     ( ( (unsigned)x + win->width ) > COLS ) )
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return ERR;
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	win->ori_y = y;
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	win->ori_x = x;
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return OK;
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Create new WINDOW
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v nlines	number of lines
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v ncols	number of columns
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v begin_y	column origin
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v begin_x	line origin
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret *win	return pointer to new window
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
12176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanWINDOW *newwin ( int nlines, int ncols, int begin_y, int begin_x ) {
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	WINDOW *win;
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( win = malloc( sizeof(WINDOW) ) ) == NULL )
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( (unsigned)( begin_y + nlines ) > stdscr->height ) &&
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     ( (unsigned)( begin_x + ncols ) > stdscr->width ) )
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	win->ori_y = begin_y;
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	win->ori_x = begin_x;
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	win->height = nlines;
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	win->width = ncols;
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	win->scr = stdscr->scr;
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	win->parent = stdscr;
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return win;
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Create a new sub-window
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v orig	parent window
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v nlines	window height
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v ncols	window width
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v begin_y	window y origin (absolute)
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v begin_x	window x origin (absolute)
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret ptr	return pointer to child window
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
14776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanWINDOW *subwin ( WINDOW *parent, int nlines, int ncols,
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			         int begin_y, int begin_x ) {
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	WINDOW *child;
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( parent == NULL )
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL )
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	child = newwin( nlines, ncols, begin_y, begin_x );
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	child->parent = parent;
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	child->scr = parent->scr;
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return child;
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
159