From 55ab8473fa339839e8daf4ffa29d6966f04b6628 Mon Sep 17 00:00:00 2001 From: y4my4my4m <8145020+y4my4my4m@users.noreply.github.com> Date: Wed, 10 May 2023 22:39:04 +0900 Subject: [PATCH] cursor movement stable(r) --- src/Home/Telnet/Telnet.ZC | 250 ++++++++++++++++---------------------- 1 file changed, 102 insertions(+), 148 deletions(-) diff --git a/src/Home/Telnet/Telnet.ZC b/src/Home/Telnet/Telnet.ZC index cf53c564..e0936c25 100755 --- a/src/Home/Telnet/Telnet.ZC +++ b/src/Home/Telnet/Telnet.ZC @@ -6,23 +6,12 @@ #define TIMEOUT_DURATION 5000 #define NEGOTIATE 0xFF -#define IAC 0xFF -#define WILL 0xFB -#define WONT 0xFC -#define DO 0xFD -#define DONT 0xFE -#define ECHO 0x01 -#define SUPPRESS_GO_AHEAD 0x03 -#define TERMINAL_TYPE 0x18 -#define LINEMODE 0x22 -#define NAWS 0x1F // (Negotiate About Window Size) -#define IS 0x00 -#define SB 0xFA -#define SE 0xF0 #define ANSI_ESC 0x1B #define ANSI_CSI 0x5B // [ +#define MAX_ANSI_PARAMS 256 + CTask *input_task = NULL; Bool force_disconnect = FALSE; Bool input_request = FALSE; @@ -31,50 +20,6 @@ U8 IsDigit(U8 ch) { return '0' <= ch <= '9'; } -Bool CursorInWin(CTask *task, I64 x, I64 y) -{ - if ( 0 <= x + task->scroll_x < task->pix_width && - 0 <= y + task->scroll_y < task->pix_height) - return TRUE; - else - return FALSE; -} - -U0 SendWindowSize(I64 sock, U16 rows, U16 cols) { - U8 buf[9]; - - buf[0] = IAC; - buf[1] = SB; - buf[2] = NAWS; - buf[3] = cols >> 8; // High byte of columns - buf[4] = cols & 0xFF; // Low byte of columns - buf[5] = rows >> 8; // High byte of rows - buf[6] = rows & 0xFF; // Low byte of rows - buf[7] = IAC; - buf[8] = SE; - - SysLog("SendWindowSize: %d x %d\n", cols, rows); - TCPSocketSendString(sock, buf); -} - -U0 SendTerminalType(I64 sock, U8 *terminal_type) { - U8 response[256]; - I64 len = StrLen(terminal_type); - - response[0] = IAC; - response[1] = SB; - response[2] = TERMINAL_TYPE; - response[3] = IS; - MemCopy(response + 4, terminal_type, len); - - SysLog("SendTerminalType: %s\n", terminal_type); - - response[len + 4] = IAC; - response[len + 5] = SE; - response[len + 6] = '\0'; - TCPSocketSendString(sock, response); -} - U0 HandleControlCodes(U8 ch) { if (ch < 32) { // ASCII code below 32 (control character) switch (ch) { @@ -173,17 +118,7 @@ U0 InputTask(U0 *args) { break; } else if (ch == CH_BACKSPACE) { - // if (input_len > 0) { - // // Decrease the length of the input - // input_len--; - // // Remove the character from the input buffer - // input_buffer[input_len] = '\0'; - // DocClear; - // DocBottom(input_task->put_doc); - // "\n$$RED$$$BK,1$Input$BK,0$$$BLACK$$:"; - // temp = MStrPrint("%s", input_buffer); - // DocPrint(input_task->put_doc, "%s", temp); - // } + break; } else if (ch == 0x0F) { // TAB? TCPSocketSendString(sock, 0x09); @@ -223,7 +158,7 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) { I64 window_left = (GR_WIDTH - window_width) / 2; I64 window_top = (Fs->win_bottom - Fs->win_top - window_height) / 2; - DocPrint(, "$$WW,1$$"); + // DocPrint(, "$$WW,1$$"); WinHorz(Fs->win_left, Fs->win_left+window_width, Fs); WinVert(Fs->win_top + window_top, Fs->win_top + window_top + window_height, Fs); // DocCursor(OFF); @@ -268,40 +203,35 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) { ptr++; if (*ptr == ANSI_CSI) { ptr++; - I64 ansi_code = 0; - I64 x_code = 1; - I64 y_code = 1; - Bool parsing_y = FALSE; + I64 ansi_code[MAX_ANSI_PARAMS]; + I64 ansi_param_count = 0; while (IsDigit(*ptr) || *ptr == ';') { if (IsDigit(*ptr)) { - ansi_code = ansi_code * 10 + (*ptr - '0'); - SysLog("ANSICODE: %d\n", ansi_code); - if (!parsing_y) { - x_code = x_code * 10 + (*ptr - '0'); - SysLog("row: %d\n", x_code); - } else { - y_code = y_code * 10 + (*ptr - '0'); - SysLog("col: %d\n", y_code); - } + ansi_code[ansi_param_count] = ansi_code[ansi_param_count] * 10 + (*ptr - '0'); ptr++; } else if (*ptr == ';') { - parsing_y = TRUE; - ptr++; - if(!IsDigit(*ptr)) { - break; + ansi_param_count++; + if (ansi_param_count >= MAX_ANSI_PARAMS) { + // Error handling: too many parameters + break; } + ptr++; + if(!IsDigit(*ptr)){ + break; + } + } } // Handle specific ANSI escape sequences switch (*ptr) { case 'n': - if (ansi_code == 5) { + if (ansi_code[0] == 5) { // Respond with terminal readiness SysLog("reported terminal readiness\n"); TCPSocketSendString(sock, "\x1B[0n"); } - else if (ansi_code == 6) { + else if (ansi_code[0] == 6) { // Respond with cursor position // U8 response[32] = "\x1B[%d;%dR", window_width, window_height; SysLog("reported cursor position\n"); @@ -322,92 +252,107 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) { // } else if (y_code >= 40 && y_code <= 47) { // bg_code = y_code - 40; // Set background color // } - if (ansi_code <= 10) { - switch (ansi_code) { - case 0: "$$BG$$$$FG$$"; break; // reset - // case 1: ""; break; // TODO: bold - // case 2: ""; break; // TODO: dim - // case 3: ""; break; // TODO: italic - // case 4: "$$UL,1$$" + string + "$$UL,0$$"; break; // TODO: underline - // case 5: "$$"; break; // TODO: blink - // case 6: ""; break; // TODO: fast blink - // case 7: "$$IV,1$$" + string + "$$IV,0$$"; break; // TODO: invert - // case 8: ""; break; // TODO: hide (rare) - // case 9: ""; break; // TODO: strikethrough - // case 10: ""; break; // TODO: primary font + I64 m; + for (m = 0; m < ansi_param_count; m++) { + if (ansi_code[m] <= 10) { + // switch (ansi_code[m]) { + // case 0: "$$BG$$$$FG$$"; break; // reset + // case 1: ""; break; // TODO: bold + // case 2: ""; break; // TODO: dim + // case 3: ""; break; // TODO: italic + // case 4: "$$UL,1$$" + string + "$$UL,0$$"; break; // TODO: underline + // case 5: "$$"; break; // TODO: blink + // case 6: ""; break; // TODO: fast blink + // case 7: "$$IV,1$$" + string + "$$IV,0$$"; break; // TODO: invert + // case 8: ""; break; // TODO: hide (rare) + // case 9: ""; break; // TODO: strikethrough + // case 10: ""; break; // TODO: primary font + // } + } + else if (ansi_code[m] >= 30 && ansi_code[m] <= 37) { + // Set foreground color + SysLog("ansi_code[%d] = %d\n", m, ansi_code[m]); + switch (ansi_code[m]) { + case 30: "$$BLACK$$"; break; + case 31: "$$RED$$"; break; + case 32: "$$GREEN$$"; break; + case 33: "$$YELLOW$$"; break; + case 34: "$$BLUE$$"; break; + case 35: "$$PURPLE$$"; break; + case 36: "$$CYAN$$"; break; + case 37: "$$WHITE$$"; break; + case 39: "$$FG$$"; break; // reset + default: break; + } + } + // this is a dumb approach, just do a CatPrint or something + // until we properly catch the `;` it will stay fucked + else if (ansi_code[m] >= 40 && ansi_code[m] <= 47) { + // Set background color + SysLog("ansi_code[%d] = %d\n", m, ansi_code[m]); + switch (ansi_code[m]) { + case 40: "$$BG,BLACK$$"; break; + case 41: "$$BG,RED$$"; break; + case 42: "$$BG,GREEN$$"; break; + case 43: "$$BG,YELLOW$$"; break; + case 44: "$$BG,BLUE$$"; break; + case 45: "$$BG,PURPLE$$"; break; + case 46: "$$BG,CYAN$$"; break; + case 47: "$$BG,WHITE$$"; break; + case 49: "$$BG$$"; break; // reset + default: break; + } } - } - switch (x_code) { - case 30: "$$BLACK$$"; break; - case 31: "$$RED$$"; break; - case 32: "$$GREEN$$"; break; - case 33: "$$YELLOW$$"; break; - case 34: "$$BLUE$$"; break; - case 35: "$$PURPLE$$"; break; - case 36: "$$CYAN$$"; break; - case 37: "$$WHITE$$"; break; - case 39: "$$BFG$$"; break; // reset - default: break; - } - // this is a dumb approach, just do a CatPrint or something - // until we properly catch the `;` it will stay fucked - switch (y_code) { - case 40: "$$BG,BLACK$$"; break; - case 41: "$$BG,RED$$"; break; - case 42: "$$BG,GREEN$$"; break; - case 43: "$$BG,YELLOW$$"; break; - case 44: "$$BG,BLUE$$"; break; - case 45: "$$BG,PURPLE$$"; break; - case 46: "$$BG,CYAN$$"; break; - case 47: "$$BG,WHITE$$"; break; - case 49: "$$BG$$"; break; // reset - default: break; } ptr++; break; case 'A': // Cursor Up SysLog("Cursor Up\n"); - "$$CM+TY,0,-%d$$", ansi_code; + // "$$CM+TY,0,-%d$$", ansi_code[0]; + "$$CM,0,-%d$$", ansi_code[0]; ptr++; break; case 'B': // Cursor Down SysLog("Cursor Down\n"); - "$$CM+TY,0,+%d$$", ansi_code; + // "$$CM+TY,0,+%d$$", ansi_code[0]; + "$$CM,0,%d$$", ansi_code[0]; ptr++; break; case 'C': // Cursor Right - SysLog("Cursor Right\n"); - "$$CM+LX,+%d,0$$", ansi_code; + // SysLog("Cursor Right %d %d\n", ansi_param_count, ansi_code[0]); + // "$$CM+LX,+%d,0$$", ansi_code[0]; + "$$CM,%d,0$$", ansi_code[0]; ptr++; break; case 'D': // Cursor Left SysLog("Cursor Left\n"); - "$$CM+TY,-%d,0$$", ansi_code; + // "$$CM+TY,-%d,0$$", ansi_code[0]; + "$$CM,-%d,0$$", ansi_code[0]; ptr++; break; case 'E': // Cursor Next Line SysLog("Cursor Next Line\n"); - "$$CM+TY,0,+%d$$", ansi_code; - "\n"; - break; + // "$$CM+TY,0,+%d$$", ansi_code[0]; + // "\n"; ptr++; + break; case 'F': // Cursor Previous Line SysLog("Cursor Previous Line\n"); - "$$CM+LY,0,-%d$$", ansi_code; - "\n"; + // "$$CM+LY,0,-%d$$", ansi_code[0]; + // "\n"; ptr++; break; case 'G': // Cursor Horizontal Absolute SysLog("Cursor Horizontal Absolute\n"); - "$$CM,%d,0$$", ansi_code; - "\n"; + // "$$CM,%d,0$$", ansi_code[0]; + // "\n"; ptr++; break; case 'H': @@ -415,24 +360,27 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) { I64 row = 1, col = 1; // default values // Parse the row number - row = x_code; - col = y_code; + // if(ansi_code[0] != 0) + // row = ansi_code[0]; + // if(ansi_code[1] != 0) + // col = ansi_code[1]; - SysLog("H or f row:%d, col:%d\n", row, col); + // SysLog("H or f row:%d, col:%d\n", row, col); // "$$CM,%d,%d$$", row, col; - "$$CM,LE=%d,RE=%d$$", col, row; + + // "$$CM,LE=%d,RE=%d$$", col, row; ptr++; break; case 'J': SysLog("J code\n"); // Erase in Display - if (ansi_code == 0) { + if (ansi_code[0] == 0) { // Erase from cursor to end of display // DocDelToNum(Fs->display_doc, Fs->display_doc->cur_entry->line_num); - } else if (ansi_code == 1) { + } else if (ansi_code[0] == 1) { // Erase from cursor to beginning of display // DocDelToEntry(Fs->display_doc, Fs->display_doc->cur_entry, FALSE); - } else if (ansi_code == 2) { + } else if (ansi_code[0] == 2) { // Erase entire display DocClear; } @@ -482,8 +430,8 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) { switch (code) { case 25: - if (*ptr == 'l') SysLog("code 25l\n");// Hide cursor - if (*ptr == 'h') SysLog("code 25h\n");// Show cursor + // if (*ptr == 'l') SysLog("code 25l\n");// Hide cursor + // if (*ptr == 'h') SysLog("code 25h\n");// Show cursor ptr++; // Move past 'l' or 'h' break; case 47: @@ -541,6 +489,12 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) { HandleControlCodes(*ptr); ptr++; } + // Reset ansi_param_count and ansi_code + ansi_param_count = 0; + I64 wtv; + for (wtv = 0; wtv < MAX_ANSI_PARAMS; wtv++) { + ansi_code[wtv] = 0; + } } } else {