- Added support for NTLDR style freeloader GUI. To enable, edit freeldr.ini and add:
[reactos.git] / reactos / boot / freeldr / freeldr / ui / tui.c
index c88f665..73ae36a 100644 (file)
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-       
-#include <freeldr.h>
-#include <ui.h>
-#include "tui.h"
-#include "keycodes.h"
-#include <rtl.h>
-#include <mm.h>
-#include <debug.h>
-#include <inifile.h>
-#include <version.h>
-#include <video.h>
-#include <machine.h>
 
+#include <freeldr.h>
 
 PVOID  TextVideoBuffer = NULL;
+extern BOOL UiDrawTime;
+extern BOOL UiMinimal;
+
+/*
+ * printf() - prints formatted text to stdout
+ * originally from GRUB
+ */
+int printf(const char *format, ... )
+{
+       va_list ap;
+       va_start(ap,format);
+       char c, *ptr, str[16];
+
+       while ((c = *(format++)))
+       {
+               if (c != '%')
+               {
+                       MachConsPutChar(c);
+               }
+               else
+               {
+                       switch (c = *(format++))
+                       {
+                       case 'd': case 'u': case 'x':
+                if (c == 'x')
+                    *_itoa(va_arg(ap, unsigned long), str, 16) = 0;
+                else
+                    *_itoa(va_arg(ap, unsigned long), str, 10) = 0;
+
+                               ptr = str;
+
+                               while (*ptr)
+                               {
+                                       MachConsPutChar(*(ptr++));
+                               }
+                               break;
+
+                       case 'c': MachConsPutChar((va_arg(ap,int))&0xff); break;
+
+                       case 's':
+                               ptr = va_arg(ap,char *);
+
+                               while ((c = *(ptr++)))
+                               {
+                                       MachConsPutChar(c);
+                               }
+                               break;
+                       case '%':
+                               MachConsPutChar(c);
+                               break;
+                       default:
+                               printf("\nprintf() invalid format specifier - %%%c\n", c);
+                               break;
+                       }
+               }
+       }
+
+       va_end(ap);
+
+       return 0;
+}
 
 BOOL TuiInitialize(VOID)
 {
@@ -63,6 +113,25 @@ VOID TuiUnInitialize(VOID)
 
 VOID TuiDrawBackdrop(VOID)
 {
+    if (UiMinimal)
+    {
+        //
+        // Fill in a black background
+        //
+        TuiFillArea(0,
+                    0,
+                    UiScreenWidth - 1,
+                    UiScreenHeight - 1,
+                    0,
+                    0);
+
+        //
+        // Update the screen buffer
+        //
+        VideoCopyOffScreenBufferToVRAM();
+        return;
+    }
+
        //
        // Fill in the background (excluding title box & status bar)
        //
@@ -136,25 +205,24 @@ VOID TuiDrawBackdrop(VOID)
  * FillArea()
  * This function assumes coordinates are zero-based
  */
-VOID TuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */)
+VOID TuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */)
 {
        PUCHAR  ScreenMemory = (PUCHAR)TextVideoBuffer;
        ULONG           i, j;
 
        // Clip the area to the screen
-       // FIXME: This code seems to have problems... Uncomment and view ;-)
-       /*if ((Left >= UiScreenWidth) || (Top >= UiScreenHeight))
+       if ((Left >= UiScreenWidth) || (Top >= UiScreenHeight))
        {
                return;
        }
-       if ((Left + Right) >= UiScreenWidth)
+       if (Right >= UiScreenWidth)
        {
-               Right = UiScreenWidth - Left;
+               Right = UiScreenWidth - 1;
        }
-       if ((Top + Bottom) >= UiScreenHeight)
+       if (Bottom >= UiScreenHeight)
        {
-               Bottom = UiScreenHeight - Top;
-       }*/
+               Bottom = UiScreenHeight - 1;
+       }
 
        // Loop through each line and fill it in
        for (i=Top; i<=Bottom; i++)
@@ -162,7 +230,7 @@ VOID TuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR FillCha
                // Loop through each character (column) in the line and fill it in
                for (j=Left; j<=Right; j++)
                {
-                       ScreenMemory[((i*2)*UiScreenWidth)+(j*2)] = FillChar;
+                       ScreenMemory[((i*2)*UiScreenWidth)+(j*2)] = (UCHAR)FillChar;
                        ScreenMemory[((i*2)*UiScreenWidth)+(j*2)+1] = Attr;
                }
        }
@@ -304,7 +372,7 @@ VOID TuiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyl
  * DrawText()
  * This function assumes coordinates are zero-based
  */
-VOID TuiDrawText(ULONG X, ULONG Y, PUCHAR Text, UCHAR Attr)
+VOID TuiDrawText(ULONG X, ULONG Y, PCSTR Text, UCHAR Attr)
 {
        PUCHAR  ScreenMemory = (PUCHAR)TextVideoBuffer;
        ULONG           i, j;
@@ -312,12 +380,12 @@ VOID TuiDrawText(ULONG X, ULONG Y, PUCHAR Text, UCHAR Attr)
        // Draw the text
        for (i=X, j=0; Text[j]  && i<UiScreenWidth; i++,j++)
        {
-               ScreenMemory[((Y*2)*UiScreenWidth)+(i*2)] = Text[j];
+               ScreenMemory[((Y*2)*UiScreenWidth)+(i*2)] = (UCHAR)Text[j];
                ScreenMemory[((Y*2)*UiScreenWidth)+(i*2)+1] = Attr;
        }
 }
 
-VOID TuiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PUCHAR TextString, UCHAR Attr)
+VOID TuiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PCSTR TextString, UCHAR Attr)
 {
        ULONG           TextLength;
        ULONG           BoxWidth;
@@ -329,7 +397,7 @@ VOID TuiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PUCHA
        ULONG           RealTop;
        ULONG           X;
        ULONG           Y;
-       UCHAR   Temp[2];
+       CHAR    Temp[2];
 
        TextLength = strlen(TextString);
 
@@ -378,10 +446,15 @@ VOID TuiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PUCHA
        }
 }
 
-VOID TuiDrawStatusText(PUCHAR StatusText)
+VOID TuiDrawStatusText(PCSTR StatusText)
 {
        ULONG           i;
 
+    //
+    // Minimal UI doesn't have a status bar
+    //
+    if (UiMinimal) return;
+
        TuiDrawText(0, UiScreenHeight-1, " ", ATTR(UiStatusBarFgColor, UiStatusBarBgColor));
        TuiDrawText(1, UiScreenHeight-1, StatusText, ATTR(UiStatusBarFgColor, UiStatusBarBgColor));
 
@@ -397,16 +470,25 @@ VOID TuiUpdateDateTime(VOID)
 {
        ULONG   Year, Month, Day;
        ULONG   Hour, Minute, Second;
-       UCHAR   DateString[40];
-       UCHAR   TimeString[40];
-       UCHAR   TempString[20];
+       CHAR    DateString[40];
+       CHAR    TimeString[40];
+       CHAR    TempString[20];
        BOOL    PMHour = FALSE;
 
+    /* Don't draw the time if this has been disabled */
+    if (!UiDrawTime) return;
+
        MachRTCGetCurrentDateTime(&Year, &Month, &Day, &Hour, &Minute, &Second);
+       if (Year < 1 || 9999 < Year || Month < 1 || 12 < Month || Day < 1 ||
+            31 < Day || 23 < Hour || 59 < Minute || 59 < Second)
+       {
+               /* This happens on QEmu sometimes. We just skip updating */
+               return;
+       }
        // Get the month name
        strcpy(DateString, UiMonthNames[Month - 1]);
        // Get the day
-       itoa(Day, TempString, 10);
+       _itoa(Day, TempString, 10);
        // Get the day postfix
        if (1 == Day || 21 == Day || 31 == Day)
        {
@@ -430,7 +512,7 @@ VOID TuiUpdateDateTime(VOID)
        strcat(DateString, " ");
 
        // Get the year and add it to the date
-       itoa(Year, TempString, 10);
+       _itoa(Year, TempString, 10);
        strcat(DateString, TempString);
 
        // Draw the date
@@ -446,18 +528,18 @@ VOID TuiUpdateDateTime(VOID)
        {
                Hour = 12;
        }
-       itoa(Hour, TempString, 10);
+       _itoa(Hour, TempString, 10);
        strcpy(TimeString, "    ");
        strcat(TimeString, TempString);
        strcat(TimeString, ":");
-       itoa(Minute, TempString, 10);
+       _itoa(Minute, TempString, 10);
        if (Minute < 10)
        {
                strcat(TimeString, "0");
        }
        strcat(TimeString, TempString);
        strcat(TimeString, ":");
-       itoa(Second, TempString, 10);
+       _itoa(Second, TempString, 10);
        if (Second < 10)
        {
                strcat(TimeString, "0");
@@ -498,7 +580,7 @@ VOID TuiRestoreScreen(PUCHAR Buffer)
        }
 }
 
-VOID TuiMessageBox(PUCHAR MessageText)
+VOID TuiMessageBox(PCSTR MessageText)
 {
        PVOID   ScreenBuffer;
 
@@ -514,12 +596,13 @@ VOID TuiMessageBox(PUCHAR MessageText)
        MmFreeMemory(ScreenBuffer);
 }
 
-VOID TuiMessageBoxCritical(PUCHAR MessageText)
+VOID TuiMessageBoxCritical(PCSTR MessageText)
 {
        int             width = 8;
-       int             height = 1;
+       unsigned int    height = 1;
        int             curline = 0;
-       int             i , j, k;
+       int             k;
+       size_t          i , j;
        int             x1, x2, y1, y2;
        char    temp[260];
        char    key;
@@ -603,22 +686,40 @@ VOID TuiMessageBoxCritical(PUCHAR MessageText)
 }
 
 
-VOID TuiDrawProgressBarCenter(ULONG Position, ULONG Range, PUCHAR ProgressText)
+VOID TuiDrawProgressBarCenter(ULONG Position, ULONG Range, PCHAR ProgressText)
 {
        ULONG           Left, Top, Right, Bottom;
        ULONG           Width = 50; // Allow for 50 "bars"
        ULONG           Height = 2;
 
-       Left = (UiScreenWidth - Width - 4) / 2;
-       Right = Left + Width + 3;
-       Top = (UiScreenHeight - Height - 2) / 2;
-       Top += 2;
+       //
+       // Is this the minimal UI?
+       //
+       if (UiMinimal)
+       {
+               //
+               // Use alternate settings
+               //
+               Width = 80;
+               Left = 0;
+               Right = Left + Width;
+               Top = UiScreenHeight - Height - 4;
+               Bottom = Top + Height + 1;
+       }
+       else
+       {
+               Left = (UiScreenWidth - Width - 4) / 2;
+               Right = Left + Width + 3;
+               Top = (UiScreenHeight - Height - 2) / 2;
+               Top += 2;
+       }
+
        Bottom = Top + Height + 1;
 
        TuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText);
 }
 
-VOID TuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range, PUCHAR ProgressText)
+VOID TuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range, PCHAR ProgressText)
 {
        ULONG           i;
        ULONG           ProgressBarWidth = (Right - Left) - 3;
@@ -631,12 +732,26 @@ VOID TuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG
                Position = Range;
        }
 
-       // Draw the box
-       TuiDrawBox(Left, Top, Right, Bottom, VERT, HORZ, TRUE, TRUE, ATTR(UiMenuFgColor, UiMenuBgColor));
-
-       // Draw the "Loading..." text
-       //TuiDrawText(70/2, Top+1, "Loading...", ATTR(UiTextColor, UiMenuBgColor));
-       TuiDrawCenteredText(Left + 2, Top + 2, Right - 2, Top + 2, ProgressText, ATTR(UiTextColor, UiMenuBgColor));
+    //
+    // Minimal UI has no box, and only generic loading text
+    //
+    if (!UiMinimal)
+    {
+           // Draw the box
+           TuiDrawBox(Left, Top, Right, Bottom, VERT, HORZ, TRUE, TRUE, ATTR(UiMenuFgColor, UiMenuBgColor));
+
+       //
+        //  Draw the "Loading..." text
+        //
+           TuiDrawCenteredText(Left + 2, Top + 2, Right - 2, Top + 2, ProgressText, ATTR(UiTextColor, UiMenuBgColor));
+    }
+    else
+    {
+       //
+        //  Draw the "Loading..." text
+        //
+        TuiDrawCenteredText(Left + 2, Top + 1, Right - 2, Top + 1, "ReactOS is loading files...", ATTR(7, 0));
+    }
 
        // Draw the percent complete
        for (i=0; i<(Position*ProgressBarWidth)/Range; i++)
@@ -644,66 +759,68 @@ VOID TuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG
                TuiDrawText(Left+2+i, Top+2, "\xDB", ATTR(UiTextColor, UiMenuBgColor));
        }
 
-       // Draw the rest
-       for (; i<ProgressBarWidth; i++)
-       {
-               TuiDrawText(Left+2+i, Top+2, "\xB2", ATTR(UiTextColor, UiMenuBgColor));
-       }
+       // Draw the shadow for non-minimal UI
+    if (!UiMinimal)
+    {
+           for (; i<ProgressBarWidth; i++)
+           {
+                   TuiDrawText(Left+2+i, Top+2, "\xB2", ATTR(UiTextColor, UiMenuBgColor));
+           }
+    }
 
        TuiUpdateDateTime();
-
        VideoCopyOffScreenBufferToVRAM();
 }
 
-UCHAR TuiTextToColor(PUCHAR ColorText)
+UCHAR TuiTextToColor(PCSTR ColorText)
 {
-       if (stricmp(ColorText, "Black") == 0)
+       if (_stricmp(ColorText, "Black") == 0)
                return COLOR_BLACK;
-       else if (stricmp(ColorText, "Blue") == 0)
+       else if (_stricmp(ColorText, "Blue") == 0)
                return COLOR_BLUE;
-       else if (stricmp(ColorText, "Green") == 0)
+       else if (_stricmp(ColorText, "Green") == 0)
                return COLOR_GREEN;
-       else if (stricmp(ColorText, "Cyan") == 0)
+       else if (_stricmp(ColorText, "Cyan") == 0)
                return COLOR_CYAN;
-       else if (stricmp(ColorText, "Red") == 0)
+       else if (_stricmp(ColorText, "Red") == 0)
                return COLOR_RED;
-       else if (stricmp(ColorText, "Magenta") == 0)
+       else if (_stricmp(ColorText, "Magenta") == 0)
                return COLOR_MAGENTA;
-       else if (stricmp(ColorText, "Brown") == 0)
+       else if (_stricmp(ColorText, "Brown") == 0)
                return COLOR_BROWN;
-       else if (stricmp(ColorText, "Gray") == 0)
+       else if (_stricmp(ColorText, "Gray") == 0)
                return COLOR_GRAY;
-       else if (stricmp(ColorText, "DarkGray") == 0)
+       else if (_stricmp(ColorText, "DarkGray") == 0)
                return COLOR_DARKGRAY;
-       else if (stricmp(ColorText, "LightBlue") == 0)
+       else if (_stricmp(ColorText, "LightBlue") == 0)
                return COLOR_LIGHTBLUE;
-       else if (stricmp(ColorText, "LightGreen") == 0)
+       else if (_stricmp(ColorText, "LightGreen") == 0)
                return COLOR_LIGHTGREEN;
-       else if (stricmp(ColorText, "LightCyan") == 0)
+       else if (_stricmp(ColorText, "LightCyan") == 0)
                return COLOR_LIGHTCYAN;
-       else if (stricmp(ColorText, "LightRed") == 0)
+       else if (_stricmp(ColorText, "LightRed") == 0)
                return COLOR_LIGHTRED;
-       else if (stricmp(ColorText, "LightMagenta") == 0)
+       else if (_stricmp(ColorText, "LightMagenta") == 0)
                return COLOR_LIGHTMAGENTA;
-       else if (stricmp(ColorText, "Yellow") == 0)
+       else if (_stricmp(ColorText, "Yellow") == 0)
                return COLOR_YELLOW;
-       else if (stricmp(ColorText, "White") == 0)
+       else if (_stricmp(ColorText, "White") == 0)
                return COLOR_WHITE;
 
        return COLOR_BLACK;
 }
 
-UCHAR TuiTextToFillStyle(PUCHAR FillStyleText)
+UCHAR TuiTextToFillStyle(PCSTR FillStyleText)
 {
-       if (stricmp(FillStyleText, "Light") == 0)
+       if (_stricmp(FillStyleText, "Light") == 0)
        {
                return LIGHT_FILL;
        }
-       else if (stricmp(FillStyleText, "Medium") == 0)
+       else if (_stricmp(FillStyleText, "Medium") == 0)
        {
                return MEDIUM_FILL;
        }
-       else if (stricmp(FillStyleText, "Dark") == 0)
+       else if (_stricmp(FillStyleText, "Dark") == 0)
        {
                return DARK_FILL;
        }
@@ -765,19 +882,20 @@ VOID TuiFadeOut(VOID)
 
 }
 
-BOOL TuiEditBox(PUCHAR MessageText, PUCHAR EditTextBuffer, ULONG Length)
+BOOL TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
 {
        int             width = 8;
-       int             height = 1;
+       unsigned int    height = 1;
        int             curline = 0;
-       int             i , j, k;
+       int             k;
+       size_t          i , j;
        int             x1, x2, y1, y2;
        char    temp[260];
        char    key;
        int             EditBoxLine;
-       int             EditBoxStartX, EditBoxEndX;
+       ULONG           EditBoxStartX, EditBoxEndX;
        int             EditBoxCursorX;
-       int             EditBoxTextCount;
+       unsigned int    EditBoxTextCount;
        int             EditBoxTextDisplayIndex;
        BOOL    ReturnCode;
        PVOID   ScreenBuffer;