readline: Initial implementation
This commit is contained in:
parent
b8b7a798d4
commit
530b4a8f3b
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
@ -206,71 +206,3 @@ int getchar(void) {
|
||||
rm_int(0x16, &r, &r);
|
||||
return getchar_internal(r.eax);
|
||||
}
|
||||
|
||||
static void gets_reprint_string(int x, int y, const char *s, size_t limit) {
|
||||
int last_x, last_y;
|
||||
get_cursor_pos(&last_x, &last_y);
|
||||
set_cursor_pos(x, y);
|
||||
for (size_t i = 0; i < limit; i++) {
|
||||
term_write(" ", 1);
|
||||
}
|
||||
set_cursor_pos(x, y);
|
||||
term_write(s, strlen(s));
|
||||
set_cursor_pos(last_x, last_y);
|
||||
}
|
||||
|
||||
void gets(const char *orig_str, char *buf, size_t limit) {
|
||||
size_t orig_str_len = strlen(orig_str);
|
||||
memmove(buf, orig_str, orig_str_len);
|
||||
buf[orig_str_len] = 0;
|
||||
|
||||
int orig_x, orig_y;
|
||||
get_cursor_pos(&orig_x, &orig_y);
|
||||
|
||||
print("%s", buf);
|
||||
|
||||
for (size_t i = orig_str_len; ; ) {
|
||||
int c = getchar();
|
||||
switch (c) {
|
||||
case GETCHAR_CURSOR_LEFT:
|
||||
if (i) {
|
||||
i--;
|
||||
term_write("\b", 1);
|
||||
}
|
||||
continue;
|
||||
case GETCHAR_CURSOR_RIGHT:
|
||||
if (i < strlen(buf)) {
|
||||
i++;
|
||||
term_write(" ", 1);
|
||||
gets_reprint_string(orig_x, orig_y, buf, limit);
|
||||
}
|
||||
continue;
|
||||
case '\b':
|
||||
if (i) {
|
||||
i--;
|
||||
for (size_t j = i; ; j++) {
|
||||
buf[j] = buf[j+1];
|
||||
if (!buf[j])
|
||||
break;
|
||||
}
|
||||
term_write("\b", 1);
|
||||
gets_reprint_string(orig_x, orig_y, buf, limit);
|
||||
}
|
||||
continue;
|
||||
case '\r':
|
||||
term_write("\n", 1);
|
||||
return;
|
||||
default:
|
||||
if (strlen(buf) < limit-1) {
|
||||
for (size_t j = strlen(buf); ; j--) {
|
||||
buf[j+1] = buf[j];
|
||||
if (j == i)
|
||||
break;
|
||||
}
|
||||
buf[i++] = c;
|
||||
term_write(" ", 1);
|
||||
gets_reprint_string(orig_x, orig_y, buf, limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ int pit_sleep_and_quit_on_keypress(uint32_t pit_ticks);
|
||||
#define GETCHAR_CURSOR_DOWN (-13)
|
||||
|
||||
int getchar(void);
|
||||
void gets(const char *orig_str, char *buf, size_t limit);
|
||||
uint64_t strtoui(const char *s);
|
||||
uint64_t strtoui16(const char *s);
|
||||
|
||||
|
100
stage2/lib/readline.c
Normal file
100
stage2/lib/readline.c
Normal file
@ -0,0 +1,100 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <lib/readline.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/term.h>
|
||||
|
||||
static void reprint_string(int x, int y, const char *s) {
|
||||
int orig_x, orig_y;
|
||||
disable_cursor();
|
||||
get_cursor_pos(&orig_x, &orig_y);
|
||||
set_cursor_pos(x, y);
|
||||
term_write(s, strlen(s));
|
||||
set_cursor_pos(orig_x, orig_y);
|
||||
enable_cursor();
|
||||
}
|
||||
|
||||
static void cursor_back(void) {
|
||||
int x, y;
|
||||
get_cursor_pos(&x, &y);
|
||||
if (x) {
|
||||
x--;
|
||||
} else if (y) {
|
||||
y--;
|
||||
x = term_cols - 1;
|
||||
}
|
||||
set_cursor_pos(x, y);
|
||||
}
|
||||
|
||||
static void cursor_fwd(void) {
|
||||
int x, y;
|
||||
get_cursor_pos(&x, &y);
|
||||
if (x < term_cols - 1) {
|
||||
x++;
|
||||
} else if (y < term_rows - 1) {
|
||||
y++;
|
||||
x = 0;
|
||||
}
|
||||
set_cursor_pos(x, y);
|
||||
}
|
||||
|
||||
void readline(const char *orig_str, char *buf, size_t limit) {
|
||||
size_t orig_str_len = strlen(orig_str);
|
||||
memmove(buf, orig_str, orig_str_len);
|
||||
buf[orig_str_len] = 0;
|
||||
|
||||
int orig_x, orig_y;
|
||||
get_cursor_pos(&orig_x, &orig_y);
|
||||
|
||||
term_write(orig_str, orig_str_len);
|
||||
|
||||
for (size_t i = orig_str_len; ; ) {
|
||||
int c = getchar();
|
||||
switch (c) {
|
||||
case GETCHAR_CURSOR_LEFT:
|
||||
if (i) {
|
||||
i--;
|
||||
cursor_back();
|
||||
}
|
||||
continue;
|
||||
case GETCHAR_CURSOR_RIGHT:
|
||||
if (i < strlen(buf)) {
|
||||
i++;
|
||||
cursor_fwd();
|
||||
}
|
||||
continue;
|
||||
case '\b':
|
||||
if (i) {
|
||||
i--;
|
||||
cursor_back();
|
||||
size_t j;
|
||||
for (j = i; ; j++) {
|
||||
buf[j] = buf[j+1];
|
||||
if (!buf[j]) {
|
||||
buf[j] = ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
reprint_string(orig_x, orig_y, buf);
|
||||
buf[j] = 0;
|
||||
}
|
||||
continue;
|
||||
case '\r':
|
||||
term_write("\n", 1);
|
||||
return;
|
||||
default:
|
||||
if (strlen(buf) < limit - 1) {
|
||||
for (size_t j = strlen(buf); ; j--) {
|
||||
buf[j+1] = buf[j];
|
||||
if (j == i)
|
||||
break;
|
||||
}
|
||||
buf[i] = c;
|
||||
i++;
|
||||
cursor_fwd();
|
||||
reprint_string(orig_x, orig_y, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
stage2/lib/readline.h
Normal file
8
stage2/lib/readline.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __LIB__READLINE_H__
|
||||
#define __LIB__READLINE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void readline(const char *orig_str, char *buf, size_t limit);
|
||||
|
||||
#endif
|
@ -22,11 +22,11 @@ void (*get_cursor_pos)(int *x, int *y);
|
||||
void (*set_text_fg)(int fg);
|
||||
void (*set_text_bg)(int bg);
|
||||
|
||||
static int rows, cols;
|
||||
int term_rows, term_cols;
|
||||
|
||||
void term_vbe(uint32_t *colours, int margin, int margin_gradient, struct image *background) {
|
||||
term_deinit();
|
||||
vbe_tty_init(&rows, &cols, colours, margin, margin_gradient, background);
|
||||
vbe_tty_init(&term_rows, &term_cols, colours, margin, margin_gradient, background);
|
||||
|
||||
raw_putchar = vbe_putchar;
|
||||
clear = vbe_clear;
|
||||
@ -42,7 +42,7 @@ void term_vbe(uint32_t *colours, int margin, int margin_gradient, struct image *
|
||||
|
||||
void term_textmode(void) {
|
||||
term_deinit();
|
||||
init_vga_textmode(&rows, &cols);
|
||||
init_vga_textmode(&term_rows, &term_cols);
|
||||
|
||||
raw_putchar = text_putchar;
|
||||
clear = text_clear;
|
||||
@ -156,16 +156,16 @@ static void escape_parse(char c) {
|
||||
case 'B':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if ((get_cursor_pos_y() + esc_value0) > (rows - 1))
|
||||
esc_value0 = (rows - 1) - get_cursor_pos_y();
|
||||
if ((get_cursor_pos_y() + esc_value0) > (term_rows - 1))
|
||||
esc_value0 = (term_rows - 1) - get_cursor_pos_y();
|
||||
set_cursor_pos(get_cursor_pos_x(),
|
||||
get_cursor_pos_y() + esc_value0);
|
||||
break;
|
||||
case 'C':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if ((get_cursor_pos_x() + esc_value0) > (cols - 1))
|
||||
esc_value0 = (cols - 1) - get_cursor_pos_x();
|
||||
if ((get_cursor_pos_x() + esc_value0) > (term_cols - 1))
|
||||
esc_value0 = (term_cols - 1) - get_cursor_pos_x();
|
||||
set_cursor_pos(get_cursor_pos_x() + esc_value0,
|
||||
get_cursor_pos_y());
|
||||
break;
|
||||
@ -184,10 +184,10 @@ static void escape_parse(char c) {
|
||||
esc_value0 = 0;
|
||||
if (esc_default1)
|
||||
esc_value1 = 0;
|
||||
if (esc_value1 >= cols)
|
||||
esc_value1 = cols - 1;
|
||||
if (esc_value0 >= rows)
|
||||
esc_value0 = rows - 1;
|
||||
if (esc_value1 >= term_cols)
|
||||
esc_value1 = term_cols - 1;
|
||||
if (esc_value0 >= term_rows)
|
||||
esc_value0 = term_rows - 1;
|
||||
set_cursor_pos(esc_value1, esc_value0);
|
||||
break;
|
||||
case 'm':
|
||||
@ -208,7 +208,7 @@ static void escape_parse(char c) {
|
||||
int x = get_cursor_pos_x();
|
||||
int y = get_cursor_pos_y();
|
||||
set_cursor_pos(0, y);
|
||||
for (int i = 0; i < cols; i++)
|
||||
for (int i = 0; i < term_cols; i++)
|
||||
raw_putchar(' ');
|
||||
set_cursor_pos(x, y);
|
||||
break;
|
||||
|
@ -19,4 +19,6 @@ void term_textmode(void);
|
||||
void term_deinit(void);
|
||||
void term_write(const char *buf, size_t count);
|
||||
|
||||
extern int term_rows, term_cols;
|
||||
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <lib/libc.h>
|
||||
#include <lib/config.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/readline.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <drivers/vbe.h>
|
||||
|
||||
@ -193,7 +194,7 @@ timeout_aborted:
|
||||
}
|
||||
}
|
||||
print("\n\n> ");
|
||||
gets(cmdline, cmdline, CMDLINE_MAX);
|
||||
readline(cmdline, cmdline, CMDLINE_MAX);
|
||||
clear(true);
|
||||
return cmdline;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user