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