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