C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
Menu Engine

Main loop and command processor for the C-Menu menu system. More...

Functions

unsigned int menu_cmd_processor (Init *init)
 Processes user input for the menu system.
unsigned int menu_engine (Init *init)
 The main loop of the menu system.

Detailed Description

Main loop and command processor for the C-Menu menu system.

This module contains the core functionality for displaying menus, processing user input, and executing commands associated with menu choices. It handles navigation through menu options, responding to special keys, and managing the display of submenus, pick lists, forms, and views.

Function Documentation

◆ menu_cmd_processor()

unsigned int menu_cmd_processor ( Init * init)

Processes user input for the menu system.

Parameters
initA pointer to an Init structure containing initialization data for the menu system.
Returns
an integer indicating the action taken by the user, such as returning to the main menu, displaying a submenu, or executing a command associated with a menu choice.

handles navigation through the menu options, executing commands associated with menu choices, and responding to special keys such as function keys and mouse clicks.

Move up to the previous menu choice

Move down to the next menu choice

Select the current menu choice and execute its associated command

Display help information for the menu system

Exit the menu and return to the previous menu or exit if at top

send default printer output file to printer

open the default editor

process mouse event

If the user presses a key that corresponds to a menu choice's letter, select that menu choice

Execute the command associated with the selected menu choice

Display help information for the menu system

Display a submenu or perform an action associated with the selected menu choice

Display a pick list or form associated with the selected menu choice

Display a form associated with the selected menu choice

Display a view associated with the selected menu choice

open ckeys (test curses keys)

return to calling program

write the current menu configuration to a file

Definition at line 133 of file menu_engine.c.

133 {
134 int i, c;
135 int len;
136 char *d;
137 int in_key;
138 char tmp_str[MAXLEN];
139 char earg_str[MAXLEN];
140 char *eargv[MAXARGS];
141 int eargc;
142 mbstate_t mbstate;
143 memset(&mbstate, 0, sizeof(mbstate));
144 cchar_t cc = {0};
145 Menu *menu = init->menu;
146 keypad(win_win[win_ptr], TRUE);
147 mousemask(BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED, nullptr);
148 MEVENT event;
149 scrollok(win_win[win_ptr], FALSE);
150
151 // Highlight the currently selected menu choice
152
153 while (1) {
154 wbkgrndset(win_win[win_ptr], &CC_NT_REV);
155 mvwaddstr_fill(win_win[win_ptr], menu->line_idx, 0,
156 menu->line[menu->line_idx]->choice_text, menu->cols);
157 wbkgrndset(win_win[win_ptr], &CC_NT);
158 // Highlight the letter of the currently selected menu choice
159 wchar_t wstr[2] = {L'\0', L'\0'};
160 len = mbrtowc(wstr, &menu->line[menu->line_idx]->choice_letter,
161 MB_CUR_MAX, &mbstate);
162 if (len < 0) {
163 wstr[0] = L'?';
164 wstr[1] = L'\0';
165 }
166 setcchar(&cc, wstr, WA_NORMAL, cp_nt_hl_rev, nullptr);
167 mvwadd_wch(win_win[win_ptr], menu->line_idx,
168 menu->line[menu->line_idx]->letter_pos, &cc);
169
170 // Wait for user input and process it
171 event.y = event.x = -1;
172 update_panels();
173 doupdate();
174 wmove(win_win[win_ptr], menu->line_idx, 1);
175 in_key = xwgetch(win_win[win_ptr], nullptr, -1);
176
177 // Remove the highlight from the currently selected menu choice
178 mvwaddstr_fill(win_win[win_ptr], menu->line_idx, 0,
179 menu->line[menu->line_idx]->choice_text, menu->cols);
180 len = mbrtowc(wstr, &menu->line[menu->line_idx]->choice_letter,
181 MB_CUR_MAX, &mbstate);
182 if (len < 0) {
183 wstr[0] = L'?';
184 wstr[1] = L'\0';
185 }
186 setcchar(&cc, wstr, WA_NORMAL, cp_nt_hl, nullptr);
187 mvwadd_wch(win_win[win_ptr], menu->line_idx,
188 menu->line[menu->line_idx]->letter_pos, &cc);
189 // Initialize the mouse event coordinates to -1 to indicate no mouse
190 // event
191 event.y = event.x = -1;
192 switch (in_key) {
194 case KEY_UP:
195 i = menu->line_idx;
196 while (i > 0) {
197 i--;
198 if (menu->line[i]->type == MT_CHOICE) {
199 menu->line_idx = i;
200 break;
201 }
202 }
203 return (MA_CONTINUE);
205 case KEY_DOWN:
206 i = menu->line_idx;
207 while (i < menu->item_count - 1) {
208 i++;
209 if (menu->line[i]->type == MT_CHOICE) {
210 menu->line_idx = i;
211 break;
212 }
213 }
214 return (MA_CONTINUE);
217 case '\n':
218 case KEY_ENTER:
219 break;
221 case '?':
222 case KEY_F(1):
223 if (menu->f_help_spec && menu->help_spec[0] != '\0')
224 strnz__cpy(tmp_str, menu->help_spec, MAXLEN - 1);
225 else {
226 strnz__cpy(tmp_str, init->mapp_help, MAXLEN - 1);
227 strnz__cat(tmp_str, "/", MAXLEN - 1);
228 strnz__cat(tmp_str, MENU_HELP_FILE, MAXLEN - 1);
229 }
230 eargc = 0;
231 eargv[eargc++] = strdup("view");
232 eargv[eargc++] = strdup("-Nf");
233 eargv[eargc++] = strdup(tmp_str);
234 eargv[eargc] = nullptr;
235 init->lines = 51;
236 init->cols = 86;
237 init->begy = menu->begy + 1;
238 init->begx = menu->begx + 1;
239 strnz__cpy(init->title, "Menu Help", MAXLEN - 1);
240 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
241 init->begx);
243 return (MA_DISPLAY_MENU);
246 case KEY_F(9):
247 case KEY_BREAK:
248 return (MA_RETURN);
250 case KEY_ALTF(9):
251 d = getenv("PRTCMD");
252 if (d == nullptr || *d == '\0')
254 else
255 strnz__cpy(earg_str, d, MAXLEN - 1);
256 strnz__cat(earg_str, " ", MAXLEN - 1);
257 d = getenv("PRTFILE");
258 if (d == nullptr || *d == '\0') {
259 d = getenv("HOME");
260 if (d == nullptr || *d == '\0')
262 else {
263 strnz__cat(earg_str, d, MAXLEN - 1);
264 strnz__cat(earg_str, "/", MAXLEN - 1);
266 }
267 } else
268 strnz__cat(earg_str, d, MAXLEN - 1);
270 return (MA_RESET_MENU);
272 case KEY_ALTF(10):
273 restore_wins();
274 return (MA_DISPLAY_MENU);
276 case KEY_MOUSE:
277 if (click_y == -1 || click_x == -1)
278 return (MA_CONTINUE);
279 if (click_y < 0 || click_y >= menu->item_count)
280 return (MA_CONTINUE);
281 menu->line_idx = click_y;
282 break;
283 default:
286 if (in_key == 'q')
287 return (MA_RETURN);
288 for (i = 0; i < menu->item_count; i++) {
289 if (menu->line[i]->raw_text[0] == '_') {
290 if (menu->line[i]->choice_letter == (char)in_key) {
291 menu->line_idx = i;
292 break;
293 }
294 } else {
295 if (menu->line[i]->choice_letter == (char)in_key) {
296 menu->line_idx = i;
297 break;
298 }
299 }
300 }
301 if (i >= menu->item_count)
302 return (MA_CONTINUE);
303 break;
304 }
305 char *s;
306 c = (int)menu->line[menu->line_idx]->command_type;
307 switch (c) {
311 case CT_DEXE:
312 s = strpbrk(menu->line[menu->line_idx]->command_str, " \t\f\v");
313 strnz__cpy(earg_str, s, MAXLEN - 1);
314 trim(earg_str);
318 return (MA_RESET_MENU);
319 case CT_EXEC:
320 s = strpbrk(menu->line[menu->line_idx]->command_str, " \t\f\v");
321 strnz__cpy(earg_str, s, MAXLEN - 1);
322 trim(earg_str);
324 stdio_names(stdio_names_str, "menu_engine.c:328");
327 return (MA_RESET_MENU);
329 case CT_HELP:
330 if (menu->f_help_spec && menu->help_spec[0] != '\0')
331 strnz__cpy(tmp_str, menu->help_spec, MAXLEN - 1);
332 else {
333 strnz__cpy(tmp_str, init->mapp_help, MAXLEN - 1);
334 strnz__cat(tmp_str, "/", MAXLEN - 1);
335 strnz__cat(tmp_str, MENU_HELP_FILE, MAXLEN - 1);
336 }
337 eargc = 0;
338 eargv[eargc++] = strdup("view");
339 eargv[eargc++] = strdup("-N");
340 eargv[eargc++] = strdup("f");
341 eargv[eargc++] = strdup(tmp_str);
342 eargv[eargc] = nullptr;
343 init->lines = 40;
344 init->cols = 60;
345 init->begy = menu->begy + 1;
346 init->begx = menu->begx + 1;
347 strnz__cpy(init->title, "Menu Help", MAXLEN - 1);
348 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
349 init->begx);
351 return (MA_DISPLAY_MENU);
354 case CT_MENU:
355 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
356 MAXLEN - 1);
358 if (eargc == 0)
359 return (MA_DISPLAY_MENU);
360 popup_menu(init, eargc, eargv, menu->begy + 1, menu->begx + 1);
362 return (MA_RESET_MENU);
365 case CT_PICK:
366 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
367 MAXLEN - 1);
369 popup_pick(init, eargc, eargv, menu->begy + 1, menu->begx + 1);
371 return (MA_DISPLAY_MENU);
374 case CT_FORM:
375 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
376 MAXLEN - 1);
378 popup_form(init, eargc, eargv, menu->begy + 1, menu->begx + 1);
380 return (MA_RESET_MENU);
383 case CT_VIEW:
384 strnz__cpy(earg_str, menu->line[menu->line_idx]->command_str,
385 MAXLEN - 1);
387 init->lines = 66;
388 init->cols = 80;
389 init->begy = menu->begy + 1;
390 init->begx = menu->begx + 1;
391 strnz__cpy(init->title, menu->line[menu->line_idx]->raw_text,
392 MAXLEN - 1);
393 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
394 init->begx);
396 return (MA_DISPLAY_MENU);
398 case CT_CKEYS:
399 popup_ckeys();
400 return (MA_DISPLAY_MENU);
402 case CT_RETURN:
403 return (MA_RETURN);
405 case CT_WRITE_CONFIG:
406 write_config(init);
407 return (MA_CONTINUE);
408 default:
409 return (MA_CONTINUE);
410 }
411 }
412 return 0;
413}
#define PRINTCMD
Definition common.h:47
#define VIEW_PRT_FILE
Definition common.h:36
int popup_ckeys()
Display Curses Keys Responds to curses keys and mouse events, displaying the key code and description...
Definition curskeys.c:23
int popup_form(Init *, int, char **, int, int)
instantiate a form popup window
Definition popups.c:112
#define MENU_HELP_FILE
Definition common.h:32
int popup_menu(Init *, int, char **, int, int)
instantiate a menu popup window
Definition popups.c:53
int popup_view(Init *, int, char **, int, int, int, int)
instantiate a view popup window
Definition popups.c:144
int popup_pick(Init *, int, char **, int, int)
instantiate a pick popup window
Definition popups.c:83
int cp_nt_hl
Definition dwin.c:185
WINDOW * win_win[MAXWIN]
Definition dwin.c:52
#define MAX_ARGS
Definition cm.h:46
#define MAXARGS
Definition cm.h:48
cchar_t CC_NT
Definition dwin.c:204
char * stdio_names(char *, char *)
Definition futil.c:1064
int click_x
Definition dwin.c:81
int cp_nt_hl_rev
Definition dwin.c:186
char stdio_names_str[MAXLEN]
Definition futil.c:134
int win_ptr
Definition dwin.c:164
int click_y
Definition dwin.c:80
#define KEY_ALTF(n)
Definition cm.h:503
cchar_t CC_NT_REV
Definition dwin.c:205
@ MT_CHOICE
Definition menu.h:24
@ CT_PICK
Definition menu.h:46
@ CT_FORM
Definition menu.h:42
@ CT_DEXE
Definition menu.h:38
@ CT_MENU
Definition menu.h:45
@ CT_RETURN
Definition menu.h:49
@ CT_HELP
Definition menu.h:40
@ CT_WRITE_CONFIG
Definition menu.h:51
@ CT_EXEC
Definition menu.h:39
@ CT_VIEW
Definition menu.h:47
@ CT_CKEYS
Definition menu.h:48
@ MA_RETURN
Definition menu.h:29
@ MA_DISPLAY_MENU
Definition menu.h:30
@ MA_RESET_MENU
Definition menu.h:31
@ MA_CONTINUE
Definition menu.h:32
Menu * menu
Definition mem.c:46
#define TRUE
Definition iloan.c:19
#define FALSE
Definition iloan.c:18
#define MAXLEN
Definition curskeys.c:15
int eargc
Definition futil.c:57
char earg_str[MAXLEN]
Definition futil.c:56
char * eargv[MAXARGS]
Definition futil.c:58
int xwgetch(WINDOW *, Chyron *, int)
Wrapper for wgetch that handles signals, mouse events, checks for clicks on the chyron line,...
Definition dwin.c:2094
void restore_wins()
Restore all windows after a screen resize.
Definition dwin.c:1225
void mvwaddstr_fill(WINDOW *, int, int, char *, int)
For lines shorter than their display area, fill the rest with spaces.
Definition dwin.c:1941
int full_screen_fork_exec(char **)
Execute a command in full screen mode.
Definition exec.c:46
int full_screen_shell(char *)
Execute a shell command in full screen mode.
Definition exec.c:62
int fork_detach_execvp(char **)
Fork, set new session ID, close files, and execute detached command.
Definition detach.c:29
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition futil.c:544
int destroy_argv(int argc, char **argv)
Deallocates memory allocated for argument strings in argv.
Definition futil.c:494
size_t trim(char *)
Trims leading and trailing spaces from string s in place.
Definition futil.c:391
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat
Definition futil.c:573
int str_to_args(char **, char *, int)
Converts a string into an array of argument strings.
Definition futil.c:440
int write_config(Init *)
Write the current configuration to a file specified in init->minitrc.
Definition init.c:1049
char title[MAXLEN]
Definition common.h:129
char mapp_help[MAXLEN]
Definition common.h:148
int begx
Definition common.h:118
int cols
Definition common.h:116
int begy
Definition common.h:117
Menu * menu
Definition common.h:182
int lines
Definition common.h:115
The Menu structure is the main data structure for the menu application, containing all the informatio...
Definition menu.h:106

References Init::begx, Menu::begx, Init::begy, Menu::begy, CC_NT, CC_NT_REV, Line::choice_letter, Line::choice_text, click_x, click_y, Init::cols, Menu::cols, Line::command_str, Line::command_type, cp_nt_hl, cp_nt_hl_rev, CT_CKEYS, CT_DEXE, CT_EXEC, CT_FORM, CT_HELP, CT_MENU, CT_PICK, CT_RETURN, CT_VIEW, CT_WRITE_CONFIG, destroy_argv(), Menu::f_help_spec, fork_detach_execvp(), full_screen_fork_exec(), full_screen_shell(), Menu::help_spec, Menu::item_count, Line::letter_pos, Menu::line, Menu::line_idx, Init::lines, MA_CONTINUE, MA_DISPLAY_MENU, MA_RESET_MENU, MA_RETURN, Init::mapp_help, Init::menu, MT_CHOICE, mvwaddstr_fill(), popup_ckeys(), popup_form(), popup_menu(), popup_pick(), popup_view(), Line::raw_text, restore_wins(), stdio_names(), stdio_names_str, str_to_args(), strnz__cat(), strnz__cpy(), Init::title, trim(), Line::type, win_ptr, win_win, write_config(), and xwgetch().

Referenced by menu_engine().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ menu_engine()

unsigned int menu_engine ( Init * init)

The main loop of the menu system.

Parameters
initA pointer to an Init structure containing initialization data for the menu system.
Returns
an integer indicating the action taken by the user, such as returning to the main menu or exiting the menu system.

displays the menu and processes user input until the user exits the menu or returns to the main menu.

Definition at line 38 of file menu_engine.c.

38 {
39 int action;
40 int i;
41 char tmp_str[MAXLEN];
42 Menu *menu = init->menu;
43 if (menu == nullptr) {
44 Perror("menu_engine: menu is nullptr");
45 return (1);
46 }
47 menu->lines = 0;
48 menu->cols = 0;
49 menu->line_idx = 0;
50 menu->item_count = 0;
51 menu->title[0] = '\0';
52 menu->choice_max_len = 0;
53 menu->text_max_len = 0;
55 if (box_new(menu->lines, menu->cols, menu->begy, menu->begx, menu->title)) {
56 ssnprintf(tmp_str, MAXLEN - 1, "box_new(%d, %d, %d, %d, %s) failed",
57 menu->lines, menu->cols, menu->begy, menu->begx, menu->title);
58 Perror(tmp_str);
59 return 1;
60 }
61
62 scrollok(win_win[win_ptr], false);
63 int len;
64 mbstate_t mbstate;
65 memset(&mbstate, 0, sizeof(mbstate));
66 cchar_t cc = {0};
67
68 action = MA_DISPLAY_MENU;
69 while (action) {
70 switch (action) {
71 case MA_RETURN:
72 win_del();
73 if (win_ptr < 0) {
74 destroy_menu(init);
75 return 0;
76 }
78 return 0;
79 case MA_DISPLAY_MENU:
80 for (menu->line_idx = 0; menu->line_idx < menu->item_count;
81 menu->line_idx++) {
82 // mvwaddstr(win_win[win_ptr], menu->line_idx, 0, menu->line[menu->line_idx]->choice_text);
84 menu->line_idx,
85 0,
86 menu->line[menu->line_idx]->choice_text,
87 menu->cols - 2);
88 // Highlight the letter of the menu choice
89 wchar_t wstr[2] = {L'\0', L'\0'};
90 len = mbrtowc(wstr, &menu->line[menu->line_idx]->choice_letter,
91 MB_CUR_MAX, &mbstate);
92 if (len < 0) {
93 wstr[0] = L'?';
94 wstr[1] = L'\0';
95 }
96 setcchar(&cc, wstr, WA_NORMAL, cp_nt_hl, nullptr);
97 mvwadd_wch(win_win[win_ptr], menu->line_idx,
98 menu->line[menu->line_idx]->letter_pos, &cc);
99 }
100 action = MA_RESET_MENU;
101 break;
102 case MA_RESET_MENU:
103 menu->line_idx = 0;
104 for (i = 0; i < menu->item_count; i++) {
105 if (menu->line[i]->type == MT_CHOICE) {
106 menu->line_idx = i;
107 break;
108 }
109 }
110 action = MA_CONTINUE;
111 break;
112 case MA_CONTINUE:
113 action = menu_cmd_processor(init);
114 break;
115 default:
116 break;
117 }
118 }
119 destroy_menu(init);
120 return 0;
121}
void win_del()
Delete the current window and its associated box window.
Definition dwin.c:1179
int box_new(int, int, int, int, char *)
Create a new window with optional box and title.
Definition dwin.c:967
int Perror(char *)
Display a simple error message window or print to stderr.
Definition dwin.c:1526
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:420
Menu * destroy_menu(Init *init)
Destroy Menu structure.
Definition mem.c:166
unsigned int menu_cmd_processor(Init *)
Processes user input for the menu system.
unsigned int parse_menu_description(Init *)
Parse menu description file and create Menu.

References Menu::begx, Menu::begy, box_new(), Line::choice_letter, Menu::choice_max_len, Line::choice_text, Menu::cols, cp_nt_hl, destroy_menu(), Menu::item_count, Line::letter_pos, Menu::line, Menu::line_idx, Menu::lines, MA_CONTINUE, MA_DISPLAY_MENU, MA_RESET_MENU, MA_RETURN, Init::menu, menu_cmd_processor(), MT_CHOICE, mvwaddstr_fill(), parse_menu_description(), Perror(), restore_wins(), ssnprintf(), Menu::text_max_len, Menu::title, Line::type, win_del(), win_ptr, and win_win.

Referenced by main(), and popup_menu().

Here is the call graph for this function:
Here is the caller graph for this function: