cursor movement stable(r)

This commit is contained in:
y4my4my4m 2023-05-10 22:39:04 +09:00
parent c1e8995a69
commit 55ab8473fa

View file

@ -6,23 +6,12 @@
#define TIMEOUT_DURATION 5000 #define TIMEOUT_DURATION 5000
#define NEGOTIATE 0xFF #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_ESC 0x1B
#define ANSI_CSI 0x5B // [ #define ANSI_CSI 0x5B // [
#define MAX_ANSI_PARAMS 256
CTask *input_task = NULL; CTask *input_task = NULL;
Bool force_disconnect = FALSE; Bool force_disconnect = FALSE;
Bool input_request = FALSE; Bool input_request = FALSE;
@ -31,50 +20,6 @@ U8 IsDigit(U8 ch) {
return '0' <= ch <= '9'; 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) { U0 HandleControlCodes(U8 ch) {
if (ch < 32) { // ASCII code below 32 (control character) if (ch < 32) { // ASCII code below 32 (control character)
switch (ch) { switch (ch) {
@ -173,17 +118,7 @@ U0 InputTask(U0 *args) {
break; break;
} }
else if (ch == CH_BACKSPACE) { else if (ch == CH_BACKSPACE) {
// if (input_len > 0) { break;
// // 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);
// }
} }
else if (ch == 0x0F) { // TAB? else if (ch == 0x0F) { // TAB?
TCPSocketSendString(sock, 0x09); 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_left = (GR_WIDTH - window_width) / 2;
I64 window_top = (Fs->win_bottom - Fs->win_top - window_height) / 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); WinHorz(Fs->win_left, Fs->win_left+window_width, Fs);
WinVert(Fs->win_top + window_top, Fs->win_top + window_top + window_height, Fs); WinVert(Fs->win_top + window_top, Fs->win_top + window_top + window_height, Fs);
// DocCursor(OFF); // DocCursor(OFF);
@ -268,40 +203,35 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
ptr++; ptr++;
if (*ptr == ANSI_CSI) { if (*ptr == ANSI_CSI) {
ptr++; ptr++;
I64 ansi_code = 0; I64 ansi_code[MAX_ANSI_PARAMS];
I64 x_code = 1; I64 ansi_param_count = 0;
I64 y_code = 1;
Bool parsing_y = FALSE;
while (IsDigit(*ptr) || *ptr == ';') { while (IsDigit(*ptr) || *ptr == ';') {
if (IsDigit(*ptr)) { if (IsDigit(*ptr)) {
ansi_code = ansi_code * 10 + (*ptr - '0'); ansi_code[ansi_param_count] = ansi_code[ansi_param_count] * 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);
}
ptr++; ptr++;
} }
else if (*ptr == ';') { else if (*ptr == ';') {
parsing_y = TRUE; ansi_param_count++;
if (ansi_param_count >= MAX_ANSI_PARAMS) {
// Error handling: too many parameters
break;
}
ptr++; ptr++;
if(!IsDigit(*ptr)){ if(!IsDigit(*ptr)){
break; break;
} }
} }
}
// Handle specific ANSI escape sequences // Handle specific ANSI escape sequences
switch (*ptr) { switch (*ptr) {
case 'n': case 'n':
if (ansi_code == 5) { if (ansi_code[0] == 5) {
// Respond with terminal readiness // Respond with terminal readiness
SysLog("reported terminal readiness\n"); SysLog("reported terminal readiness\n");
TCPSocketSendString(sock, "\x1B[0n"); TCPSocketSendString(sock, "\x1B[0n");
} }
else if (ansi_code == 6) { else if (ansi_code[0] == 6) {
// Respond with cursor position // Respond with cursor position
// U8 response[32] = "\x1B[%d;%dR", window_width, window_height; // U8 response[32] = "\x1B[%d;%dR", window_width, window_height;
SysLog("reported cursor position\n"); SysLog("reported cursor position\n");
@ -322,9 +252,11 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
// } else if (y_code >= 40 && y_code <= 47) { // } else if (y_code >= 40 && y_code <= 47) {
// bg_code = y_code - 40; // Set background color // bg_code = y_code - 40; // Set background color
// } // }
if (ansi_code <= 10) { I64 m;
switch (ansi_code) { for (m = 0; m < ansi_param_count; m++) {
case 0: "$$BG$$$$FG$$"; break; // reset if (ansi_code[m] <= 10) {
// switch (ansi_code[m]) {
// case 0: "$$BG$$$$FG$$"; break; // reset
// case 1: ""; break; // TODO: bold // case 1: ""; break; // TODO: bold
// case 2: ""; break; // TODO: dim // case 2: ""; break; // TODO: dim
// case 3: ""; break; // TODO: italic // case 3: ""; break; // TODO: italic
@ -335,9 +267,12 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
// case 8: ""; break; // TODO: hide (rare) // case 8: ""; break; // TODO: hide (rare)
// case 9: ""; break; // TODO: strikethrough // case 9: ""; break; // TODO: strikethrough
// case 10: ""; break; // TODO: primary font // case 10: ""; break; // TODO: primary font
// }
} }
} else if (ansi_code[m] >= 30 && ansi_code[m] <= 37) {
switch (x_code) { // Set foreground color
SysLog("ansi_code[%d] = %d\n", m, ansi_code[m]);
switch (ansi_code[m]) {
case 30: "$$BLACK$$"; break; case 30: "$$BLACK$$"; break;
case 31: "$$RED$$"; break; case 31: "$$RED$$"; break;
case 32: "$$GREEN$$"; break; case 32: "$$GREEN$$"; break;
@ -346,12 +281,16 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
case 35: "$$PURPLE$$"; break; case 35: "$$PURPLE$$"; break;
case 36: "$$CYAN$$"; break; case 36: "$$CYAN$$"; break;
case 37: "$$WHITE$$"; break; case 37: "$$WHITE$$"; break;
case 39: "$$BFG$$"; break; // reset case 39: "$$FG$$"; break; // reset
default: break; default: break;
} }
}
// this is a dumb approach, just do a CatPrint or something // this is a dumb approach, just do a CatPrint or something
// until we properly catch the `;` it will stay fucked // until we properly catch the `;` it will stay fucked
switch (y_code) { 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 40: "$$BG,BLACK$$"; break;
case 41: "$$BG,RED$$"; break; case 41: "$$BG,RED$$"; break;
case 42: "$$BG,GREEN$$"; break; case 42: "$$BG,GREEN$$"; break;
@ -363,51 +302,57 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
case 49: "$$BG$$"; break; // reset case 49: "$$BG$$"; break; // reset
default: break; default: break;
} }
}
}
ptr++; ptr++;
break; break;
case 'A': case 'A':
// Cursor Up // Cursor Up
SysLog("Cursor Up\n"); SysLog("Cursor Up\n");
"$$CM+TY,0,-%d$$", ansi_code; // "$$CM+TY,0,-%d$$", ansi_code[0];
"$$CM,0,-%d$$", ansi_code[0];
ptr++; ptr++;
break; break;
case 'B': case 'B':
// Cursor Down // Cursor Down
SysLog("Cursor Down\n"); SysLog("Cursor Down\n");
"$$CM+TY,0,+%d$$", ansi_code; // "$$CM+TY,0,+%d$$", ansi_code[0];
"$$CM,0,%d$$", ansi_code[0];
ptr++; ptr++;
break; break;
case 'C': case 'C':
// Cursor Right // Cursor Right
SysLog("Cursor Right\n"); // SysLog("Cursor Right %d %d\n", ansi_param_count, ansi_code[0]);
"$$CM+LX,+%d,0$$", ansi_code; // "$$CM+LX,+%d,0$$", ansi_code[0];
"$$CM,%d,0$$", ansi_code[0];
ptr++; ptr++;
break; break;
case 'D': case 'D':
// Cursor Left // Cursor Left
SysLog("Cursor Left\n"); SysLog("Cursor Left\n");
"$$CM+TY,-%d,0$$", ansi_code; // "$$CM+TY,-%d,0$$", ansi_code[0];
"$$CM,-%d,0$$", ansi_code[0];
ptr++; ptr++;
break; break;
case 'E': case 'E':
// Cursor Next Line // Cursor Next Line
SysLog("Cursor Next Line\n"); SysLog("Cursor Next Line\n");
"$$CM+TY,0,+%d$$", ansi_code; // "$$CM+TY,0,+%d$$", ansi_code[0];
"\n"; // "\n";
break;
ptr++; ptr++;
break;
case 'F': case 'F':
// Cursor Previous Line // Cursor Previous Line
SysLog("Cursor Previous Line\n"); SysLog("Cursor Previous Line\n");
"$$CM+LY,0,-%d$$", ansi_code; // "$$CM+LY,0,-%d$$", ansi_code[0];
"\n"; // "\n";
ptr++; ptr++;
break; break;
case 'G': case 'G':
// Cursor Horizontal Absolute // Cursor Horizontal Absolute
SysLog("Cursor Horizontal Absolute\n"); SysLog("Cursor Horizontal Absolute\n");
"$$CM,%d,0$$", ansi_code; // "$$CM,%d,0$$", ansi_code[0];
"\n"; // "\n";
ptr++; ptr++;
break; break;
case 'H': case 'H':
@ -415,24 +360,27 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
I64 row = 1, col = 1; // default values I64 row = 1, col = 1; // default values
// Parse the row number // Parse the row number
row = x_code; // if(ansi_code[0] != 0)
col = y_code; // 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,%d,%d$$", row, col;
"$$CM,LE=%d,RE=%d$$", col, row;
// "$$CM,LE=%d,RE=%d$$", col, row;
ptr++; ptr++;
break; break;
case 'J': case 'J':
SysLog("J code\n"); SysLog("J code\n");
// Erase in Display // Erase in Display
if (ansi_code == 0) { if (ansi_code[0] == 0) {
// Erase from cursor to end of display // Erase from cursor to end of display
// DocDelToNum(Fs->display_doc, Fs->display_doc->cur_entry->line_num); // 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 // Erase from cursor to beginning of display
// DocDelToEntry(Fs->display_doc, Fs->display_doc->cur_entry, FALSE); // DocDelToEntry(Fs->display_doc, Fs->display_doc->cur_entry, FALSE);
} else if (ansi_code == 2) { } else if (ansi_code[0] == 2) {
// Erase entire display // Erase entire display
DocClear; DocClear;
} }
@ -482,8 +430,8 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
switch (code) { switch (code) {
case 25: case 25:
if (*ptr == 'l') SysLog("code 25l\n");// Hide cursor // if (*ptr == 'l') SysLog("code 25l\n");// Hide cursor
if (*ptr == 'h') SysLog("code 25h\n");// Show cursor // if (*ptr == 'h') SysLog("code 25h\n");// Show cursor
ptr++; // Move past 'l' or 'h' ptr++; // Move past 'l' or 'h'
break; break;
case 47: case 47:
@ -541,6 +489,12 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
HandleControlCodes(*ptr); HandleControlCodes(*ptr);
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 { } else {