iPXE
mucurses.c
Go to the documentation of this file.
00001 #include <curses.h>
00002 #include "mucurses.h"
00003 
00004 /** @file
00005  *
00006  * MuCurses core functions
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 static void _wupdcurs ( WINDOW *win ) __nonnull;
00013 void _wputch ( WINDOW *win, chtype ch, int wrap ) __nonnull;
00014 void _wputc ( WINDOW *win, char c, int wrap ) __nonnull;
00015 void _wcursback ( WINDOW *win ) __nonnull;
00016 void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) __nonnull;
00017 void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) __nonnull;
00018 int wmove ( WINDOW *win, int y, int x ) __nonnull;
00019 
00020 WINDOW _stdscr = {
00021         .attrs = A_DEFAULT,
00022         .ori_y = 0,
00023         .ori_x = 0,
00024         .curs_y = 0,
00025         .curs_x = 0,
00026         .scr = &_ansi_screen,
00027 };
00028 
00029 /*
00030  *  Primitives
00031  */
00032 
00033 /**
00034  * Update cursor position
00035  *
00036  * @v *win      window in which to update position
00037  */
00038 static void _wupdcurs ( WINDOW *win ) {
00039         win->scr->movetoyx ( win->scr, win->ori_y + win->curs_y,
00040                              win->ori_x + win->curs_x );
00041 }
00042 
00043 /**
00044  * Write a single character rendition to a window
00045  *
00046  * @v *win      window in which to write
00047  * @v ch        character rendition to write
00048  * @v wrap      wrap "switch"
00049  */
00050 void _wputch ( WINDOW *win, chtype ch, int wrap ) {
00051         /* make sure we set the screen cursor to the right position
00052            first! */
00053         _wupdcurs(win);
00054         win->scr->putc(win->scr, ch);
00055         if ( ++(win->curs_x) - win->width == 0 ) {
00056                 if ( wrap == WRAP ) {
00057                         win->curs_x = 0;
00058                         /* specification says we should really scroll,
00059                            but we have no buffer to scroll with, so we
00060                            can only overwrite back at the beginning of
00061                            the window */
00062                         if ( ++(win->curs_y) - win->height == 0 )
00063                                 win->curs_y = 0;
00064                 } else {
00065                         (win->curs_x)--;
00066                 }
00067         }
00068 }
00069 
00070 /**
00071  * Write a single character to a window
00072  *
00073  * @v *win      window in which to write
00074  * @v c         character rendition to write
00075  * @v wrap      wrap "switch"
00076  */
00077 void _wputc ( WINDOW *win, char c, int wrap ) {
00078         _wputch ( win, ( ( ( unsigned char ) c ) | win->attrs ), wrap );
00079 }
00080 
00081 /**
00082  * Retreat the cursor back one position (useful for a whole host of
00083  * ops)
00084  *
00085  * @v *win      window in which to retreat
00086  */
00087 void _wcursback ( WINDOW *win ) {
00088         if ( win->curs_x == 0 ) {
00089                 if ( win->curs_y == 0 )
00090                         win->curs_y = win->height - 1;
00091                 win->curs_x = win->width = 1;
00092         } else {
00093                 win->curs_x--;
00094         }
00095 
00096         _wupdcurs(win);
00097 }
00098 
00099 /**
00100  * Write a chtype string to a window
00101  *
00102  * @v *win      window in which to write
00103  * @v *chstr    chtype string
00104  * @v wrap      wrap "switch"
00105  * @v n         write at most n chtypes
00106  */
00107 void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) {
00108         for ( ; *chstr && n-- ; chstr++ ) {
00109                 _wputch(win,*chstr,wrap);
00110         }
00111 }
00112 
00113 /**
00114  * Write a standard c-style string to a window
00115  *
00116  * @v *win      window in which to write
00117  * @v *str      string
00118  * @v wrap      wrap "switch"
00119  * @v n         write at most n chars from *str
00120  */
00121 void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) {
00122         for ( ; *str && n-- ; str++ ) {
00123                 _wputc ( win, *str, wrap );
00124         }
00125 }
00126 
00127 /**
00128  * Move a window's cursor to the specified position
00129  *
00130  * @v *win      window to be operated on
00131  * @v y         Y position
00132  * @v x         X position
00133  * @ret rc      return status code
00134  */
00135 int wmove ( WINDOW *win, int y, int x ) {
00136         /* chech for out-of-bounds errors */
00137         if ( ( (unsigned)y >= win->height ) ||
00138              ( (unsigned)x >= win->width ) ) {
00139                 return ERR;
00140         }
00141 
00142         win->curs_y = y;
00143         win->curs_x = x;
00144         _wupdcurs(win);
00145         return OK;
00146 }
00147 
00148 /**
00149  * Set cursor visibility
00150  *
00151  * @v visibility cursor visibility
00152  */
00153 int curs_set ( int visibility ) {
00154         stdscr->scr->cursor ( stdscr->scr, visibility );
00155         return OK;
00156 }