--- lbbs/src/editor.c 2025/09/30 06:05:48 1.42 +++ lbbs/src/editor.c 2025/11/04 14:58:56 1.52 @@ -1,24 +1,17 @@ -/*************************************************************************** - editor.h - description - ------------------- - copyright : (C) 2004-2025 by Leaflet - email : leaflet@leafok.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * editor + * - user interactive full-screen text editor + * + * Copyright (C) 2004-2025 Leaflet + */ #include "bbs.h" #include "common.h" #include "editor.h" #include "io.h" #include "log.h" +#include "login.h" #include "memory_pool.h" #include "str_process.h" #include @@ -48,7 +41,7 @@ int editor_memory_pool_init(void) } p_mp_editor_data = memory_pool_init(sizeof(EDITOR_DATA), 1, 1); - if (p_mp_data_line == NULL) + if (p_mp_editor_data == NULL) { log_error("Memory pool init error\n"); return -3; @@ -82,7 +75,7 @@ EDITOR_DATA *editor_data_load(const char if (p_data == NULL) { - log_error("editor_data_load() error: NULL pointer\n"); + log_error("NULL pointer error\n"); return NULL; } @@ -149,7 +142,7 @@ long editor_data_save(const EDITOR_DATA if (p_editor_data == NULL || p_data == NULL) { - log_error("editor_data_save() error: NULL pointer\n"); + log_error("NULL pointer error\n"); return -1; } @@ -223,7 +216,7 @@ int editor_data_insert(EDITOR_DATA *p_ed if (p_editor_data == NULL || p_last_updated_line == NULL) { - log_error("editor_data_op() error: NULL pointer\n"); + log_error("NULL pointer error\n"); return -1; } @@ -444,7 +437,7 @@ int editor_data_insert(EDITOR_DATA *p_ed } int editor_data_delete(EDITOR_DATA *p_editor_data, long *p_display_line, long *p_offset, - long *p_last_updated_line) + long *p_last_updated_line, int del_line) { long display_line = *p_display_line; long offset = *p_offset; @@ -461,7 +454,7 @@ int editor_data_delete(EDITOR_DATA *p_ed if (p_editor_data == NULL || p_last_updated_line == NULL) { - log_error("editor_data_op() error: NULL pointer\n"); + log_error("NULL pointer error\n"); return -1; } @@ -499,18 +492,22 @@ int editor_data_delete(EDITOR_DATA *p_ed } // Check str to be deleted - if (p_data_line[offset_data_line] > 0 && p_data_line[offset_data_line] < 127) + if (del_line) + { + str_len = (int)(p_editor_data->display_line_lengths[display_line] - offset); + } + else if (p_data_line[offset_data_line] > 0 && p_data_line[offset_data_line] < 127) { str_len = 1; } - else if (p_data_line[offset_data_line] & 0b10000000) // head of multi-byte character + else if (p_data_line[offset_data_line] & 0x80) // head of multi-byte character { str_len = 1; - c = (p_data_line[offset_data_line] & 0b01110000) << 1; - while (c & 0b10000000) + c = (p_data_line[offset_data_line] & 0x70) << 1; + while (c & 0x80) { str_len++; - c = (c & 0b01111111) << 1; + c = (c & 0x7f) << 1; } } else @@ -522,7 +519,8 @@ int editor_data_delete(EDITOR_DATA *p_ed // Current display line is (almost) empty if (offset_data_line + str_len > len_data_line || - (offset_data_line + str_len == len_data_line && p_data_line[offset_data_line] == '\n')) + (offset_data_line + str_len == len_data_line && + p_data_line[del_line ? len_data_line - 1 : offset_data_line] == '\n')) { if (display_line + 1 >= p_editor_data->display_line_total) // No additional display line (data line) { @@ -662,6 +660,7 @@ int editor_display(EDITOR_DATA *p_editor int key_insert = 1; int i, j; char *p_str; + int del_line; clrline(output_current_row, SCREEN_ROWS); @@ -704,23 +703,28 @@ int editor_display(EDITOR_DATA *p_editor ch = igetch_t(MAX_DELAY_TIME); while (!SYS_server_exit) { + if (ch != KEY_NULL && ch != KEY_TIMEOUT) + { + BBS_last_access_tm = time(NULL); + } + // extended key handler if (editor_display_key_handler(&ch, &ctx) != 0) { goto cleanup; } - if (ch < 256 && (ch & 0b10000000)) // head of multi-byte character + if (ch < 256 && (ch & 0x80)) // head of multi-byte character { str_len = 0; - c = (char)(ch & 0b11110000); - while (c & 0b10000000) + c = (char)(ch & 0xf0); + while (c & 0x80) { input_str[str_len] = (char)(ch - 256); str_len++; - c = (c & 0b01111111) << 1; + c = (c & 0x7f) << 1; - if ((c & 0b10000000) == 0) // Input completed + if ((c & 0x80) == 0) // Input completed { break; } @@ -741,7 +745,11 @@ int editor_display(EDITOR_DATA *p_editor if ((ch >= 32 && ch < 127) || str_len >= 2 || // Printable character or multi-byte character ch == CR || ch == KEY_ESC) // Special character { - BBS_last_access_tm = time(NULL); + // Refresh current action while user input + if (user_online_update(NULL) < 0) + { + log_error("user_online_update(NULL) error\n"); + } if (str_len == 0) // ch >= 32 && ch < 127 { @@ -759,7 +767,7 @@ int editor_display(EDITOR_DATA *p_editor if (!key_insert) // overwrite { if (editor_data_delete(p_editor_data, &display_line_out, &offset_out, - &last_updated_line) < 0) + &last_updated_line, 0) < 0) { log_error("editor_data_delete() error\n"); } @@ -828,9 +836,15 @@ int editor_display(EDITOR_DATA *p_editor str_len = 0; continue; } - else if (ch == KEY_DEL || ch == BACKSPACE) // Del + else if (ch == KEY_DEL || ch == BACKSPACE || ch == Ctrl('K') || ch == Ctrl('Y')) // Del { - BBS_last_access_tm = time(NULL); + // Refresh current action while user input + if (user_online_update(NULL) < 0) + { + log_error("user_online_update(NULL) error\n"); + } + + del_line = 0; if (ch == BACKSPACE) { @@ -856,6 +870,15 @@ int editor_display(EDITOR_DATA *p_editor col_pos = MAX(1, p_editor_data->display_line_widths[line_current - output_current_row + row_pos]); } } + else if (ch == Ctrl('K')) + { + del_line = 1; + } + else if (ch == Ctrl('Y')) + { + col_pos = 1; + del_line = 1; + } display_line_in = line_current - output_current_row + row_pos; offset_in = split_line(p_editor_data->p_display_lines[display_line_in], (int)col_pos - 1, &eol, &display_len, 0); @@ -863,9 +886,9 @@ int editor_display(EDITOR_DATA *p_editor offset_out = offset_in; if ((str_len = editor_data_delete(p_editor_data, &display_line_out, &offset_out, - &last_updated_line)) < 0) + &last_updated_line, del_line)) < 0) { - log_error("editor_data_delete() error\n"); + log_error("editor_data_delete() error: %d\n", str_len); } else { @@ -917,7 +940,10 @@ int editor_display(EDITOR_DATA *p_editor switch (ch) { case KEY_NULL: + log_error("KEY_NULL\n"); + goto cleanup; case KEY_TIMEOUT: + log_error("User input timeout\n"); goto cleanup; case Ctrl('W'): case Ctrl('X'): @@ -1026,8 +1052,6 @@ int editor_display(EDITOR_DATA *p_editor output_end_row = SCREEN_ROWS - 1; // Legacy Fterm only works with this line col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_widths[line_current - output_current_row + row_pos])); break; - case KEY_SPACE: - break; case KEY_RIGHT: offset_in = split_line(p_editor_data->p_display_lines[line_current - output_current_row + row_pos], (int)col_pos - 1, &eol, &display_len, 0); @@ -1097,14 +1121,15 @@ int editor_display(EDITOR_DATA *p_editor col_pos = MIN(col_pos, MAX(1, p_editor_data->display_line_widths[line_current - output_current_row + row_pos])); clrline(output_current_row, SCREEN_ROWS); break; + case Ctrl('Q'): case KEY_F1: - if (!show_help) // Not reentrant + if (!show_help) // Not re-entrant { break; } // Display help information show_help = 0; - display_file(DATA_READ_HELP, 1); + display_file(DATA_EDITOR_HELP, 1); show_help = 1; case KEY_F5: // Refresh after display help information @@ -1120,7 +1145,11 @@ int editor_display(EDITOR_DATA *p_editor break; } - BBS_last_access_tm = time(NULL); + // Refresh current action while user input + if (user_online_update(NULL) < 0) + { + log_error("user_online_update(NULL) error\n"); + } if (input_ok) {