/[LeafOK_CVS]/lbbs/src/screen.c
ViewVC logotype

Diff of /lbbs/src/screen.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.30 by sysadm, Sun May 4 14:54:55 2025 UTC Revision 1.42 by sysadm, Sat May 10 13:17:36 2025 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2                                                    screen.c  -  description                                                    screen.c  -  description
3                                                           -------------------                                                           -------------------
4          begin                : Mon Oct 18 2004          Copyright            : (C) 2004-2025 by Leaflet
5          copyright            : (C) 2004 by Leaflet          Email                : leaflet@leafok.com
         email                : leaflet@leafok.com  
6   ***************************************************************************/   ***************************************************************************/
7    
8  /***************************************************************************  /***************************************************************************
9   *                                                                         *   *                                                                         *
10   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
11   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
12   *   the Free Software Foundation; either version 2 of the License, or     *   *   the Free Software Foundation; either version 3 of the License, or     *
13   *   (at your option) any later version.                                   *   *   (at your option) any later version.                                   *
14   *                                                                         *   *                                                                         *
15   ***************************************************************************/   ***************************************************************************/
# Line 23  Line 22 
22  #include "screen.h"  #include "screen.h"
23  #include <string.h>  #include <string.h>
24  #include <ctype.h>  #include <ctype.h>
 #include <sys/types.h>  
 #include <sys/stat.h>  
25  #include <unistd.h>  #include <unistd.h>
26  #include <stdlib.h>  #include <stdlib.h>
27    #include <sys/types.h>
28    #include <sys/stat.h>
29    #include <sys/param.h>
30    
31  #define ACTIVE_BOARD_HEIGHT 8  #define ACTIVE_BOARD_HEIGHT 8
32    
# Line 82  int press_any_key() Line 82  int press_any_key()
82          prints("                           \033[1;33m按任意键继续...\033[0;37m");          prints("                           \033[1;33m按任意键继续...\033[0;37m");
83          iflush();          iflush();
84    
85          return igetch_t(60);          return igetch_t(MIN(MAX_DELAY_TIME, 60));
86  }  }
87    
88  void set_input_echo(int echo)  void set_input_echo(int echo)
# Line 102  void set_input_echo(int echo) Line 102  void set_input_echo(int echo)
102          }          }
103  }  }
104    
105  static int _str_input(char *buffer, int buffer_length, int echo_mode)  static int _str_input(char *buffer, int buf_size, int echo_mode)
106  {  {
107          int c, offset = 0, i, hz = 0;          int c;
108            int offset = 0;
109            int hz = 0;
110    
111          for (i = 0; i < buffer_length && buffer[i] != '\0'; i++)          buffer[buf_size - 1] = '\0';
112          {          for (offset = 0; offset < buf_size - 1 && buffer[offset] != '\0'; offset++)
113                  offset++;                  ;
         }  
114    
115          while ((c = igetch_t(60)))          while ((c = igetch_t(MIN(MAX_DELAY_TIME, 60))))
116          {          {
117                  if (c == KEY_NULL || c == KEY_TIMEOUT || c == CR)                  if (c == CR)
118                  {                  {
119                          igetch(1); // Cleanup remaining '\n' in the buffer                          igetch(1); // Cleanup remaining '\n' in the buffer
120                          break;                          break;
121                  }                  }
122                  if (c == LF)                  if (c == KEY_TIMEOUT)
123                    {
124                            return -1;
125                    }
126                    if (c == KEY_NULL || c == LF)
127                  {                  {
128                          continue;                          continue;
129                  }                  }
# Line 126  static int _str_input(char *buffer, int Line 131  static int _str_input(char *buffer, int
131                  {                  {
132                          if (offset > 0)                          if (offset > 0)
133                          {                          {
134                                  buffer[--offset] = '\0';                                  offset--;
135                                  prints("\b \b");                                  if (buffer[offset] < 0 || buffer[offset] > 127)
136                                  //            clrtoeol ();                                  {
137                                            prints("\033[D \033[D");
138                                            offset--;
139                                            if (offset < 0) // should not happen
140                                            {
141                                                    log_error("Offset of buffer is negative\n");
142                                                    offset = 0;
143                                            }
144                                    }
145                                    buffer[offset] = '\0';
146                                    prints("\033[D \033[D");
147                                  iflush();                                  iflush();
148                          }                          }
149                          continue;                          continue;
# Line 139  static int _str_input(char *buffer, int Line 154  static int _str_input(char *buffer, int
154                  }                  }
155                  if (c > 127 && c <= 255)                  if (c > 127 && c <= 255)
156                  {                  {
157                            if (!hz && offset + 2 > buf_size - 1) // No enough space for Chinese character
158                            {
159                                    igetch(1); // Cleanup remaining input
160                                    outc('\a');
161                                    iflush();
162                                    continue;
163                            }
164                          hz = (!hz);                          hz = (!hz);
165                  }                  }
166                  if (offset >= buffer_length)                  if (offset + 1 > buf_size - 1)
167                  {                  {
168                          outc('\a');                          outc('\a');
169                            iflush();
170                          continue;                          continue;
171                  }                  }
172                  buffer[offset++] = (char)c;                  buffer[offset++] = (char)c;
# Line 163  static int _str_input(char *buffer, int Line 186  static int _str_input(char *buffer, int
186                  }                  }
187          }          }
188    
         prints("\r\n");  
         iflush();  
   
189          return offset;          return offset;
190  }  }
191    
192  int str_input(char *buffer, int buffer_length, int echo_mode)  int str_input(char *buffer, int buf_size, int echo_mode)
193  {  {
194          int offset;          int len;
195    
196          memset(buffer, '\0', buffer_length);          buffer[0] = '\0';
197    
198          offset = _str_input(buffer, buffer_length, echo_mode);          len = _str_input(buffer, buf_size, echo_mode);
199    
200          return offset;          prints("\r\n");
201            iflush();
202    
203            return len;
204  };  };
205    
206  int get_data(int row, int col, char *prompt, char *buffer, int buffer_length, int echo_mode)  int get_data(int row, int col, char *prompt, char *buffer, int buf_size, int echo_mode)
207  {  {
208          int len;          int len;
209    
210            igetch(1); // Cleanup input buffer
211    
212          moveto(row, col);          moveto(row, col);
213          prints(prompt);          prints(prompt);
214          prints(buffer);          prints(buffer);
215          iflush();          iflush();
216    
217          len = _str_input(buffer, buffer_length, echo_mode);          len = _str_input(buffer, buf_size, echo_mode);
218    
219          return len;          return len;
220  }  }
# Line 198  int display_file(const char *filename) Line 223  int display_file(const char *filename)
223  {  {
224          char buffer[LINE_BUFFER_LEN];          char buffer[LINE_BUFFER_LEN];
225          FILE *fin;          FILE *fin;
226          int i;          size_t i;
227    
228          if ((fin = fopen(filename, "r")) == NULL)          if ((fin = fopen(filename, "r")) == NULL)
229          {          {
# Line 224  int display_file(const char *filename) Line 249  int display_file(const char *filename)
249    
250  int display_file_ex(const char *filename, int begin_line, int wait)  int display_file_ex(const char *filename, int begin_line, int wait)
251  {  {
252            static int show_help = 1;
253          char buffer[LINE_BUFFER_LEN];          char buffer[LINE_BUFFER_LEN];
254          int ch = 0;          int ch = 0;
255          int input_ok, line, max_lines;          int input_ok, line, max_lines;
256          long int c_line_current = 0, c_line_total = 0;          long int c_line_current = 0;
257            long int c_line_total = 0;
258          FILE *fin;          FILE *fin;
259          long *p_line_offsets;          long *p_line_offsets;
260          int len;          long int len;
261          int percentile;          long int percentile;
262          int loop = 1;          int loop = 1;
263    
264          if ((fin = fopen(filename, "r")) == NULL)          if ((fin = fopen(filename, "r")) == NULL)
# Line 277  int display_file_ex(const char *filename Line 304  int display_file_ex(const char *filename
304                          }                          }
305    
306                          moveto(screen_rows, 0);                          moveto(screen_rows, 0);
307                          prints("\033[1;44;32m%s (%d%%)%s\033[33m  │ 结束 ← <q> │ ↑/↓/PgUp/PgDn 移动 │ ? 辅助说明 │     \033[m",                          prints("\033[1;44;32m%s (%d%%)%s\033[33m          │ 结束 ← <q> │ ↑/↓/PgUp/PgDn 移动 │ ? 辅助说明 │     \033[m",
308                                     (percentile < 100 ? "下面还有喔" : "没有更多了"), percentile,                                     (percentile < 100 ? "下面还有喔" : "没有更多了"), percentile,
309                                     (percentile < 10 ? "  " : (percentile < 100 ? " " : "")));                                     (percentile < 10 ? "  " : (percentile < 100 ? " " : "")));
310                          iflush();                          iflush();
# Line 289  int display_file_ex(const char *filename Line 316  int display_file_ex(const char *filename
316                                  input_ok = 1;                                  input_ok = 1;
317                                  switch (ch)                                  switch (ch)
318                                  {                                  {
319                                    case KEY_NULL:
320                                    case KEY_TIMEOUT:
321                                            goto cleanup;
322                                  case KEY_UP:                                  case KEY_UP:
323                                          if (c_line_current - line < 0) // Reach top                                          if (c_line_current - line < 0) // Reach top
324                                          {                                          {
# Line 296  int display_file_ex(const char *filename Line 326  int display_file_ex(const char *filename
326                                          }                                          }
327                                          c_line_current -= line;                                          c_line_current -= line;
328                                          line = begin_line;                                          line = begin_line;
329                                          max_lines = begin_line + 1;                                          // max_lines = begin_line + 1;
330                                          prints("\033[T"); // Scroll down 1 line                                          // prints("\033[T"); // Scroll down 1 line
331                                          // max_lines = screen_rows - 1; // Legacy Fterm only works with this line                                          max_lines = screen_rows - 1; // Legacy Fterm only works with this line
332                                          break;                                          break;
333                                  case KEY_DOWN:                                  case KEY_DOWN:
334                                  case CR:                                  case CR:
# Line 345  int display_file_ex(const char *filename Line 375  int display_file_ex(const char *filename
375                                          max_lines = screen_rows - 1;                                          max_lines = screen_rows - 1;
376                                          clrline(begin_line, screen_rows);                                          clrline(begin_line, screen_rows);
377                                          break;                                          break;
                                 case KEY_NULL:  
                                 case KEY_TIMEOUT:  
378                                  case KEY_LEFT:                                  case KEY_LEFT:
379                                  case 'q':                                  case 'q':
380                                  case 'Q':                                  case 'Q':
# Line 355  int display_file_ex(const char *filename Line 383  int display_file_ex(const char *filename
383                                  case '?':                                  case '?':
384                                  case 'h':                                  case 'h':
385                                  case 'H':                                  case 'H':
386                                            if (!show_help)
387                                            {
388                                                    break;
389                                            }
390    
391                                          // Display help information                                          // Display help information
392                                            show_help = 0;
393                                          display_file_ex(DATA_READ_HELP, begin_line, 1);                                          display_file_ex(DATA_READ_HELP, begin_line, 1);
394                                            show_help = 1;
395    
396                                          // Refresh after display help information                                          // Refresh after display help information
397                                          c_line_current -= (line - 1);                                          c_line_current -= (line - 1);
# Line 368  int display_file_ex(const char *filename Line 403  int display_file_ex(const char *filename
403                                          input_ok = 0;                                          input_ok = 0;
404                                          break;                                          break;
405                                  }                                  }
406    
407                                    BBS_last_access_tm = time(0);
408                          }                          }
409    
410                          continue;                          continue;
# Line 380  int display_file_ex(const char *filename Line 417  int display_file_ex(const char *filename
417                          log_error("Error length exceeds buffer size: %d\n", len);                          log_error("Error length exceeds buffer size: %d\n", len);
418                          len = LINE_BUFFER_LEN - 1;                          len = LINE_BUFFER_LEN - 1;
419                  }                  }
420                  if (fgets(buffer, len + 1, fin) == NULL)                  if (fgets(buffer, (int)len + 1, fin) == NULL)
421                  {                  {
422                          log_error("Reach EOF\n");                          log_error("Reach EOF\n");
423                          break;                          break;
# Line 392  int display_file_ex(const char *filename Line 429  int display_file_ex(const char *filename
429                  line++;                  line++;
430          }          }
431    
432    cleanup:
433          free(p_line_offsets);          free(p_line_offsets);
434          fclose(fin);          fclose(fin);
435    
# Line 400  int display_file_ex(const char *filename Line 438  int display_file_ex(const char *filename
438    
439  int show_top(char *status)  int show_top(char *status)
440  {  {
441          char buffer[LINE_BUFFER_LEN];          int end_of_line;
442            int display_len;
443            unsigned int len;
444    
445          str_space(buffer, 20 - strlen(BBS_current_section_name));          char space1[LINE_BUFFER_LEN];
446            char space2[LINE_BUFFER_LEN];
447    
448            len = split_line(status, 20, &end_of_line, &display_len);
449            if (end_of_line)
450            {
451                    status[len] = '\0';
452            }
453            str_space(space1, 31 - display_len);
454    
455            len = split_line(BBS_current_section_name, 20, &end_of_line, &display_len);
456            if (end_of_line)
457            {
458                    status[len] = '\0';
459            }
460            str_space(space2, 30 - display_len);
461    
462          moveto(1, 0);          moveto(1, 0);
463          clrtoeol();          clrtoeol();
464          prints("\033[1;44;33m%-20s \033[37m%20s"          prints("\033[1;44;33m%s \033[37m%s%s%s\033[33m 讨论区 [%s]\033[m",
465                     "         %s\033[33m讨论区 [%s]\033[m",                     status, space1, BBS_name, space2, BBS_current_section_name);
                    status, BBS_name, buffer, BBS_current_section_name);  
466          iflush();          iflush();
467    
468          return 0;          return 0;
# Line 417  int show_top(char *status) Line 471  int show_top(char *status)
471  int show_bottom(char *msg)  int show_bottom(char *msg)
472  {  {
473          char str_time[LINE_BUFFER_LEN];          char str_time[LINE_BUFFER_LEN];
474          char buffer[LINE_BUFFER_LEN];          char space[LINE_BUFFER_LEN];
475          time_t time_online;          time_t time_online;
476          struct tm *tm_online;          struct tm *tm_online;
477    
478          get_time_str(str_time, sizeof(str_time));          get_time_str(str_time, sizeof(str_time));
479          str_space(buffer, 33 - strlen(BBS_username));          str_space(space, 34 - (int)strnlen(BBS_username, sizeof(BBS_username)));
480    
481          time_online = time(0) - BBS_login_tm;          time_online = time(0) - BBS_login_tm;
482          tm_online = gmtime(&time_online);          tm_online = gmtime(&time_online);
483    
484          moveto(screen_rows, 0);          moveto(screen_rows, 0);
485          clrtoeol();          clrtoeol();
486          prints("\033[1;44;33m[\033[36m%s\033[33m]"          prints("\033[1;44;33m[\033[36m%s\033[33m]%s帐号[\033[36m%s\033[33m]"
                    "%s帐号[\033[36m%s\033[33m]"  
487                     "[\033[36m%1d\033[33m:\033[36m%2d\033[33m:\033[36m%2d\033[33m]\033[m",                     "[\033[36m%1d\033[33m:\033[36m%2d\033[33m:\033[36m%2d\033[33m]\033[m",
488                     str_time, buffer, BBS_username, tm_online->tm_mday - 1,                     str_time, space, BBS_username, tm_online->tm_mday - 1,
489                     tm_online->tm_hour, tm_online->tm_min);                     tm_online->tm_hour, tm_online->tm_min);
490          iflush();          iflush();
491    
# Line 445  int show_active_board() Line 498  int show_active_board()
498          char buffer[LINE_BUFFER_LEN];          char buffer[LINE_BUFFER_LEN];
499          FILE *fin;          FILE *fin;
500          static int line;          static int line;
501          int len;          unsigned int len;
502          int end_of_line;          int end_of_line;
503            int display_len;
504    
505          clrline(3, 2 + ACTIVE_BOARD_HEIGHT);          clrline(3, 2 + ACTIVE_BOARD_HEIGHT);
506    
# Line 474  int show_active_board() Line 528  int show_active_board()
528                          break;                          break;
529                  }                  }
530                  line++;                  line++;
531                  len = split_line(buffer, screen_cols, &end_of_line);                  len = split_line(buffer, screen_cols, &end_of_line, &display_len);
532                  buffer[len] = '\0'; // Truncate over-length line                  buffer[len] = '\0'; // Truncate over-length line
533                  moveto(3 + i, 0);                  moveto(3 + i, 0);
534                  prints("%s", buffer);                  prints("%s", buffer);


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1