diff --git a/ce/Makefile b/ce/Makefile index c9f6740..6cc8099 100644 --- a/ce/Makefile +++ b/ce/Makefile @@ -6,6 +6,7 @@ $(eval $(call add_lib,libaux)) $(eval $(call add_lib,libarena)) $(eval $(call add_lib,libioutil)) $(eval $(call add_include,libterminal)) +$(eval $(call add_include,libkb)) cflags += -DPRINTF_INCLUDE_CONFIG_H=1 diff --git a/ce/ce.c b/ce/ce.c index d3468bf..ac36517 100644 --- a/ce/ce.c +++ b/ce/ce.c @@ -1,29 +1,29 @@ #include "arena_alloc.h" #include "context.h" +#include "gapbuffer.h" #include "interp.h" #include "mprintf.h" #include "self.h" #include "strbuf.h" #include -#include -#include -#include -#include +#include #include -#include -#include #include -#include #include #include #include -#include #include #include -#include +#include +#include -#define LINE_BUFFER_MAX 1024 -#define PROMPT "$ " +#define LINE_INIT_MAX 2 +#define PROMPT "$ " + +struct edit_line { + struct gapbuffer gb; + size_t cursor; +}; static void exec_line (const char* line) { struct list_node_link* tokens = NULL; @@ -32,39 +32,84 @@ static void exec_line (const char* line) { if (tokens != NULL) parse_and_execute (tokens); - - arena_reset (&arena); } void app_main (void) { e_pid = get_exec_pid (); e_pgid = get_procgroup (e_pid); - size_t line_cursor = 0; - char line_buffer[LINE_BUFFER_MAX + 1]; - memset (line_buffer, 0, sizeof (line_buffer)); + struct edit_line edit_line; + + const char* render = NULL; while (interp_is_running ()) { + gapbuffer_init (&edit_line.gb, LINE_INIT_MAX); + edit_line.cursor = 0; + mprintf (PROMPT); - char ch = 0; + uint8_t ch = 0; for (;;) { mail_receive (&ch, 1); if (ch == '\n') break; - if (line_cursor < LINE_BUFFER_MAX) { - line_buffer[line_cursor++] = ch; - mprintf ("%c", ch); + switch (ch) { + case '\b': + if (edit_line.cursor > 0) { + gapbuffer_backspace (&edit_line.gb); + edit_line.cursor--; + + mprintf ("\b"); + + char* tail = gapbuffer_string_at (&edit_line.gb, edit_line.cursor); + mprintf ("%s" ANSIQ_SCR_CLR2END, tail); + + int move_back = (int)strlen (tail); + if (move_back > 0) + mprintf (ANSIQ_DYN_CUR_LEFT, move_back); + } + break; + case KB_LEFT: + if (edit_line.cursor > 0) { + edit_line.cursor--; + mprintf (ANSIQ_CUR_LEFT (1)); + } + break; + case KB_RIGHT: + if (edit_line.cursor < gapbuffer_length (&edit_line.gb)) { + edit_line.cursor++; + mprintf (ANSIQ_CUR_RIGHT (1)); + } + break; + default: + if (isascii (ch)) { + gapbuffer_insert (&edit_line.gb, ch); + edit_line.cursor++; + + char* tail = gapbuffer_string_at (&edit_line.gb, edit_line.cursor - 1); + mprintf ("%s" ANSIQ_SCR_CLR2LEND, tail); + + int move_back = (int)strlen (tail) - 1; + if (move_back > 0) + mprintf (ANSIQ_DYN_CUR_LEFT, move_back); + } + break; } + + gapbuffer_move (&edit_line.gb, edit_line.cursor); } mprintf ("\n"); - exec_line (line_buffer); - line_cursor = 0; - memset (line_buffer, 0, sizeof (line_buffer)); + render = gapbuffer_get_string (&edit_line.gb); + + if (render != NULL) + exec_line (render); + + gapbuffer_fini (&edit_line.gb); + arena_reset (&arena); } arena_destroy (&arena); diff --git a/ce/gapbuffer.c b/ce/gapbuffer.c new file mode 100644 index 0000000..e7248b4 --- /dev/null +++ b/ce/gapbuffer.c @@ -0,0 +1,126 @@ +#include "gapbuffer.h" +#include "arena_alloc.h" +#include +#include +#include + +void gapbuffer_init (struct gapbuffer* gb, size_t capacity) { + gb->buffer = arena_malloc (&arena, capacity); + + if (gb->buffer == NULL) + return; + + memset (gb->buffer, 0, capacity); + gb->size = capacity; + gb->gap_start = 0; + gb->gap_end = capacity; +} + +void gapbuffer_fini (struct gapbuffer* gb) { memset (gb, 0, sizeof (*gb)); } + +void gapbuffer_grow (struct gapbuffer* gb) { + size_t old_size = gb->size; + size_t new_size = gb->size * 2; + + char* new = arena_realloc (&arena, gb->buffer, old_size, new_size); + + if (new == NULL) + return; + + gb->buffer = new; + + size_t post_gap_size = old_size - gb->gap_end; + size_t new_gap_end = new_size - post_gap_size; + + memmove (gb->buffer + new_gap_end, gb->buffer + gb->gap_end, post_gap_size); + + gb->gap_end = new_gap_end; + gb->size = new_size; +} + +void gapbuffer_move (struct gapbuffer* gb, size_t pos) { + if (pos > (gb->size - (gb->gap_end - gb->gap_start))) + pos = (gb->size - (gb->gap_end - gb->gap_start)); + + while (gb->gap_start > pos) { + gb->gap_start--; + gb->gap_end--; + gb->buffer[gb->gap_end] = gb->buffer[gb->gap_start]; + } + + while (gb->gap_start < pos) { + gb->buffer[gb->gap_start] = gb->buffer[gb->gap_end]; + gb->gap_start++; + gb->gap_end++; + } +} + +void gapbuffer_insert (struct gapbuffer* gb, char c) { + if (gb->gap_start == gb->gap_end) + gapbuffer_grow (gb); + + gb->buffer[gb->gap_start] = c; + gb->gap_start++; +} + +void gapbuffer_backspace (struct gapbuffer* gb) { + if (gb->gap_start > 0) + gb->gap_start--; +} + +char* gapbuffer_get_string (struct gapbuffer* gb) { + size_t size = gb->size - (gb->gap_end - gb->gap_start); + + char* str = arena_malloc (&arena, size + 1); + + if (str == NULL) + return NULL; + + memcpy (str, gb->buffer, gb->gap_start); + + memcpy (str + gb->gap_start, gb->buffer + gb->gap_end, gb->size - gb->gap_end); + + str[size] = '\0'; + return str; +} + +size_t gapbuffer_length (struct gapbuffer* gb) { return gb->size - (gb->gap_end - gb->gap_start); } + +char* gapbuffer_string_at (struct gapbuffer* gb, size_t pos) { + size_t total_size = gapbuffer_length (gb); + + if (pos >= total_size) + return ""; + + size_t tail_size = total_size - pos; + + char* res = arena_malloc (&arena, tail_size + 1); + + if (res == NULL) + return NULL; + + size_t written = 0; + + if (pos < gb->gap_start) { + size_t copy = gb->gap_start - pos; + + if (copy > tail_size) + copy = tail_size; + + memcpy (res, &gb->buffer[pos], copy); + written += copy; + pos += copy; + } + + if (written < tail_size) { + size_t gap_size = gb->gap_end - gb->gap_start; + size_t phys_pos = pos + gap_size; + + size_t copy = tail_size - written; + memcpy (&res[written], &gb->buffer[phys_pos], copy); + written += copy; + } + + res[written] = '\0'; + return res; +} diff --git a/ce/gapbuffer.h b/ce/gapbuffer.h new file mode 100644 index 0000000..d266468 --- /dev/null +++ b/ce/gapbuffer.h @@ -0,0 +1,31 @@ +#ifndef _GAPBUFFER_H +#define _GAPBUFFER_H + +#include + +struct gapbuffer { + char* buffer; + size_t size; + size_t gap_start; + size_t gap_end; +}; + +void gapbuffer_init (struct gapbuffer* gb, size_t capacity); + +void gapbuffer_fini (struct gapbuffer* gb); + +void gapbuffer_move (struct gapbuffer* gb, size_t pos); + +void gapbuffer_insert (struct gapbuffer* gb, char c); + +void gapbuffer_backspace (struct gapbuffer* gb); + +void gapbuffer_grow (struct gapbuffer* gb); + +char* gapbuffer_get_string (struct gapbuffer* gb); + +size_t gapbuffer_length (struct gapbuffer* gb); + +char* gapbuffer_string_at (struct gapbuffer* gb, size_t pos); + +#endif // _GAPBUFFER_H diff --git a/ce/interp.c b/ce/interp.c index c1f85b4..c73e549 100644 --- a/ce/interp.c +++ b/ce/interp.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -13,8 +14,6 @@ #include #include -#define CTRL(x) ((x) - '@') - static bool run = true; bool interp_is_running (void) { return run; } @@ -164,7 +163,7 @@ static void cmd_cancel_proc (void) { for (;;) { mail_receive (&ch, 1); - if (ch == CTRL ('C')) + if (ch == KB_CTRL ('C')) break; } diff --git a/ce/src.mk b/ce/src.mk index 57a6a3c..bfed501 100644 --- a/ce/src.mk +++ b/ce/src.mk @@ -5,7 +5,8 @@ c += ce.c \ parser.c \ interp.c \ mprintf.c \ - self.c + self.c \ + gapbuffer.c o += ce.o \ arena_alloc.o \ @@ -14,4 +15,5 @@ o += ce.o \ parser.o \ interp.o \ mprintf.o \ - self.o + self.o \ + gapbuffer.o diff --git a/include/kb_defs.h b/include/kb_defs.h new file mode 100644 index 0000000..28e71ae --- /dev/null +++ b/include/kb_defs.h @@ -0,0 +1,26 @@ +#ifndef _KB_DEFS_H +#define _KB_DEFS_H + +#define KB_SHIFT (1 << 0) +#define KB_CTL (1 << 1) +#define KB_ALT (1 << 2) + +#define KB_CAPSLOCK (1 << 3) +#define KB_NUMLOCK (1 << 4) +#define KB_SCRLLOCK (1 << 5) +#define KB_E0ESC (1 << 6) + +#define KB_HOME 0xe0 +#define KB_END 0xe1 +#define KB_UP 0xe2 +#define KB_DOWN 0xe3 +#define KB_LEFT 0xe4 +#define KB_RIGHT 0xe5 +#define KB_PAGEUP 0xe6 +#define KB_PAGEDN 0xe7 +#define KB_INSERT 0xe8 +#define KB_DELETE 0xe9 + +#define KB_CTRL(x) ((x) - '@') + +#endif // _KB_DEFS_H diff --git a/init/init.c b/init/init.c index eda9f2e..deaf2bf 100644 --- a/init/init.c +++ b/init/init.c @@ -29,7 +29,7 @@ void app_main (void) { for (;;) { int ch = kb_read_key (); - if (ch <= 0) + if (ch == 0) continue; mail_send (ce_pgid, (uint8_t*)&ch, 1); diff --git a/kernel/device/ps2_kb.c b/kernel/device/ps2_kb.c index 9de2609..c2cb414 100644 --- a/kernel/device/ps2_kb.c +++ b/kernel/device/ps2_kb.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -20,28 +21,6 @@ #define KB_DATA_IN_BUF 0x01 #define KB_DATA 0x60 -#define KB_SHIFT (1 << 0) -#define KB_CTL (1 << 1) -#define KB_ALT (1 << 2) - -#define KB_CAPSLOCK (1 << 3) -#define KB_NUMLOCK (1 << 4) -#define KB_SCRLLOCK (1 << 5) -#define KB_E0ESC (1 << 6) - -#define KB_HOME 0xe0 -#define KB_END 0xe1 -#define KB_UP 0xe2 -#define KB_DOWN 0xe3 -#define KB_LEFT 0xe4 -#define KB_RIGHT 0xe5 -#define KB_PAGEUP 0xe6 -#define KB_PAGEDN 0xe7 -#define KB_INSERT 0xe8 -#define KB_DELETE 0xe9 - -#define C(x) ((x) - '@') - #define PS2KB_RINGBUFFER_MAX 2048 static struct ringbuffer ps2kb_ringbuffer; @@ -110,12 +89,12 @@ static uint8_t shiftmap[256] = { static uint8_t ctlmap[256] = { /* clang-format off */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - C ('Q'), C ('W'), C ('E'), C ('R'), C ('T'), C ('Y'), C ('U'), C ('I'), C ('O'), - C ('P'), 0x0, 0x0, '\r', 0x0, C ('A'), C ('S'), C ('D'), C ('F'), C ('G'), C ('H'), - C ('J'), C ('K'), C ('L'), 0x0, 0x0, 0x0, 0x0, C ('\\'), C ('Z'), C ('X'), C ('C'), - C ('V'), C ('B'), C ('N'), C ('M'), 0x0, 0x0, C ('/'), 0x0, 0x0, + KB_CTRL ('Q'), KB_CTRL ('W'), KB_CTRL ('E'), KB_CTRL ('R'), KB_CTRL ('T'), KB_CTRL ('Y'), KB_CTRL ('U'), KB_CTRL ('I'), KB_CTRL ('O'), + KB_CTRL ('P'), 0x0, 0x0, '\r', 0x0, KB_CTRL ('A'), KB_CTRL ('S'), KB_CTRL ('D'), KB_CTRL ('F'), KB_CTRL ('G'), KB_CTRL ('H'), + KB_CTRL ('J'), KB_CTRL ('K'), KB_CTRL ('L'), 0x0, 0x0, 0x0, 0x0, KB_CTRL ('\\'), KB_CTRL ('Z'), KB_CTRL ('X'), KB_CTRL ('C'), + KB_CTRL ('V'), KB_CTRL ('B'), KB_CTRL ('N'), KB_CTRL ('M'), 0x0, 0x0, KB_CTRL ('/'), 0x0, 0x0, [0x9C] = '\r', - [0xB5] = C ('/'), + [0xB5] = KB_CTRL ('/'), [0xc8] = KB_UP, [0xd0] = KB_DOWN, [0xc9] = KB_PAGEUP, diff --git a/kernel/device/ps2_kb.h b/kernel/device/ps2_kb.h index 13aed72..ae59661 100644 --- a/kernel/device/ps2_kb.h +++ b/kernel/device/ps2_kb.h @@ -7,7 +7,6 @@ #include struct device; -struct device_op_ctx; int ps2kb_read_key (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); diff --git a/libkb/kb.h b/libkb/kb.h index 6d796d5..5f8e561 100644 --- a/libkb/kb.h +++ b/libkb/kb.h @@ -2,6 +2,7 @@ #define _LIBKB_KB_H #include +#include #include /* \brief Read key from keyboard diff --git a/libstring/string.c b/libstring/string.c index aeb42e7..3f3b02c 100644 --- a/libstring/string.c +++ b/libstring/string.c @@ -118,3 +118,25 @@ int isxdigit (int c) { return isdigit (c) || (c >= 'A' && c <= 'F') || (c >= 'a' int isascii (int c) { return (c >= 0 && c <= 127); } int isblank (int c) { return (c == ' ' || c == '\t'); } + +/* SOURCE: https://aticleworld.com/memmove-function-implementation-in-c/ */ +void* memmove (void* dest, const void* src, unsigned int n) { + unsigned char isCopyRequire = 0; // flag bit + char* pcSource = (char*)src; + char* pcDstn = (char*)dest; + // return if pcDstn and pcSource is NULL + if ((pcSource == NULL) || (pcDstn == NULL)) { + return NULL; + } + // overlap buffer + if ((pcSource < pcDstn) && (pcDstn < pcSource + n)) { + for (pcDstn += n, pcSource += n; n--;) { + *--pcDstn = *--pcSource; + } + } else { + while (n--) { + *pcDstn++ = *pcSource++; + } + } + return dest; +} diff --git a/libstring/string.h b/libstring/string.h index 2b08386..ae42eb7 100644 --- a/libstring/string.h +++ b/libstring/string.h @@ -57,4 +57,6 @@ int isascii (int c); int isblank (int c); +void* memmove (void* dest, const void* src, unsigned int n); + #endif // _LIBSTRING_STRING_H diff --git a/libterminal/terminal_common.h b/libterminal/tcommon.h similarity index 100% rename from libterminal/terminal_common.h rename to libterminal/tcommon.h diff --git a/libterminal/tcursor.h b/libterminal/tcursor.h new file mode 100644 index 0000000..aa85451 --- /dev/null +++ b/libterminal/tcursor.h @@ -0,0 +1,33 @@ +#ifndef ANSIQ_CURSOR_H +#define ANSIQ_CURSOR_H +#include + +/* clang-format off */ +#define ANSIQ_CUR_HOME ANSIQ_ESC"[H" +#define ANSIQ_CUR_SET(l, c) ANSIQ_ESC"["#l";"#c"H" +#define ANSIQ_DYN_CUR_SET ANSIQ_CUR_SET(%d,%d) +#define ANSIQ_CUR_UP(n) ANSIQ_ESC"["#n"A" +#define ANSIQ_DYN_CUR_UP ANSIQ_CUR_UP(%d) +#define ANSIQ_CUR_DOWN(n) ANSIQ_ESC"["#n"B" +#define ANSIQ_DYN_CUR_DOWN ANSIQ_CUR_DOWN(%d) +#define ANSIQ_CUR_RIGHT(n) ANSIQ_ESC"["#n"C" +#define ANSIQ_DYN_CUR_RIGHT ANSIQ_CUR_RIGHT(%d) +#define ANSIQ_CUR_LEFT(n) ANSIQ_ESC"["#n"D" +#define ANSIQ_DYN_CUR_LEFT ANSIQ_CUR_LEFT(%d) +#define ANSIQ_CUR_UP_BEG(n) ANSIQ_ESC"["#n"E" +#define ANSIQ_DYN_CUR_UP_BEG ANSIQ_CUR_UP_BEG(%d) +#define ANSIQ_CUR_DOWN_BEG(n) ANSIQ_ESC"["#n"F" +#define ANSIQ_DYN_CUR_DOWN_BEG ANSIQ_CUR_DOWN_BEG(%d) +#define ANSIQ_CUR_SET_COL(n) ANSIQ_ESC"["#n"G" +#define ANSIQ_DYN_CUR_SET_COL ANSIQ_CUR_SET_COL(%d) +#define ANSIQ_CUR_REQ_POS ANSIQ_ESC"[6n" +#define ANSIQ_CUR_MOVE_1UP ANSIQ_ESC"M" +#define ANSIQ_CUR_SAVE_DEC ANSIQ_ESC"7" +#define ANSIQ_CUR_RESTORE_DEC ANSIQ_ESC"8" +#define ANSIQ_CUR_SAVE_SCO ANSIQ_ESC"[s" +#define ANSIQ_CUR_RESTORE_SCO ANSIQ_ESC"[u" +#define ANSIQ_CUR_INVISIBLE ANSIQ_ESC"[?25l" +#define ANSIQ_CUR_VISIBLE ANSIQ_ESC"[?25h" +/* clang-format on */ + +#endif /* ANSIQ_CURSOR_H */ diff --git a/libterminal/terminal_cursor.h b/libterminal/terminal_cursor.h deleted file mode 100644 index 2536919..0000000 --- a/libterminal/terminal_cursor.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef ANSIQ_CURSOR_H -#define ANSIQ_CURSOR_H -#include - -#define ANSIQ_CUR_HOME ANSIQ_ESC "[H" -#define ANSIQ_CUR_SET(l, c) ANSIQ_ESC "[" #l ";" #c "H" -#define ANSIQ_DYN_CUR_SET ANSIQ_CUR_SET (% d, % d) -#define ANSIQ_CUR_UP(n) ANSIQ_ESC "[" #n "A" -#define ANSIQ_DYN_CUR_UP ANSIQ_CUR_UP (% d) -#define ANSIQ_CUR_DOWN(n) ANSIQ_ESC "[" #n "B" -#define ANSIQ_DYN_CUR_DOWN ANSIQ_CUR_DOWN (% d) -#define ANSIQ_CUR_RIGHT(n) ANSIQ_ESC "[" #n "C" -#define ANSIQ_DYN_CUR_RIGHT ANSIQ_CUR_RIGHT (% d) -#define ANSIQ_CUR_LEFT(n) ANSIQ_ESC "[" #n "D" -#define ANSIQ_DYN_CUR_LEFT ANSIQ_CUR_LEFT (% d) -#define ANSIQ_CUR_UP_BEG(n) ANSIQ_ESC "[" #n "E" -#define ANSIQ_DYN_CUR_UP_BEG ANSIQ_CUR_UP_BEG (% d) -#define ANSIQ_CUR_DOWN_BEG(n) ANSIQ_ESC "[" #n "F" -#define ANSIQ_DYN_CUR_DOWN_BEG ANSIQ_CUR_DOWN_BEG (% d) -#define ANSIQ_CUR_SET_COL(n) ANSIQ_ESC "[" #n "G" -#define ANSIQ_DYN_CUR_SET_COL ANSIQ_CUR_SET_COL (% d) -#define ANSIQ_CUR_REQ_POS ANSIQ_ESC "[6n" -#define ANSIQ_CUR_MOVE_1UP ANSIQ_ESC "M" -#define ANSIQ_CUR_SAVE_DEC ANSIQ_ESC "7" -#define ANSIQ_CUR_RESTORE_DEC ANSIQ_ESC "8" -#define ANSIQ_CUR_SAVE_SCO ANSIQ_ESC "[s" -#define ANSIQ_CUR_RESTORE_SCO ANSIQ_ESC "[u" -#define ANSIQ_CUR_INVISIBLE ANSIQ_ESC "[?25l" -#define ANSIQ_CUR_VISIBLE ANSIQ_ESC "[?25h" - -#endif /* ANSIQ_CURSOR_H */ diff --git a/libterminal/terminal_graphics.h b/libterminal/terminal_graphics.h deleted file mode 100644 index c0ed5e8..0000000 --- a/libterminal/terminal_graphics.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef ANSIQ_GRAPHICS_H -#define ANSIQ_GRAPHICS_H -#include - -#define ANSIQ_GR_SEQ(s) ANSIQ_ESC "[" s "m" - -/* Text colors */ -#define ANSIQ_FG_BLACK ";30" -#define ANSIQ_FG_RED ";31" -#define ANSIQ_FG_GREEN ";32" -#define ANSIQ_FG_YELLOW ";33" -#define ANSIQ_FG_BLUE ";34" -#define ANSIQ_FG_MAGENTA ";35" -#define ANSIQ_FG_CYAN ";36" -#define ANSIQ_FG_WHITE ";37" - -#define __ANSIQ_SETFG_BLACK ANSIQ_ESC "[" ANSIQ_FG_BLACK -#define __ANSIQ_SETFG_RED ANSIQ_ESC "[" ANSIQ_FG_RED -#define __ANSIQ_SETFG_GREEN ANSIQ_ESC "[" ANSIQ_FG_GREEN -#define __ANSIQ_SETFG_YELLOW ANSIQ_ESC "[" ANSIQ_FG_YELLOW -#define __ANSIQ_SETFG_BLUE ANSIQ_ESC "[" ANSIQ_FG_BLUE -#define __ANSIQ_SETFG_MAGENTA ANSIQ_ESC "[" ANSIQ_FG_MAGENTA -#define __ANSIQ_SETFG_CYAN ANSIQ_ESC "[" ANSIQ_FG_CYAN -#define __ANSIQ_SETFG_WHITE ANSIQ_ESC "[" ANSIQ_FG_WHITE - -#define ANSIQ_SETFG_BLACK __ANSIQ_SETFG_BLACK "m" -#define ANSIQ_SETFG_RED __ANSIQ_SETFG_RED "m" -#define ANSIQ_SETFG_GREEN __ANSIQ_SETFG_GREEN "m" -#define ANSIQ_SETFG_YELLOW __ANSIQ_SETFG_YELLOW "m" -#define ANSIQ_SETFG_BLUE __ANSIQ_SETFG_BLUE "m" -#define ANSIQ_SETFG_MAGENTA __ANSIQ_SETFG_MAGENTA "m" -#define ANSIQ_SETFG_CYAN __ANSIQ_SETFG_CYAN "m" -#define ANSIQ_SETFG_WHITE __ANSIQ_SETFG_WHITE "m" - -#define ANSIQ_BRIGHT_FG(c) ANSIQ_FG_##c ";1" -#define ANSIQ_FG256(n) ";38;5;" #n -#define ANSIQ_SETBRIGHT_FG(c) ANSIQ_ESC "[" ANSIQ_BRIGHT_FG (c) "m" -#define ANSIQ_SETFG256(n) ANSIQ_ESC "[" ANSIQ_FG256 (n) "m" -#define ANSIQ_DYN_BRIGHT_FG ANSIQ_BRIGHT_FG (% d) -#define ANSIQ_DYN_FG256 ANSIQ_FG256 (% d) -#define ANSIQ_DYN_SETBRIGHT_FG ANSIQ_SETBRIGHT_FG (% d) -#define ANSIQ_DYN_SETFG256 ANSIQ_SETFG256 (% d) - -#define ANSIQ_FG_RGB(r, g, b) ";38;2;" #r ";" #g ";" #b -#define ANSIQ_SETFG_RGB(r, g, b) ANSIQ_ESC "[" ANSIQ_FG_RGB (r, g, b) "m" -#define ANSIQ_DYN_FG_RGB ANSIQ_FG_RGB (% d, % d, % d) -#define ANSIQ_DYN_SETFG_RGB ANSIQ_SETFG_RGB (% d, % d, % d) - -#define ANSIQ_FG_DEFAULT \ - ANSIQ_ESC "[39m" // Set the foreground - // color to the default one - // (i.e. reset foreground - // colof only) - -/* Background colors */ -#define ANSIQ_BG_BLACK ";40" -#define ANSIQ_BG_RED ";41" -#define ANSIQ_BG_GREEN ";42" -#define ANSIQ_BG_YELLOW ";43" -#define ANSIQ_BG_BLUE ";44" -#define ANSIQ_BG_MAGENTA ";45" -#define ANSIQ_BG_CYAN ";46" -#define ANSIQ_BG_WHITE ";47" - -#define __ANSIQ_SETBG_BLACK ANSIQ_ESC "[" ANSIQ_BG_BLACK -#define __ANSIQ_SETBG_RED ANSIQ_ESC "[" ANSIQ_BG_RED -#define __ANSIQ_SETBG_GREEN ANSIQ_ESC "[" ANSIQ_BG_GREEN -#define __ANSIQ_SETBG_YELLOW ANSIQ_ESC "[" ANSIQ_BG_YELLOW -#define __ANSIQ_SETBG_BLUE ANSIQ_ESC "[" ANSIQ_BG_BLUE -#define __ANSIQ_SETBG_MAGENTA ANSIQ_ESC "[" ANSIQ_BG_MAGENTA -#define __ANSIQ_SETBG_CYAN ANSIQ_ESC "[" ANSIQ_BG_CYAN -#define __ANSIQ_SETBG_WHITE ANSIQ_ESC "[" ANSIQ_BG_WHITE - -#define ANSIQ_SETBG_BLACK __ANSIQ_SETBG_BLACK "m" -#define ANSIQ_SETBG_RED __ANSIQ_SETBG_RED "m" -#define ANSIQ_SETBG_GREEN __ANSIQ_SETBG_GREEN "m" -#define ANSIQ_SETBG_YELLOW __ANSIQ_SETBG_YELLOW "m" -#define ANSIQ_SETBG_BLUE __ANSIQ_SETBG_BLUE "m" -#define ANSIQ_SETBG_MAGENTA __ANSIQ_SETBG_MAGENTA "m" -#define ANSIQ_SETBG_CYAN __ANSIQ_SETBG_CYAN "m" -#define ANSIQ_SETBG_WHITE __ANSIQ_SETBG_WHITE "m" - -#define ANSIQ_BRIGHT_BG(c) ANSIQ_BG_##c ";1" -#define ANSIQ_BG256(n) ";48;5;" #n -#define ANSIQ_SETBRIGHT_BG(c) ANSIQ_ESC "[" ANSIQ_BRIGHT_BG (c) "m" -#define ANSIQ_SETBG256(n) ANSIQ_ESC "[" ANSIQ_BG256 (n) "m" -#define ANSIQ_DYN_BRIGHT_BG ANSIQ_BRIGHT_BG (% d) -#define ANSIQ_DYN_BG256 ANSIQ_BG256 (% d) -#define ANSIQ_DYN_SETBRIGHT_BG ANSIQ_SETBRIGHT_BG (% d) -#define ANSIQ_DYN_SETBG256 ANSIQ_SETBG256 (% d) - -#define ANSIQ_BG_RGB(r, g, b) ";48;2;" #r ";" #g ";" #b -#define ANSIQ_SETBG_RGB(r, g, b) ANSIQ_ESC "[" ANSIQ_BG_RGB (r, g, b) "m" -#define ANSIQ_DYN_BG_RGB ANSIQ_BG_RGB (% d, % d, % d) -#define ANSIQ_DYN_SETBG_RGB ANSIQ_SETBG_RGB (% d, % d, % d) - -#define ANSIQ_BG_DEFAULT \ - ANSIQ_ESC "[49m" // Set the background color - // to the default one - // (i.e. reset background - // color only) - -/* Text styles */ -#define ANSIQ_TXT_BLD ";1" // bold -#define ANSIQ_TXT_DIM ";2" // dim/faint -#define ANSIQ_TXT_ITL ";3" // italic -#define ANSIQ_TXT_UNL ";4" // underline -#define ANSIQ_TXT_BLK ";5" // blinking mode (idk what it does) -#define ANSIQ_TXT_REV ";7" // reversed -#define ANSIQ_TXT_HID ";8" // hidden/invisible -#define ANSIQ_TXT_STK ";9" // strikethrough - -#define ANSIQ_SETTXT_BLD ANSIQ_ESC "[" ANSIQ_TXT_BLD "m" -#define ANSIQ_SETTXT_DIM ANSIQ_ESC "[" ANSIQ_TXT_DIM "m" -#define ANSIQ_SETTXT_ITL ANSIQ_ESC "[" ANSIQ_TXT_ITL "m" -#define ANSIQ_SETTXT_UNL ANSIQ_ESC "[" ANSIQ_TXT_UNL "m" -#define ANSIQ_SETTXT_BLK ANSIQ_ESC "[" ANSIQ_TXT_BLK "m" -#define ANSIQ_SETTXT_REV ANSIQ_ESC "[" ANSIQ_TXT_REV "m" -#define ANSIQ_SETTXT_HID ANSIQ_ESC "[" ANSIQ_TXT_HID "m" -#define ANSIQ_SETTXT_STK ANSIQ_ESC "[" ANSIQ_TXT_STK "m" - -#define ANSIQ_GR_RESET \ - ANSIQ_ESC "[" \ - "0m" - -#endif /* ANSIQ_GRAPHICS_H */ diff --git a/libterminal/terminal_screen.h b/libterminal/terminal_screen.h deleted file mode 100644 index 0c9430a..0000000 --- a/libterminal/terminal_screen.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef ANSIQ_SCREEN_H -#define ANSIQ_SCREEN_H -#include - -#define ANSIQ_SCR_CLR2END ANSIQ_ESC "[0J" // Clear to end of screen -#define ANSIQ_SCR_CLR2BEG ANSIQ_ESC "[1J" // Clear to begining of screen -#define ANSIQ_SCR_CLR_ALL ANSIQ_ESC "[2J" // Clear entire screen -#define ANSIQ_SCR_CLR_SAV ANSIQ_ESC "[3J" // Clear saved lines -#define ANSIQ_SCR_CLR2LEND ANSIQ_ESC "[0K" // Clear to end of line -#define ANSIQ_SCR_CLR2LBEG ANSIQ_ESC "[1K" // Clear to begining of line -#define ANSIQ_SCR_CLR_LINE ANSIQ_ESC "[1K" // Clear entire line -#define ANSIQ_SCR_RESTORE ANSIQ_ESC "[?47l" -#define ANSIQ_SCR_SAVE ANSIQ_ESC "[?47h" - -#endif /* ANSIQ_SCREEN_H */ diff --git a/libterminal/tgraphics.h b/libterminal/tgraphics.h new file mode 100644 index 0000000..4c13f25 --- /dev/null +++ b/libterminal/tgraphics.h @@ -0,0 +1,124 @@ +#ifndef ANSIQ_GRAPHICS_H +#define ANSIQ_GRAPHICS_H +#include + +/* clang-format off */ +#define ANSIQ_GR_SEQ(s) ANSIQ_ESC "["s"m" + +/* Text colors */ +#define ANSIQ_FG_BLACK ";30" +#define ANSIQ_FG_RED ";31" +#define ANSIQ_FG_GREEN ";32" +#define ANSIQ_FG_YELLOW ";33" +#define ANSIQ_FG_BLUE ";34" +#define ANSIQ_FG_MAGENTA ";35" +#define ANSIQ_FG_CYAN ";36" +#define ANSIQ_FG_WHITE ";37" + +#define __ANSIQ_SETFG_BLACK ANSIQ_ESC"["ANSIQ_FG_BLACK +#define __ANSIQ_SETFG_RED ANSIQ_ESC"["ANSIQ_FG_RED +#define __ANSIQ_SETFG_GREEN ANSIQ_ESC"["ANSIQ_FG_GREEN +#define __ANSIQ_SETFG_YELLOW ANSIQ_ESC"["ANSIQ_FG_YELLOW +#define __ANSIQ_SETFG_BLUE ANSIQ_ESC"["ANSIQ_FG_BLUE +#define __ANSIQ_SETFG_MAGENTA ANSIQ_ESC"["ANSIQ_FG_MAGENTA +#define __ANSIQ_SETFG_CYAN ANSIQ_ESC"["ANSIQ_FG_CYAN +#define __ANSIQ_SETFG_WHITE ANSIQ_ESC"["ANSIQ_FG_WHITE + +#define ANSIQ_SETFG_BLACK __ANSIQ_SETFG_BLACK"m" +#define ANSIQ_SETFG_RED __ANSIQ_SETFG_RED"m" +#define ANSIQ_SETFG_GREEN __ANSIQ_SETFG_GREEN"m" +#define ANSIQ_SETFG_YELLOW __ANSIQ_SETFG_YELLOW"m" +#define ANSIQ_SETFG_BLUE __ANSIQ_SETFG_BLUE"m" +#define ANSIQ_SETFG_MAGENTA __ANSIQ_SETFG_MAGENTA"m" +#define ANSIQ_SETFG_CYAN __ANSIQ_SETFG_CYAN"m" +#define ANSIQ_SETFG_WHITE __ANSIQ_SETFG_WHITE"m" + +#define ANSIQ_BRIGHT_FG(c) ANSIQ_FG_##c";1" +#define ANSIQ_FG256(n) ";38;5;"#n +#define ANSIQ_SETBRIGHT_FG(c) ANSIQ_ESC"["ANSIQ_BRIGHT_FG(c)"m" +#define ANSIQ_SETFG256(n) ANSIQ_ESC"["ANSIQ_FG256(n)"m" +#define ANSIQ_DYN_BRIGHT_FG ANSIQ_BRIGHT_FG(%d) +#define ANSIQ_DYN_FG256 ANSIQ_FG256(%d) +#define ANSIQ_DYN_SETBRIGHT_FG ANSIQ_SETBRIGHT_FG(%d) +#define ANSIQ_DYN_SETFG256 ANSIQ_SETFG256(%d) + +#define ANSIQ_FG_RGB(r, g, b) ";38;2;"#r";"#g";"#b +#define ANSIQ_SETFG_RGB(r, g, b) ANSIQ_ESC"["ANSIQ_FG_RGB(r,g,b)"m" +#define ANSIQ_DYN_FG_RGB ANSIQ_FG_RGB (%d,%d,%d) +#define ANSIQ_DYN_SETFG_RGB ANSIQ_SETFG_RGB(%d,%d,%d) + +#define ANSIQ_FG_DEFAULT ANSIQ_ESC "[39m" // Set the foreground + // color to the default one + // (i.e. reset foreground + // colof only) + +/* Background colors */ +#define ANSIQ_BG_BLACK ";40" +#define ANSIQ_BG_RED ";41" +#define ANSIQ_BG_GREEN ";42" +#define ANSIQ_BG_YELLOW ";43" +#define ANSIQ_BG_BLUE ";44" +#define ANSIQ_BG_MAGENTA ";45" +#define ANSIQ_BG_CYAN ";46" +#define ANSIQ_BG_WHITE ";47" + +#define __ANSIQ_SETBG_BLACK ANSIQ_ESC"["ANSIQ_BG_BLACK +#define __ANSIQ_SETBG_RED ANSIQ_ESC"["ANSIQ_BG_RED +#define __ANSIQ_SETBG_GREEN ANSIQ_ESC"["ANSIQ_BG_GREEN +#define __ANSIQ_SETBG_YELLOW ANSIQ_ESC"["ANSIQ_BG_YELLOW +#define __ANSIQ_SETBG_BLUE ANSIQ_ESC"["ANSIQ_BG_BLUE +#define __ANSIQ_SETBG_MAGENTA ANSIQ_ESC"["ANSIQ_BG_MAGENTA +#define __ANSIQ_SETBG_CYAN ANSIQ_ESC"["ANSIQ_BG_CYAN +#define __ANSIQ_SETBG_WHITE ANSIQ_ESC"["ANSIQ_BG_WHITE + +#define ANSIQ_SETBG_BLACK __ANSIQ_SETBG_BLACK"m" +#define ANSIQ_SETBG_RED __ANSIQ_SETBG_RED"m" +#define ANSIQ_SETBG_GREEN __ANSIQ_SETBG_GREEN"m" +#define ANSIQ_SETBG_YELLOW __ANSIQ_SETBG_YELLOW"m" +#define ANSIQ_SETBG_BLUE __ANSIQ_SETBG_BLUE"m" +#define ANSIQ_SETBG_MAGENTA __ANSIQ_SETBG_MAGENTA"m" +#define ANSIQ_SETBG_CYAN __ANSIQ_SETBG_CYAN"m" +#define ANSIQ_SETBG_WHITE __ANSIQ_SETBG_WHITE"m" + +#define ANSIQ_BRIGHT_BG(c) ANSIQ_BG_##c";1" +#define ANSIQ_BG256(n) ";48;5;"#n +#define ANSIQ_SETBRIGHT_BG(c) ANSIQ_ESC"["ANSIQ_BRIGHT_BG (c)"m" +#define ANSIQ_SETBG256(n) ANSIQ_ESC"["ANSIQ_BG256 (n)"m" +#define ANSIQ_DYN_BRIGHT_BG ANSIQ_BRIGHT_BG(%d) +#define ANSIQ_DYN_BG256 ANSIQ_BG256(%d) +#define ANSIQ_DYN_SETBRIGHT_BG ANSIQ_SETBRIGHT_BG(%d) +#define ANSIQ_DYN_SETBG256 ANSIQ_SETBG256(%d) + +#define ANSIQ_BG_RGB(r, g, b) ";48;2;"#r";"#g";"#b +#define ANSIQ_SETBG_RGB(r, g, b) ANSIQ_ESC"["ANSIQ_BG_RGB(r,g,b)"m" +#define ANSIQ_DYN_BG_RGB ANSIQ_BG_RGB (%d,%d,%d) +#define ANSIQ_DYN_SETBG_RGB ANSIQ_SETBG_RGB(%d,%d,%d) + +#define ANSIQ_BG_DEFAULT ANSIQ_ESC "[49m" // Set the background color + // to the default one + // (i.e. reset background + // color only) + +/* Text styles */ +#define ANSIQ_TXT_BLD";1" // bold +#define ANSIQ_TXT_DIM";2" // dim/faint +#define ANSIQ_TXT_ITL";3" // italic +#define ANSIQ_TXT_UNL";4" // underline +#define ANSIQ_TXT_BLK";5" // blinking mode (idk what it does) +#define ANSIQ_TXT_REV";7" // reversed +#define ANSIQ_TXT_HID";8" // hidden/invisible +#define ANSIQ_TXT_STK";9" // strikethrough + +#define ANSIQ_SETTXT_BLD ANSIQ_ESC"["ANSIQ_TXT_BLD"m" +#define ANSIQ_SETTXT_DIM ANSIQ_ESC"["ANSIQ_TXT_DIM"m" +#define ANSIQ_SETTXT_ITL ANSIQ_ESC"["ANSIQ_TXT_ITL"m" +#define ANSIQ_SETTXT_UNL ANSIQ_ESC"["ANSIQ_TXT_UNL"m" +#define ANSIQ_SETTXT_BLK ANSIQ_ESC"["ANSIQ_TXT_BLK"m" +#define ANSIQ_SETTXT_REV ANSIQ_ESC"["ANSIQ_TXT_REV"m" +#define ANSIQ_SETTXT_HID ANSIQ_ESC"["ANSIQ_TXT_HID"m" +#define ANSIQ_SETTXT_STK ANSIQ_ESC"["ANSIQ_TXT_STK"m" + +#define ANSIQ_GR_RESET ANSIQ_ESC "[" "0m" +/* clang-format on */ + +#endif /* ANSIQ_GRAPHICS_H */ diff --git a/libterminal/tscreen.h b/libterminal/tscreen.h new file mode 100644 index 0000000..31a24d0 --- /dev/null +++ b/libterminal/tscreen.h @@ -0,0 +1,17 @@ +#ifndef ANSIQ_SCREEN_H +#define ANSIQ_SCREEN_H +#include + +/* clang-format off */ +#define ANSIQ_SCR_CLR2END ANSIQ_ESC"[0J" // Clear to end of screen +#define ANSIQ_SCR_CLR2BEG ANSIQ_ESC"[1J" // Clear to begining of screen +#define ANSIQ_SCR_CLR_ALL ANSIQ_ESC"[2J" // Clear entire screen +#define ANSIQ_SCR_CLR_SAV ANSIQ_ESC"[3J" // Clear saved lines +#define ANSIQ_SCR_CLR2LEND ANSIQ_ESC"[0K" // Clear to end of line +#define ANSIQ_SCR_CLR2LBEG ANSIQ_ESC"[1K" // Clear to begining of line +#define ANSIQ_SCR_CLR_LINE ANSIQ_ESC"[1K" // Clear entire line +#define ANSIQ_SCR_RESTORE ANSIQ_ESC"[?47l" +#define ANSIQ_SCR_SAVE ANSIQ_ESC"[?47h" +/* clang-format on */ + +#endif /* ANSIQ_SCREEN_H */