- Remove duplicated code in "rtl" and use libstring and librtl instead (their code...
[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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <freeldr.h>
21
22 #define NDEBUG
23 #include <debug.h>
24
25
26 ULONG UiScreenWidth = 80; // Screen Width
27 ULONG UiScreenHeight = 25; // 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 BOOL UserInterfaceUp = FALSE; // Tells us if the user interface is displayed
49
50 VIDEODISPLAYMODE UiDisplayMode = VideoTextMode; // Tells us if we are in text or graphics mode
51
52 BOOL UiUseSpecialEffects = FALSE; // Tells us if we should use fade effects
53
54 const CHAR UiMonthNames[12][15] = { "January ", "February ", "March ", "April ", "May ", "June ", "July ", "August ", "September ", "October ", "November ", "December " };
55
56
57 BOOL UiInitialize(BOOLEAN ShowGui)
58 {
59 ULONG SectionId;
60 CHAR DisplayModeText[260];
61 CHAR SettingText[260];
62 ULONG Depth;
63
64 if (!ShowGui) {
65 if (!TuiInitialize())
66 {
67 MachVideoSetDisplayMode(NULL, FALSE);
68 return FALSE;
69 }
70 UserInterfaceUp = FALSE;
71 return TRUE;
72 }
73
74 DbgPrint((DPRINT_UI, "Initializing User Interface.\n"));
75
76 DbgPrint((DPRINT_UI, "Reading in UI settings from [Display] section.\n"));
77
78 DisplayModeText[0] = '\0';
79 if (IniOpenSection("Display", &SectionId))
80 {
81 if (! IniReadSettingByName(SectionId, "DisplayMode", DisplayModeText, 260))
82 {
83 DisplayModeText[0] = '\0';
84 }
85
86 if (IniReadSettingByName(SectionId, "TitleText", SettingText, 260))
87 {
88 strcpy(UiTitleBoxTitleText, SettingText);
89 }
90 if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText, 260))
91 {
92 UiStatusBarBgColor = UiTextToColor(SettingText);
93 }
94 if (IniReadSettingByName(SectionId, "StatusBarTextColor", SettingText, 260))
95 {
96 UiStatusBarFgColor = UiTextToColor(SettingText);
97 }
98 if (IniReadSettingByName(SectionId, "BackdropTextColor", SettingText, 260))
99 {
100 UiBackdropFgColor = UiTextToColor(SettingText);
101 }
102 if (IniReadSettingByName(SectionId, "BackdropColor", SettingText, 260))
103 {
104 UiBackdropBgColor = UiTextToColor(SettingText);
105 }
106 if (IniReadSettingByName(SectionId, "BackdropFillStyle", SettingText, 260))
107 {
108 UiBackdropFillStyle = UiTextToFillStyle(SettingText);
109 }
110 if (IniReadSettingByName(SectionId, "TitleBoxTextColor", SettingText, 260))
111 {
112 UiTitleBoxFgColor = UiTextToColor(SettingText);
113 }
114 if (IniReadSettingByName(SectionId, "TitleBoxColor", SettingText, 260))
115 {
116 UiTitleBoxBgColor = UiTextToColor(SettingText);
117 }
118 if (IniReadSettingByName(SectionId, "MessageBoxTextColor", SettingText, 260))
119 {
120 UiMessageBoxFgColor = UiTextToColor(SettingText);
121 }
122 if (IniReadSettingByName(SectionId, "MessageBoxColor", SettingText, 260))
123 {
124 UiMessageBoxBgColor = UiTextToColor(SettingText);
125 }
126 if (IniReadSettingByName(SectionId, "MenuTextColor", SettingText, 260))
127 {
128 UiMenuFgColor = UiTextToColor(SettingText);
129 }
130 if (IniReadSettingByName(SectionId, "MenuColor", SettingText, 260))
131 {
132 UiMenuBgColor = UiTextToColor(SettingText);
133 }
134 if (IniReadSettingByName(SectionId, "TextColor", SettingText, 260))
135 {
136 UiTextColor = UiTextToColor(SettingText);
137 }
138 if (IniReadSettingByName(SectionId, "SelectedTextColor", SettingText, 260))
139 {
140 UiSelectedTextColor = UiTextToColor(SettingText);
141 }
142 if (IniReadSettingByName(SectionId, "SelectedColor", SettingText, 260))
143 {
144 UiSelectedTextBgColor = UiTextToColor(SettingText);
145 }
146 if (IniReadSettingByName(SectionId, "EditBoxTextColor", SettingText, 260))
147 {
148 UiEditBoxTextColor = UiTextToColor(SettingText);
149 }
150 if (IniReadSettingByName(SectionId, "EditBoxColor", SettingText, 260))
151 {
152 UiEditBoxBgColor = UiTextToColor(SettingText);
153 }
154 if (IniReadSettingByName(SectionId, "SpecialEffects", SettingText, 260))
155 {
156 if (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3)
157 {
158 UiUseSpecialEffects = TRUE;
159 }
160 else
161 {
162 UiUseSpecialEffects = FALSE;
163 }
164 }
165 }
166
167 UiDisplayMode = MachVideoSetDisplayMode(DisplayModeText, TRUE);
168 MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth);
169
170
171 if (VideoTextMode == UiDisplayMode)
172 {
173 if (!TuiInitialize())
174 {
175 MachVideoSetDisplayMode(NULL, FALSE);
176 return FALSE;
177 }
178 }
179 else
180 {
181 UNIMPLEMENTED();
182 //if (!GuiInitialize())
183 //{
184 // MachSetDisplayMode(NULL, FALSE);
185 // return FALSE;
186 //}
187 }
188
189 // Draw the backdrop and fade it in if special effects are enabled
190 UiFadeInBackdrop();
191
192 UserInterfaceUp = TRUE;
193
194 DbgPrint((DPRINT_UI, "UiInitialize() returning TRUE.\n"));
195 return TRUE;
196 }
197
198 BOOL SetupUiInitialize(VOID)
199 {
200
201 CHAR DisplayModeText[260];
202 ULONG Depth;
203
204
205 DisplayModeText[0] = '\0';
206
207
208 UiDisplayMode = MachVideoSetDisplayMode(DisplayModeText, TRUE);
209 MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth);
210
211 TuiInitialize();
212
213 // Draw the backdrop and fade it in if special effects are enabled
214 TuiFillArea(0,
215 0,
216 UiScreenWidth - 1,
217 UiScreenHeight - 2,
218 0,
219 ATTR(UiBackdropFgColor, UiBackdropBgColor));
220
221 UiStatusBarBgColor = 7;
222 UserInterfaceUp = TRUE;
223
224 TuiDrawText(4, 1, "ReactOS " KERNEL_VERSION_STR " Setup", ATTR(COLOR_GRAY, UiBackdropBgColor));
225 TuiDrawText(3, 2, "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD", ATTR(COLOR_GRAY, UiBackdropBgColor));
226
227 DbgPrint((DPRINT_UI, "UiInitialize() returning TRUE.\n"));
228
229 return TRUE;
230 }
231
232 VOID UiUnInitialize(PCSTR BootText)
233 {
234 UiDrawBackdrop();
235 UiDrawStatusText("Booting...");
236 UiInfoBox(BootText);
237
238 if (VideoTextMode == UiDisplayMode)
239 {
240 TuiUnInitialize();
241 }
242 else
243 {
244 UNIMPLEMENTED();
245 //GuiUnInitialize();
246 }
247 }
248
249 VOID UiDrawBackdrop(VOID)
250 {
251 if (!UserInterfaceUp) return;
252
253 if (VideoTextMode == UiDisplayMode)
254 {
255 TuiDrawBackdrop();
256 }
257 else
258 {
259 UNIMPLEMENTED();
260 //GuiDrawBackdrop();
261 }
262 }
263
264 VOID UiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */)
265 {
266 if (VideoTextMode == UiDisplayMode)
267 {
268 TuiFillArea(Left, Top, Right, Bottom, FillChar, Attr);
269 }
270 else
271 {
272 UNIMPLEMENTED();
273 //GuiFillArea(Left, Top, Right, Bottom, FillChar, Attr);
274 }
275 }
276
277 VOID UiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom)
278 {
279 if (VideoTextMode == UiDisplayMode)
280 {
281 TuiDrawShadow(Left, Top, Right, Bottom);
282 }
283 else
284 {
285 UNIMPLEMENTED();
286 //GuiDrawShadow(Left, Top, Right, Bottom);
287 }
288 }
289
290 VOID UiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOL Fill, BOOL Shadow, UCHAR Attr)
291 {
292 if (VideoTextMode == UiDisplayMode)
293 {
294 TuiDrawBox(Left, Top, Right, Bottom, VertStyle, HorzStyle, Fill, Shadow, Attr);
295 }
296 else
297 {
298 UNIMPLEMENTED();
299 //GuiDrawBox(Left, Top, Right, Bottom, VertStyle, HorzStyle, Fill, Shadow, Attr);
300 }
301 }
302
303 VOID UiDrawText(ULONG X, ULONG Y, PCSTR Text, UCHAR Attr)
304 {
305 if (VideoTextMode == UiDisplayMode)
306 {
307 TuiDrawText(X, Y, Text, Attr);
308 }
309 else
310 {
311 UNIMPLEMENTED();
312 //GuiDrawText(X, Y, Text, Attr);
313 }
314 }
315
316 VOID UiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PCSTR TextString, UCHAR Attr)
317 {
318 if (VideoTextMode == UiDisplayMode)
319 {
320 TuiDrawCenteredText(Left, Top, Right, Bottom, TextString, Attr);
321 }
322 else
323 {
324 UNIMPLEMENTED();
325 //GuiDrawCenteredText(Left, Top, Right, Bottom, TextString, Attr);
326 }
327 }
328
329 VOID UiDrawStatusText(PCSTR StatusText)
330 {
331 if (!UserInterfaceUp) return;
332
333 if (VideoTextMode == UiDisplayMode)
334 {
335 TuiDrawStatusText(StatusText);
336 }
337 else
338 {
339 UNIMPLEMENTED();
340 //GuiDrawStatusText(StatusText);
341 }
342 }
343
344 VOID UiUpdateDateTime(VOID)
345 {
346 if (VideoTextMode == UiDisplayMode)
347 {
348 TuiUpdateDateTime();
349 }
350 else
351 {
352 UNIMPLEMENTED();
353 //GuiUpdateDateTime();
354 }
355 }
356
357 VOID UiInfoBox(PCSTR MessageText)
358 {
359 ULONG TextLength;
360 ULONG BoxWidth;
361 ULONG BoxHeight;
362 ULONG LineBreakCount;
363 ULONG Index;
364 ULONG LastIndex;
365 ULONG Left;
366 ULONG Top;
367 ULONG Right;
368 ULONG Bottom;
369
370 TextLength = strlen(MessageText);
371
372 // Count the new lines and the box width
373 LineBreakCount = 0;
374 BoxWidth = 0;
375 LastIndex = 0;
376 for (Index=0; Index<TextLength; Index++)
377 {
378 if (MessageText[Index] == '\n')
379 {
380 LastIndex = Index;
381 LineBreakCount++;
382 }
383 else
384 {
385 if ((Index - LastIndex) > BoxWidth)
386 {
387 BoxWidth = (Index - LastIndex);
388 }
389 }
390 }
391
392 // Calc the box width & height
393 BoxWidth += 6;
394 BoxHeight = LineBreakCount + 4;
395
396 // Calc the box coordinates
397 Left = (UiScreenWidth / 2) - (BoxWidth / 2);
398 Top =(UiScreenHeight / 2) - (BoxHeight / 2);
399 Right = (UiScreenWidth / 2) + (BoxWidth / 2);
400 Bottom = (UiScreenHeight / 2) + (BoxHeight / 2);
401
402 // Draw the box
403 UiDrawBox(Left,
404 Top,
405 Right,
406 Bottom,
407 VERT,
408 HORZ,
409 TRUE,
410 TRUE,
411 ATTR(UiMenuFgColor, UiMenuBgColor)
412 );
413
414 // Draw the text
415 UiDrawCenteredText(Left, Top, Right, Bottom, MessageText, ATTR(UiTextColor, UiMenuBgColor));
416 }
417
418 VOID UiMessageBox(PCSTR MessageText)
419 {
420 // We have not yet displayed the user interface
421 // We are probably still reading the .ini file
422 // and have encountered an error. Just use printf()
423 // and return.
424 if (!UserInterfaceUp)
425 {
426 printf("%s\n", MessageText);
427 printf("Press any key\n");
428 MachConsGetCh();
429 return;
430 }
431
432 if (VideoTextMode == UiDisplayMode)
433 {
434 TuiMessageBox(MessageText);
435 }
436 else
437 {
438 UNIMPLEMENTED();
439 //GuiMessageBox(MessageText);
440 }
441 }
442
443 VOID UiMessageBoxCritical(PCSTR MessageText)
444 {
445 // We have not yet displayed the user interface
446 // We are probably still reading the .ini file
447 // and have encountered an error. Just use printf()
448 // and return.
449 if (!UserInterfaceUp)
450 {
451 printf("%s\n", MessageText);
452 printf("Press any key\n");
453 MachConsGetCh();
454 return;
455 }
456
457 if (VideoTextMode == UiDisplayMode)
458 {
459 TuiMessageBoxCritical(MessageText);
460 }
461 else
462 {
463 UNIMPLEMENTED();
464 //GuiMessageBoxCritical(MessageText);
465 }
466 }
467
468 UCHAR UiTextToColor(PCSTR ColorText)
469 {
470 if (VideoTextMode == UiDisplayMode)
471 {
472 return TuiTextToColor(ColorText);
473 }
474 else
475 {
476 UNIMPLEMENTED();
477 return 0;
478 //return GuiTextToColor(ColorText);
479 }
480 }
481
482 UCHAR UiTextToFillStyle(PCSTR FillStyleText)
483 {
484 if (VideoTextMode == UiDisplayMode)
485 {
486 return TuiTextToFillStyle(FillStyleText);
487 }
488 else
489 {
490 UNIMPLEMENTED();
491 return 0;
492 //return GuiTextToFillStyle(FillStyleText);
493 }
494 }
495
496 VOID UiDrawProgressBarCenter(ULONG Position, ULONG Range, PCHAR ProgressText)
497 {
498 if (!UserInterfaceUp) return;
499
500 if (VideoTextMode == UiDisplayMode)
501 {
502 TuiDrawProgressBarCenter(Position, Range, ProgressText);
503 }
504 else
505 {
506 UNIMPLEMENTED();
507 //GuiDrawProgressBarCenter(Position, Range, ProgressText);
508 }
509 }
510
511 VOID UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range, PCHAR ProgressText)
512 {
513 if (VideoTextMode == UiDisplayMode)
514 {
515 TuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText);
516 }
517 else
518 {
519 UNIMPLEMENTED();
520 //GuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText);
521 }
522 }
523
524 VOID UiShowMessageBoxesInSection(PCSTR SectionName)
525 {
526 ULONG Idx;
527 CHAR SettingName[80];
528 CHAR SettingValue[80];
529 PCHAR MessageBoxText;
530 ULONG MessageBoxTextSize;
531 ULONG SectionId;
532
533 if (!IniOpenSection(SectionName, &SectionId))
534 {
535 sprintf(SettingName, "Section %s not found in freeldr.ini.\n", SectionName);
536 UiMessageBox(SettingName);
537 return;
538 }
539
540 //
541 // Find all the message box settings and run them
542 //
543 for (Idx=0; Idx<IniGetNumSectionItems(SectionId); Idx++)
544 {
545 IniReadSettingByNumber(SectionId, Idx, SettingName, 79, SettingValue, 79);
546
547 if (_stricmp(SettingName, "MessageBox") == 0)
548 {
549 // Get the real length of the MessageBox text
550 MessageBoxTextSize = IniGetSectionSettingValueSize(SectionId, Idx);
551
552 //if (MessageBoxTextSize > 0)
553 {
554 // Allocate enough memory to hold the text
555 MessageBoxText = MmAllocateMemory(MessageBoxTextSize);
556
557 if (MessageBoxText)
558 {
559 // Get the MessageBox text
560 IniReadSettingByNumber(SectionId, Idx, SettingName, 80, MessageBoxText, MessageBoxTextSize);
561
562 // Fix it up
563 UiEscapeString(MessageBoxText);
564
565 // Display it
566 UiMessageBox(MessageBoxText);
567
568 // Free the memory
569 MmFreeMemory(MessageBoxText);
570 }
571 }
572 }
573 }
574 }
575
576 VOID UiEscapeString(PCHAR String)
577 {
578 ULONG Idx;
579
580 for (Idx=0; Idx<strlen(String); Idx++)
581 {
582 // Escape the new line characters
583 if (String[Idx] == '\\' && String[Idx+1] == 'n')
584 {
585 // Escape the character
586 String[Idx] = '\n';
587
588 // Move the rest of the string up
589 strcpy(&String[Idx+1], &String[Idx+2]);
590 }
591 }
592 }
593
594 VOID UiTruncateStringEllipsis(PCHAR StringText, ULONG MaxChars)
595 {
596 if (strlen(StringText) > MaxChars)
597 {
598 strcpy(&StringText[MaxChars - 3], "...");
599 }
600 }
601
602 BOOL UiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOL CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter)
603 {
604 if (VideoTextMode == UiDisplayMode)
605 {
606 return TuiDisplayMenu(MenuItemList, MenuItemCount, DefaultMenuItem, MenuTimeOut, SelectedMenuItem, CanEscape, KeyPressFilter);
607 }
608 else
609 {
610 UNIMPLEMENTED();
611 return FALSE;
612 //return GuiDisplayMenu(MenuItemList, MenuItemCount, DefaultMenuItem, MenuTimeOut, SelectedMenuItem, CanEscape, KeyPressFilter);
613 }
614 }
615
616 VOID UiFadeInBackdrop(VOID)
617 {
618 if (VideoTextMode == UiDisplayMode)
619 {
620 TuiFadeInBackdrop();
621 }
622 else
623 {
624 UNIMPLEMENTED();
625 //GuiFadeInBackdrop();
626 }
627 }
628
629 VOID UiFadeOut(VOID)
630 {
631 if (VideoTextMode == UiDisplayMode)
632 {
633 TuiFadeOut();
634 }
635 else
636 {
637 UNIMPLEMENTED();
638 //GuiFadeInOut();
639 }
640 }
641
642 BOOL UiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
643 {
644 if (VideoTextMode == UiDisplayMode)
645 {
646 return TuiEditBox(MessageText, EditTextBuffer, Length);
647 }
648 else
649 {
650 UNIMPLEMENTED();
651 return FALSE;
652 //return GuiEditBox(MessageText, EditTextBuffer, Length);
653 }
654 }