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

Contents of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14 - (show annotations)
Tue Mar 22 12:12:33 2005 UTC (21 years ago) by sysadm
Branch: MAIN
Changes since 1.13: +14 -1 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 p_menu_set->p_menu[i]->title.show = 0;
79 p_menu_set->p_menu[i]->screen.show = 0;
80
81 strncpy (p_menu_set->p_menu[i]->name,
82 buffer + pmatch[1].rm_so,
83 pmatch[1].rm_eo - pmatch[1].rm_so);
84 p_menu_set->p_menu[i]->name[pmatch[1].rm_eo - pmatch[1].rm_so] =
85 '\0';
86
87 j = 0;
88
89 while (fgets (buffer, 255, fin))
90 {
91 if (buffer[0] == '#')
92 {
93 continue;
94 }
95 if (buffer[0] == '%')
96 {
97 p_menu_set->p_menu[i]->item_count = j;
98 p_menu_set->p_menu[i]->item_cur_pos = 0;
99 i++;
100 break;
101 }
102 if (ireg ("^!([A-Za-z0-9_.]+)[[:space:]]*([0-9]+),"
103 "[[:space:]]*([0-9]+),[[:space:]]*([0-9]+),"
104 "[[:space:]]*([0-9]+),[[:space:]]*\"([A-Za-z0-9_]+)\","
105 "[[:space:]]*\"([^\"]+)\"",
106 buffer, 8, pmatch) == 0)
107 {
108 p_menu_set->p_menu[i]->items[j] =
109 malloc (sizeof (MENU_ITEM));
110 p_menu_set->p_menu[i]->items[j]->submenu = 1;
111 strncpy (p_menu_set->p_menu[i]->items[j]->action,
112 buffer + pmatch[1].rm_so,
113 pmatch[1].rm_eo - pmatch[1].rm_so);
114 p_menu_set->p_menu[i]->items[j]->action[pmatch[1].
115 rm_eo -
116 pmatch[1].
117 rm_so] = '\0';
118 strncpy (temp, buffer + pmatch[2].rm_so,
119 pmatch[2].rm_eo - pmatch[2].rm_so);
120 temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
121 p_menu_set->p_menu[i]->items[j]->row = atoi (temp);
122 strncpy (temp,
123 buffer + pmatch[3].rm_so,
124 pmatch[3].rm_eo - pmatch[3].rm_so);
125 temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
126 p_menu_set->p_menu[i]->items[j]->col = atoi (temp);
127 strncpy (temp,
128 buffer + pmatch[4].rm_so,
129 pmatch[4].rm_eo - pmatch[4].rm_so);
130 temp[pmatch[4].rm_eo - pmatch[4].rm_so] = '\0';
131 p_menu_set->p_menu[i]->items[j]->priv = atoi (temp);
132 strncpy (temp,
133 buffer + pmatch[5].rm_so,
134 pmatch[5].rm_eo - pmatch[5].rm_so);
135 temp[pmatch[5].rm_eo - pmatch[5].rm_so] = '\0';
136 p_menu_set->p_menu[i]->items[j]->level = atoi (temp);
137 strncpy (p_menu_set->p_menu[i]->items[j]->name,
138 buffer + pmatch[6].rm_so,
139 pmatch[6].rm_eo - pmatch[6].rm_so);
140 p_menu_set->p_menu[i]->items[j]->name[pmatch[6].rm_eo -
141 pmatch[6].rm_so] =
142 '\0';
143 strncpy (p_menu_set->p_menu[i]->items[j]->text,
144 buffer + pmatch[7].rm_so,
145 pmatch[7].rm_eo - pmatch[7].rm_so);
146 p_menu_set->p_menu[i]->items[j]->text[pmatch[7].rm_eo -
147 pmatch[7].rm_so] =
148 '\0';
149 j++;
150 continue;
151 }
152 if (ireg ("^@([A-Za-z0-9_]+)[[:space:]]*([0-9]+),"
153 "[[:space:]]*([0-9]+),[[:space:]]*([0-9]+),"
154 "[[:space:]]*([0-9]+),[[:space:]]*\"([A-Za-z0-9_]+)\","
155 "[[:space:]]*\"([^\"]+)\"",
156 buffer, 8, pmatch) == 0)
157 {
158 p_menu_set->p_menu[i]->items[j] =
159 malloc (sizeof (MENU_ITEM));
160 p_menu_set->p_menu[i]->items[j]->submenu = 0;
161 strncpy (p_menu_set->p_menu[i]->items[j]->action,
162 buffer + pmatch[1].rm_so,
163 pmatch[1].rm_eo - pmatch[1].rm_so);
164 p_menu_set->p_menu[i]->items[j]->action[pmatch[1].
165 rm_eo -
166 pmatch[1].
167 rm_so] = '\0';
168 strncpy (temp, buffer + pmatch[2].rm_so,
169 pmatch[2].rm_eo - pmatch[2].rm_so);
170 temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
171 p_menu_set->p_menu[i]->items[j]->row = atoi (temp);
172 strncpy (temp,
173 buffer + pmatch[3].rm_so,
174 pmatch[3].rm_eo - pmatch[3].rm_so);
175 temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
176 p_menu_set->p_menu[i]->items[j]->col = atoi (temp);
177 strncpy (temp,
178 buffer + pmatch[4].rm_so,
179 pmatch[4].rm_eo - pmatch[4].rm_so);
180 temp[pmatch[4].rm_eo - pmatch[4].rm_so] = '\0';
181 p_menu_set->p_menu[i]->items[j]->priv = atoi (temp);
182 strncpy (temp,
183 buffer + pmatch[5].rm_so,
184 pmatch[5].rm_eo - pmatch[5].rm_so);
185 temp[pmatch[5].rm_eo - pmatch[5].rm_so] = '\0';
186 p_menu_set->p_menu[i]->items[j]->level = atoi (temp);
187 strncpy (p_menu_set->p_menu[i]->items[j]->name,
188 buffer + pmatch[6].rm_so,
189 pmatch[6].rm_eo - pmatch[6].rm_so);
190 p_menu_set->p_menu[i]->items[j]->name[pmatch[6].rm_eo -
191 pmatch[6].rm_so] =
192 '\0';
193 strncpy (p_menu_set->p_menu[i]->items[j]->text,
194 buffer + pmatch[7].rm_so,
195 pmatch[7].rm_eo - pmatch[7].rm_so);
196 p_menu_set->p_menu[i]->items[j]->text[pmatch[7].rm_eo -
197 pmatch[7].rm_so] =
198 '\0';
199 j++;
200 continue;
201 }
202 if (ireg ("^title[[:space:]]*([0-9]+),"
203 "[[:space:]]*([0-9]+),[[:space:]]*\"([^\"]+)\"",
204 buffer, 4, pmatch) == 0)
205 {
206 p_menu_set->p_menu[i]->title.show = 1;
207 strncpy (temp,
208 buffer + pmatch[1].rm_so,
209 pmatch[1].rm_eo - pmatch[1].rm_so);
210 temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
211 p_menu_set->p_menu[i]->title.row = atoi (temp);
212 strncpy (temp,
213 buffer + pmatch[2].rm_so,
214 pmatch[2].rm_eo - pmatch[2].rm_so);
215 temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
216 p_menu_set->p_menu[i]->title.col = atoi (temp);
217 strncpy (p_menu_set->p_menu[i]->title.text,
218 buffer + pmatch[3].rm_so,
219 pmatch[3].rm_eo - pmatch[3].rm_so);
220 p_menu_set->p_menu[i]->title.text[pmatch[3].rm_eo -
221 pmatch[3].rm_so] =
222 '\0';
223 continue;
224 }
225 if (ireg ("^screen[[:space:]]*([0-9]+),"
226 "[[:space:]]*([0-9]+),[[:space:]]*S_([A-Za-z0-9_]+)",
227 buffer, 4, pmatch) == 0)
228 {
229 p_menu_set->p_menu[i]->screen.show = 1;
230 strncpy (temp,
231 buffer + pmatch[1].rm_so,
232 pmatch[1].rm_eo - pmatch[1].rm_so);
233 temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
234 p_menu_set->p_menu[i]->screen.row = atoi (temp);
235 strncpy (temp,
236 buffer + pmatch[2].rm_so,
237 pmatch[2].rm_eo - pmatch[2].rm_so);
238 temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
239 p_menu_set->p_menu[i]->screen.col = atoi (temp);
240 strncpy (temp,
241 buffer + pmatch[3].rm_so,
242 pmatch[3].rm_eo - pmatch[3].rm_so);
243 temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
244 sprintf (p_menu_set->p_menu[i]->screen.filename,
245 "%sMENU_SCR_%s", app_temp_dir, temp);
246 continue;
247 }
248 }
249 }
250 break;
251 }
252 }
253 fclose (fin);
254
255 p_menu_set->menu_count = i;
256 p_menu_set->menu_select_depth = 0;
257 p_menu_set->p_menu_select[p_menu_set->menu_select_depth]
258 = (i == 0 ? NULL : p_menu_set->p_menu[0]);
259
260 return 0;
261 }
262
263 MENU *
264 get_menu (MENU_SET * p_menu_set, const char *menu_name)
265 {
266 int i;
267
268 for (i = 0; i < p_menu_set->menu_count; i++)
269 {
270 if (strcmp (p_menu_set->p_menu[i]->name, menu_name) == 0)
271 {
272 return p_menu_set->p_menu[i];
273 }
274 }
275
276 return NULL;
277 }
278
279 void
280 display_menu_cursor (MENU * p_menu, int show)
281 {
282 moveto ((p_menu->items[p_menu->item_cur_pos])->r_row,
283 (p_menu->items[p_menu->item_cur_pos])->r_col - 2);
284 prints (show ? ">" : " ");
285 iflush ();
286 }
287
288 int
289 display_menu (MENU * p_menu)
290 {
291 int i, row, col, menu_selectable = 0;
292
293 if (p_menu == NULL)
294 return -1;
295
296 if (p_menu->title.show)
297 show_top (p_menu->title.text);
298
299 if (p_menu->screen.show)
300 {
301 moveto (p_menu->screen.row, p_menu->screen.col);
302 if (display_file (p_menu->screen.filename) != 0)
303 log_error ("Display menu screen <%s> failed!\n",
304 p_menu->screen.filename);
305 }
306
307 row = p_menu->items[0]->row;
308 col = p_menu->items[0]->col;
309
310 for (i = 0; i < p_menu->item_count; i++)
311 {
312 if (checkpriv (&BBS_priv, 0, p_menu->items[i]->priv) == 0
313 || checklevel (&BBS_priv, p_menu->items[i]->level) == 0)
314 {
315 p_menu->items[i]->display = 0;
316 }
317 else
318 {
319 p_menu->items[i]->display = 1;
320
321 menu_selectable = 1;
322
323 if (p_menu->items[i]->row != 0)
324 row = p_menu->items[i]->row;
325 else
326 row++;
327 p_menu->items[i]->r_row = row;
328 if (p_menu->items[i]->col != 0)
329 col = p_menu->items[i]->col;
330 p_menu->items[i]->r_col = col;
331 moveto (row, col);
332 prints (p_menu->items[i]->text);
333 iflush ();
334 }
335 }
336
337 if (!menu_selectable)
338 return -1;
339
340 display_menu_cursor (p_menu, 1);
341
342 return 0;
343 }
344
345 int
346 display_current_menu (MENU_SET * p_menu_set)
347 {
348 MENU *p_menu;
349
350 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
351
352 return display_menu (p_menu);
353 }
354
355 const char *
356 menu_control (MENU_SET * p_menu_set, int key)
357 {
358 int i;
359 MENU *p_menu;
360
361 if (p_menu_set->menu_count == 0)
362 return "";
363
364 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
365
366 switch (key)
367 {
368 case CR:
369 case KEY_RIGHT:
370 if (p_menu->items[p_menu->item_cur_pos]->submenu)
371 {
372 if (strcmp (p_menu->items[p_menu->item_cur_pos]->action, "..") == 0)
373 return menu_control (p_menu_set, KEY_LEFT);
374 p_menu_set->menu_select_depth++;
375 p_menu =
376 p_menu_set->p_menu_select[p_menu_set->menu_select_depth] =
377 get_menu (p_menu_set,
378 p_menu->items[p_menu->item_cur_pos]->action);
379 if (display_menu (p_menu) != 0)
380 return menu_control (p_menu_set, KEY_LEFT);
381 break;
382 }
383 else
384 {
385 return (p_menu->items[p_menu->item_cur_pos]->action);
386 }
387 case KEY_LEFT:
388 if (p_menu_set->menu_select_depth > 0)
389 {
390 p_menu_set->menu_select_depth--;
391 if (display_current_menu (p_menu_set) != 0)
392 return menu_control (p_menu_set, KEY_LEFT);
393 break;
394 }
395 else
396 {
397 display_menu_cursor (p_menu, 0);
398 p_menu->item_cur_pos = p_menu->item_count - 1;
399 while (!p_menu->items[p_menu->item_cur_pos]->display
400 || p_menu->items[p_menu->item_cur_pos]->priv != 0
401 || p_menu->items[p_menu->item_cur_pos]->level != 0)
402 p_menu->item_cur_pos--;
403 display_menu_cursor (p_menu, 1);
404 break;
405 }
406 case KEY_UP:
407 display_menu_cursor (p_menu, 0);
408 do
409 {
410 p_menu->item_cur_pos--;
411 if (p_menu->item_cur_pos < 0)
412 p_menu->item_cur_pos = p_menu->item_count - 1;
413 }
414 while (!p_menu->items[p_menu->item_cur_pos]->display);
415 display_menu_cursor (p_menu, 1);
416 break;
417 case KEY_DOWN:
418 display_menu_cursor (p_menu, 0);
419 do
420 {
421 p_menu->item_cur_pos++;
422 if (p_menu->item_cur_pos >= p_menu->item_count)
423 p_menu->item_cur_pos = 0;
424 }
425 while (!p_menu->items[p_menu->item_cur_pos]->display);
426 display_menu_cursor (p_menu, 1);
427 break;
428 default:
429 for (i = 0; i < p_menu->item_count; i++)
430 {
431 if (key == p_menu->items[i]->name[0])
432 {
433 display_menu_cursor (p_menu, 0);
434 p_menu->item_cur_pos = i;
435 display_menu_cursor (p_menu, 1);
436 return "";
437 }
438 }
439 if (isalpha (key))
440 {
441 for (i = 0; i < p_menu->item_count; i++)
442 {
443 if (toupper (key) == toupper (p_menu->items[i]->name[0]))
444 {
445 display_menu_cursor (p_menu, 0);
446 p_menu->item_cur_pos = i;
447 display_menu_cursor (p_menu, 1);
448 return "";
449 }
450 }
451 }
452 }
453
454 return "";
455 }

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