1 #include <console.h>
2 #include <curses.h>
3 #include "mucurses.h"
4 
5 /** @file
6  *
7  * MuCurses core functions
8  *
9  */
10 
11 FILE_LICENCE ( GPL2_OR_LATER );
12 
13 static void _wupdcurs ( WINDOW *win ) __nonnull;
14 void _wputch ( WINDOW *win, chtype ch, int wrap ) __nonnull;
15 void _wputc ( WINDOW *win, char c, int wrap ) __nonnull;
16 void _wcursback ( WINDOW *win ) __nonnull;
17 void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) __nonnull;
18 void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) __nonnull;
19 int wmove ( WINDOW *win, int y, int x ) __nonnull;
20 
21 WINDOW _stdscr = {
22 	.attrs = A_DEFAULT,
23 	.ori_y = 0,
24 	.ori_x = 0,
25 	.curs_y = 0,
26 	.curs_x = 0,
27 	.scr = &_ansi_screen,
28 };
29 
30 /*
31  *  Primitives
32  */
33 
34 /**
35  * Update cursor position
36  *
37  * @v *win	window in which to update position
38  */
_wupdcurs(WINDOW * win)39 static void _wupdcurs ( WINDOW *win ) {
40 	win->scr->movetoyx ( win->scr, win->ori_y + win->curs_y,
41 			     win->ori_x + win->curs_x );
42 }
43 
44 /**
45  * Write a single character rendition to a window
46  *
47  * @v *win	window in which to write
48  * @v ch	character rendition to write
49  * @v wrap	wrap "switch"
50  */
_wputch(WINDOW * win,chtype ch,int wrap)51 void _wputch ( WINDOW *win, chtype ch, int wrap ) {
52 	/* make sure we set the screen cursor to the right position
53 	   first! */
54 	_wupdcurs(win);
55 	win->scr->putc(win->scr, ch);
56 	if ( ++(win->curs_x) - win->width == 0 ) {
57 		if ( wrap == WRAP ) {
58 			win->curs_x = 0;
59 			/* specification says we should really scroll,
60 			   but we have no buffer to scroll with, so we
61 			   can only overwrite back at the beginning of
62 			   the window */
63 			if ( ++(win->curs_y) - win->height == 0 )
64 				win->curs_y = 0;
65 		} else {
66 			(win->curs_x)--;
67 		}
68 	}
69 }
70 
71 /**
72  * Write a single character to a window
73  *
74  * @v *win	window in which to write
75  * @v c		character rendition to write
76  * @v wrap	wrap "switch"
77  */
_wputc(WINDOW * win,char c,int wrap)78 void _wputc ( WINDOW *win, char c, int wrap ) {
79 	_wputch ( win, ( c | win->attrs ), wrap );
80 }
81 
82 /**
83  * Retreat the cursor back one position (useful for a whole host of
84  * ops)
85  *
86  * @v *win	window in which to retreat
87  */
_wcursback(WINDOW * win)88 void _wcursback ( WINDOW *win ) {
89 	if ( win->curs_x == 0 ) {
90 		if ( win->curs_y == 0 )
91 			win->curs_y = win->height - 1;
92 		win->curs_x = win->width = 1;
93 	} else {
94 		win->curs_x--;
95 	}
96 
97 	_wupdcurs(win);
98 }
99 
100 /**
101  * Write a chtype string to a window
102  *
103  * @v *win	window in which to write
104  * @v *chstr	chtype string
105  * @v wrap	wrap "switch"
106  * @v n		write at most n chtypes
107  */
_wputchstr(WINDOW * win,const chtype * chstr,int wrap,int n)108 void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) {
109 	for ( ; *chstr && n-- ; chstr++ ) {
110 		_wputch(win,*chstr,wrap);
111 	}
112 }
113 
114 /**
115  * Write a standard c-style string to a window
116  *
117  * @v *win	window in which to write
118  * @v *str	string
119  * @v wrap	wrap "switch"
120  * @v n		write at most n chars from *str
121  */
_wputstr(WINDOW * win,const char * str,int wrap,int n)122 void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) {
123 	for ( ; *str && n-- ; str++ ) {
124 		_wputc ( win, *str, wrap );
125 	}
126 }
127 
128 /**
129  * Move a window's cursor to the specified position
130  *
131  * @v *win	window to be operated on
132  * @v y		Y position
133  * @v x		X position
134  * @ret rc	return status code
135  */
wmove(WINDOW * win,int y,int x)136 int wmove ( WINDOW *win, int y, int x ) {
137 	/* chech for out-of-bounds errors */
138 	if ( ( (unsigned)y >= win->height ) ||
139 	     ( (unsigned)x >= win->width ) ) {
140 		return ERR;
141 	}
142 
143 	win->curs_y = y;
144 	win->curs_x = x;
145 	_wupdcurs(win);
146 	return OK;
147 }
148