--- lbbs/src/screen.c 2025/11/04 13:49:51 1.121 +++ lbbs/src/screen.c 2025/11/08 09:05:59 1.128 @@ -3,7 +3,7 @@ * screen * - advanced telnet-based user interactive input / output features * - * Copyright (C) 2004-2025 by Leaflet + * Copyright (C) 2004-2025 Leaflet */ #include "bbs.h" @@ -21,16 +21,19 @@ #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 +130,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 +148,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 +213,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 +280,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 +302,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 +325,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 +352,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 +426,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 +458,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 +537,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 +562,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 +639,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 +694,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 +849,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) { @@ -892,6 +941,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 +971,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; }