summaryrefslogtreecommitdiffstats
path: root/src/hci/mucurses/windows.c
blob: 63d0af08c41389f882c7057745c4f7b67f6b2e08 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <curses.h>
#include <stddef.h>
#include <stdlib.h>
#include "mucurses.h"

/** @file
 *
 * MuCurses windows instance functions
 *
 */

/**
 * Delete a window
 *
 * @v *win	pointer to window being deleted
 * @ret rc	return status code
 */
int delwin ( WINDOW *win ) {
	if ( win == NULL )
		return ERR;

	/* I think we should blank the region covered by the window -
	   ncurses doesn't do this, but they have a buffer, so they
	   may just be deleting from an offscreen context whereas we
	   are guaranteed to be deleting something onscreen */
	wmove( win, 0, 0 );
	chtype killch = (chtype)' ';
	do {
		_wputch( win, killch, WRAP );
	} while ( win->curs_x + win->curs_y );

	free( win );

	wmove ( stdscr, 0, 0 );

	return OK;
}

/**
 * Create a new derived window
 *
 * @v parent	parent window
 * @v nlines	window height
 * @v ncols	window width
 * @v begin_y	window y origin (relative to parent)
 * @v begin_x	window x origin (relative to parent)
 * @ret ptr	return pointer to child window
 */
WINDOW *derwin ( WINDOW *parent, int nlines, int ncols,
	     		  	 int begin_y, int begin_x ) {
	WINDOW *child;
	if ( parent == NULL )
		return NULL;
	if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL )
		return NULL;
	if ( ( (unsigned)ncols > parent->width ) || 
	     ( (unsigned)nlines > parent->height ) )
		return NULL;
	child->ori_y = parent->ori_y + begin_y;
	child->ori_x = parent->ori_x + begin_x;
	child->height = nlines;
	child->width = ncols;
	child->parent = parent;
	child->scr = parent->scr;
	return child;
}

/**
 * Create a duplicate of the specified window
 *
 * @v orig	original window
 * @ret ptr	pointer to duplicate window
 */
WINDOW *dupwin ( WINDOW *orig ) {
	WINDOW *copy;
	if ( orig == NULL )
		return NULL;
	if ( ( copy = malloc( sizeof( WINDOW ) ) ) == NULL )
		return NULL;
	copy->scr = orig->scr;
	copy->attrs = orig->attrs;
	copy->ori_y = orig->ori_y;
	copy->ori_x = orig->ori_x;
	copy->curs_y = orig->curs_y;
	copy->curs_x = orig->curs_x;
	copy->height = orig->height;
	copy->width = orig->width;
	return copy;
}

/**
 * Move window origin to specified coordinates
 *
 * @v *win	window to move
 * @v y		Y position
 * @v x		X position
 * @ret rc	return status code
 */
int mvwin ( WINDOW *win, int y, int x ) {
	if ( win == NULL )
		return ERR;
	if ( ( ( (unsigned)y + win->height ) > LINES ) ||
	     ( ( (unsigned)x + win->width ) > COLS ) )
		return ERR;

	win->ori_y = y;
	win->ori_x = x;

	return OK;
}

/**
 * Create new WINDOW
 *
 * @v nlines	number of lines
 * @v ncols	number of columns
 * @v begin_y	column origin
 * @v begin_x	line origin
 * @ret *win	return pointer to new window
 */
WINDOW *newwin ( int nlines, int ncols, int begin_y, int begin_x ) {
	WINDOW *win;
	if ( ( win = malloc( sizeof(WINDOW) ) ) == NULL )
		return NULL;
	if ( ( (unsigned)( begin_y + nlines ) > stdscr->height ) &&
	     ( (unsigned)( begin_x + ncols ) > stdscr->width ) )
		return NULL;
	win->ori_y = begin_y;
	win->ori_x = begin_x;
	win->height = nlines;
	win->width = ncols;
	win->scr = stdscr->scr;
	win->parent = stdscr;
	return win;
}

/**
 * Create a new sub-window
 *
 * @v orig	parent window
 * @v nlines	window height
 * @v ncols	window width
 * @v begin_y	window y origin (absolute)
 * @v begin_x	window x origin (absolute)
 * @ret ptr	return pointer to child window
 */
WINDOW *subwin ( WINDOW *parent, int nlines, int ncols,
			         int begin_y, int begin_x ) {
	WINDOW *child;
	if ( parent == NULL )
		return NULL;
	if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL )
		return NULL;
	child = newwin( nlines, ncols, begin_y, begin_x );
	child->parent = parent;
	child->scr = parent->scr;
	return child;
}