mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-25 23:10:32 +00:00
cursor movement stable(r)
This commit is contained in:
parent
c1e8995a69
commit
55ab8473fa
1 changed files with 102 additions and 148 deletions
|
@ -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++;
|
||||||
ptr++;
|
if (ansi_param_count >= MAX_ANSI_PARAMS) {
|
||||||
if(!IsDigit(*ptr)) {
|
// Error handling: too many parameters
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ptr++;
|
||||||
|
if(!IsDigit(*ptr)){
|
||||||
|
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,92 +252,107 @@ 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) {
|
||||||
// case 1: ""; break; // TODO: bold
|
// switch (ansi_code[m]) {
|
||||||
// case 2: ""; break; // TODO: dim
|
// case 0: "$$BG$$$$FG$$"; break; // reset
|
||||||
// case 3: ""; break; // TODO: italic
|
// case 1: ""; break; // TODO: bold
|
||||||
// case 4: "$$UL,1$$" + string + "$$UL,0$$"; break; // TODO: underline
|
// case 2: ""; break; // TODO: dim
|
||||||
// case 5: "$$"; break; // TODO: blink
|
// case 3: ""; break; // TODO: italic
|
||||||
// case 6: ""; break; // TODO: fast blink
|
// case 4: "$$UL,1$$" + string + "$$UL,0$$"; break; // TODO: underline
|
||||||
// case 7: "$$IV,1$$" + string + "$$IV,0$$"; break; // TODO: invert
|
// case 5: "$$"; break; // TODO: blink
|
||||||
// case 8: ""; break; // TODO: hide (rare)
|
// case 6: ""; break; // TODO: fast blink
|
||||||
// case 9: ""; break; // TODO: strikethrough
|
// case 7: "$$IV,1$$" + string + "$$IV,0$$"; break; // TODO: invert
|
||||||
// case 10: ""; break; // TODO: primary font
|
// 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++;
|
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 {
|
||||||
|
|
Loading…
Reference in a new issue