| 27 |
#define _POSIX_C_SOURCE 200809L |
#define _POSIX_C_SOURCE 200809L |
| 28 |
#include <string.h> |
#include <string.h> |
| 29 |
|
|
| 30 |
|
#define EDITOR_ESC_DISPLAY_STR "\033[32m*\033[m" |
| 31 |
|
|
| 32 |
EDITOR_DATA *editor_data_load(const char *p_data) |
EDITOR_DATA *editor_data_load(const char *p_data) |
| 33 |
{ |
{ |
| 34 |
EDITOR_DATA *p_editor_data; |
EDITOR_DATA *p_editor_data; |
| 35 |
char *p_data_line = NULL; |
char *p_data_line = NULL; |
| 36 |
long line_offsets[MAX_EDITOR_DATA_LINES]; |
long line_offsets[MAX_EDITOR_DATA_LINES]; |
| 37 |
long current_data_line_length = 0; |
long current_data_line_length = 0; |
| 38 |
long i, j; |
long i; |
| 39 |
|
|
| 40 |
if (p_data == NULL) |
if (p_data == NULL) |
| 41 |
{ |
{ |
| 50 |
return NULL; |
return NULL; |
| 51 |
} |
} |
| 52 |
|
|
|
p_editor_data->data_line_total = 0; |
|
| 53 |
p_editor_data->display_line_total = split_data_lines(p_data, SCREEN_COLS, line_offsets, MAX_EDITOR_DATA_LINES); |
p_editor_data->display_line_total = split_data_lines(p_data, SCREEN_COLS, line_offsets, MAX_EDITOR_DATA_LINES); |
| 54 |
|
|
| 55 |
for (i = 0; i < p_editor_data->display_line_total; i++) |
for (i = 0; i < p_editor_data->display_line_total; i++) |
| 60 |
current_data_line_length + p_editor_data->display_line_lengths[i] + 1 > MAX_EDITOR_DATA_LINE_LENGTH || |
current_data_line_length + p_editor_data->display_line_lengths[i] + 1 > MAX_EDITOR_DATA_LINE_LENGTH || |
| 61 |
(p_editor_data->display_line_lengths[i - 1] > 0 && p_data[line_offsets[i - 1] + p_editor_data->display_line_lengths[i - 1] - 1] == '\n')) |
(p_editor_data->display_line_lengths[i - 1] > 0 && p_data[line_offsets[i - 1] + p_editor_data->display_line_lengths[i - 1] - 1] == '\n')) |
| 62 |
{ |
{ |
|
if (p_editor_data->data_line_total >= MAX_EDITOR_DATA_LINES) |
|
|
{ |
|
|
log_error("Append line error, data_line_total(%ld) reach limit(%d)\n", p_editor_data->data_line_total, MAX_EDITOR_DATA_LINES); |
|
|
return NULL; |
|
|
} |
|
|
|
|
| 63 |
// Allocate new data line |
// Allocate new data line |
| 64 |
p_data_line = malloc(MAX_EDITOR_DATA_LINE_LENGTH); |
p_data_line = malloc(MAX_EDITOR_DATA_LINE_LENGTH); |
| 65 |
if (p_data_line == NULL) |
if (p_data_line == NULL) |
| 66 |
{ |
{ |
| 67 |
log_error("malloc(MAX_EDITOR_DATA_LINE_LENGTH * %d) error: OOM\n", i); |
log_error("malloc(MAX_EDITOR_DATA_LINE_LENGTH * %d) error: OOM\n", i); |
| 68 |
// Cleanup |
// Cleanup |
| 69 |
for (j = p_editor_data->data_line_total - 1; j >= 0; j--) |
editor_data_cleanup(p_editor_data); |
|
{ |
|
|
free(p_editor_data->p_data_lines[j]); |
|
|
} |
|
|
free(p_editor_data); |
|
| 70 |
return NULL; |
return NULL; |
| 71 |
} |
} |
|
p_editor_data->p_data_lines[p_editor_data->data_line_total] = p_data_line; |
|
|
(p_editor_data->data_line_total)++; |
|
| 72 |
|
|
| 73 |
p_editor_data->p_display_lines[i] = p_data_line; |
p_editor_data->p_display_lines[i] = p_data_line; |
| 74 |
current_data_line_length = 0; |
current_data_line_length = 0; |
| 83 |
p_data_line[current_data_line_length] = '\0'; |
p_data_line[current_data_line_length] = '\0'; |
| 84 |
} |
} |
| 85 |
|
|
|
bzero(p_editor_data->p_data_lines + p_editor_data->data_line_total, MAX_EDITOR_DATA_LINES - (size_t)p_editor_data->data_line_total); |
|
| 86 |
bzero(p_editor_data->p_display_lines + p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES - (size_t)p_editor_data->display_line_total); |
bzero(p_editor_data->p_display_lines + p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES - (size_t)p_editor_data->display_line_total); |
| 87 |
|
|
| 88 |
return p_editor_data; |
return p_editor_data; |
| 119 |
|
|
| 120 |
void editor_data_cleanup(EDITOR_DATA *p_editor_data) |
void editor_data_cleanup(EDITOR_DATA *p_editor_data) |
| 121 |
{ |
{ |
| 122 |
|
char *p_data_line = NULL; |
| 123 |
long i; |
long i; |
| 124 |
|
|
| 125 |
if (p_editor_data == NULL) |
if (p_editor_data == NULL) |
| 127 |
return; |
return; |
| 128 |
} |
} |
| 129 |
|
|
| 130 |
for (i = p_editor_data->data_line_total - 1; i >= 0; i--) |
for (i = 0; i < p_editor_data->display_line_total; i++) |
| 131 |
|
{ |
| 132 |
|
if (p_data_line == NULL) |
| 133 |
|
{ |
| 134 |
|
p_data_line = p_editor_data->p_display_lines[i]; |
| 135 |
|
} |
| 136 |
|
|
| 137 |
|
if (p_editor_data->display_line_lengths[i] > 0 && |
| 138 |
|
p_editor_data->p_display_lines[i][p_editor_data->display_line_lengths[i] - 1] == '\n') |
| 139 |
|
{ |
| 140 |
|
free(p_data_line); |
| 141 |
|
p_data_line = NULL; |
| 142 |
|
} |
| 143 |
|
} |
| 144 |
|
|
| 145 |
|
if (p_data_line != NULL) |
| 146 |
{ |
{ |
| 147 |
free(p_editor_data->p_data_lines[i]); |
free(p_data_line); |
|
p_editor_data->p_data_lines[i] = NULL; |
|
| 148 |
} |
} |
| 149 |
|
|
| 150 |
free(p_editor_data); |
free(p_editor_data); |
| 213 |
// Split current data line if over-length |
// Split current data line if over-length |
| 214 |
if (len_data_line + str_len + 1 > MAX_EDITOR_DATA_LINE_LENGTH || str[0] == CR) |
if (len_data_line + str_len + 1 > MAX_EDITOR_DATA_LINE_LENGTH || str[0] == CR) |
| 215 |
{ |
{ |
| 216 |
if (p_editor_data->display_line_total >= MAX_EDITOR_DATA_LINES || p_editor_data->data_line_total >= MAX_EDITOR_DATA_LINES) |
if (p_editor_data->display_line_total >= MAX_EDITOR_DATA_LINES) |
| 217 |
{ |
{ |
| 218 |
log_error("Split line error, display_line_total(%ld) or data_line_total(%ld) reach limit(%d)\n", |
log_error("Split line error, display_line_total(%ld) reach limit(%d)\n", |
| 219 |
p_editor_data->display_line_total, p_editor_data->data_line_total, MAX_EDITOR_DATA_LINES); |
p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES); |
| 220 |
return -2; |
return -2; |
| 221 |
} |
} |
| 222 |
|
|
| 227 |
log_error("malloc(MAX_EDITOR_DATA_LINE_LENGTH) error: OOM\n"); |
log_error("malloc(MAX_EDITOR_DATA_LINE_LENGTH) error: OOM\n"); |
| 228 |
return -2; |
return -2; |
| 229 |
} |
} |
|
p_editor_data->p_data_lines[p_editor_data->data_line_total] = p_data_line; |
|
|
(p_editor_data->data_line_total)++; |
|
| 230 |
|
|
| 231 |
if (offset_data_line + str_len + 1 >= MAX_EDITOR_DATA_LINE_LENGTH || str[0] == CR) |
if (offset_data_line + str_len + 1 >= MAX_EDITOR_DATA_LINE_LENGTH || str[0] == CR) |
| 232 |
{ |
{ |
| 332 |
|
|
| 333 |
*p_last_updated_line = MAX(display_line + MIN(i, split_line_total - 1), *p_last_updated_line); |
*p_last_updated_line = MAX(display_line + MIN(i, split_line_total - 1), *p_last_updated_line); |
| 334 |
|
|
| 335 |
if (*p_offset > p_editor_data->display_line_lengths[*p_display_line] || |
if (*p_offset >= p_editor_data->display_line_lengths[*p_display_line]) |
|
(*p_offset > 0 && *p_offset == p_editor_data->display_line_lengths[*p_display_line] && |
|
|
p_editor_data->p_display_lines[*p_display_line][*p_offset - 1] == '\n')) |
|
| 336 |
{ |
{ |
| 337 |
*p_offset -= p_editor_data->display_line_lengths[*p_display_line]; |
*p_offset -= p_editor_data->display_line_lengths[*p_display_line]; |
| 338 |
(*p_display_line)++; |
(*p_display_line)++; |
| 428 |
{ |
{ |
| 429 |
if (display_line + 1 >= p_editor_data->display_line_total) // No additional display line (data line) |
if (display_line + 1 >= p_editor_data->display_line_total) // No additional display line (data line) |
| 430 |
{ |
{ |
|
log_common("Debug: No additional display line: %ld + 1 >= %ld\n", display_line, p_editor_data->display_line_total); |
|
| 431 |
return 0; |
return 0; |
| 432 |
} |
} |
| 433 |
|
|
| 447 |
|
|
| 448 |
if (offset_data_line + len_data_line + 1 > MAX_EDITOR_DATA_LINE_LENGTH) // No enough buffer to merge current data line with next data line |
if (offset_data_line + len_data_line + 1 > MAX_EDITOR_DATA_LINE_LENGTH) // No enough buffer to merge current data line with next data line |
| 449 |
{ |
{ |
|
log_common("Debug: No enough buffer to merge with next data line: %ld > %ld\n", |
|
|
offset_data_line + len_data_line + 1, MAX_EDITOR_DATA_LINE_LENGTH); |
|
| 450 |
return 0; |
return 0; |
| 451 |
} |
} |
| 452 |
|
|
| 455 |
p_data_line[offset_data_line + len_data_line] = '\0'; |
p_data_line[offset_data_line + len_data_line] = '\0'; |
| 456 |
|
|
| 457 |
// Recycle next data line |
// Recycle next data line |
| 458 |
// TODO: free(p_editor_data->p_display_lines[display_line + 1]); |
free(p_editor_data->p_display_lines[display_line + 1]); |
| 459 |
} |
} |
| 460 |
else |
else |
| 461 |
{ |
{ |
| 528 |
char input_str[4]; |
char input_str[4]; |
| 529 |
int str_len = 0; |
int str_len = 0; |
| 530 |
int input_ok; |
int input_ok; |
|
int screen_current_row; |
|
| 531 |
const int screen_begin_row = 1; |
const int screen_begin_row = 1; |
| 532 |
int screen_end_row = SCREEN_ROWS - 1; |
const int screen_row_total = SCREEN_ROWS - screen_begin_row; |
| 533 |
const int screen_row_total = screen_end_row - screen_begin_row + 1; |
int output_current_row = screen_begin_row; |
| 534 |
|
int output_end_row = SCREEN_ROWS - 1; |
| 535 |
long int line_current = 0; |
long int line_current = 0; |
| 536 |
long int len; |
long int len; |
| 537 |
int loop; |
int loop; |
| 542 |
int scroll_rows; |
int scroll_rows; |
| 543 |
long last_updated_line = 0; |
long last_updated_line = 0; |
| 544 |
int key_insert = 1; |
int key_insert = 1; |
| 545 |
int i; |
int i, j; |
| 546 |
|
char *p_str; |
| 547 |
|
|
| 548 |
screen_current_row = screen_begin_row; |
clrline(output_current_row, SCREEN_ROWS); |
|
clrline(screen_begin_row, SCREEN_ROWS); |
|
| 549 |
|
|
| 550 |
// update msg_ext with extended key handler |
// update msg_ext with extended key handler |
| 551 |
if (editor_display_key_handler(&ch, &ctx) != 0) |
if (editor_display_key_handler(&ch, &ctx) != 0) |
| 556 |
loop = 1; |
loop = 1; |
| 557 |
while (!SYS_server_exit && loop) |
while (!SYS_server_exit && loop) |
| 558 |
{ |
{ |
| 559 |
if (line_current >= p_editor_data->display_line_total || screen_current_row > screen_end_row) |
if (line_current >= p_editor_data->display_line_total || output_current_row > output_end_row) |
| 560 |
{ |
{ |
| 561 |
ctx.line_cursor = line_current - screen_current_row + row_pos + 1; |
ctx.line_cursor = line_current - output_current_row + row_pos + 1; |
| 562 |
|
|
| 563 |
snprintf(buffer, sizeof(buffer), |
snprintf(buffer, sizeof(buffer), |
| 564 |
"\033[1;44;33m[\033[32m%ld\033[33m;\033[32m%ld\033[33m] " |
"\033[1;44;33m[\033[32m%ld\033[33m;\033[32m%ld\033[33m] " |
| 605 |
str_len = 0; |
str_len = 0; |
| 606 |
} |
} |
| 607 |
|
|
| 608 |
if ((ch >= 32 && ch < 127) || (ch > 127 && ch <= 255 && str_len == 2) || ch == CR) // printable character or GBK |
if ((ch >= 32 && ch < 127) || (ch > 127 && ch <= 255 && str_len == 2) || // Printable character or GBK |
| 609 |
|
ch == CR || ch == KEY_ESC) // Special character |
| 610 |
{ |
{ |
| 611 |
if (str_len == 0) |
if (str_len == 0) |
| 612 |
{ |
{ |
| 615 |
} |
} |
| 616 |
|
|
| 617 |
last_updated_line = line_current; |
last_updated_line = line_current; |
| 618 |
display_line_in = line_current - screen_current_row + row_pos; |
display_line_in = line_current - output_current_row + row_pos; |
| 619 |
offset_in = col_pos - 1; |
offset_in = col_pos - 1; |
| 620 |
display_line_out = display_line_in; |
display_line_out = display_line_in; |
| 621 |
offset_out = offset_in; |
offset_out = offset_in; |
| 632 |
if (editor_data_insert(p_editor_data, &display_line_out, &offset_out, |
if (editor_data_insert(p_editor_data, &display_line_out, &offset_out, |
| 633 |
input_str, str_len, &last_updated_line) < 0) |
input_str, str_len, &last_updated_line) < 0) |
| 634 |
{ |
{ |
| 635 |
log_error("editor_data_insert(%s) error\n", input_str); |
log_error("editor_data_insert(str_len=%d) error\n", str_len); |
| 636 |
str_len = 0; |
str_len = 0; |
| 637 |
} |
} |
| 638 |
else |
else |
| 639 |
{ |
{ |
| 640 |
str_len = 0; |
str_len = 0; |
| 641 |
|
|
| 642 |
screen_end_row = MIN(SCREEN_ROWS - 1, screen_current_row + (int)(last_updated_line - line_current)); |
output_end_row = MIN(SCREEN_ROWS - 1, output_current_row + (int)(last_updated_line - line_current)); |
| 643 |
line_current -= (screen_current_row - row_pos); |
line_current -= (output_current_row - row_pos); |
| 644 |
screen_current_row = (int)row_pos; |
output_current_row = (int)row_pos; |
| 645 |
|
|
| 646 |
scroll_rows = MAX(0, (int)(display_line_out - display_line_in) - (screen_end_row - screen_current_row)); |
scroll_rows = MAX(0, (int)(display_line_out - display_line_in) - (output_end_row - output_current_row)); |
| 647 |
|
|
| 648 |
if (scroll_rows > 0) |
if (scroll_rows > 0) |
| 649 |
{ |
{ |
| 654 |
prints("\033[S"); // Scroll up 1 line |
prints("\033[S"); // Scroll up 1 line |
| 655 |
} |
} |
| 656 |
|
|
| 657 |
screen_current_row -= scroll_rows; |
output_current_row -= scroll_rows; |
| 658 |
if (screen_current_row < screen_begin_row) |
if (output_current_row < screen_begin_row) |
| 659 |
{ |
{ |
| 660 |
line_current += (screen_begin_row - screen_current_row); |
line_current += (screen_begin_row - output_current_row); |
| 661 |
screen_current_row = screen_begin_row; |
output_current_row = screen_begin_row; |
| 662 |
} |
} |
| 663 |
row_pos = screen_end_row; |
row_pos = output_end_row; |
| 664 |
} |
} |
| 665 |
else // if (scroll_lines == 0) |
else // if (scroll_lines == 0) |
| 666 |
{ |
{ |
| 667 |
row_pos += (display_line_out - display_line_in); |
row_pos += (display_line_out - display_line_in); |
| 668 |
} |
} |
| 669 |
col_pos = offset_out + 1; |
col_pos = offset_out + 1; |
|
|
|
|
continue; |
|
| 670 |
} |
} |
| 671 |
|
|
| 672 |
|
continue; |
| 673 |
} |
} |
| 674 |
else if (ch == KEY_DEL || ch == BACKSPACE) // Del |
else if (ch == KEY_DEL || ch == BACKSPACE) // Del |
| 675 |
{ |
{ |
| 676 |
if (ch == BACKSPACE) |
if (ch == BACKSPACE) |
| 677 |
{ |
{ |
| 678 |
col_pos--; |
col_pos--; |
| 679 |
if (col_pos < 1 && line_current - screen_current_row + row_pos >= 0) |
if (col_pos < 1 && line_current - output_current_row + row_pos >= 0) |
| 680 |
{ |
{ |
| 681 |
row_pos--; |
row_pos--; |
| 682 |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos]); |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos]); |
| 683 |
} |
} |
| 684 |
} |
} |
| 685 |
|
|
| 686 |
if ((str_len = editor_data_delete(p_editor_data, line_current - screen_current_row + row_pos, col_pos - 1, |
if ((str_len = editor_data_delete(p_editor_data, line_current - output_current_row + row_pos, col_pos - 1, |
| 687 |
&last_updated_line)) < 0) |
&last_updated_line)) < 0) |
| 688 |
{ |
{ |
| 689 |
log_error("editor_data_delete() error\n"); |
log_error("editor_data_delete() error\n"); |
| 695 |
for (i = 1; i < str_len; i++) |
for (i = 1; i < str_len; i++) |
| 696 |
{ |
{ |
| 697 |
col_pos--; |
col_pos--; |
| 698 |
if (col_pos < 1 && line_current - screen_current_row + row_pos >= 0) |
if (col_pos < 1 && line_current - output_current_row + row_pos >= 0) |
| 699 |
{ |
{ |
| 700 |
row_pos--; |
row_pos--; |
| 701 |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos]); |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos]); |
| 702 |
} |
} |
| 703 |
} |
} |
| 704 |
} |
} |
| 705 |
|
|
| 706 |
screen_end_row = MIN(SCREEN_ROWS - 1, screen_current_row + (int)(last_updated_line - line_current)); |
output_end_row = MIN(SCREEN_ROWS - 1, output_current_row + (int)(last_updated_line - line_current)); |
| 707 |
line_current -= (screen_current_row - row_pos); |
line_current -= (output_current_row - row_pos); |
| 708 |
screen_current_row = (int)row_pos; |
output_current_row = (int)row_pos; |
| 709 |
|
|
| 710 |
if (screen_current_row < screen_begin_row) // row_pos <= 0 |
if (output_current_row < screen_begin_row) // row_pos <= 0 |
| 711 |
{ |
{ |
| 712 |
screen_current_row = screen_begin_row; |
output_current_row = screen_begin_row; |
| 713 |
row_pos = screen_begin_row; |
row_pos = screen_begin_row; |
| 714 |
screen_end_row = SCREEN_ROWS - 1; |
output_end_row = SCREEN_ROWS - 1; |
| 715 |
|
} |
| 716 |
|
|
| 717 |
|
// Exceed end |
| 718 |
|
if (line_current + (screen_row_total - output_current_row) >= p_editor_data->display_line_total && |
| 719 |
|
p_editor_data->display_line_total > screen_row_total) |
| 720 |
|
{ |
| 721 |
|
scroll_rows = (int)((line_current - (output_current_row - screen_begin_row)) - |
| 722 |
|
(p_editor_data->display_line_total - screen_row_total)); |
| 723 |
|
|
| 724 |
|
line_current = p_editor_data->display_line_total - screen_row_total; |
| 725 |
|
row_pos += scroll_rows; |
| 726 |
|
output_current_row = screen_begin_row; |
| 727 |
|
output_end_row = SCREEN_ROWS - 1; |
| 728 |
|
clrline(output_current_row, SCREEN_ROWS); |
| 729 |
} |
} |
| 730 |
} |
} |
| 731 |
|
|
| 740 |
case Ctrl('C'): |
case Ctrl('C'): |
| 741 |
loop = 0; |
loop = 0; |
| 742 |
break; |
break; |
| 743 |
|
case Ctrl('S'): // Start of line |
| 744 |
case KEY_CTRL_LEFT: |
case KEY_CTRL_LEFT: |
| 745 |
col_pos = 1; |
col_pos = 1; |
| 746 |
break; |
break; |
| 747 |
|
case Ctrl('E'): // End of line |
| 748 |
case KEY_CTRL_RIGHT: |
case KEY_CTRL_RIGHT: |
| 749 |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos]); |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos]); |
| 750 |
break; |
break; |
| 751 |
|
case Ctrl('T'): // Top of screen |
| 752 |
case KEY_CTRL_UP: |
case KEY_CTRL_UP: |
| 753 |
row_pos = screen_begin_row; |
row_pos = screen_begin_row; |
| 754 |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos])); |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos])); |
| 755 |
break; |
break; |
| 756 |
|
case Ctrl('B'): // Bottom of screen |
| 757 |
case KEY_CTRL_DOWN: |
case KEY_CTRL_DOWN: |
| 758 |
row_pos = SCREEN_ROWS - 1; |
row_pos = SCREEN_ROWS - 1; |
| 759 |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos])); |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos])); |
| 760 |
break; |
break; |
| 761 |
case KEY_INS: |
case KEY_INS: |
| 762 |
key_insert = !key_insert; |
key_insert = !key_insert; |
| 764 |
case KEY_HOME: |
case KEY_HOME: |
| 765 |
row_pos = 1; |
row_pos = 1; |
| 766 |
col_pos = 1; |
col_pos = 1; |
| 767 |
if (line_current - screen_current_row < 0) // Reach begin |
if (line_current - output_current_row < 0) // Reach begin |
| 768 |
{ |
{ |
| 769 |
break; |
break; |
| 770 |
} |
} |
| 771 |
line_current = 0; |
line_current = 0; |
| 772 |
screen_current_row = screen_begin_row; |
output_current_row = screen_begin_row; |
| 773 |
screen_end_row = SCREEN_ROWS - 1; |
output_end_row = SCREEN_ROWS - 1; |
| 774 |
clrline(screen_begin_row, SCREEN_ROWS); |
clrline(output_current_row, SCREEN_ROWS); |
| 775 |
break; |
break; |
| 776 |
case KEY_END: |
case KEY_END: |
| 777 |
if (p_editor_data->display_line_total < screen_row_total) |
if (p_editor_data->display_line_total < screen_row_total) |
| 778 |
{ |
{ |
| 779 |
row_pos = p_editor_data->display_line_total; |
row_pos = p_editor_data->display_line_total; |
| 780 |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos]); |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos]); |
| 781 |
break; |
break; |
| 782 |
} |
} |
| 783 |
line_current = p_editor_data->display_line_total - screen_row_total; |
line_current = p_editor_data->display_line_total - screen_row_total; |
| 784 |
screen_current_row = screen_begin_row; |
output_current_row = screen_begin_row; |
| 785 |
screen_end_row = SCREEN_ROWS - 1; |
output_end_row = SCREEN_ROWS - 1; |
| 786 |
row_pos = screen_row_total; |
row_pos = SCREEN_ROWS - 1; |
| 787 |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos]); |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos]); |
| 788 |
clrline(screen_begin_row, SCREEN_ROWS); |
clrline(output_current_row, SCREEN_ROWS); |
| 789 |
break; |
break; |
| 790 |
case KEY_LEFT: |
case KEY_LEFT: |
| 791 |
if (col_pos > 1) |
if (col_pos > 1) |
| 798 |
if (row_pos > screen_begin_row) |
if (row_pos > screen_begin_row) |
| 799 |
{ |
{ |
| 800 |
row_pos--; |
row_pos--; |
| 801 |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos])); |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos])); |
| 802 |
break; |
break; |
| 803 |
} |
} |
| 804 |
if (line_current - screen_current_row < 0) // Reach begin |
if (line_current - output_current_row < 0) // Reach begin |
| 805 |
{ |
{ |
| 806 |
col_pos = 1; |
col_pos = 1; |
| 807 |
break; |
break; |
| 808 |
} |
} |
| 809 |
line_current -= screen_current_row; |
line_current -= output_current_row; |
| 810 |
screen_current_row = screen_begin_row; |
output_current_row = screen_begin_row; |
| 811 |
// screen_end_line = begin_line; |
// screen_end_line = begin_line; |
| 812 |
// prints("\033[T"); // Scroll down 1 line |
// prints("\033[T"); // Scroll down 1 line |
| 813 |
screen_end_row = SCREEN_ROWS - 1; // Legacy Fterm only works with this line |
output_end_row = SCREEN_ROWS - 1; // Legacy Fterm only works with this line |
| 814 |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos])); |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos])); |
| 815 |
break; |
break; |
| 816 |
case KEY_SPACE: |
case KEY_SPACE: |
| 817 |
break; |
break; |
| 818 |
case KEY_RIGHT: |
case KEY_RIGHT: |
| 819 |
if (col_pos < p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos]) |
if (col_pos < p_editor_data->display_line_lengths[line_current - output_current_row + row_pos]) |
| 820 |
{ |
{ |
| 821 |
col_pos++; |
col_pos++; |
| 822 |
break; |
break; |
| 826 |
if (row_pos < MIN(screen_row_total, p_editor_data->display_line_total)) |
if (row_pos < MIN(screen_row_total, p_editor_data->display_line_total)) |
| 827 |
{ |
{ |
| 828 |
row_pos++; |
row_pos++; |
| 829 |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos])); |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos])); |
| 830 |
break; |
break; |
| 831 |
} |
} |
| 832 |
if (line_current + (screen_row_total - (screen_current_row - screen_begin_row)) >= p_editor_data->display_line_total) // Reach end |
if (line_current + (screen_row_total - (output_current_row - screen_begin_row)) >= p_editor_data->display_line_total) // Reach end |
| 833 |
{ |
{ |
| 834 |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos]); |
col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos]); |
| 835 |
break; |
break; |
| 836 |
} |
} |
| 837 |
line_current += (screen_row_total - (screen_current_row - screen_begin_row)); |
line_current += (screen_row_total - (output_current_row - screen_begin_row)); |
| 838 |
screen_current_row = screen_row_total; |
output_current_row = screen_row_total; |
| 839 |
screen_end_row = SCREEN_ROWS - 1; |
output_end_row = SCREEN_ROWS - 1; |
| 840 |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos])); |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos])); |
| 841 |
moveto(SCREEN_ROWS, 0); |
moveto(SCREEN_ROWS, 0); |
| 842 |
clrtoeol(); |
clrtoeol(); |
| 843 |
prints("\033[S"); // Scroll up 1 line |
prints("\033[S"); // Scroll up 1 line |
| 844 |
break; |
break; |
| 845 |
case KEY_PGUP: |
case KEY_PGUP: |
| 846 |
if (line_current - screen_current_row < 0) // Reach begin |
if (line_current - output_current_row < 0) // Reach begin |
| 847 |
{ |
{ |
| 848 |
break; |
break; |
| 849 |
} |
} |
| 850 |
line_current -= ((screen_row_total - 1) + (screen_current_row - screen_begin_row)); |
line_current -= ((screen_row_total - 1) + (output_current_row - screen_begin_row)); |
| 851 |
if (line_current < 0) |
if (line_current < 0) |
| 852 |
{ |
{ |
| 853 |
line_current = 0; |
line_current = 0; |
| 854 |
} |
} |
| 855 |
screen_current_row = screen_begin_row; |
output_current_row = screen_begin_row; |
| 856 |
screen_end_row = SCREEN_ROWS - 1; |
output_end_row = SCREEN_ROWS - 1; |
| 857 |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos])); |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos])); |
| 858 |
clrline(screen_begin_row, SCREEN_ROWS); |
clrline(output_current_row, SCREEN_ROWS); |
| 859 |
break; |
break; |
| 860 |
case KEY_PGDN: |
case KEY_PGDN: |
| 861 |
if (line_current + screen_row_total - (screen_current_row - screen_begin_row) >= p_editor_data->display_line_total) // Reach end |
if (line_current + screen_row_total - (output_current_row - screen_begin_row) >= p_editor_data->display_line_total) // Reach end |
| 862 |
{ |
{ |
| 863 |
break; |
break; |
| 864 |
} |
} |
| 865 |
line_current += (screen_row_total - 1) - (screen_current_row - screen_begin_row); |
line_current += (screen_row_total - 1) - (output_current_row - screen_begin_row); |
| 866 |
if (line_current + screen_row_total > p_editor_data->display_line_total) // No enough lines to display |
if (line_current + screen_row_total > p_editor_data->display_line_total) // No enough lines to display |
| 867 |
{ |
{ |
| 868 |
line_current = p_editor_data->display_line_total - screen_row_total; |
line_current = p_editor_data->display_line_total - screen_row_total; |
| 869 |
} |
} |
| 870 |
screen_current_row = screen_begin_row; |
output_current_row = screen_begin_row; |
| 871 |
screen_end_row = SCREEN_ROWS - 1; |
output_end_row = SCREEN_ROWS - 1; |
| 872 |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - screen_current_row + row_pos])); |
col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos])); |
| 873 |
clrline(screen_begin_row, SCREEN_ROWS); |
clrline(output_current_row, SCREEN_ROWS); |
|
break; |
|
|
case KEY_ESC: |
|
| 874 |
break; |
break; |
| 875 |
case KEY_F1: |
case KEY_F1: |
| 876 |
if (!show_help) // Not reentrant |
if (!show_help) // Not reentrant |
| 883 |
show_help = 1; |
show_help = 1; |
| 884 |
case KEY_F5: |
case KEY_F5: |
| 885 |
// Refresh after display help information |
// Refresh after display help information |
| 886 |
line_current -= (screen_current_row - screen_begin_row); |
line_current -= (output_current_row - screen_begin_row); |
| 887 |
screen_current_row = screen_begin_row; |
output_current_row = screen_begin_row; |
| 888 |
screen_end_row = SCREEN_ROWS - 1; |
output_end_row = SCREEN_ROWS - 1; |
| 889 |
clrline(screen_begin_row, SCREEN_ROWS); |
clrline(output_current_row, SCREEN_ROWS); |
| 890 |
break; |
break; |
| 891 |
case 0: // Refresh bottom line |
case 0: // Refresh bottom line |
| 892 |
break; |
break; |
| 896 |
} |
} |
| 897 |
|
|
| 898 |
BBS_last_access_tm = time(0); |
BBS_last_access_tm = time(0); |
| 899 |
|
|
| 900 |
|
if (input_ok) |
| 901 |
|
{ |
| 902 |
|
break; |
| 903 |
|
} |
| 904 |
} |
} |
| 905 |
|
|
| 906 |
continue; |
continue; |
| 918 |
len = 0; |
len = 0; |
| 919 |
} |
} |
| 920 |
|
|
| 921 |
memcpy(buffer, (const char *)p_editor_data->p_display_lines[line_current], (size_t)len); |
// memcpy(buffer, p_editor_data->p_display_lines[line_current], (size_t)len); |
| 922 |
buffer[len] = '\0'; |
// Replace '\033' with '*' |
| 923 |
|
p_str = p_editor_data->p_display_lines[line_current]; |
| 924 |
|
for (i = 0, j = 0; i < len; i++) |
| 925 |
|
{ |
| 926 |
|
if (p_str[i] == '\033') |
| 927 |
|
{ |
| 928 |
|
memcpy(buffer + j, EDITOR_ESC_DISPLAY_STR, sizeof(EDITOR_ESC_DISPLAY_STR) - 1); |
| 929 |
|
j += (int)(sizeof(EDITOR_ESC_DISPLAY_STR) - 1); |
| 930 |
|
} |
| 931 |
|
else |
| 932 |
|
{ |
| 933 |
|
buffer[j] = p_str[i]; |
| 934 |
|
j++; |
| 935 |
|
} |
| 936 |
|
} |
| 937 |
|
buffer[j] = '\0'; |
| 938 |
|
|
| 939 |
moveto(screen_current_row, 0); |
moveto(output_current_row, 0); |
| 940 |
clrtoeol(); |
clrtoeol(); |
| 941 |
prints("%s", buffer); |
prints("%s", buffer); |
| 942 |
line_current++; |
line_current++; |
| 943 |
screen_current_row++; |
output_current_row++; |
| 944 |
} |
} |
| 945 |
|
|
| 946 |
cleanup: |
cleanup: |