From 04360877619f3b9908c34aa57dcca37a387e1830 Mon Sep 17 00:00:00 2001 From: cowmonk Date: Thu, 23 Jan 2025 08:45:09 -0700 Subject: [PATCH] UTF-8 Fixes, attempt at scrolling, & minor changes Changed some global -> local const vars --- cowterm.c | 89 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 28 deletions(-) diff --git a/cowterm.c b/cowterm.c index 6fae07f..c8df53d 100644 --- a/cowterm.c +++ b/cowterm.c @@ -21,10 +21,10 @@ #include "config.h" // There isn't a need for MAX_ROWS or MAX_COLS, but ¯\_(ツ)_/¯ -#define MAX_ROWS 1000 -#define MAX_COLS 1000 -#define CHAR_WIDTH 8 -#define CHAR_HEIGHT 16 +const int MAX_ROWS = 1000; +const int MAX_COLS = 1000; +const int CHAR_WIDTH = 8; +const int CHAR_HEIGHT = 16; // General window/terminal stuff static pid_t child_pid; @@ -1250,40 +1250,61 @@ static int master_cb(int fd, void *data, Window window) { default: if (cursor_y >= term_rows || cursor_x >= term_cols) break; - if ((buf[i] >= 32 && buf[i] <= 126) || buf[i] == '\t') { + if (buf[i] & 0x80) { // UTF-8 + char mb_buf[MB_CUR_MAX]; + int mb_len = 0; + int j = i; + while (mb_len < (int)MB_CUR_MAX && j < n) { + if (mb_len == 0) { + if ((buf[j] & 0x80) == 0) + break; + mb_buf[mb_len] = buf[j]; + mb_len++; + } else if ((buf[j] & 0xC0) == 0x80) { + mb_buf[mb_len] = buf[j]; + mb_len++; + } else { + break; + } + j++; + } + if (mb_len > 0) { + wchar_t wc; + mbstate_t ps; + memset(&ps, 0, sizeof(ps)); + if (mbrtowc(&wc, mb_buf, mb_len, &ps) > 0) { + terminal_buffer[cursor_y][cursor_x] = wc; + color_buffer[cursor_y][cursor_x] = current_color; + attr_buffer[cursor_y][cursor_x] = current_attr; + bg_color_buffer[cursor_y][cursor_x] = current_bg_color; + needs_refresh = 1; + cursor_x++; + if (cursor_x >= term_cols) { + cursor_x = 0; + cursor_y++; + if (cursor_y >= term_rows) { + scroll_region_up(1); + cursor_y = term_rows - 1; + } + } + } + i += mb_len - 1; + } + } else if (buf[i] >= 32) { terminal_buffer[cursor_y][cursor_x] = buf[i]; color_buffer[cursor_y][cursor_x] = current_color; attr_buffer[cursor_y][cursor_x] = current_attr; bg_color_buffer[cursor_y][cursor_x] = current_bg_color; needs_refresh = 1; - if (++cursor_x >= term_cols) { + cursor_x++; + if (cursor_x >= term_cols) { cursor_x = 0; - if (++cursor_y >= term_rows) { + cursor_y++; + if (cursor_y >= term_rows) { scroll_region_up(1); cursor_y = term_rows - 1; } } - } else if (buf[i] & 0x80) { // UTF-8 - mbstate_t ps; - memset(&ps, 0, sizeof(ps)); - wchar_t wc; - size_t len = mbrtowc(&wc, buf + i, n - i, &ps); - - if (len != (size_t)-1 && len != (size_t)-2 && len != 0) { - terminal_buffer[cursor_y][cursor_x] = wc; - color_buffer[cursor_y][cursor_x] = current_color; - attr_buffer[cursor_y][cursor_x] = current_attr; - bg_color_buffer[cursor_y][cursor_x] = current_bg_color; - needs_refresh = 1; - if (++cursor_x >= term_cols) { - cursor_x = 0; - if (++cursor_y >= term_rows) { - scroll_region_up(1); - cursor_y = term_rows - 1; - } - } - i += len - 1; // -1 because loop will increment i - } } break; } @@ -1328,6 +1349,18 @@ static void key_press_cb(XKeyEvent *event, void *data) { return; } + if (event->state & ShiftMask) { + if (keysym == XK_Page_Up) { + scroll_region_up(term_rows / 2); + needs_refresh = 1; + return; + } else if (keysym == XK_Page_Down) { + scroll_region_down(term_rows / 2); + needs_refresh = 1; + return; + } + } + if (keysym == XK_Return || keysym == XK_KP_Enter) { write(*master, "\r", 1); // Shell handles return } else if (keysym == XK_BackSpace) {