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

Diff of /lbbs/src/menu.c

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

Revision 1.46 by sysadm, Sun May 18 06:57:56 2025 UTC Revision 1.64 by sysadm, Mon Jun 16 14:30:44 2025 UTC
# Line 14  Line 14 
14   *                                                                         *   *                                                                         *
15   ***************************************************************************/   ***************************************************************************/
16    
17    #define _POSIX_C_SOURCE 200809L
18    
19  #include "bbs.h"  #include "bbs.h"
20  #include "bbs_cmd.h"  #include "bbs_cmd.h"
21  #include "user_priv.h"  #include "user_priv.h"
# Line 48  int load_menu(MENU_SET *p_menu_set, cons Line 50  int load_menu(MENU_SET *p_menu_set, cons
50          char temp[LINE_BUFFER_LEN];          char temp[LINE_BUFFER_LEN];
51          char *p = NULL;          char *p = NULL;
52          char *q = NULL;          char *q = NULL;
53            char *r = NULL;
54          char *saveptr = NULL;          char *saveptr = NULL;
55          MENU *p_menu = NULL;          MENU *p_menu = NULL;
56          MENU_ITEM *p_menu_item = NULL;          MENU_ITEM *p_menu_item = NULL;
# Line 159  int load_menu(MENU_SET *p_menu_set, cons Line 162  int load_menu(MENU_SET *p_menu_set, cons
162                                  p_menu->item_count = 0;                                  p_menu->item_count = 0;
163                                  p_menu->title.show = 0;                                  p_menu->title.show = 0;
164                                  p_menu->screen_show = 0;                                  p_menu->screen_show = 0;
165                                    p_menu->page_item_limit = 0;
166                                    p_menu->use_filter = 0;
167                                    p_menu->filter_handler = NULL;
168    
169                                  q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);                                  q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
170                                  if (q == NULL)                                  if (q == NULL)
# Line 167  int load_menu(MENU_SET *p_menu_set, cons Line 173  int load_menu(MENU_SET *p_menu_set, cons
173                                          return -1;                                          return -1;
174                                  }                                  }
175                                  p = q;                                  p = q;
176                                  while (isalnum(*q) || *q == '_')                                  while (isalnum(*q) || *q == '_' || *q == '-')
177                                  {                                  {
178                                          q++;                                          q++;
179                                  }                                  }
# Line 250  int load_menu(MENU_SET *p_menu_set, cons Line 256  int load_menu(MENU_SET *p_menu_set, cons
256                                                  else                                                  else
257                                                  {                                                  {
258                                                          q = p;                                                          q = p;
259                                                          while (isalnum(*q) || *q == '_')                                                          while (isalnum(*q) || *q == '_' || *q == '-')
260                                                          {                                                          {
261                                                                  q++;                                                                  q++;
262                                                          }                                                          }
# Line 356  int load_menu(MENU_SET *p_menu_set, cons Line 362  int load_menu(MENU_SET *p_menu_set, cons
362                                                  p = q;                                                  p = q;
363                                                  while (*q != '\0' && *q != '\"')                                                  while (*q != '\0' && *q != '\"')
364                                                  {                                                  {
365                                                            if (*q == '\\')
366                                                            {
367                                                                    r = q;
368                                                                    while (*r != '\0')
369                                                                    {
370                                                                            *r = *(r + 1);
371                                                                            r++;
372                                                                    }
373                                                            }
374                                                          q++;                                                          q++;
375                                                  }                                                  }
376                                                  if (*q != '\"' || *(q + 1) != '\0')                                                  if (*q != '\"' || *(q + 1) != '\0')
# Line 384  int load_menu(MENU_SET *p_menu_set, cons Line 399  int load_menu(MENU_SET *p_menu_set, cons
399                                                  p = q;                                                  p = q;
400                                                  while (*q != '\0' && *q != '\"')                                                  while (*q != '\0' && *q != '\"')
401                                                  {                                                  {
402                                                            if (*q == '\\')
403                                                            {
404                                                                    r = q;
405                                                                    while (*r != '\0')
406                                                                    {
407                                                                            *r = *(r + 1);
408                                                                            r++;
409                                                                    }
410                                                            }
411                                                          q++;                                                          q++;
412                                                  }                                                  }
413                                                  if (*q != '\"')                                                  if (*q != '\"')
# Line 462  int load_menu(MENU_SET *p_menu_set, cons Line 486  int load_menu(MENU_SET *p_menu_set, cons
486                                                  p = q;                                                  p = q;
487                                                  while (*q != '\0' && *q != '\"')                                                  while (*q != '\0' && *q != '\"')
488                                                  {                                                  {
489                                                            if (*q == '\\')
490                                                            {
491                                                                    r = q;
492                                                                    while (*r != '\0')
493                                                                    {
494                                                                            *r = *(r + 1);
495                                                                            r++;
496                                                                    }
497                                                            }
498                                                          q++;                                                          q++;
499                                                  }                                                  }
500                                                  if (*q != '\"')                                                  if (*q != '\"')
# Line 471  int load_menu(MENU_SET *p_menu_set, cons Line 504  int load_menu(MENU_SET *p_menu_set, cons
504                                                  }                                                  }
505                                                  *q = '\0';                                                  *q = '\0';
506    
507                                                  if (q - p > sizeof(p_menu_item->text) - 1)                                                  if (q - p > sizeof(p_menu->title.text) - 1)
508                                                  {                                                  {
509                                                          log_error("Too longer menu title text in menu config line %d\n", fin_line);                                                          log_error("Too longer menu title text in menu config line %d\n", fin_line);
510                                                          return -1;                                                          return -1;
# Line 537  int load_menu(MENU_SET *p_menu_set, cons Line 570  int load_menu(MENU_SET *p_menu_set, cons
570                                                          return -1;                                                          return -1;
571                                                  }                                                  }
572                                                  p = q;                                                  p = q;
573                                                  while (isalnum(*q) || *q == '_')                                                  while (isalnum(*q) || *q == '_' || *q == '-')
574                                                  {                                                  {
575                                                          q++;                                                          q++;
576                                                  }                                                  }
# Line 546  int load_menu(MENU_SET *p_menu_set, cons Line 579  int load_menu(MENU_SET *p_menu_set, cons
579                                                          log_error("Error menu screen name in menu config line %d\n", fin_line);                                                          log_error("Error menu screen name in menu config line %d\n", fin_line);
580                                                          return -1;                                                          return -1;
581                                                  }                                                  }
582                                                  if (trie_dict_get(p_menu_set->p_menu_screen_dict, p, (int64_t *)&screen_id) != 1)                                                  strncpy(p_menu->screen_name, p, sizeof(p_menu->screen_name) - 1);
583                                                    p_menu->screen_name[sizeof(p_menu->screen_name) - 1] = '\0';
584    
585                                                    // Check syntax
586                                                    q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
587                                                    if (q != NULL)
588                                                    {
589                                                            log_error("Unknown extra content in menu config line %d\n", fin_line);
590                                                            return -1;
591                                                    }
592                                            }
593                                            else if (strcmp(p, "page") == 0)
594                                            {
595                                                    // Menu page row
596                                                    q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
597                                                    if (q == NULL)
598                                                    {
599                                                            log_error("Error menu page row in menu config line %d\n", fin_line);
600                                                            return -1;
601                                                    }
602                                                    p = q;
603                                                    while (isdigit(*q))
604                                                    {
605                                                            q++;
606                                                    }
607                                                    if (*q != '\0')
608                                                    {
609                                                            log_error("Error menu page row in menu config line %d\n", fin_line);
610                                                            return -1;
611                                                    }
612                                                    p_menu->page_row = (int16_t)atoi(p);
613    
614                                                    // Menu page col
615                                                    q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
616                                                    if (q == NULL)
617                                                    {
618                                                            log_error("Error menu page col in menu config line %d\n", fin_line);
619                                                            return -1;
620                                                    }
621                                                    p = q;
622                                                    while (isdigit(*q))
623                                                    {
624                                                            q++;
625                                                    }
626                                                    if (*q != '\0')
627                                                    {
628                                                            log_error("Error menu page col in menu config line %d\n", fin_line);
629                                                            return -1;
630                                                    }
631                                                    p_menu->page_col = (int16_t)atoi(p);
632    
633                                                    // Menu page item limit
634                                                    q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
635                                                    if (q == NULL)
636                                                    {
637                                                            log_error("Error menu page item limit in menu config line %d\n", fin_line);
638                                                            return -1;
639                                                    }
640                                                    p = q;
641                                                    while (isdigit(*q))
642                                                    {
643                                                            q++;
644                                                    }
645                                                    if (*q != '\0')
646                                                    {
647                                                            log_error("Error menu page item limit in menu config line %d\n", fin_line);
648                                                            return -1;
649                                                    }
650                                                    p_menu->page_item_limit = (int16_t)atoi(p);
651    
652                                                    // Check syntax
653                                                    q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
654                                                    if (q != NULL)
655                                                  {                                                  {
656                                                          log_error("Undefined menu screen [%s]\n", p);                                                          log_error("Unknown extra content in menu config line %d\n", fin_line);
657                                                          return -1;                                                          return -1;
658                                                  }                                                  }
659                                                  p_menu->screen_id = screen_id;                                          }
660                                            else if (strcmp(p, "use_filter") == 0)
661                                            {
662                                                    p_menu->use_filter = 1;
663    
664                                                  // Check syntax                                                  // Check syntax
665                                                  q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);                                                  q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
# Line 576  int load_menu(MENU_SET *p_menu_set, cons Line 684  int load_menu(MENU_SET *p_menu_set, cons
684                                  p_screen = get_menu_screen_by_id(p_menu_set, screen_id);                                  p_screen = get_menu_screen_by_id(p_menu_set, screen_id);
685    
686                                  q = p;                                  q = p;
687                                  while (isalnum(*q) || *q == '_')                                  while (isalnum(*q) || *q == '_' || *q == '-')
688                                  {                                  {
689                                          q++;                                          q++;
690                                  }                                  }
# Line 628  int load_menu(MENU_SET *p_menu_set, cons Line 736  int load_menu(MENU_SET *p_menu_set, cons
736                                                  break;                                                  break;
737                                          }                                          }
738    
739                                            // Clear line
740                                            if (p_menu_set->p_menu_screen_buf_free + strlen(CTRL_SEQ_CLR_LINE) > q)
741                                            {
742                                                    log_error("Menu screen buffer depleted (%p + %d > %p)\n", p_menu_set->p_menu_screen_buf_free, q, strlen(CTRL_SEQ_CLR_LINE));
743                                                    return -3;
744                                            }
745                                            p_menu_set->p_menu_screen_buf_free = stpcpy(p_menu_set->p_menu_screen_buf_free, CTRL_SEQ_CLR_LINE);
746    
747                                          p = buffer;                                          p = buffer;
748                                          while (*p != '\0')                                          while (*p != '\0')
749                                          {                                          {
# Line 663  int load_menu(MENU_SET *p_menu_set, cons Line 779  int load_menu(MENU_SET *p_menu_set, cons
779          }          }
780          fclose(fin);          fclose(fin);
781    
782            for (menu_id = 0; menu_id < p_menu_set->menu_count; menu_id++)
783            {
784                    p_menu = get_menu_by_id(p_menu_set, menu_id);
785    
786                    if (trie_dict_get(p_menu_set->p_menu_screen_dict, p_menu->screen_name, (int64_t *)(&(p_menu->screen_id))) != 1)
787                    {
788                            log_error("Undefined menu screen [%s]\n", p);
789                            return -1;
790                    }
791    
792                    // Set menu->filter_handler of each menu pointing to filter
793                    if (p_menu->use_filter == 1)
794                    {
795                            if ((p_menu->filter_handler = get_cmd_handler(p_menu->name)) == NULL)
796                            {
797                                    log_error("Undefined menu filter handler [%s]\n", p_menu->name);
798                                    return -1;
799                            }
800                    }
801            }
802    
803          for (menu_item_id = 0; menu_item_id < p_menu_set->menu_item_count; menu_item_id++)          for (menu_item_id = 0; menu_item_id < p_menu_set->menu_item_count; menu_item_id++)
804          {          {
805                  p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);                  p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
# Line 681  int load_menu(MENU_SET *p_menu_set, cons Line 818  int load_menu(MENU_SET *p_menu_set, cons
818                  {                  {
819                          if (trie_dict_get(p_menu_set->p_menu_name_dict, p_menu_item->action, (int64_t *)&menu_id) != 1)                          if (trie_dict_get(p_menu_set->p_menu_name_dict, p_menu_item->action, (int64_t *)&menu_id) != 1)
820                          {                          {
821                                  log_error("Undefined menu action [%s]\n", p_menu_item->action);                                  log_error("Undefined sub menu id [%s]\n", p_menu_item->action);
822                                  return -1;                                  return -1;
823                          }                          }
824                          p_menu_item->action_menu_id = menu_id;                          p_menu_item->action_menu_id = menu_id;
# Line 696  int load_menu(MENU_SET *p_menu_set, cons Line 833  int load_menu(MENU_SET *p_menu_set, cons
833          return 0;          return 0;
834  }  }
835    
836  static int display_menu_cursor(MENU_SET *p_menu_set, int show)  int display_menu_cursor(MENU_SET *p_menu_set, int show)
837  {  {
838          MENU_ID menu_id;          MENU_ID menu_id;
839          MENU_ITEM_ID menu_item_id;          MENU_ITEM_ID menu_item_id;
# Line 723  static int display_menu_cursor(MENU_SET Line 860  static int display_menu_cursor(MENU_SET
860    
861          moveto(p_menu_set->menu_item_r_row[menu_item_pos], p_menu_set->menu_item_r_col[menu_item_pos] - 2);          moveto(p_menu_set->menu_item_r_row[menu_item_pos], p_menu_set->menu_item_r_col[menu_item_pos] - 2);
862          outc(show ? '>' : ' ');          outc(show ? '>' : ' ');
         iflush();  
863    
864          return 0;          return 0;
865  }  }
866    
867  int display_menu(MENU_SET *p_menu_set)  static int display_menu_current_page(MENU_SET *p_menu_set)
868  {  {
869          int16_t row = 0;          int16_t row = 0;
870          int16_t col = 0;          int16_t col = 0;
         int menu_selectable = 0;  
871          MENU_ID menu_id;          MENU_ID menu_id;
872          MENU_ITEM_ID menu_item_id;          MENU_ITEM_ID menu_item_id;
873          MENU *p_menu;          MENU *p_menu;
874          MENU_ITEM *p_menu_item;          MENU_ITEM *p_menu_item;
         MENU_SCREEN *p_menu_screen;  
875          int16_t menu_item_pos;          int16_t menu_item_pos;
876            int16_t page_id = 0;
877            MENU_SCREEN *p_menu_screen;
878    
879          menu_id = p_menu_set->menu_id_path[p_menu_set->choose_step];          menu_id = p_menu_set->menu_id_path[p_menu_set->choose_step];
880          p_menu = get_menu_by_id(p_menu_set, menu_id);          p_menu = get_menu_by_id(p_menu_set, menu_id);
# Line 748  int display_menu(MENU_SET *p_menu_set) Line 884  int display_menu(MENU_SET *p_menu_set)
884                  return -1;                  return -1;
885          }          }
886    
887          menu_item_pos = p_menu_set->menu_item_pos[p_menu_set->choose_step];          clrline(p_menu->page_row, p_menu->page_row + p_menu->page_item_limit - 1);
         menu_item_id = p_menu->items[menu_item_pos];  
         p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);  
         if (p_menu_item == NULL)  
         {  
                 log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);  
                 return -1;  
         }  
   
         if (menu_item_pos > 0 &&  
                 checkpriv(&BBS_priv, 0, p_menu_item->priv) != 0 &&  
                 checklevel(&BBS_priv, p_menu_item->level) != 0)  
         {  
                 menu_selectable = 1;  
         }  
888    
889          if (p_menu->title.show)          if (p_menu->title.show)
890          {          {
891                  show_top(p_menu->title.text);                  if (p_menu->title.row == 0 && p_menu->title.col == 0)
892                    {
893                            show_top(p_menu->title.text, BBS_name, "");
894                    }
895                    else
896                    {
897                            moveto(p_menu->title.row, p_menu->title.col);
898                            prints("%s", p_menu->title.text);
899                    }
900          }          }
901    
902          if (p_menu->screen_show)          if (p_menu->screen_show)
# Line 778  int display_menu(MENU_SET *p_menu_set) Line 908  int display_menu(MENU_SET *p_menu_set)
908                          return -1;                          return -1;
909                  }                  }
910    
911                  moveto(p_menu->screen_row, p_menu->screen_col);                  row = p_menu->screen_row;
912                    col = p_menu->screen_col;
913    
914                    moveto(row, col);
915                  prints("%s", p_menu_set->p_menu_screen_buf + p_menu_screen->buf_offset);                  prints("%s", p_menu_set->p_menu_screen_buf + p_menu_screen->buf_offset);
916                  iflush();          }
917    
918            menu_item_pos = p_menu_set->menu_item_pos[p_menu_set->choose_step];
919            page_id = p_menu_set->menu_item_page_id[menu_item_pos];
920    
921            while (menu_item_pos >= 0)
922            {
923                    if (p_menu_set->menu_item_page_id[menu_item_pos] != page_id)
924                    {
925                            menu_item_pos++;
926                            break;
927                    }
928    
929                    if (menu_item_pos == 0)
930                    {
931                            break;
932                    }
933    
934                    menu_item_pos--;
935            }
936    
937            for (; menu_item_pos < p_menu->item_count; menu_item_pos++)
938            {
939                    if (p_menu_set->menu_item_page_id[menu_item_pos] != page_id)
940                    {
941                            break;
942                    }
943    
944                    menu_item_id = p_menu->items[menu_item_pos];
945                    p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
946    
947                    if (p_menu_set->menu_item_display[menu_item_pos] == 0)
948                    {
949                            continue;
950                    }
951    
952                    row = p_menu_set->menu_item_r_row[menu_item_pos];
953                    col = p_menu_set->menu_item_r_col[menu_item_pos];
954    
955                    moveto(row, col);
956                    prints("%s", p_menu_item->text);
957            }
958    
959            return 0;
960    }
961    
962    int display_menu(MENU_SET *p_menu_set)
963    {
964            int16_t row = 0;
965            int16_t col = 0;
966            int menu_selectable = 0;
967            MENU_ID menu_id;
968            MENU_ITEM_ID menu_item_id;
969            MENU *p_menu;
970            MENU_ITEM *p_menu_item;
971            int16_t menu_item_pos;
972            int16_t page_id = 0;
973            int page_item_count = 0;
974    
975            menu_id = p_menu_set->menu_id_path[p_menu_set->choose_step];
976            p_menu = get_menu_by_id(p_menu_set, menu_id);
977            if (p_menu == NULL)
978            {
979                    log_error("get_menu_by_id(%d) return NULL pointer\n", menu_id);
980                    if (p_menu_set->choose_step > 0)
981                    {
982                            p_menu_set->choose_step--;
983                            return REDRAW;
984                    }
985                    return EXITBBS;
986            }
987    
988            menu_item_pos = p_menu_set->menu_item_pos[p_menu_set->choose_step];
989            menu_item_id = p_menu->items[menu_item_pos];
990            p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
991            if (p_menu_item == NULL)
992            {
993                    log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
994                    menu_item_pos = 0;
995            }
996    
997            if (menu_item_pos > 0 &&
998                    !(p_menu->use_filter ? (p_menu->filter_handler((void *)p_menu_item) == 0)
999                                                             : (checkpriv(&BBS_priv, 0, p_menu_item->priv) == 0 ||
1000                                                                    checklevel2(&BBS_priv, p_menu_item->level) == 0)))
1001            {
1002                    menu_selectable = 1;
1003          }          }
1004    
1005          for (menu_item_pos = 0; menu_item_pos < p_menu->item_count; menu_item_pos++)          for (menu_item_pos = 0; menu_item_pos < p_menu->item_count; menu_item_pos++)
# Line 797  int display_menu(MENU_SET *p_menu_set) Line 1016  int display_menu(MENU_SET *p_menu_set)
1016                          col = p_menu_item->col;                          col = p_menu_item->col;
1017                  }                  }
1018    
1019                  if (checkpriv(&BBS_priv, 0, p_menu_item->priv) == 0 || checklevel(&BBS_priv, p_menu_item->level) == 0)                  p_menu_set->menu_item_page_id[menu_item_pos] = page_id;
1020    
1021                    if (p_menu->use_filter ? (p_menu->filter_handler((void *)p_menu_item) == 0)
1022                                                               : (checkpriv(&BBS_priv, 0, p_menu_item->priv) == 0 ||
1023                                                                      checklevel2(&BBS_priv, p_menu_item->level) == 0))
1024                  {                  {
1025                          p_menu_set->menu_item_display[menu_item_pos] = 0;                          p_menu_set->menu_item_display[menu_item_pos] = 0;
1026                          p_menu_set->menu_item_r_row[menu_item_pos] = 0;                          p_menu_set->menu_item_r_row[menu_item_pos] = 0;
# Line 816  int display_menu(MENU_SET *p_menu_set) Line 1039  int display_menu(MENU_SET *p_menu_set)
1039                          p_menu_set->menu_item_r_row[menu_item_pos] = row;                          p_menu_set->menu_item_r_row[menu_item_pos] = row;
1040                          p_menu_set->menu_item_r_col[menu_item_pos] = col;                          p_menu_set->menu_item_r_col[menu_item_pos] = col;
1041    
                         moveto(row, col);  
                         prints("%s", p_menu_item->text);  
   
1042                          row++;                          row++;
1043    
1044                            page_item_count++;
1045                            if (p_menu->page_item_limit > 0 && page_item_count >= p_menu->page_item_limit)
1046                            {
1047                                    page_id++;
1048                                    page_item_count = 0;
1049                                    row = p_menu->page_row;
1050                                    col = p_menu->page_col;
1051                            }
1052                  }                  }
1053          }          }
1054    
1055          if (!menu_selectable)          if (!menu_selectable)
1056          {          {
1057                    moveto(p_menu->screen_row, p_menu->screen_col);
1058                    prints("ûÓпÉÑ¡Ïî");
1059                    press_any_key();
1060                    return -1;
1061            }
1062    
1063            if (display_menu_current_page(p_menu_set) != 0)
1064            {
1065                  return -1;                  return -1;
1066          }          }
1067    
# Line 840  int menu_control(MENU_SET *p_menu_set, i Line 1077  int menu_control(MENU_SET *p_menu_set, i
1077          MENU *p_menu;          MENU *p_menu;
1078          MENU_ITEM *p_menu_item;          MENU_ITEM *p_menu_item;
1079          int16_t menu_item_pos;          int16_t menu_item_pos;
1080            int16_t page_id;
1081            int require_page_change = 0;
1082    
1083          if (p_menu_set->menu_count == 0)          if (p_menu_set->menu_count == 0)
1084          {          {
1085                  return 0;                  log_error("Empty menu set\n");
1086                    return EXITBBS;
1087          }          }
1088    
1089          menu_id = p_menu_set->menu_id_path[p_menu_set->choose_step];          menu_id = p_menu_set->menu_id_path[p_menu_set->choose_step];
# Line 851  int menu_control(MENU_SET *p_menu_set, i Line 1091  int menu_control(MENU_SET *p_menu_set, i
1091          if (p_menu == NULL)          if (p_menu == NULL)
1092          {          {
1093                  log_error("get_menu_by_id(%d) return NULL pointer\n", menu_id);                  log_error("get_menu_by_id(%d) return NULL pointer\n", menu_id);
1094                  return -1;                  if (p_menu_set->choose_step > 0)
1095                    {
1096                            p_menu_set->choose_step--;
1097                            return REDRAW;
1098                    }
1099                    return EXITBBS;
1100          }          }
1101    
1102          if (p_menu->item_count == 0)          if (p_menu->item_count == 0)
1103          {          {
1104                  return 0;                  log_error("Empty menu (%s)\n", p_menu->name);
1105                    if (p_menu_set->choose_step > 0)
1106                    {
1107                            p_menu_set->choose_step--;
1108                            return REDRAW;
1109                    }
1110                    return EXITBBS;
1111          }          }
1112    
1113          menu_item_pos = p_menu_set->menu_item_pos[p_menu_set->choose_step];          menu_item_pos = p_menu_set->menu_item_pos[p_menu_set->choose_step];
1114            page_id = p_menu_set->menu_item_page_id[menu_item_pos];
1115    
1116          menu_item_id = p_menu->items[menu_item_pos];          menu_item_id = p_menu->items[menu_item_pos];
1117          p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);          p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
1118          if (p_menu_item == NULL)          if (p_menu_item == NULL)
1119          {          {
1120                  log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);                  log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
1121                  return -1;                  p_menu_set->menu_item_pos[p_menu_set->choose_step] = 0;
1122                    return REDRAW;
1123          }          }
1124    
1125          switch (key)          switch (key)
# Line 893  int menu_control(MENU_SET *p_menu_set, i Line 1147  int menu_control(MENU_SET *p_menu_set, i
1147                          return ((*(p_menu_item->action_cmd_handler))((void *)(p_menu_item->name)));                          return ((*(p_menu_item->action_cmd_handler))((void *)(p_menu_item->name)));
1148                  }                  }
1149                  break;                  break;
1150            case KEY_ESC:
1151          case KEY_LEFT:          case KEY_LEFT:
1152                  if (p_menu_set->choose_step > 0)                  if (p_menu_set->choose_step > 0)
1153                  {                  {
1154                          p_menu_set->choose_step--;                          p_menu_set->choose_step--;
1155                            if (p_menu_set->choose_step == 0)
1156                            {
1157                                    return REDRAW;
1158                            }
1159                          if (display_menu(p_menu_set) != 0)                          if (display_menu(p_menu_set) != 0)
1160                          {                          {
1161                                  return menu_control(p_menu_set, KEY_LEFT);                                  return menu_control(p_menu_set, KEY_LEFT);
# Line 929  int menu_control(MENU_SET *p_menu_set, i Line 1188  int menu_control(MENU_SET *p_menu_set, i
1188                          display_menu_cursor(p_menu_set, 1);                          display_menu_cursor(p_menu_set, 1);
1189                  }                  }
1190                  break;                  break;
1191            case KEY_PGUP:
1192                    require_page_change = 1;
1193          case KEY_UP:          case KEY_UP:
1194                  display_menu_cursor(p_menu_set, 0);                  display_menu_cursor(p_menu_set, 0);
1195                  do                  do
# Line 937  int menu_control(MENU_SET *p_menu_set, i Line 1198  int menu_control(MENU_SET *p_menu_set, i
1198                          if (menu_item_pos < 0)                          if (menu_item_pos < 0)
1199                          {                          {
1200                                  menu_item_pos = p_menu->item_count - 1;                                  menu_item_pos = p_menu->item_count - 1;
1201                                    require_page_change = 0;
1202                          }                          }
1203                          menu_item_id = p_menu->items[menu_item_pos];                          menu_item_id = p_menu->items[menu_item_pos];
1204                          p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);                          p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
# Line 945  int menu_control(MENU_SET *p_menu_set, i Line 1207  int menu_control(MENU_SET *p_menu_set, i
1207                                  log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);                                  log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
1208                                  return -1;                                  return -1;
1209                          }                          }
1210                  } while (!p_menu_set->menu_item_display[menu_item_pos]);                          if (require_page_change && p_menu_set->menu_item_page_id[menu_item_pos] != page_id)
1211                            {
1212                                    require_page_change = 0;
1213                            }
1214                    } while (require_page_change || !p_menu_set->menu_item_display[menu_item_pos]);
1215                  p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;                  p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1216                    if (p_menu_set->menu_item_page_id[menu_item_pos] != page_id)
1217                    {
1218                            display_menu_current_page(p_menu_set);
1219                    }
1220                  display_menu_cursor(p_menu_set, 1);                  display_menu_cursor(p_menu_set, 1);
1221                  break;                  break;
1222            case KEY_PGDN:
1223                    require_page_change = 1;
1224          case KEY_DOWN:          case KEY_DOWN:
1225                  display_menu_cursor(p_menu_set, 0);                  display_menu_cursor(p_menu_set, 0);
1226                  do                  do
# Line 957  int menu_control(MENU_SET *p_menu_set, i Line 1229  int menu_control(MENU_SET *p_menu_set, i
1229                          if (menu_item_pos >= p_menu->item_count)                          if (menu_item_pos >= p_menu->item_count)
1230                          {                          {
1231                                  menu_item_pos = 0;                                  menu_item_pos = 0;
1232                                    require_page_change = 0;
1233                          }                          }
1234                          menu_item_id = p_menu->items[menu_item_pos];                          menu_item_id = p_menu->items[menu_item_pos];
1235                          p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);                          p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
# Line 965  int menu_control(MENU_SET *p_menu_set, i Line 1238  int menu_control(MENU_SET *p_menu_set, i
1238                                  log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);                                  log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
1239                                  return -1;                                  return -1;
1240                          }                          }
1241                  } while (!p_menu_set->menu_item_display[menu_item_pos]);                          if (require_page_change && p_menu_set->menu_item_page_id[menu_item_pos] != page_id)
1242                            {
1243                                    require_page_change = 0;
1244                            }
1245                    } while (require_page_change || !p_menu_set->menu_item_display[menu_item_pos]);
1246                  p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;                  p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1247                    if (p_menu_set->menu_item_page_id[menu_item_pos] != page_id)
1248                    {
1249                            display_menu_current_page(p_menu_set);
1250                    }
1251                  display_menu_cursor(p_menu_set, 1);                  display_menu_cursor(p_menu_set, 1);
1252                  break;                  break;
1253          case KEY_HOME:          case KEY_HOME:
         case KEY_PGUP:  
1254                  display_menu_cursor(p_menu_set, 0);                  display_menu_cursor(p_menu_set, 0);
1255                  menu_item_pos = 0;                  menu_item_pos = 0;
1256                  while (menu_item_pos < p_menu->item_count - 1)                  while (menu_item_pos < p_menu->item_count - 1)
# Line 991  int menu_control(MENU_SET *p_menu_set, i Line 1271  int menu_control(MENU_SET *p_menu_set, i
1271                          menu_item_pos++;                          menu_item_pos++;
1272                  }                  }
1273                  p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;                  p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1274                    if (p_menu_set->menu_item_page_id[menu_item_pos] != page_id)
1275                    {
1276                            display_menu_current_page(p_menu_set);
1277                    }
1278                  display_menu_cursor(p_menu_set, 1);                  display_menu_cursor(p_menu_set, 1);
1279                  break;                  break;
1280          case KEY_END:          case KEY_END:
         case KEY_PGDN:  
1281                  display_menu_cursor(p_menu_set, 0);                  display_menu_cursor(p_menu_set, 0);
1282                  menu_item_pos = p_menu->item_count - 1;                  menu_item_pos = p_menu->item_count - 1;
1283                  while (menu_item_pos > 0)                  while (menu_item_pos > 0)
# Line 1015  int menu_control(MENU_SET *p_menu_set, i Line 1298  int menu_control(MENU_SET *p_menu_set, i
1298                          menu_item_pos--;                          menu_item_pos--;
1299                  }                  }
1300                  p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;                  p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1301                    if (p_menu_set->menu_item_page_id[menu_item_pos] != page_id)
1302                    {
1303                            display_menu_current_page(p_menu_set);
1304                    }
1305                  display_menu_cursor(p_menu_set, 1);                  display_menu_cursor(p_menu_set, 1);
1306                  break;                  break;
1307          default:          default:
# Line 1034  int menu_control(MENU_SET *p_menu_set, i Line 1321  int menu_control(MENU_SET *p_menu_set, i
1321                                  {                                  {
1322                                          display_menu_cursor(p_menu_set, 0);                                          display_menu_cursor(p_menu_set, 0);
1323                                          p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;                                          p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1324                                            if (p_menu_set->menu_item_page_id[menu_item_pos] != page_id)
1325                                            {
1326                                                    display_menu_current_page(p_menu_set);
1327                                            }
1328                                          display_menu_cursor(p_menu_set, 1);                                          display_menu_cursor(p_menu_set, 1);
1329                                          return 0;                                          break;
1330                                  }                                  }
1331                          }                          }
1332                  }                  }
1333                  break;                  break;
1334          }          }
1335    
1336          return 0;          return NOREDRAW;
1337  }  }
1338    
1339  int unload_menu(MENU_SET *p_menu_set)  int unload_menu(MENU_SET *p_menu_set)
1340  {  {
1341            int shmid;
1342    
1343            if (p_menu_set == NULL)
1344            {
1345                    return -1;
1346            }
1347    
1348          if (p_menu_set->p_menu_name_dict != NULL)          if (p_menu_set->p_menu_name_dict != NULL)
1349          {          {
1350                  trie_dict_destroy(p_menu_set->p_menu_name_dict);                  trie_dict_destroy(p_menu_set->p_menu_name_dict);
# Line 1059  int unload_menu(MENU_SET *p_menu_set) Line 1357  int unload_menu(MENU_SET *p_menu_set)
1357                  p_menu_set->p_menu_screen_dict = NULL;                  p_menu_set->p_menu_screen_dict = NULL;
1358          }          }
1359    
1360          unload_menu_shm(p_menu_set);          shmid = p_menu_set->shmid;
1361    
1362          if (shmctl(p_menu_set->shmid, IPC_RMID, NULL) == -1)          detach_menu_shm(p_menu_set);
1363    
1364            if (shmctl(shmid, IPC_RMID, NULL) == -1)
1365          {          {
1366                  log_error("shmctl(shmid=%d, IPC_RMID) error (%d)\n", p_menu_set->shmid, errno);                  log_error("shmctl(shmid=%d, IPC_RMID) error (%d)\n", shmid, errno);
1367                  return -1;                  return -1;
1368          }          }
1369    
1370          return 0;          return 0;
1371  }  }
1372    
1373  int load_menu_shm(MENU_SET *p_menu_set)  int set_menu_shm_readonly(MENU_SET *p_menu_set)
1374  {  {
1375          // Mount shared memory          void *p_shm;
1376          if (p_menu_set->p_reserved == NULL)  
1377            // Remap shared memory in read-only mode
1378            p_shm = shmat(p_menu_set->shmid, p_menu_set->p_reserved, SHM_RDONLY | SHM_REMAP);
1379            if (p_shm == (void *)-1)
1380          {          {
1381                  p_menu_set->p_reserved = shmat(p_menu_set->shmid, NULL, SHM_RDONLY);                  log_error("shmat(menu_shm shmid = %d) error (%d)\n", p_menu_set->shmid, errno);
1382                  if (p_menu_set->p_reserved == (void *)-1)                  return -1;
                 {  
                         log_error("shmat() error (%d)\n", errno);  
                         return -1;  
                 }  
1383          }          }
1384    
1385          p_menu_set->p_menu_pool = p_menu_set->p_reserved + MENU_SET_RESERVED_LENGTH;          p_menu_set->p_reserved = p_shm;
         p_menu_set->p_menu_item_pool = p_menu_set->p_menu_pool + sizeof(MENU) * MAX_MENUS;  
         p_menu_set->p_menu_screen_pool = p_menu_set->p_menu_item_pool + sizeof(MENU_ITEM) * MAX_MENUITEMS;  
         p_menu_set->p_menu_screen_buf = p_menu_set->p_menu_screen_pool + sizeof(MENU_SCREEN) * MAX_MENUS;  
         p_menu_set->p_menu_screen_buf_free = p_menu_set->p_menu_screen_buf;  
   
         // Restore status varaibles into reserved memory area  
         p_menu_set->menu_count = *((int16_t *)p_menu_set->p_reserved);  
         p_menu_set->menu_item_count = *(((int16_t *)p_menu_set->p_reserved) + 1);  
         p_menu_set->menu_screen_count = *(((int16_t *)p_menu_set->p_reserved) + 2);  
   
         p_menu_set->choose_step = 0;  
         p_menu_set->menu_id_path[0] = 0;  
   
         p_menu_set->p_menu_name_dict = NULL;  
         p_menu_set->p_menu_screen_dict = NULL;  
1386    
1387          return 0;          return 0;
1388  }  }
1389    
1390  int unload_menu_shm(MENU_SET *p_menu_set)  int detach_menu_shm(MENU_SET *p_menu_set)
1391  {  {
1392          p_menu_set->menu_count = 0;          p_menu_set->menu_count = 0;
1393          p_menu_set->menu_item_count = 0;          p_menu_set->menu_item_count = 0;
# Line 1116  int unload_menu_shm(MENU_SET *p_menu_set Line 1400  int unload_menu_shm(MENU_SET *p_menu_set
1400          p_menu_set->p_menu_screen_buf = NULL;          p_menu_set->p_menu_screen_buf = NULL;
1401          p_menu_set->p_menu_screen_buf_free = NULL;          p_menu_set->p_menu_screen_buf_free = NULL;
1402    
1403            p_menu_set->p_menu_name_dict = NULL;
1404            p_menu_set->p_menu_screen_dict = NULL;
1405    
1406          if (p_menu_set->p_reserved != NULL && shmdt(p_menu_set->p_reserved) == -1)          if (p_menu_set->p_reserved != NULL && shmdt(p_menu_set->p_reserved) == -1)
1407          {          {
1408                  log_error("shmdt() error (%d)\n", errno);                  log_error("shmdt() error (%d)\n", errno);
1409                  return -1;                  return -1;
1410          }          }
1411    
1412          p_menu_set->p_reserved = NULL;          p_menu_set->p_reserved = NULL;
1413    
1414          return 0;          return 0;


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

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