From d2b8a0e380c96ae3b6c7d5989ec2f462679685d9 Mon Sep 17 00:00:00 2001 From: Zihao Yu Date: Thu, 11 Jan 2024 00:20:29 +0800 Subject: [PATCH] uart: merge rx terminal into tx terminal * RX should send each key directly, instead of providing cook mode --- include/term.h | 3 +++ include/uart.h | 8 +++---- src/event.cpp | 22 +++++++++---------- src/term.cpp | 11 +++++++++- src/uart.cpp | 58 ++++++++++++++------------------------------------ 5 files changed, 43 insertions(+), 59 deletions(-) diff --git a/include/term.h b/include/term.h index 38f08cc..3d09f55 100644 --- a/include/term.h +++ b/include/term.h @@ -9,7 +9,9 @@ private: std::vector lines; int cursor_x, cursor_y; // cursor_y start with all history when scrolling is supported bool is_cursor_visible; + bool is_focus; SDL_Texture *cursor_texture; + SDL_Texture *get_focus_cursor_texture; int screen_y; bool dirty_screen; bool *dirty_line; @@ -32,6 +34,7 @@ public: void feed_str(const char *s); void clear(); void set_cursor_visibility(bool v); + void set_focus(bool v); void update_gui(); }; diff --git a/include/uart.h b/include/uart.h index a77353f..e3a758c 100644 --- a/include/uart.h +++ b/include/uart.h @@ -7,14 +7,12 @@ class UART : public Component{ private: - Term *tx_term, *rx_term; + Term *term; int tx_state, rx_state; uint16_t divisor; uint8_t tx_data, rx_data; - std::string rx_input; std::string rx_sending_str; - static constexpr const char *rx_input_prompt = "(Press Enter to issue): "; - bool tx_update_gui, rx_update_gui; + bool need_update_gui; uint8_t *p_tx; public: UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h); @@ -26,7 +24,7 @@ public: void tx_receive(); void rx_send(); void rx_getchar(uint8_t ch); - void rx_term_focus(bool v); + void term_focus(bool v); }; #endif diff --git a/src/event.cpp b/src/event.cpp index 9e1197a..ada0b73 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -4,28 +4,28 @@ extern std::vector components; void uart_rx_getchar(uint8_t ch); -void uart_rx_term_focus(bool v); +void uart_term_focus(bool v); void kb_push_key(uint8_t scancode, bool is_keydown); -static bool focus_uart_rx_term = false; +static bool uart_term_get_focus = false; static void mousedown_handler(const SDL_Event &ev) { int x_pos = ev.button.x; int y_pos = ev.button.y; - bool click_uart_rx_term = false; + bool click_uart_term = false; for (auto i : components) { if (i->in_rect(x_pos, y_pos)) { switch (i->get_component_type()) { case BUTTON_TYPE: pin_poke(i->get_pin(), 1); break; case SWITCH_TYPE: pin_poke(i->get_pin(), i->get_state() ^ 1); break; - case UART_TYPE: click_uart_rx_term = true; break; + case UART_TYPE: click_uart_term = true; break; } } } - if (focus_uart_rx_term ^ click_uart_rx_term) { - if (click_uart_rx_term) SDL_StartTextInput(); + if (uart_term_get_focus ^ click_uart_term) { + if (click_uart_term) SDL_StartTextInput(); else SDL_StopTextInput(); - focus_uart_rx_term = click_uart_rx_term; - uart_rx_term_focus(focus_uart_rx_term); + uart_term_get_focus = click_uart_term; + uart_term_focus(uart_term_get_focus); } } @@ -52,15 +52,15 @@ void read_event() { case SDL_MOUSEBUTTONDOWN: mousedown_handler(ev); break; case SDL_MOUSEBUTTONUP: mouseup_handler(ev); break; case SDL_KEYDOWN: - if (focus_uart_rx_term) { + if (uart_term_get_focus) { switch (ev.key.keysym.sym) { case SDLK_RETURN: uart_rx_getchar('\n'); break; case SDLK_BACKSPACE: uart_rx_getchar('\b'); break; } } case SDL_KEYUP: - if (!focus_uart_rx_term) kb_push_key(ev.key.keysym.scancode, ev.key.type == SDL_KEYDOWN); + if (!uart_term_get_focus) kb_push_key(ev.key.keysym.scancode, ev.key.type == SDL_KEYDOWN); break; - case SDL_TEXTINPUT: if (focus_uart_rx_term) uart_rx_getchar(ev.text.text[0]); break; + case SDL_TEXTINPUT: if (uart_term_get_focus) uart_rx_getchar(ev.text.text[0]); break; } } diff --git a/src/term.cpp b/src/term.cpp index b7fb776..38704de 100644 --- a/src/term.cpp +++ b/src/term.cpp @@ -8,7 +8,9 @@ Term::Term(SDL_Renderer *r, int x, int y, int w, int h): h_in_char = region.h / CH_HEIGHT; uint8_t *l = add_line(); cursor_texture = new_texture(r, CH_WIDTH, CH_HEIGHT, 0x10, 0x10, 0x10); + get_focus_cursor_texture = new_texture(r, CH_WIDTH, CH_HEIGHT, 0xff, 0x00, 0xff); is_cursor_visible = true; + is_focus = false; clear_screen(); dirty_line = new bool[h_in_char]; dirty_char = new bool[w_in_char * h_in_char]; @@ -35,6 +37,12 @@ void Term::set_cursor_visibility(bool v) { if (update_cursor_gui) draw_cursor(); } +void Term::set_focus(bool v) { + bool update_cursor_gui = is_focus ^ v; + is_focus = v; + if (update_cursor_gui) draw_cursor(); +} + void Term::clear() { while (lines.size() > 1) { delete [] lines.back(); @@ -123,7 +131,8 @@ void Term::draw_cursor() { rect.w = CH_WIDTH, rect.h = CH_HEIGHT; rect.y += CH_HEIGHT * y; rect.x += CH_WIDTH * x; - SDL_Texture *t = is_cursor_visible ? cursor_texture : ch2texture_term(' '); + SDL_Texture *t = is_cursor_visible ? (is_focus ? get_focus_cursor_texture : + cursor_texture) : ch2texture_term(' '); SDL_RenderCopy(renderer, t, NULL, &rect); set_redraw(); } diff --git a/src/uart.cpp b/src/uart.cpp index e468381..9f86e60 100644 --- a/src/uart.cpp +++ b/src/uart.cpp @@ -8,15 +8,13 @@ static UART* uart = NULL; int16_t uart_divisor_cnt = 0; bool is_uart_rx_idle = true; - UART::UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h): Component(rend, cnt, init_val, ct), - tx_state(0), rx_state(0), divisor(16), tx_update_gui(false) { - tx_term = new Term(rend, x, y, w, h); - rx_term = new Term(rend, x, y + h + 1, w, CH_HEIGHT); + tx_state(0), rx_state(0), divisor(16), need_update_gui(false) { + term = new Term(rend, x, y, w, h); - SDL_Rect *rect_ptr = new SDL_Rect; // rx terminal - *rect_ptr = (SDL_Rect){x, y + h + 1, w, CH_HEIGHT}; + SDL_Rect *rect_ptr = new SDL_Rect; + *rect_ptr = (SDL_Rect){x, y, w, h}; set_rect(rect_ptr, 0); uart_divisor_cnt = divisor - 1; @@ -24,17 +22,11 @@ UART::UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int assert(len == 0 || len == 1); // either unbound or bound to 1 bit signal p_tx = (uint8_t *)pin_array[UART_TX].ptr; - rx_term->feed_str(rx_input_prompt); - rx_term->set_cursor_visibility(false); - rx_input = ""; - rx_sending_str = ""; - SDL_SetRenderDrawColor(rend, 0x00, 0x00, 0x00, 0); SDL_RenderDrawLine(rend, x, y + h, x + w, y + h); - SDL_RenderDrawLine(rend, x, y + h + 1 + CH_HEIGHT, x + w, y + h + 1 + CH_HEIGHT); SDL_SetRenderDrawColor(rend, 0xff, 0xff, 0xff, 0); - rx_update_gui = true; + rx_sending_str = ""; pin_poke(UART_RX, 1); } @@ -60,8 +52,8 @@ void UART::tx_receive() { } else if (tx_state == 9) { if (tx) { // stop bit tx_state = 0; - tx_term->feed_ch(tx_data); - tx_update_gui = true; + term->feed_ch(tx_data); + need_update_gui = true; } } } @@ -88,46 +80,28 @@ void UART::rx_send() { } void UART::rx_getchar(uint8_t ch) { - if (ch == '\b') { - if (rx_input.empty()) return; - rx_input.pop_back(); - rx_term->backspace(true); - } else { - rx_input += ch; - if (ch == '\n') { - rx_sending_str += rx_input; - is_uart_rx_idle = false; - rx_term->clear(); - rx_term->feed_str(rx_input_prompt); - rx_input = ""; - } - else { rx_term->feed_ch(ch); } - } - rx_update_gui = true; + rx_sending_str += ch; + is_uart_rx_idle = false; } void UART::update_state() { - if (tx_update_gui) { + if (need_update_gui) { static uint64_t last = 0; uint64_t now = nvboard_get_time(); if (now - last > 1000000 / UART_TX_FPS) { last = now; - tx_update_gui = false; - tx_term->update_gui(); + need_update_gui = false; + term->update_gui(); } } - if (rx_update_gui) { - rx_update_gui = false; - rx_term->update_gui(); - } } void UART::set_divisor(uint16_t d) { divisor = d; } -void UART::rx_term_focus(bool v) { - rx_term->set_cursor_visibility(v); +void UART::term_focus(bool v) { + term->set_focus(v); } static void init_render_local(SDL_Renderer *renderer) { @@ -173,6 +147,6 @@ void uart_rx_getchar(uint8_t ch) { uart->rx_getchar(ch); } -void uart_rx_term_focus(bool v) { - uart->rx_term_focus(v); +void uart_term_focus(bool v) { + uart->term_focus(v); }