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