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

Contents of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (show annotations)
Mon Mar 21 04:43:47 2005 UTC (21 years ago) by sysadm
Branch: MAIN
Changes since 1.10: +31 -18 lines
Content type: text/x-csrc
*** empty log message ***

1 /***************************************************************************
2 menu.c - description
3 -------------------
4 begin : Wed Mar 16 2004
5 copyright : (C) 2005 by Leaflet
6 email : leaflet@leafok.com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "bbs.h"
19 #include "menu.h"
20 #include "io.h"
21 #include "common.h"
22 #include <stdio.h>
23 #include <ctype.h>
24 #include <regex.h>
25 #include <stdlib.h>
26
27 MENU_SET bbs_menu;
28
29 int
30 load_menu (MENU_SET * p_menu_set, const char *conf_file)
31 {
32 FILE *fin, *fout;
33 int i = 0, j;
34 char buffer[256], screen_filename[256], temp[256];
35 regmatch_t pmatch[10];
36
37 if ((fin = fopen (conf_file, "r")) == NULL)
38 {
39 log_error ("Open %s failed", conf_file);
40 return -1;
41 }
42
43 while (fgets (buffer, 255, fin))
44 {
45 switch (buffer[0])
46 {
47 case '#':
48 break;
49 case '%':
50 if (ireg ("^%S_([A-Za-z0-9_]+)", buffer, 2, pmatch) == 0)
51 {
52 strncpy (temp, buffer + pmatch[1].rm_so,
53 pmatch[1].rm_eo - pmatch[1].rm_so);
54 temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
55 sprintf (screen_filename, "%sMENU_SCR_%s", app_temp_dir, temp);
56
57 if ((fout = fopen (screen_filename, "w")) == NULL)
58 {
59 log_error ("Open %s failed", screen_filename);
60 return -2;
61 }
62
63 while (fgets (buffer, 255, fin))
64 {
65 if (buffer[0] != '%')
66 fputs (buffer, fout);
67 else
68 break;
69 }
70
71 fclose (fout);
72 break;
73 }
74
75 if (ireg ("^%menu ([A-Za-z0-9_]+)", buffer, 2, pmatch) == 0)
76 {
77 p_menu_set->p_menu[i] = malloc (sizeof (MENU));
78
79 strncpy (p_menu_set->p_menu[i]->name,
80 buffer + pmatch[1].rm_so,
81 pmatch[1].rm_eo - pmatch[1].rm_so);
82 p_menu_set->p_menu[i]->name[pmatch[1].rm_eo - pmatch[1].rm_so] =
83 '\0';
84
85 j = 0;
86
87 while (fgets (buffer, 255, fin))
88 {
89 if (buffer[0] == '#')
90 {
91 continue;
92 }
93 if (buffer[0] == '%')
94 {
95 p_menu_set->p_menu[i]->item_count = j;
96 p_menu_set->p_menu[i]->item_cur_pos = 0;
97 i++;
98 break;
99 }
100 if (ireg ("^!([A-Za-z0-9_.]+)[[:space:]]*([0-9]+),"
101 "[[:space:]]*([0-9]+),[[:space:]]*([0-9]+),"
102 "[[:space:]]*([0-9]+),[[:space:]]*\"([A-Za-z0-9_]+)\","
103 "[[:space:]]*\"([^\"]+)\"",
104 buffer, 8, pmatch) == 0)
105 {
106 p_menu_set->p_menu[i]->items[j] =
107 malloc (sizeof (MENU_ITEM));
108 p_menu_set->p_menu[i]->items[j]->submenu = 1;
109 strncpy (p_menu_set->p_menu[i]->items[j]->action,
110 buffer + pmatch[1].rm_so,
111 pmatch[1].rm_eo - pmatch[1].rm_so);
112 p_menu_set->p_menu[i]->items[j]->action[pmatch[1].
113 rm_eo -
114 pmatch[1].
115 rm_so] = '\0';
116 strncpy (temp, buffer + pmatch[2].rm_so,
117 pmatch[2].rm_eo - pmatch[2].rm_so);
118 temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
119 p_menu_set->p_menu[i]->items[j]->row = atoi (temp);
120 strncpy (temp,
121 buffer + pmatch[3].rm_so,
122 pmatch[3].rm_eo - pmatch[3].rm_so);
123 temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
124 p_menu_set->p_menu[i]->items[j]->col = atoi (temp);
125 strncpy (temp,
126 buffer + pmatch[4].rm_so,
127 pmatch[4].rm_eo - pmatch[4].rm_so);
128 temp[pmatch[4].rm_eo - pmatch[4].rm_so] = '\0';
129 p_menu_set->p_menu[i]->items[j]->priv = atoi (temp);
130 strncpy (temp,
131 buffer + pmatch[5].rm_so,
132 pmatch[5].rm_eo - pmatch[5].rm_so);
133 temp[pmatch[5].rm_eo - pmatch[5].rm_so] = '\0';
134 p_menu_set->p_menu[i]->items[j]->level = atoi (temp);
135 strncpy (p_menu_set->p_menu[i]->items[j]->name,
136 buffer + pmatch[6].rm_so,
137 pmatch[6].rm_eo - pmatch[6].rm_so);
138 p_menu_set->p_menu[i]->items[j]->name[pmatch[6].rm_eo -
139 pmatch[6].rm_so] =
140 '\0';
141 strncpy (p_menu_set->p_menu[i]->items[j]->text,
142 buffer + pmatch[7].rm_so,
143 pmatch[7].rm_eo - pmatch[7].rm_so);
144 p_menu_set->p_menu[i]->items[j]->text[pmatch[7].rm_eo -
145 pmatch[7].rm_so] =
146 '\0';
147 j++;
148 continue;
149 }
150 if (ireg ("^@([A-Za-z0-9_]+)[[:space:]]*([0-9]+),"
151 "[[:space:]]*([0-9]+),[[:space:]]*([0-9]+),"
152 "[[:space:]]*([0-9]+),[[:space:]]*\"([A-Za-z0-9_]+)\","
153 "[[:space:]]*\"([^\"]+)\"",
154 buffer, 8, pmatch) == 0)
155 {
156 p_menu_set->p_menu[i]->items[j] =
157 malloc (sizeof (MENU_ITEM));
158 p_menu_set->p_menu[i]->items[j]->submenu = 0;
159 strncpy (p_menu_set->p_menu[i]->items[j]->action,
160 buffer + pmatch[1].rm_so,
161 pmatch[1].rm_eo - pmatch[1].rm_so);
162 p_menu_set->p_menu[i]->items[j]->action[pmatch[0].
163 rm_eo -
164 pmatch[0].
165 rm_so] = '\0';
166 strncpy (temp, buffer + pmatch[2].rm_so,
167 pmatch[2].rm_eo - pmatch[2].rm_so);
168 temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
169 p_menu_set->p_menu[i]->items[j]->row = atoi (temp);
170 strncpy (temp,
171 buffer + pmatch[3].rm_so,
172 pmatch[3].rm_eo - pmatch[3].rm_so);
173 temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
174 p_menu_set->p_menu[i]->items[j]->col = atoi (temp);
175 strncpy (temp,
176 buffer + pmatch[4].rm_so,
177 pmatch[4].rm_eo - pmatch[4].rm_so);
178 temp[pmatch[4].rm_eo - pmatch[4].rm_so] = '\0';
179 p_menu_set->p_menu[i]->items[j]->priv = atoi (temp);
180 strncpy (temp,
181 buffer + pmatch[5].rm_so,
182 pmatch[5].rm_eo - pmatch[5].rm_so);
183 temp[pmatch[5].rm_eo - pmatch[5].rm_so] = '\0';
184 p_menu_set->p_menu[i]->items[j]->level = atoi (temp);
185 strncpy (p_menu_set->p_menu[i]->items[j]->name,
186 buffer + pmatch[6].rm_so,
187 pmatch[6].rm_eo - pmatch[6].rm_so);
188 p_menu_set->p_menu[i]->items[j]->name[pmatch[6].rm_eo -
189 pmatch[6].rm_so] =
190 '\0';
191 strncpy (p_menu_set->p_menu[i]->items[j]->text,
192 buffer + pmatch[7].rm_so,
193 pmatch[7].rm_eo - pmatch[7].rm_so);
194 p_menu_set->p_menu[i]->items[j]->text[pmatch[7].rm_eo -
195 pmatch[7].rm_so] =
196 '\0';
197 j++;
198 continue;
199 }
200 if (ireg ("^title[[:space:]]*([0-9]+),"
201 "[[:space:]]*([0-9]+),[[:space:]]*\"([^\"]+)\"",
202 buffer, 4, pmatch) == 0)
203 {
204 strncpy (temp,
205 buffer + pmatch[1].rm_so,
206 pmatch[1].rm_eo - pmatch[1].rm_so);
207 temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
208 p_menu_set->p_menu[i]->title.row = atoi (temp);
209 strncpy (temp,
210 buffer + pmatch[2].rm_so,
211 pmatch[2].rm_eo - pmatch[2].rm_so);
212 temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
213 p_menu_set->p_menu[i]->title.col = atoi (temp);
214 strncpy (p_menu_set->p_menu[i]->title.text,
215 buffer + pmatch[3].rm_so,
216 pmatch[3].rm_eo - pmatch[3].rm_so);
217 p_menu_set->p_menu[i]->title.text[pmatch[3].rm_eo -
218 pmatch[3].rm_so] =
219 '\0';
220 continue;
221 }
222 if (ireg ("^screen[[:space:]]*([0-9]+),"
223 "[[:space:]]*([0-9]+),[[:space:]]*S_([A-Za-z0-9_]+)",
224 buffer, 4, pmatch) == 0)
225 {
226 strncpy (temp,
227 buffer + pmatch[1].rm_so,
228 pmatch[1].rm_eo - pmatch[1].rm_so);
229 temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
230 p_menu_set->p_menu[i]->screen.row = atoi (temp);
231 strncpy (temp,
232 buffer + pmatch[2].rm_so,
233 pmatch[2].rm_eo - pmatch[2].rm_so);
234 temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
235 p_menu_set->p_menu[i]->screen.col = atoi (temp);
236 strncpy (temp,
237 buffer + pmatch[3].rm_so,
238 pmatch[3].rm_eo - pmatch[3].rm_so);
239 temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
240 sprintf (p_menu_set->p_menu[i]->screen.filename,
241 "%sMENU_SCR_%s", app_temp_dir, temp);
242 continue;
243 }
244 }
245 }
246 break;
247 }
248 }
249 fclose (fin);
250
251 p_menu_set->menu_count = i;
252 p_menu_set->menu_select_depth = 0;
253 p_menu_set->p_menu_select[p_menu_set->menu_select_depth]
254 = (i == 0 ? NULL : p_menu_set->p_menu[0]);
255
256 return 0;
257 }
258
259 MENU *
260 get_menu (MENU_SET * p_menu_set, const char *menu_name)
261 {
262 int i;
263
264 for (i = 0; i < p_menu_set->menu_count; i++)
265 {
266 if (strcmp (p_menu_set->p_menu[i]->name, menu_name) == 0)
267 {
268 return p_menu_set->p_menu[i];
269 }
270 }
271
272 return NULL;
273 }
274
275 void
276 display_menu_cursor (MENU * p_menu, int show)
277 {
278 moveto ((p_menu->items[p_menu->item_cur_pos])->r_row,
279 (p_menu->items[p_menu->item_cur_pos])->r_col - 2);
280 prints (show ? ">" : " ");
281 iflush ();
282 }
283
284 int
285 display_menu (MENU * p_menu)
286 {
287 int i, row, col, menu_selectable = 0;
288
289 if (p_menu == NULL)
290 return -1;
291
292 show_top (p_menu->title.text);
293
294 moveto (p_menu->screen.row, p_menu->screen.col);
295 if (display_file (p_menu->screen.filename) != 0)
296 log_error ("Display menu screen <%s> failed!\n", p_menu->screen.filename);
297
298 row = p_menu->items[0]->row;
299 col = p_menu->items[0]->col;
300
301 for (i = 0; i < p_menu->item_count; i++)
302 {
303 if (checkpriv (&BBS_priv, 0, p_menu->items[i]->priv) == 0
304 || checklevel (&BBS_priv, p_menu->items[i]->level) == 0)
305 {
306 p_menu->items[i]->display = 0;
307 }
308 else
309 {
310 p_menu->items[i]->display = 1;
311
312 menu_selectable = 1;
313
314 if (p_menu->items[i]->row != 0)
315 row = p_menu->items[i]->row;
316 else
317 row++;
318 p_menu->items[i]->r_row = row;
319 if (p_menu->items[i]->col != 0)
320 col = p_menu->items[i]->col;
321 p_menu->items[i]->r_col = col;
322 moveto (row, col);
323 prints (p_menu->items[i]->text);
324 iflush ();
325 }
326 }
327
328 if (!menu_selectable)
329 return -1;
330
331 display_menu_cursor (p_menu, 1);
332
333 return 0;
334 }
335
336 const char *
337 menu_control (MENU_SET * p_menu_set, int key)
338 {
339 int i;
340 MENU *p_menu;
341
342 if (p_menu_set->menu_count == 0)
343 return "";
344
345 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
346
347 switch (key)
348 {
349 case CR:
350 case KEY_RIGHT:
351 if (p_menu->items[p_menu->item_cur_pos]->submenu)
352 {
353 if (strcmp (p_menu->items[p_menu->item_cur_pos]->action, "..") == 0)
354 return menu_control (p_menu_set, KEY_LEFT);
355 p_menu_set->menu_select_depth++;
356 p_menu =
357 p_menu_set->p_menu_select[p_menu_set->menu_select_depth] =
358 get_menu (p_menu_set,
359 p_menu->items[p_menu->item_cur_pos]->action);
360 if (display_menu (p_menu) != 0)
361 return menu_control (p_menu_set, KEY_LEFT);
362 break;
363 }
364 else
365 {
366 return (p_menu->items[p_menu->item_cur_pos]->action);
367 }
368 case KEY_LEFT:
369 if (p_menu_set->menu_select_depth > 0)
370 {
371 p_menu_set->menu_select_depth--;
372 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
373 if (display_menu (p_menu) != 0)
374 return menu_control (p_menu_set, KEY_LEFT);
375 break;
376 }
377 else
378 {
379 display_menu_cursor (p_menu, 0);
380 p_menu->item_cur_pos = p_menu->item_count - 1;
381 while (!p_menu->items[p_menu->item_cur_pos]->display)
382 p_menu->item_cur_pos--;
383 display_menu_cursor (p_menu, 1);
384 break;
385 }
386 case KEY_UP:
387 display_menu_cursor (p_menu, 0);
388 do
389 {
390 p_menu->item_cur_pos--;
391 if (p_menu->item_cur_pos < 0)
392 p_menu->item_cur_pos = p_menu->item_count - 1;
393 }
394 while (!p_menu->items[p_menu->item_cur_pos]->display);
395 display_menu_cursor (p_menu, 1);
396 break;
397 case KEY_DOWN:
398 display_menu_cursor (p_menu, 0);
399 do
400 {
401 p_menu->item_cur_pos++;
402 if (p_menu->item_cur_pos >= p_menu->item_count)
403 p_menu->item_cur_pos = 0;
404 }
405 while (!p_menu->items[p_menu->item_cur_pos]->display);
406 display_menu_cursor (p_menu, 1);
407 break;
408 default:
409 for (i = 0; i < p_menu->item_count; i++)
410 {
411 if (toupper (key) == toupper (p_menu->items[i]->name[0]))
412 {
413 display_menu_cursor (p_menu, 0);
414 p_menu->item_cur_pos = i;
415 display_menu_cursor (p_menu, 1);
416 break;
417 }
418 }
419 }
420
421 return "";
422 }

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