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