diff options
author | hpa <hpa> | 2004-12-22 13:40:34 +0000 |
---|---|---|
committer | hpa <hpa> | 2004-12-22 13:40:34 +0000 |
commit | ea742162cc082fec3a3164d75fc5af67ceb7ef0a (patch) | |
tree | 019379d8710cd5abec780e0e539e00d051b15964 | |
parent | 24afa3e22a17856083b738d8ed6e3a3c9076979d (diff) | |
download | syslinux-ea742162cc082fec3a3164d75fc5af67ceb7ef0a.tar.gz syslinux-ea742162cc082fec3a3164d75fc5af67ceb7ef0a.tar.xz syslinux-ea742162cc082fec3a3164d75fc5af67ceb7ef0a.zip |
Support cursor on/cursor off sequences, and use them in the menu system
-rw-r--r-- | com32/lib/sys/ansicon_write.c | 52 | ||||
-rw-r--r-- | com32/modules/menu.c | 28 |
2 files changed, 61 insertions, 19 deletions
diff --git a/com32/lib/sys/ansicon_write.c b/com32/lib/sys/ansicon_write.c index dbcf7412..2b7cff00 100644 --- a/com32/lib/sys/ansicon_write.c +++ b/com32/lib/sys/ansicon_write.c @@ -40,14 +40,6 @@ #include <klibc/compiler.h> #include "file.h" -static void __constructor ansicon_init(void) -{ - static com32sys_t ireg; /* Auto-initalized to all zero */ - - ireg.eax.w[0] = 0x0005; /* Force text mode */ - __intcall(0x22, &ireg, NULL); -} - struct curxy { uint8_t x, y; } __attribute__((packed)); @@ -74,7 +66,9 @@ static struct { int bg; int autocr; struct curxy saved_xy; + uint16_t cursor_type; enum ansi_state state; + int pvt; /* Private code? */ int nparms; /* Number of parameters seen */ int parms[MAX_PARMS]; } st = { @@ -87,10 +81,28 @@ static struct { .bg = 0, .autocr = 0, .saved_xy = { 0, 0 }, + .cursor_type = 0x0607, .state = st_init, + .pvt = 0, .nparms = 0, }; +/* Common setup */ +static void __constructor ansicon_init(void) +{ + static com32sys_t ireg; /* Auto-initalized to all zero */ + + /* Force text mode */ + ireg.eax.w[0] = 0x0005; + __intcall(0x22, &ireg, NULL); + + /* Get cursor shape */ + ireg.eax.b[1] = 0x03; + ireg.ebx.b[1] = BIOS_PAGE; + __intcall(0x10, &ireg, &ireg); + st.cursor_type = ireg.ecx.w[0]; +} + /* Erase a region of the screen */ static void ansicon_erase(int x0, int y0, int x1, int y1) { @@ -105,6 +117,16 @@ static void ansicon_erase(int x0, int y0, int x1, int y1) __intcall(0x10, &ireg, NULL); } +/* Show or hide the cursor */ +static void showcursor(int yes) +{ + static com32sys_t ireg; + + ireg.eax.b[1] = 0x01; + ireg.ecx.w[0] = yes ? st.cursor_type : 0x2020; + __intcall(0x10, &ireg, NULL); +} + static void ansicon_putchar(int ch) { static com32sys_t ireg; @@ -168,7 +190,7 @@ static void ansicon_putchar(int ch) break; case '[': st.state = st_csi; - st.nparms = 0; + st.nparms = st.pvt = 0; memset(st.parms, 0, sizeof st.parms); break; default: @@ -189,6 +211,8 @@ static void ansicon_putchar(int ch) if ( st.nparms >= MAX_PARMS ) st.nparms = MAX_PARMS-1; break; + } else if ( ch == '?' ) { + st.pvt = 1; } else { switch ( ch ) { case 'A': @@ -229,6 +253,13 @@ static void ansicon_putchar(int ch) xy.x = 0; } break; + case 'G': + case '\'': + { + int x = st.parms[0] - 1; + xy.x = (x >= cols) ? cols-1 : (x < 0) ? 0 : x; + } + break; case 'H': case 'f': { @@ -295,6 +326,9 @@ static void ansicon_putchar(int ch) case 20: st.autocr = set; break; + case 25: + showcursor(set); + break; default: /* Ignore */ break; diff --git a/com32/modules/menu.c b/com32/modules/menu.c index fe4d94a5..064afa59 100644 --- a/com32/modules/menu.c +++ b/com32/modules/menu.c @@ -142,7 +142,7 @@ void draw_menu(int sel, int top) printf("%s\033[%d;1H", menu_attrib->screen, END_ROW); } -char *edit_cmdline(char *input, int top) +const char *edit_cmdline(char *input, int top) { static char cmdline[MAX_CMDLINE_LEN]; int key, len; @@ -228,13 +228,15 @@ const char *run_menu(void) int entry = defentry; int top = 0; int clear = 1; - char *cmdline; + const char *cmdline = NULL; clock_t key_timeout; /* Convert timeout from deciseconds to clock ticks */ /* Note: for both key_timeout and timeout == 0 means no limit */ key_timeout = (clock_t)(CLK_TCK*timeout+9)/10; + printf("\033[?25l"); /* Hide cursor */ + while ( !done ) { if ( entry < 0 ) entry = 0; @@ -261,14 +263,17 @@ const char *run_menu(void) e.g. on serial ports. */ if ( entry != defentry ) entry = defentry; - else + else { + cmdline = menu_entries[defentry].label; done = 1; + } break; case KEY_CTRL('L'): clear = 1; break; case KEY_ENTER: case KEY_CTRL('J'): + cmdline = menu_entries[entry].label; done = 1; break; case 'P': @@ -302,24 +307,27 @@ const char *run_menu(void) break; case KEY_TAB: if ( allowedit ) { + printf("\033[?25h"); /* Show cursor */ cmdline = edit_cmdline(menu_entries[entry].cmdline, top); - if ( cmdline ) - return cmdline; - else - clear = 1; + printf("\033[?25l"); /* Hide cursor */ + done = !!cmdline; + clear = 1; /* In case we hit [Esc] and done is null */ } break; case KEY_CTRL('C'): /* Ctrl-C */ case KEY_ESC: /* Esc */ if ( allowedit ) - return NULL; + done = 1; + break; default: break; } } + printf("\033[?25h"); /* Show cursor */ + /* Return the label name so localboot and ipappend work */ - return menu_entries[entry].label; + return cmdline; } @@ -353,7 +361,7 @@ int main(int argc, char *argv[]) parse_config(argv[1]); cmdline = run_menu(); - printf("\033[%d;1H\033[0m", END_ROW); + printf("\033[?25h\033[%d;1H\033[0m", END_ROW); if ( cmdline ) execute(cmdline); else |