diff --git a/PROTOCOL.md b/PROTOCOL.md index ab792984..1770c79d 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -444,10 +444,14 @@ context, and refresh the terminal fully. In order to achieve this, special values for the `length` argument are passed. These values are: ```c +/* Response revision 0 */ #define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) #define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) #define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) #define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) +/* Response revision 1 */ +#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) ``` For `CTX_SIZE`, the `ptr` variable has to point to a location to which the @@ -464,6 +468,25 @@ For `FULL_REFRESH`, the `ptr` variable is unused. This routine is to be used after control of the framebuffer is taken over and the bootloader's terminal has to *fully* repaint the framebuffer to avoid inconsistencies. +If the response revision is equal or greater than 1 +`OOB_OUTPUT_GET` and `OOB_OUTPUT_SET` allow getting and setting the +out-of-band terminal output settings. `ptr` points to a location to where +the terminal will *write* or *read* a single `uint64_t` value containing the +bits representing the settings. +The possible settings are as follows: +```c +#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) +#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) +#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) +``` +The effect of each of these options matches the effect of the `stty(1)` +options by the same name. + #### x86_64 Additionally, the kernel must ensure, when calling `write()`, that: diff --git a/common/lib/term.c b/common/lib/term.c index 0034cebc..66a23f3f 100644 --- a/common/lib/term.c +++ b/common/lib/term.c @@ -320,6 +320,14 @@ static void context_restore(struct term_context *term, uint64_t buf) { void _term_write(struct term_context *term, uint64_t buf, uint64_t count) { switch (count) { + case TERM_OOB_OUTPUT_GET: { + memcpy32to64(buf, (uint64_t)(uintptr_t)&term->oob_output, sizeof(uint64_t)); + return; + } + case TERM_OOB_OUTPUT_SET: { + memcpy32to64((uint64_t)(uintptr_t)&term->oob_output, buf, sizeof(uint64_t)); + return; + } case TERM_CTX_SIZE: { uint64_t ret = context_size(term); memcpy32to64(buf, (uint64_t)(uintptr_t)&ret, sizeof(uint64_t)); diff --git a/common/lib/term.h b/common/lib/term.h index 47812fb7..d0cbd5b4 100644 --- a/common/lib/term.h +++ b/common/lib/term.h @@ -26,6 +26,8 @@ extern int term_backend; #define TERM_CTX_SAVE ((uint64_t)(-2)) #define TERM_CTX_RESTORE ((uint64_t)(-3)) #define TERM_FULL_REFRESH ((uint64_t)(-4)) +#define TERM_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define TERM_OOB_OUTPUT_SET ((uint64_t)(-11)) #define FOR_TERM(...) do { \ for (size_t FOR_TERM_i = 0; FOR_TERM_i < terms_i; FOR_TERM_i++) { \ diff --git a/common/protos/limine.c b/common/protos/limine.c index d65005af..1163cfa7 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -689,6 +689,8 @@ FEAT_START struct limine_terminal_response *terminal_response = ext_mem_alloc(sizeof(struct limine_terminal_response)); + terminal_response->revision = 1; + struct limine_terminal *terminal = ext_mem_alloc(sizeof(struct limine_terminal)); quiet = false; diff --git a/limine.h b/limine.h index 62f78616..365de87e 100644 --- a/limine.h +++ b/limine.h @@ -143,7 +143,7 @@ struct limine_framebuffer { uint8_t unused[7]; uint64_t edid_size; LIMINE_PTR(void *) edid; - /* Revision 1 */ + /* Response revision 1 */ uint64_t mode_count; LIMINE_PTR(struct limine_video_mode **) modes; }; @@ -178,6 +178,19 @@ struct limine_framebuffer_request { #define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) #define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) +/* Response revision 1 */ +#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) + +#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) +#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) +#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) + struct limine_terminal; typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t);