/[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.106 by sysadm, Sun Jul 20 02:04:21 2025 UTC Revision 1.111 by sysadm, Fri Oct 17 01:25:08 2025 UTC
# Line 38  Line 38 
38    
39  #define STR_TOP_LEFT_MAX_LEN 80  #define STR_TOP_LEFT_MAX_LEN 80
40  #define STR_TOP_MIDDLE_MAX_LEN 40  #define STR_TOP_MIDDLE_MAX_LEN 40
41  #define STR_TOP_RIGHT_MAX_LEN 40  #define STR_TOP_RIGHT_MAX_LEN 80
42    
43    static const char *get_time_str(char *s, size_t len)
44    {
45            static const char *weekday[] = {
46                    "天", "一", "二", "三", "四", "五", "六"};
47            time_t curtime;
48            struct tm local_tm;
49    
50            time(&curtime);
51            localtime_r(&curtime, &local_tm);
52            size_t j = strftime(s, len, "%b %d %H:%M 星期", &local_tm);
53    
54            if (j == 0 || j + strlen(weekday[local_tm.tm_wday]) + 1 > len)
55            {
56                    return NULL;
57            }
58    
59            strncat(s, weekday[local_tm.tm_wday], len - 1 - j);
60    
61            return s;
62    }
63    
64  void moveto(int row, int col)  void moveto(int row, int col)
65  {  {
# Line 97  void set_input_echo(int echo) Line 118  void set_input_echo(int echo)
118          if (echo)          if (echo)
119          {          {
120                  outc('\x83'); // ASCII code 131                  outc('\x83'); // ASCII code 131
                 iflush();  
121          }          }
122          else          else
123          {          {
124                  //    outc ('\x85'); // ASCII code 133                  // outc ('\x85'); // ASCII code 133
125                  prints("\xff\xfb\x01\xff\xfb\x03");                  prints("\xff\xfb\x01\xff\xfb\x03");
                 iflush();  
                 igetch(0);  
                 igetch_reset();  
126          }          }
127            iflush();
128  }  }
129    
130  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, int echo_mode)
# Line 130  static int _str_input(char *buffer, int Line 148  static int _str_input(char *buffer, int
148    
149                  if (ch == CR)                  if (ch == CR)
150                  {                  {
                         igetch_reset();  
151                          break;                          break;
152                  }                  }
153                  else if (ch == KEY_TIMEOUT || ch == KEY_NULL) // timeout or broken pipe                  else if (ch == KEY_TIMEOUT || ch == KEY_NULL) // timeout or broken pipe
# Line 268  int str_input(char *buffer, int buf_size Line 285  int str_input(char *buffer, int buf_size
285          return len;          return len;
286  };  };
287    
288  int get_data(int row, int col, char *prompt, char *buffer, int buf_size, int max_display_len, int echo_mode)  int get_data(int row, int col, char *prompt, char *buffer, int buf_size, int max_display_len)
289  {  {
290          int len;          int len = 0;
291            int col_cur = 0;
292            int ch;
293            int offset = 0;
294            int eol;
295            int display_len;
296            char input_str[4];
297            int str_len = 0;
298            char c;
299    
300            buffer[buf_size - 1] = '\0';
301            offset = split_line(buffer, max_display_len, &eol, &display_len, 0);
302            buffer[offset] = '\0';
303            len = offset;
304            col_cur = col + str_length(prompt, 1) + display_len;
305    
306          moveto(row, col);          moveto(row, col);
307          prints("%s", prompt);          prints("%s", prompt);
308          prints("%s", buffer);          prints("%s", buffer);
309            prints("%*s", max_display_len - display_len, "");
310            moveto(row, col_cur);
311          iflush();          iflush();
312    
313          len = _str_input(buffer, buf_size, max_display_len, echo_mode);          igetch_reset();
314    
315            while (!SYS_server_exit)
316            {
317                    ch = igetch_t(MIN(MAX_DELAY_TIME, 60));
318    
319                    if (ch == CR)
320                    {
321                            break;
322                    }
323                    else if (ch == KEY_TIMEOUT || ch == KEY_NULL) // timeout or broken pipe
324                    {
325                            return -1;
326                    }
327                    else if (ch == LF || ch == '\0')
328                    {
329                            continue;
330                    }
331                    else if (ch == BACKSPACE)
332                    {
333                            if (offset > 0)
334                            {
335                                    str_len = 1;
336                                    offset--;
337                                    if (buffer[offset] < 0 || buffer[offset] > 127) // UTF8
338                                    {
339                                            while (offset > 0 && (buffer[offset] & 0b11000000) != 0b11000000)
340                                            {
341                                                    str_len++;
342                                                    offset--;
343                                            }
344                                            display_len--;
345                                            col_cur--;
346                                    }
347    
348                                    memmove(buffer + offset, buffer + offset + str_len, (size_t)(len - offset - str_len));
349                                    len -= str_len;
350                                    buffer[len] = '\0';
351                                    display_len--;
352                                    col_cur--;
353    
354                                    moveto(row, col_cur);
355                                    prints("%s", buffer + offset);
356                                    prints("%*s", max_display_len - display_len, "");
357                                    moveto(row, col_cur);
358                                    iflush();
359                            }
360                            continue;
361                    }
362                    else if (ch == KEY_DEL)
363                    {
364                            if (offset < len)
365                            {
366                                    if ((buffer[offset] & 0x80) == 0x80) // head of multi-byte character
367                                    {
368                                            str_len = 0;
369                                            c = (char)(buffer[offset] & 0b11110000);
370                                            while (c & 0b10000000)
371                                            {
372                                                    str_len++;
373                                                    c = (c & 0b01111111) << 1;
374                                            }
375                                            display_len--;
376                                    }
377                                    else
378                                    {
379                                            str_len = 1;
380                                    }
381    
382                                    memmove(buffer + offset, buffer + offset + str_len, (size_t)(len - offset - str_len));
383                                    len -= str_len;
384                                    buffer[len] = '\0';
385                                    display_len--;
386    
387                                    moveto(row, col_cur);
388                                    prints("%s", buffer + offset);
389                                    prints("%*s", max_display_len - display_len, "");
390                                    moveto(row, col_cur);
391                                    iflush();
392                            }
393                            continue;
394                    }
395                    else if (ch == KEY_LEFT)
396                    {
397                            if (offset > 0)
398                            {
399                                    str_len = 1;
400                                    offset--;
401                                    if (buffer[offset] < 0 || buffer[offset] > 127) // UTF8
402                                    {
403                                            while (offset > 0 && (buffer[offset] & 0b11000000) != 0b11000000)
404                                            {
405                                                    str_len++;
406                                                    offset--;
407                                            }
408                                            col_cur--;
409                                    }
410                                    col_cur--;
411    
412                                    moveto(row, col_cur);
413                                    iflush();
414                            }
415                            continue;
416                    }
417                    else if (ch == KEY_RIGHT)
418                    {
419                            if (offset < len)
420                            {
421                                    str_len = 0;
422                                    if ((buffer[offset] & 0x80) == 0x80) // head of multi-byte character
423                                    {
424                                            c = (char)(buffer[offset] & 0b11110000);
425                                            while (c & 0b10000000)
426                                            {
427                                                    str_len++;
428                                                    c = (c & 0b01111111) << 1;
429                                            }
430                                            col_cur++;
431                                    }
432                                    else
433                                    {
434                                            str_len = 1;
435                                    }
436    
437                                    col_cur++;
438                                    offset += str_len;
439    
440                                    moveto(row, col_cur);
441                                    iflush();
442                            }
443                            continue;
444                    }
445                    else if (ch == KEY_HOME || ch == KEY_UP)
446                    {
447                            if (offset > 0)
448                            {
449                                    offset = 0;
450                                    col_cur = col + str_length(prompt, 1);
451    
452                                    moveto(row, col_cur);
453                                    iflush();
454                            }
455                            continue;
456                    }
457                    else if (ch == KEY_END || ch == KEY_DOWN)
458                    {
459                            if (offset < len)
460                            {
461                                    offset = len;
462                                    col_cur = col + str_length(prompt, 1) + display_len;
463    
464                                    moveto(row, col_cur);
465                                    iflush();
466                            }
467                            continue;
468                    }
469                    else if (ch > 255 || iscntrl(ch))
470                    {
471                            continue;
472                    }
473                    else if ((ch & 0xff80) == 0x80) // head of multi-byte character
474                    {
475                            str_len = 0;
476                            c = (char)(ch & 0b11110000);
477                            while (c & 0b10000000)
478                            {
479                                    input_str[str_len] = (char)(ch - 256);
480                                    str_len++;
481                                    c = (c & 0b01111111) << 1;
482    
483                                    if ((c & 0b10000000) == 0) // Input completed
484                                    {
485                                            break;
486                                    }
487    
488                                    // Expect additional bytes of input
489                                    ch = igetch(100);                                                // 0.1 second
490                                    if (ch == KEY_NULL || ch == KEY_TIMEOUT) // Ignore received bytes if no futher input
491                                    {
492    #ifdef _DEBUG
493                                            log_error("Ignore %d bytes of incomplete UTF8 character\n", str_len);
494    #endif
495                                            str_len = 0;
496                                            break;
497                                    }
498                            }
499    
500                            if (str_len == 0) // Incomplete input
501                            {
502                                    continue;
503                            }
504    
505                            if (len + str_len > buf_size - 1 || display_len + 2 > max_display_len) // No enough space for Chinese character
506                            {
507                                    outc('\a');
508                                    iflush();
509                                    continue;
510                            }
511    
512                            memmove(buffer + offset + str_len, buffer + offset, (size_t)(len - offset));
513                            memcpy(buffer + offset, input_str, (size_t)str_len);
514                            len += str_len;
515                            buffer[len] = '\0';
516                            display_len += 2;
517    
518                            moveto(row, col_cur);
519                            prints("%s", buffer + offset);
520                            prints("%*s", max_display_len - display_len, "");
521    
522                            col_cur += 2;
523    
524                            moveto(row, col_cur);
525                            iflush();
526    
527                            offset += str_len;
528                    }
529                    else if (ch >= 32 && ch < 127) // Printable character
530                    {
531                            if (len + 1 > buf_size - 1 || display_len + 1 > max_display_len)
532                            {
533                                    outc('\a');
534                                    iflush();
535                                    continue;
536                            }
537    
538                            memmove(buffer + offset + 1, buffer + offset, (size_t)(len - offset));
539                            buffer[offset] = (char)ch;
540                            len++;
541                            buffer[len] = '\0';
542                            display_len++;
543    
544                            moveto(row, col_cur);
545                            prints("%s", buffer + offset);
546                            prints("%*s", max_display_len - display_len, "");
547    
548                            col_cur++;
549    
550                            moveto(row, col_cur);
551                            iflush();
552    
553                            offset++;
554                    }
555                    else // Invalid character
556                    {
557                            continue;
558                    }
559            }
560    
561          return len;          return len;
562  }  }
# Line 369  int display_data(const void *p_data, lon Line 648  int display_data(const void *p_data, lon
648                                  ch = igetch_t(MAX_DELAY_TIME);                                  ch = igetch_t(MAX_DELAY_TIME);
649                                  input_ok = 1;                                  input_ok = 1;
650    
651                                    if (ch != KEY_NULL && ch != KEY_TIMEOUT)
652                                    {
653                                            BBS_last_access_tm = time(NULL);
654                                    }
655    
656                                  // extended key handler                                  // extended key handler
657                                  if (key_handler(&ch, &ctx) != 0)                                  if (key_handler(&ch, &ctx) != 0)
658                                  {                                  {
# Line 378  int display_data(const void *p_data, lon Line 662  int display_data(const void *p_data, lon
662                                  switch (ch)                                  switch (ch)
663                                  {                                  {
664                                  case KEY_NULL:                                  case KEY_NULL:
665                                            log_error("KEY_NULL\n");
666                                            goto cleanup;
667                                  case KEY_TIMEOUT:                                  case KEY_TIMEOUT:
668                                            log_error("User input timeout\n");
669                                          goto cleanup;                                          goto cleanup;
670                                  case KEY_HOME:                                  case KEY_HOME:
671                                          if (line_current - output_current_row < 0) // Reach begin                                          if (line_current - output_current_row < 0) // Reach begin
# Line 412  int display_data(const void *p_data, lon Line 699  int display_data(const void *p_data, lon
699                                          output_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
700                                          break;                                          break;
701                                  case CR:                                  case CR:
                                         igetch_reset();  
702                                  case KEY_SPACE:                                  case KEY_SPACE:
703                                  case KEY_DOWN:                                  case KEY_DOWN:
704                                          if (line_current + (screen_row_total - (output_current_row - screen_begin_row)) >= display_line_total) // Reach end                                          if (line_current + (screen_row_total - (output_current_row - screen_begin_row)) >= display_line_total) // Reach end
# Line 481  int display_data(const void *p_data, lon Line 767  int display_data(const void *p_data, lon
767                                          input_ok = 0;                                          input_ok = 0;
768                                          break;                                          break;
769                                  }                                  }
   
                                 BBS_last_access_tm = time(NULL);  
770                          }                          }
771    
772                          continue;                          continue;


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

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