3 * Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 LONG MenuTimeRemaining
;
33 ULONG SelectedMenuItem
;
40 } MENU_INFO
, *PMENU_INFO
;
42 VOID
CalcMenuBoxSize(PMENU_INFO MenuInfo
);
43 VOID
DrawMenu(PMENU_INFO MenuInfo
);
44 VOID
DrawMenuBox(PMENU_INFO MenuInfo
);
45 VOID
DrawMenuItem(PMENU_INFO MenuInfo
, ULONG MenuItemNumber
);
46 ULONG
ProcessMenuKeyboardEvent(PMENU_INFO MenuInfo
);
48 extern ULONG nScreenWidth
; // Screen Width
49 extern ULONG nScreenHeight
; // Screen Height
51 extern CHAR cStatusBarFgColor
; // Status bar foreground color
52 extern CHAR cStatusBarBgColor
; // Status bar background color
53 extern CHAR cBackdropFgColor
; // Backdrop foreground color
54 extern CHAR cBackdropBgColor
; // Backdrop background color
55 extern CHAR cBackdropFillStyle
; // Backdrop fill style
56 extern CHAR cTitleBoxFgColor
; // Title box foreground color
57 extern CHAR cTitleBoxBgColor
; // Title box background color
58 extern CHAR cMessageBoxFgColor
; // Message box foreground color
59 extern CHAR cMessageBoxBgColor
; // Message box background color
60 extern CHAR cMenuFgColor
; // Menu foreground color
61 extern CHAR cMenuBgColor
; // Menu background color
62 extern CHAR cTextColor
; // Normal text color
63 extern CHAR cSelectedTextColor
; // Selected text color
64 extern CHAR cSelectedTextBgColor
; // Selected text background color
66 BOOL
DisplayMenu(PUCHAR MenuItemList
[], ULONG MenuItemCount
, ULONG DefaultMenuItem
, LONG MenuTimeOut
, PULONG SelectedMenuItem
)
69 MENU_INFO MenuInformation
;
70 ULONG CurrentClockSecond
;
73 // The first thing we need to check is the timeout
74 // If it's zero then don't bother with anything,
75 // just return the default item
79 if (SelectedMenuItem
!= NULL
)
81 *SelectedMenuItem
= DefaultMenuItem
;
88 // Allocate memory to hold screen contents before menu is drawn
90 ScreenBuffer
= AllocateMemory(4000);
91 if (ScreenBuffer
== NULL
)
97 // Save screen contents to our buffer
99 SaveScreen(ScreenBuffer
);
102 // Setup the MENU_INFO structure
104 MenuInformation
.MenuItemList
= MenuItemList
;
105 MenuInformation
.MenuItemCount
= MenuItemCount
;
106 MenuInformation
.MenuTimeRemaining
= MenuTimeOut
;
107 MenuInformation
.SelectedMenuItem
= DefaultMenuItem
;
110 // Calculate the size of the menu box
112 CalcMenuBoxSize(&MenuInformation
);
117 DrawMenu(&MenuInformation
);
120 // Get the current second of time
122 CurrentClockSecond
= getsecond();
130 // Process key presses
132 if (ProcessMenuKeyboardEvent(&MenuInformation
) == KEY_ENTER
)
135 // If they pressed enter then exit this loop
141 // Update the date & time
145 if (MenuInformation
.MenuTimeRemaining
> 0)
147 if (getsecond() != CurrentClockSecond
)
150 // Update the time information
152 CurrentClockSecond
= getsecond();
153 MenuInformation
.MenuTimeRemaining
--;
158 DrawMenuBox(&MenuInformation
);
161 else if (MenuInformation
.MenuTimeRemaining
== 0)
164 // A time out occurred, exit this loop and return default OS
171 // Update the selected menu item information
173 if (SelectedMenuItem
!= NULL
)
175 *SelectedMenuItem
= MenuInformation
.SelectedMenuItem
;
181 VOID
CalcMenuBoxSize(PMENU_INFO MenuInfo
)
189 // Height is the menu item count plus 2 (top border & bottom border)
191 Height
= MenuInfo
->MenuItemCount
+ 2;
192 Height
-= 1; // Height is zero-based
195 // Find the length of the longest string in the menu
198 for(Idx
=0; Idx
<MenuInfo
->MenuItemCount
; Idx
++)
200 Length
= strlen(MenuInfo
->MenuItemList
[Idx
]);
209 // Allow room for left & right borders, plus 8 spaces on each side
214 // Calculate the menu box area
216 MenuInfo
->Left
= (nScreenWidth
- Width
) / 2;
217 MenuInfo
->Right
= (MenuInfo
->Left
) + Width
;
218 MenuInfo
->Top
= (( (nScreenHeight
- TITLE_BOX_HEIGHT
) - Height
) / 2 + 1) + (TITLE_BOX_HEIGHT
/ 2);
219 MenuInfo
->Bottom
= (MenuInfo
->Top
) + Height
;
222 VOID
DrawMenu(PMENU_INFO MenuInfo
)
229 DrawMenuBox(MenuInfo
);
232 // Draw each line of the menu
234 for (Idx
=0; Idx
<MenuInfo
->MenuItemCount
; Idx
++)
236 DrawMenuItem(MenuInfo
, Idx
);
240 VOID
DrawMenuBox(PMENU_INFO MenuInfo
)
242 UCHAR MenuLineText
[80];
243 UCHAR TempString
[80];
246 // Update the status bar
248 DrawStatusText(" Use \x18\x19 to select, ENTER to boot.");
253 DrawBox(MenuInfo
->Left
,
261 ATTR(cMenuFgColor
, cMenuBgColor
));
264 // If there is a timeout draw the time remaining
266 if (MenuInfo
->MenuTimeRemaining
>= 0)
268 strcpy(MenuLineText
, "[ Time Remaining: ");
269 itoa(MenuInfo
->MenuTimeRemaining
, TempString
, 10);
270 strcat(MenuLineText
, TempString
);
271 strcat(MenuLineText
, " ]");
273 DrawText(MenuInfo
->Right
- strlen(MenuLineText
) - 1,
276 ATTR(cMenuFgColor
, cMenuBgColor
));
280 VOID
DrawMenuItem(PMENU_INFO MenuInfo
, ULONG MenuItemNumber
)
283 UCHAR MenuLineText
[80];
289 // We will want the string centered so calculate
290 // how many spaces will be to the left and right
292 SpaceTotal
= (MenuInfo
->Right
- MenuInfo
->Left
- 2) - strlen(MenuInfo
->MenuItemList
[MenuItemNumber
]);
293 SpaceLeft
= (SpaceTotal
/ 2) + 1;
294 SpaceRight
= (SpaceTotal
- SpaceLeft
) + 1;
297 // Insert the spaces on the left
299 for (Idx
=0; Idx
<SpaceLeft
; Idx
++)
301 MenuLineText
[Idx
] = ' ';
303 MenuLineText
[Idx
] = '\0';
306 // Now append the text string
308 strcat(MenuLineText
, MenuInfo
->MenuItemList
[MenuItemNumber
]);
311 // Now append the spaces on the right
313 for (Idx
=0; Idx
<SpaceRight
; Idx
++)
315 strcat(MenuLineText
, " ");
319 // If this is the selected menu item then draw it as selected
320 // otherwise just draw it using the normal colors
322 if (MenuItemNumber
== MenuInfo
->SelectedMenuItem
)
324 DrawText(MenuInfo
->Left
+ 1,
325 MenuInfo
->Top
+ 1 + MenuItemNumber
,
327 ATTR(cSelectedTextColor
, cSelectedTextBgColor
));
331 DrawText(MenuInfo
->Left
+ 1,
332 MenuInfo
->Top
+ 1 + MenuItemNumber
,
334 ATTR(cTextColor
, cMenuBgColor
));
338 ULONG
ProcessMenuKeyboardEvent(PMENU_INFO MenuInfo
)
343 // Check for a keypress
348 // Cancel the timeout
350 if (MenuInfo
->MenuTimeRemaining
!= -1)
352 MenuInfo
->MenuTimeRemaining
= -1;
353 DrawMenuBox(MenuInfo
);
365 KeyEvent
= getch(); // Yes - so get the extended key
374 if (MenuInfo
->SelectedMenuItem
> 0)
376 MenuInfo
->SelectedMenuItem
--;
381 DrawMenuItem(MenuInfo
, MenuInfo
->SelectedMenuItem
+ 1); // Deselect previous item
382 DrawMenuItem(MenuInfo
, MenuInfo
->SelectedMenuItem
); // Select new item
389 if (MenuInfo
->SelectedMenuItem
< (MenuInfo
->MenuItemCount
- 1))
391 MenuInfo
->SelectedMenuItem
++;
396 DrawMenuItem(MenuInfo
, MenuInfo
->SelectedMenuItem
- 1); // Deselect previous item
397 DrawMenuItem(MenuInfo
, MenuInfo
->SelectedMenuItem
); // Select new item