summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhpa <hpa>2004-12-22 13:40:34 +0000
committerhpa <hpa>2004-12-22 13:40:34 +0000
commitea742162cc082fec3a3164d75fc5af67ceb7ef0a (patch)
tree019379d8710cd5abec780e0e539e00d051b15964
parent24afa3e22a17856083b738d8ed6e3a3c9076979d (diff)
downloadsyslinux-ea742162cc082fec3a3164d75fc5af67ceb7ef0a.tar.gz
Support cursor on/cursor off sequences, and use them in the menu system
-rw-r--r--com32/lib/sys/ansicon_write.c52
-rw-r--r--com32/modules/menu.c28
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