[prefix] Use garbage-collectable section names
[ipxe.git] / src / hci / mucurses / mucurses.c
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
153 int curs_set ( int visibility ) {
154 stdscr->scr->cursor ( stdscr->scr, visibility );
155 return OK;
156 }