-
Notifications
You must be signed in to change notification settings - Fork 0
/
MENU.C
353 lines (302 loc) · 6.73 KB
/
MENU.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
/* menu.c - display menu and handle commands
*
* Author:
* Benjamin W. Slivka
* (c) 1987,1988
* Microsoft Corporation
*
* History:
* 17-Aug-1987 bws Use keyboard queue for keystrokes
* 08-Oct-1987 bws Change quit logic to account for signals
*/
#include <stddef.h>
#include <malloc.h>
#include "asrt.h" /* assertion checking */
#include "vio.h"
#include "ps.h"
#include "os2.h"
#include "queue.h"
#include "vars.h"
#include "os2def.h"
typedef struct {
char *miKeys; /* key(s) which activate menu item */
char *miName; /* menu name */
void (*miFunc)(int); /* menu function */
int miCol; /* menu column */
int miLen; /* length of menu name */
} menu_t;
extern void mQuit (int);
extern void mMemory (int);
extern void mLibrary (int);
extern void mSemaphore (int);
extern void mProcess (int);
extern void mExplain (int);
extern void mOption (int);
extern void mUpdate (int);
extern char *PopUpStart (void);
extern void PopUpEnd (char *);
extern void showHelp (int);
extern void showExplain ();
extern qu_t *pQu; /* ptr to keyboard queue */
extern BOOL fKilled; /* TRUE if killed by signal */
menu_t menu[] = {
{"hH", "Help", showHelp, 0, 0},
{"eE", "Explain", mExplain, 0, 0},
{"oO", "Options", mOption, 0, 0},
{"qQ", "Quit", mQuit, 0, 0},
{"lL", "Library", mLibrary, 0, 0},
{"mM", "Memory", mMemory, 0, 0},
{"pP", "Process", mProcess, 0, 0},
{"sS", "Semaphore",mSemaphore, 0, 0},
{"uU", "Update", mUpdate, 0, 0}
};
#define nMenu (sizeof(menu)/sizeof(menu_t))
#define miHelp 0 /* These must match order of menu[] */
#define miExplain 1
#define miOption 2
#define miQuit 3
#define miLibrary 4
#define miMemory 5
#define miProcess 6
#define miSemaphore 7
int lastStatus=-1; /* index marked menu item */
int lastMenu; /* index of highlighted menu item */
int m_row; /* menu row */
int m_col; /* menu column (leftmost) */
int fAlive=TRUE; /* TRUE while we are to continue running */
#define MENU_SEPARATION 2 /* amount of space between menu items */
/*** menuInit - initialize menu data
*
*/
menuInit ()
{
int i;
int col;
m_row = N_of_Rows - 1;
m_col = MENU_SEPARATION;
col = m_col;
for (i=0; i<nMenu; i++) {
menu[i].miCol = col;
menu[i].miLen = strlen(menu[i].miName);
col += menu[i].miLen + MENU_SEPARATION;
}
}
/*** drawMenu - display menu
*
*/
drawMenu ()
{
Attr a;
Cell_s c;
int i;
a = color[menuC]; /* Clear menu area */
c.ch = ' ';
c.at = color[menuC];
VioWrtNCell((FPCe)&c, N_of_Cols, m_row, 0, VioHandle);
for (i=0; i<nMenu; i++) /* Draw menu items */
drawCursor (i, a);
}
/*** doMenu - Handle menu keystrokes
*
*/
doMenu ()
{
int row,col;
word key;
int i;
Attr a;
int iMenu;
int changeData; /* TRUE if data display has changed */
drawMenu();
iMenu = 6; /* Start with PROCESS display */
lastMenu = iMenu;
(*(menu[iMenu].miFunc))(iMenu); /* do Process function */
while (fAlive) {
#ifdef DEBUG
showFreeSpace();
#endif
updateCursor (iMenu);
changeData = FALSE;
do {
if (!fKilled) /* catch kill from help/option screens */
key = (word)QueueReadTO(pQu,refreshPeriod);
if (fKilled)
key = quitKey; /* Change kill into quit command */
else if (key == NULL)
mUpdate(0); /* update screen */
else
; /* exit loop */
} while (key == NULL);
switch (key) {
case rightKey:
if (++iMenu > (nMenu - 1))
iMenu = 0;
break;
case leftKey:
if (--iMenu < 0)
iMenu = nMenu - 1;
break;
case upKey:
doScroll (-1);
break;
case downKey:
doScroll (1);
break;
case pgUpKey:
doScroll (-dataRows);
break;
case pgDownKey:
doScroll (dataRows);
break;
case helpKey:
showHelp (miHelp);
break;
default:
if ((i = findKey(key)) != -1) {
iMenu = i;
changeData = TRUE;
}
break;
case enterKey:
case spaceKey:
changeData = TRUE;
break;
} /* switch */
if (changeData) {
updateCursor (iMenu);
(*(menu[iMenu].miFunc))(iMenu);
}
} /* while */
}
/*** updateCursor - Move cursor to "i"th menu item
*
*/
updateCursor (i)
int i;
{
if (i != lastMenu) /* user moved to different field */
drawCursor (lastMenu, color[menuC]); /* revert to normal color */
drawCursor (i, color[cursorC]); /* highlight current field */
lastMenu = i;
}
/*** markMenu - Move mark to "i"th menu item
*
*/
markMenu (i)
int i;
{
Attr a;
a=color[menuC];
if (lastStatus != -1)
VioWrtCharStrAtt ((FPC)" ", 1, m_row, menu[lastStatus].miCol-1,
(FPAt)&a, VioHandle);
VioWrtCharStrAtt ((FPC)"*", 1, m_row, menu[i].miCol-1,(FPAt)&a, VioHandle);
lastStatus=i;
}
/*** findKey - Map key to menu index, if any
*
*/
findKey (key)
unsigned key;
{
int i;
int found=-1;
char k=key>>8;
if (k != 0) /* Not IBM extended code, so scan */
for (i=0; i<nMenu && found==-1; i++)
if (strchr(menu[i].miKeys,k))
found=i;
return found;
}
/*** drawCursor - draw individual menu item
*
*/
drawCursor (i, color)
int i;
Attr color;
{
VioWrtCharStrAtt ((FPC)menu[i].miName, menu[i].miLen, m_row,
menu[i].miCol, (FPAt)&color, VioHandle);
}
/*** mQuit - do QUIT menu option
*
*/
void mQuit (i)
int i;
{
fAlive=FALSE;
}
/*** mProcess - do PROCESS menu option
*
*/
void mProcess (i)
int i;
{
markMenu(i);
doScreen(iProcess);
}
/*** mLibrary - do LIBRARY menu option
*
*/
void mLibrary (i)
int i;
{
markMenu(i);
doScreen(iLibrary);
}
/*** mSemaphore - do SEMAPHORE menu option
*
*/
void mSemaphore (i)
int i;
{
markMenu(i);
doScreen(iSemaphore);
}
/*** mMemory - do MEMORY menu option
*
*/
void mMemory (i)
int i;
{
markMenu(i);
doScreen(iMemory);
}
/*** mExplain - do EXPLAIN menu option
*
*/
void mExplain (i)
int i;
{
switch (lastStatus) { /* map menu index to table index */
case miLibrary: i = iLibrary; break;
case miMemory: i = iMemory; break;
case miProcess: i = iProcess; break;
case miSemaphore: i = iSemaphore; break;
default:
Fatal ("invalid menu index");
}
showExplain(i); /* show explanation screen */
}
/*** mOption - do OPTION menu option
*
*/
void mOption (i)
int i;
{
char *buf;
if (buf=PopUpStart()) {
doOption();
PopUpEnd(buf);
}
}
/*** mUpdate - do UPDATE menu option
*
*/
void mUpdate (i)
int i;
{
freeImages();
buildDatabase();
updateScreen();
}