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