[FREELDR]
[reactos.git] / reactos / boot / freeldr / freeldr / ui / ui.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 *
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.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 #ifndef _M_ARM
20
21 #include <freeldr.h>
22 #include <debug.h>
23
24 DBG_DEFAULT_CHANNEL(UI);
25
26 ULONG UiScreenWidth; // Screen Width
27 ULONG UiScreenHeight; // Screen Height
28
29 UCHAR UiStatusBarFgColor = COLOR_BLACK; // Status bar foreground color
30 UCHAR UiStatusBarBgColor = COLOR_CYAN; // Status bar background color
31 UCHAR UiBackdropFgColor = COLOR_WHITE; // Backdrop foreground color
32 UCHAR UiBackdropBgColor = COLOR_BLUE; // Backdrop background color
33 UCHAR UiBackdropFillStyle = MEDIUM_FILL; // Backdrop fill style
34 UCHAR UiTitleBoxFgColor = COLOR_WHITE; // Title box foreground color
35 UCHAR UiTitleBoxBgColor = COLOR_RED; // Title box background color
36 UCHAR UiMessageBoxFgColor = COLOR_WHITE; // Message box foreground color
37 UCHAR UiMessageBoxBgColor = COLOR_BLUE; // Message box background color
38 UCHAR UiMenuFgColor = COLOR_WHITE; // Menu foreground color
39 UCHAR UiMenuBgColor = COLOR_BLUE; // Menu background color
40 UCHAR UiTextColor = COLOR_YELLOW; // Normal text color
41 UCHAR UiSelectedTextColor = COLOR_BLACK; // Selected text color
42 UCHAR UiSelectedTextBgColor = COLOR_GRAY; // Selected text background color
43 UCHAR UiEditBoxTextColor = COLOR_WHITE; // Edit box text color
44 UCHAR UiEditBoxBgColor = COLOR_BLACK; // Edit box text background color
45
46 CHAR UiTitleBoxTitleText[260] = "Boot Menu"; // Title box's title text
47
48 BOOLEAN UiUseSpecialEffects = FALSE; // Tells us if we should use fade effects
49 BOOLEAN UiDrawTime = TRUE; // Tells us if we should draw the time
50 BOOLEAN UiCenterMenu = TRUE; // Tells us if we should use a centered or left-aligned menu
51 BOOLEAN UiMenuBox = TRUE; // Tells us if we shuld draw a box around the menu
52 CHAR UiTimeText[260] = "[Time Remaining: ] ";
53
54 const CHAR UiMonthNames[12][15] = { "January ", "February ", "March ", "April ", "May ", "June ", "July ", "August ", "September ", "October ", "November ", "December " };
55
56 UIVTBL UiVtbl =
57 {
58 NoUiInitialize,
59 NoUiUnInitialize,
60 NoUiDrawBackdrop,
61 NoUiFillArea,
62 NoUiDrawShadow,
63 NoUiDrawBox,
64 NoUiDrawText,
65 NoUiDrawCenteredText,
66 NoUiDrawStatusText,
67 NoUiUpdateDateTime,
68 NoUiMessageBox,
69 NoUiMessageBoxCritical,
70 NoUiDrawProgressBarCenter,
71 NoUiDrawProgressBar,
72 NoUiEditBox,
73 NoUiTextToColor,
74 NoUiTextToFillStyle,
75 NoUiFadeInBackdrop,
76 NoUiFadeOut,
77 NoUiDisplayMenu,
78 NoUiDrawMenu,
79 };
80
81 BOOLEAN UiInitialize(BOOLEAN ShowGui)
82 {
83 VIDEODISPLAYMODE UiDisplayMode; // Tells us if we are in text or graphics mode
84 BOOLEAN UiMinimal = FALSE; // Tells us if we are using a minimal console-like UI
85 ULONG_PTR SectionId;
86 CHAR DisplayModeText[260];
87 CHAR SettingText[260];
88 ULONG Depth;
89
90 if (!ShowGui)
91 {
92 if (!UiVtbl.Initialize())
93 {
94 MachVideoSetDisplayMode(NULL, FALSE);
95 return FALSE;
96 }
97 return TRUE;
98 }
99
100 TRACE("Initializing User Interface.\n");
101 TRACE("Reading in UI settings from [Display] section.\n");
102
103 DisplayModeText[0] = '\0';
104 if (IniOpenSection("Display", &SectionId))
105 {
106 if (!IniReadSettingByName(SectionId, "DisplayMode", DisplayModeText, sizeof(DisplayModeText)))
107 {
108 DisplayModeText[0] = '\0';
109 }
110 if (IniReadSettingByName(SectionId, "MinimalUI", SettingText, sizeof(SettingText)))
111 {
112 UiMinimal = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
113 }
114 }
115
116 UiDisplayMode = MachVideoSetDisplayMode(DisplayModeText, TRUE);
117 MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth);
118
119 if (VideoTextMode == UiDisplayMode)
120 UiVtbl = (UiMinimal ? MiniTuiVtbl : TuiVtbl);
121 else
122 UiVtbl = GuiVtbl;
123
124 if (!UiVtbl.Initialize())
125 {
126 MachVideoSetDisplayMode(NULL, FALSE);
127 return FALSE;
128 }
129
130 if (IniOpenSection("Display", &SectionId))
131 {
132 if (IniReadSettingByName(SectionId, "TitleText", SettingText, sizeof(SettingText)))
133 {
134 strcpy(UiTitleBoxTitleText, SettingText);
135 }
136 if (IniReadSettingByName(SectionId, "TimeText", SettingText, sizeof(SettingText)))
137 {
138 strcpy(UiTimeText, SettingText);
139 }
140 if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText, sizeof(SettingText)))
141 {
142 UiStatusBarBgColor = UiTextToColor(SettingText);
143 }
144 if (IniReadSettingByName(SectionId, "StatusBarTextColor", SettingText, sizeof(SettingText)))
145 {
146 UiStatusBarFgColor = UiTextToColor(SettingText);
147 }
148 if (IniReadSettingByName(SectionId, "BackdropTextColor", SettingText, sizeof(SettingText)))
149 {
150 UiBackdropFgColor = UiTextToColor(SettingText);
151 }
152 if (IniReadSettingByName(SectionId, "BackdropColor", SettingText, sizeof(SettingText)))
153 {
154 UiBackdropBgColor = UiTextToColor(SettingText);
155 }
156 if (IniReadSettingByName(SectionId, "BackdropFillStyle", SettingText, sizeof(SettingText)))
157 {
158 UiBackdropFillStyle = UiTextToFillStyle(SettingText);
159 }
160 if (IniReadSettingByName(SectionId, "TitleBoxTextColor", SettingText, sizeof(SettingText)))
161 {
162 UiTitleBoxFgColor = UiTextToColor(SettingText);
163 }
164 if (IniReadSettingByName(SectionId, "TitleBoxColor", SettingText, sizeof(SettingText)))
165 {
166 UiTitleBoxBgColor = UiTextToColor(SettingText);
167 }
168 if (IniReadSettingByName(SectionId, "MessageBoxTextColor", SettingText, sizeof(SettingText)))
169 {
170 UiMessageBoxFgColor = UiTextToColor(SettingText);
171 }
172 if (IniReadSettingByName(SectionId, "MessageBoxColor", SettingText, sizeof(SettingText)))
173 {
174 UiMessageBoxBgColor = UiTextToColor(SettingText);
175 }
176 if (IniReadSettingByName(SectionId, "MenuTextColor", SettingText, sizeof(SettingText)))
177 {
178 UiMenuFgColor = UiTextToColor(SettingText);
179 }
180 if (IniReadSettingByName(SectionId, "MenuColor", SettingText, sizeof(SettingText)))
181 {
182 UiMenuBgColor = UiTextToColor(SettingText);
183 }
184 if (IniReadSettingByName(SectionId, "TextColor", SettingText, sizeof(SettingText)))
185 {
186 UiTextColor = UiTextToColor(SettingText);
187 }
188 if (IniReadSettingByName(SectionId, "SelectedTextColor", SettingText, sizeof(SettingText)))
189 {
190 UiSelectedTextColor = UiTextToColor(SettingText);
191 }
192 if (IniReadSettingByName(SectionId, "SelectedColor", SettingText, sizeof(SettingText)))
193 {
194 UiSelectedTextBgColor = UiTextToColor(SettingText);
195 }
196 if (IniReadSettingByName(SectionId, "EditBoxTextColor", SettingText, sizeof(SettingText)))
197 {
198 UiEditBoxTextColor = UiTextToColor(SettingText);
199 }
200 if (IniReadSettingByName(SectionId, "EditBoxColor", SettingText, sizeof(SettingText)))
201 {
202 UiEditBoxBgColor = UiTextToColor(SettingText);
203 }
204 if (IniReadSettingByName(SectionId, "SpecialEffects", SettingText, sizeof(SettingText)))
205 {
206 UiUseSpecialEffects = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
207 }
208 if (IniReadSettingByName(SectionId, "ShowTime", SettingText, sizeof(SettingText)))
209 {
210 UiDrawTime = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
211 }
212 if (IniReadSettingByName(SectionId, "MenuBox", SettingText, sizeof(SettingText)))
213 {
214 UiMenuBox = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
215 }
216 if (IniReadSettingByName(SectionId, "CenterMenu", SettingText, sizeof(SettingText)))
217 {
218 UiCenterMenu = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
219 }
220 }
221
222 // Draw the backdrop and fade it in if special effects are enabled
223 UiFadeInBackdrop();
224
225 TRACE("UiInitialize() returning TRUE.\n");
226 return TRUE;
227 }
228
229 VOID UiUnInitialize(PCSTR BootText)
230 {
231 UiDrawBackdrop();
232 UiDrawStatusText("Booting...");
233 UiInfoBox(BootText);
234
235 UiVtbl.UnInitialize();
236 }
237
238 VOID UiDrawBackdrop(VOID)
239 {
240 UiVtbl.DrawBackdrop();
241 }
242
243 VOID UiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */)
244 {
245 UiVtbl.FillArea(Left, Top, Right, Bottom, FillChar, Attr);
246 }
247
248 VOID UiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom)
249 {
250 UiVtbl.DrawShadow(Left, Top, Right, Bottom);
251 }
252
253 VOID UiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOLEAN Fill, BOOLEAN Shadow, UCHAR Attr)
254 {
255 UiVtbl.DrawBox(Left, Top, Right, Bottom, VertStyle, HorzStyle, Fill, Shadow, Attr);
256 }
257
258 VOID UiDrawText(ULONG X, ULONG Y, PCSTR Text, UCHAR Attr)
259 {
260 UiVtbl.DrawText(X, Y, Text, Attr);
261 }
262
263 VOID UiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PCSTR TextString, UCHAR Attr)
264 {
265 UiVtbl.DrawCenteredText(Left, Top, Right, Bottom, TextString, Attr);
266 }
267
268 VOID UiDrawStatusText(PCSTR StatusText)
269 {
270 UiVtbl.DrawStatusText(StatusText);
271 }
272
273 VOID UiUpdateDateTime(VOID)
274 {
275 UiVtbl.UpdateDateTime();
276 }
277
278 VOID UiInfoBox(PCSTR MessageText)
279 {
280 SIZE_T TextLength;
281 ULONG BoxWidth;
282 ULONG BoxHeight;
283 ULONG LineBreakCount;
284 SIZE_T Index;
285 SIZE_T LastIndex;
286 ULONG Left;
287 ULONG Top;
288 ULONG Right;
289 ULONG Bottom;
290
291 TextLength = strlen(MessageText);
292
293 // Count the new lines and the box width
294 LineBreakCount = 0;
295 BoxWidth = 0;
296 LastIndex = 0;
297 for (Index=0; Index<TextLength; Index++)
298 {
299 if (MessageText[Index] == '\n')
300 {
301 LastIndex = Index;
302 LineBreakCount++;
303 }
304 else
305 {
306 if ((Index - LastIndex) > BoxWidth)
307 {
308 BoxWidth = (ULONG)(Index - LastIndex);
309 }
310 }
311 }
312
313 // Calc the box width & height
314 BoxWidth += 6;
315 BoxHeight = LineBreakCount + 4;
316
317 // Calc the box coordinates
318 Left = (UiScreenWidth / 2) - (BoxWidth / 2);
319 Top =(UiScreenHeight / 2) - (BoxHeight / 2);
320 Right = (UiScreenWidth / 2) + (BoxWidth / 2);
321 Bottom = (UiScreenHeight / 2) + (BoxHeight / 2);
322
323 // Draw the box
324 UiDrawBox(Left,
325 Top,
326 Right,
327 Bottom,
328 VERT,
329 HORZ,
330 TRUE,
331 TRUE,
332 ATTR(UiMenuFgColor, UiMenuBgColor)
333 );
334
335 // Draw the text
336 UiDrawCenteredText(Left, Top, Right, Bottom, MessageText, ATTR(UiTextColor, UiMenuBgColor));
337 }
338
339 VOID UiMessageBox(PCSTR MessageText)
340 {
341 UiVtbl.MessageBox(MessageText);
342 }
343
344 VOID UiMessageBoxCritical(PCSTR MessageText)
345 {
346 UiVtbl.MessageBoxCritical(MessageText);
347 }
348
349 UCHAR UiTextToColor(PCSTR ColorText)
350 {
351 return UiVtbl.TextToColor(ColorText);
352 }
353
354 UCHAR UiTextToFillStyle(PCSTR FillStyleText)
355 {
356 return UiVtbl.TextToFillStyle(FillStyleText);
357 }
358
359 VOID UiDrawProgressBarCenter(ULONG Position, ULONG Range, PCHAR ProgressText)
360 {
361 UiVtbl.DrawProgressBarCenter(Position, Range, ProgressText);
362 }
363
364 VOID UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range, PCHAR ProgressText)
365 {
366 UiVtbl.DrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText);
367 }
368
369 VOID UiShowMessageBoxesInSection(PCSTR SectionName)
370 {
371 ULONG Idx;
372 CHAR SettingName[80];
373 CHAR SettingValue[80];
374 PCHAR MessageBoxText;
375 ULONG MessageBoxTextSize;
376 ULONG_PTR SectionId;
377
378 if (!IniOpenSection(SectionName, &SectionId))
379 {
380 return;
381 }
382
383 //
384 // Find all the message box settings and run them
385 //
386 for (Idx=0; Idx<IniGetNumSectionItems(SectionId); Idx++)
387 {
388 IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), SettingValue, sizeof(SettingValue));
389
390 if (_stricmp(SettingName, "MessageBox") == 0)
391 {
392 // Get the real length of the MessageBox text
393 MessageBoxTextSize = IniGetSectionSettingValueSize(SectionId, Idx);
394
395 //if (MessageBoxTextSize > 0)
396 {
397 // Allocate enough memory to hold the text
398 MessageBoxText = MmHeapAlloc(MessageBoxTextSize);
399
400 if (MessageBoxText)
401 {
402 // Get the MessageBox text
403 IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), MessageBoxText, MessageBoxTextSize);
404
405 // Fix it up
406 UiEscapeString(MessageBoxText);
407
408 // Display it
409 UiMessageBox(MessageBoxText);
410
411 // Free the memory
412 MmHeapFree(MessageBoxText);
413 }
414 }
415 }
416 }
417 }
418
419 VOID UiEscapeString(PCHAR String)
420 {
421 ULONG Idx;
422
423 for (Idx=0; Idx<strlen(String); Idx++)
424 {
425 // Escape the new line characters
426 if (String[Idx] == '\\' && String[Idx+1] == 'n')
427 {
428 // Escape the character
429 String[Idx] = '\n';
430
431 // Move the rest of the string up
432 strcpy(&String[Idx+1], &String[Idx+2]);
433 }
434 }
435 }
436
437 VOID UiTruncateStringEllipsis(PCHAR StringText, ULONG MaxChars)
438 {
439 if (strlen(StringText) > MaxChars)
440 {
441 strcpy(&StringText[MaxChars - 3], "...");
442 }
443 }
444
445 BOOLEAN UiDisplayMenu(PCSTR MenuTitle, PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter)
446 {
447 return UiVtbl.DisplayMenu(MenuTitle, MenuItemList, MenuItemCount, DefaultMenuItem, MenuTimeOut, SelectedMenuItem, CanEscape, KeyPressFilter);
448 }
449
450 VOID UiFadeInBackdrop(VOID)
451 {
452 UiVtbl.FadeInBackdrop();
453 }
454
455 VOID UiFadeOut(VOID)
456 {
457 UiVtbl.FadeOut();
458 }
459
460 BOOLEAN UiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
461 {
462 return UiVtbl.EditBox(MessageText, EditTextBuffer, Length);
463 }
464
465 #endif