//---------------------------------------------------------------------------// // ____ PythonExtra // //.-'`_ o `;__, A community port of MicroPython for CASIO calculators. // //.-'` `---` ' License: MIT (except some files; see LICENSE) // //---------------------------------------------------------------------------// // pe.console: Terminal emulator // // This header implements a basic terminal emulator compatible with // MicroPython's readline() implementation. // // The main features are: // * Dynamically-sized lines with reflow // * Cap memory usage based on the total amount of text, not just line count // * Basic ANSI-escape-based edition features (but only on the last line) //--- #ifndef __PYTHONEXTRA_CONSOLE_H #define __PYTHONEXTRA_CONSOLE_H #include #include /* Maximum line length, to ensure the console can threshold its memory usage while cleaning only entire lines. Lines longer than this get split. */ #define PE_CONSOLE_LINE_MAX_LENGTH 1024 //=== Dynamic console lines ===// typedef struct { /* Line contents, NUL-terminated. The buffer might be larger. */ char *data; /* Size of contents (not counting the NUL). */ int size; /* Allocated size (always ≥ size+1). */ int alloc_size; /* Number or render lines used (updated on-demand). */ int render_lines; } console_line_t; /* Create a new console line with at least init_chars characters of content available. Returns false on error. Previous contents are not freed! */ bool console_line_init(console_line_t *line, int init_chars); /* Clean up a line and free its contents. */ void console_line_deinit(console_line_t *line); /* Realloc the line to ensure n characters plus a NUL can be written. */ bool console_line_alloc(console_line_t *line, int n); /* Determine how many characters can be written before the line has to be broken up. */ int console_line_capacity(console_line_t *line); /* Insert n characters at position p. */ bool console_line_insert(console_line_t *line, int p, char const *str, int n); /* Remove n characters at position p. */ void console_line_delete(console_line_t *line, int p, int n); /* Update the number of render lines for the chosen width. */ void console_line_update_render_lines(console_line_t *line, int width); //=== Terminal emulator ===// typedef struct { /* A dynamic array of console_line_t. Never empty. */ console_line_t *lines; int line_count; /* Maximum (not 100% strict) amount of storage that is conserved in log. When this limit is exceeded, old lines are cleaned. This must be more than PE_CONSOLE_LINE_MAX_LENGTH. */ int backlog_size; /* Cursor position within the last line. */ int cursor; /* Whether new data has been added and a frame should be rendered. */ bool render_needed; } console_t; /* Create a new console with the specified backlog size. */ console_t *console_create(int backlog_size); /* Create a new empty line at the bottom of the console, and move the cursor there. Previous lines can no longer be edited. Returns false on error. */ bool console_new_line(console_t *cons); /* Clean up backlog if the total memory usage is exceeded. */ void console_clean_backlog(console_t *cons); /* Write string at the cursor's position within the last line. This writes a raw string without interpreting escape sequences and newlines. */ bool console_write_block_at_cursor(console_t *cons, char const *str, int n); /* Write string at the cursor's position within the last line. This function interprets escape sequences and newlines. */ bool console_write_at_cursor(console_t *cons, char const *str, int n); /* TODO: Expand this function */ void console_render(int x, int y, console_t const *cons, int w, int dy, int lines); void console_clear_render_flag(console_t *cons); void console_destroy(console_t *cons); //=== Input method ===// /* Interpret a key event into a terminal input. This is a pretty raw input method with no shift/alpha lock, kept for legacy as a VT-100-style terminal emulator. */ int console_key_event_to_char(key_event_t ev); #endif /* __PYTHONEXTRA_CONSOLE_H */