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