--- lbbs/src/screen.c 2025/11/04 13:49:51 1.121 +++ lbbs/src/screen.c 2025/11/20 09:02:46 1.131 @@ -3,9 +3,13 @@ * screen * - advanced telnet-based user interactive input / output features * - * Copyright (C) 2004-2025 by Leaflet + * Copyright (C) 2004-2025 Leaflet */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "bbs.h" #include "common.h" #include "editor.h" @@ -21,16 +25,18 @@ #include #include #include +#include #include #include -#include #include -#define ACTIVE_BOARD_HEIGHT 8 +const char CTRL_SEQ_CLR_LINE[] = "\033[K"; -#define STR_TOP_LEFT_MAX_LEN 80 -#define STR_TOP_MIDDLE_MAX_LEN 40 -#define STR_TOP_RIGHT_MAX_LEN 80 +static const int ACTIVE_BOARD_HEIGHT = 8; + +static const int STR_TOP_LEFT_MAX_LEN = 80; +static const int STR_TOP_MIDDLE_MAX_LEN = 40; +static const int STR_TOP_RIGHT_MAX_LEN = 80; static size_t get_time_str(char *s, size_t len) { @@ -127,14 +133,15 @@ void set_input_echo(int echo) iflush(); } -static int _str_input(char *buffer, int buf_size, int max_display_len, int echo_mode) +static int _str_input(char *buffer, int buf_size, int max_display_len, enum io_echo_t echo_mode) { int ch; int offset = 0; int eol; int display_len; - char input_str[4]; + char input_str[5]; int str_len = 0; + wchar_t wcs[2]; char c; buffer[buf_size - 1] = '\0'; @@ -144,7 +151,7 @@ static int _str_input(char *buffer, int while (!SYS_server_exit) { - ch = igetch_t(MIN(MAX_DELAY_TIME, 60)); + ch = igetch_t(MIN(BBS_max_user_idle_time, 60)); if (ch == CR) { @@ -209,13 +216,18 @@ static int _str_input(char *buffer, int break; } } + input_str[str_len] = '\0'; if (str_len == 0) // Incomplete input { continue; } - if (offset + str_len > buf_size - 1 || display_len + 2 > max_display_len) // No enough space for Chinese character + if (mbstowcs(wcs, input_str, 1) == (size_t)-1) + { + log_error("mbstowcs() error\n"); + } + if (offset + str_len > buf_size - 1 || display_len + (UTF8_fixed_width ? 2 : wcwidth(wcs[0])) > max_display_len) // No enough space for Chinese character { outc('\a'); iflush(); @@ -271,7 +283,7 @@ static int _str_input(char *buffer, int return offset; } -int str_input(char *buffer, int buf_size, int echo_mode) +int str_input(char *buffer, int buf_size, enum io_echo_t echo_mode) { int len; @@ -293,8 +305,10 @@ int get_data(int row, int col, char *pro int offset = 0; int eol; int display_len; - char input_str[4]; + char input_str[5]; int str_len = 0; + wchar_t wcs[2]; + int wc_len; char c; buffer[buf_size - 1] = '\0'; @@ -314,7 +328,7 @@ int get_data(int row, int col, char *pro while (!SYS_server_exit) { - ch = igetch_t(MIN(MAX_DELAY_TIME, 60)); + ch = igetch_t(MIN(BBS_max_user_idle_time, 60)); if (ch == CR) { @@ -341,8 +355,18 @@ int get_data(int row, int col, char *pro str_len++; offset--; } - display_len--; - col_cur--; + + if (mbstowcs(wcs, buffer + offset, 1) == (size_t)-1) + { + log_error("mbstowcs() error\n"); + } + wc_len = (UTF8_fixed_width ? 2 : wcwidth(wcs[0])); + + if (wc_len == 2) + { + display_len--; + col_cur--; + } } memmove(buffer + offset, buffer + offset + str_len, (size_t)(len - offset - str_len)); @@ -405,7 +429,17 @@ int get_data(int row, int col, char *pro str_len++; offset--; } - col_cur--; + + if (mbstowcs(wcs, buffer + offset, 1) == (size_t)-1) + { + log_error("mbstowcs() error\n"); + } + wc_len = (UTF8_fixed_width ? 2 : wcwidth(wcs[0])); + + if (wc_len == 2) + { + col_cur--; + } } col_cur--; @@ -427,7 +461,17 @@ int get_data(int row, int col, char *pro str_len++; c = (c & 0x7f) << 1; } - col_cur++; + + if (mbstowcs(wcs, buffer + offset, 1) == (size_t)-1) + { + log_error("mbstowcs() error\n"); + } + wc_len = (UTF8_fixed_width ? 2 : wcwidth(wcs[0])); + + if (wc_len == 2) + { + col_cur++; + } } else { @@ -496,13 +540,21 @@ int get_data(int row, int col, char *pro break; } } + input_str[str_len] = '\0'; if (str_len == 0) // Incomplete input { continue; } - if (len + str_len > buf_size - 1 || display_len + 2 > max_display_len) // No enough space for Chinese character + if (mbstowcs(wcs, input_str, 1) == (size_t)-1) + { + log_error("mbstowcs() error\n"); + } + wc_len = (UTF8_fixed_width ? 2 : wcwidth(wcs[0])); + + if (len + str_len > buf_size - 1 || + display_len + wc_len > max_display_len) // No enough space for Chinese character { outc('\a'); iflush(); @@ -513,13 +565,13 @@ int get_data(int row, int col, char *pro memcpy(buffer + offset, input_str, (size_t)str_len); len += str_len; buffer[len] = '\0'; - display_len += 2; + display_len += wc_len; moveto(row, col_cur); prints("%s", buffer + offset); prints("%*s", max_display_len - display_len, ""); - col_cur += 2; + col_cur += wc_len; moveto(row, col_cur); iflush(); @@ -590,7 +642,7 @@ int display_data(const void *p_data, lon loop = 1; while (!SYS_server_exit && loop) { - if (eof_exit > 0 && line_current >= display_line_total && display_line_total <= screen_row_total) + if (eof_exit > 0 && line_current >= display_line_total) { if (eof_exit == 1) { @@ -645,7 +697,7 @@ int display_data(const void *p_data, lon input_ok = 0; while (!SYS_server_exit && !input_ok) { - ch = igetch_t(MAX_DELAY_TIME); + ch = igetch_t(BBS_max_user_idle_time); input_ok = 1; if (ch != KEY_NULL && ch != KEY_TIMEOUT) @@ -800,7 +852,7 @@ cleanup: return ch; } -static int display_file_key_handler(int *p_key, DISPLAY_CTX *p_ctx) +int display_file_key_handler(int *p_key, DISPLAY_CTX *p_ctx) { switch (*p_key) { @@ -818,7 +870,7 @@ static int display_file_key_handler(int int display_file(const char *filename, int eof_exit) { int ret; - const void *p_shm; + void *p_shm; size_t data_len; long line_total; const void *p_data; @@ -892,6 +944,7 @@ int show_bottom(const char *msg) int len; int len_username; char str_tm_online[LINE_BUFFER_LEN]; + int len_str_tm_online; len_str_time = (int)get_time_str(str_time, sizeof(str_time)); @@ -921,11 +974,13 @@ int show_bottom(const char *msg) "\033[36m%d\033[33m:\033[36m%.2d", tm_online->tm_hour, tm_online->tm_min); } + len_str_tm_online = str_length(str_tm_online, 1); moveto(SCREEN_ROWS, 0); clrtoeol(); prints("\033[1;44;33m时间[\033[36m%s\033[33m]%s%*s \033[33m用户[\033[36m%s\033[33m][%s\033[33m]\033[m", - str_time, msg_f, 61 - len_str_time - len_msg - len_username, "", BBS_username, str_tm_online); + str_time, msg_f, 65 - len_str_time - len_msg - len_username - len_str_tm_online, + "", BBS_username, str_tm_online); return 0; }