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

Contents of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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