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

Contents of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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