Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / 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 );
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 }