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