[FREELDR] Check for any user keypress in menu even when the timeout is zero.
[reactos.git] / boot / freeldr / freeldr / ui / tuimenu.c
index 861dd20..86690af 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         FreeLoader
- * FILE:            freeldr/ui/tuimenu.c
+ * FILE:            boot/freeldr/freeldr/ui/tuimenu.c
  * PURPOSE:         UI Menu Functions
  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
  *                  Brian Palmer (brianp@sginet.com)
@@ -14,7 +14,9 @@
 /* FUNCTIONS *****************************************************************/
 
 BOOLEAN
-TuiDisplayMenu(PCSTR MenuTitle,
+TuiDisplayMenu(PCSTR MenuHeader,
+               PCSTR MenuFooter,
+               BOOLEAN ShowBootOptions,
                PCSTR MenuItemList[],
                ULONG MenuItemCount,
                ULONG DefaultMenuItem,
@@ -28,8 +30,40 @@ TuiDisplayMenu(PCSTR MenuTitle,
     ULONG CurrentClockSecond;
     ULONG KeyPress;
 
+    //
+    // Before taking any default action if there is no timeout,
+    // check whether the supplied key filter callback function
+    // may handle a specific user keypress. If it does, the
+    // timeout is cancelled.
+    //
+    if (!MenuTimeOut && KeyPressFilter && MachConsKbHit())
+    {
+        //
+        // Get the key
+        //
+        KeyPress = MachConsGetCh();
+
+        //
+        // Is it extended? Then get the extended key
+        //
+        if (!KeyPress) KeyPress = MachConsGetCh();
+
+        //
+        // Call the supplied key filter callback function to see
+        // if it is going to handle this keypress.
+        //
+        if (KeyPressFilter(KeyPress))
+        {
+            //
+            // It processed the key character, cancel the timeout
+            //
+            MenuTimeOut = -1;
+        }
+    }
+
     //
     // Check if there's no timeout
+    //
     if (!MenuTimeOut)
     {
         //
@@ -42,7 +76,9 @@ TuiDisplayMenu(PCSTR MenuTitle,
     //
     // Setup the MENU_INFO structure
     //
-    MenuInformation.MenuTitle = MenuTitle;
+    MenuInformation.MenuHeader = MenuHeader;
+    MenuInformation.MenuFooter = MenuFooter;
+    MenuInformation.ShowBootOptions = ShowBootOptions;
     MenuInformation.MenuItemList = MenuItemList;
     MenuInformation.MenuItemCount = MenuItemCount;
     MenuInformation.MenuTimeRemaining = MenuTimeOut;
@@ -89,7 +125,7 @@ TuiDisplayMenu(PCSTR MenuTitle,
         //
         // Check if there is a countdown
         //
-        if (MenuInformation.MenuTimeRemaining)
+        if (MenuInformation.MenuTimeRemaining > 0)
         {
             //
             // Get the updated time, seconds only
@@ -114,7 +150,7 @@ TuiDisplayMenu(PCSTR MenuTitle,
                 VideoCopyOffScreenBufferToVRAM();
             }
         }
-        else
+        else if (MenuInformation.MenuTimeRemaining == 0)
         {
             //
             // A time out occurred, exit this loop and return default OS
@@ -155,8 +191,11 @@ TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo)
         //
         // Get the string length and make it become the new width if necessary
         //
-        Length = (ULONG)strlen(MenuInfo->MenuItemList[i]);
-        if (Length > Width) Width = Length;
+        if (MenuInfo->MenuItemList[i])
+        {
+            Length = (ULONG)strlen(MenuInfo->MenuItemList[i]);
+            if (Length > Width) Width = Length;
+        }
     }
 
     //
@@ -220,6 +259,12 @@ TuiDrawMenu(PUI_MENU_INFO MenuInfo)
         TuiDrawMenuItem(MenuInfo, i);
     }
 
+    /* Display the boot options if needed */
+    if (MenuInfo->ShowBootOptions)
+    {
+        DisplayBootTimeOptions();
+    }
+
     VideoCopyOffScreenBufferToVRAM();
 }
 
@@ -332,7 +377,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo)
         //
         // Check if it's a separator
         //
-        if (!(_stricmp(MenuInfo->MenuItemList[i], "SEPARATOR")))
+        if (MenuInfo->MenuItemList[i] == NULL)
         {
             //
             // Draw the separator line
@@ -371,7 +416,8 @@ TuiDrawMenuItem(PUI_MENU_INFO MenuInfo,
         // how many spaces will be to the left and right
         //
         SpaceTotal = (MenuInfo->Right - MenuInfo->Left - 2) -
-                     (ULONG)strlen(MenuInfo->MenuItemList[MenuItemNumber]);
+                     (ULONG)(MenuInfo->MenuItemList[MenuItemNumber] ?
+                             strlen(MenuInfo->MenuItemList[MenuItemNumber]) : 0);
         SpaceLeft = (SpaceTotal / 2) + 1;
         SpaceRight = (SpaceTotal - SpaceLeft) + 1;
 
@@ -393,7 +439,8 @@ TuiDrawMenuItem(PUI_MENU_INFO MenuInfo,
     //
     // Now append the text string
     //
-    strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]);
+    if (MenuInfo->MenuItemList[MenuItemNumber])
+        strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]);
 
     //
     // Check if using centered menu, and add spaces on the right if so
@@ -403,7 +450,7 @@ TuiDrawMenuItem(PUI_MENU_INFO MenuInfo,
     //
     // If it is a separator
     //
-    if (!(_stricmp(MenuInfo->MenuItemList[MenuItemNumber], "SEPARATOR")))
+    if (MenuInfo->MenuItemList[MenuItemNumber] == NULL)
     {
         //
         // Make it a separator line and use menu colors
@@ -480,7 +527,8 @@ TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo,
         //
         // Process the key
         //
-        if ((KeyEvent == KEY_UP) || (KeyEvent == KEY_DOWN))
+        if ((KeyEvent == KEY_UP  ) || (KeyEvent == KEY_DOWN) ||
+            (KeyEvent == KEY_HOME) || (KeyEvent == KEY_END ))
         {
             //
             // Get the current selected item and count
@@ -489,28 +537,37 @@ TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo,
             Count = MenuInfo->MenuItemCount - 1;
 
             //
-            // Check if this was a key up and there's a selected menu item
+            // Check the key and change the selected menu item
             //
-            if ((KeyEvent == KEY_UP) && (Selected))
+            if ((KeyEvent == KEY_UP) && (Selected > 0))
             {
                 //
-                // Update the menu (Deselect previous item)
+                // Deselect previous item and go up
                 //
                 MenuInfo->SelectedMenuItem--;
                 TuiDrawMenuItem(MenuInfo, Selected);
                 Selected--;
 
                 // Skip past any separators
-                if ((Selected) &&
-                    !(_stricmp(MenuInfo->MenuItemList[Selected], "SEPARATOR")))
+                if ((Selected > 0) &&
+                    (MenuInfo->MenuItemList[Selected] == NULL))
                 {
                     MenuInfo->SelectedMenuItem--;
                 }
             }
+            else if ( ((KeyEvent == KEY_UP) && (Selected == 0)) ||
+                       (KeyEvent == KEY_END) )
+            {
+                //
+                // Go to the end
+                //
+                MenuInfo->SelectedMenuItem = Count;
+                TuiDrawMenuItem(MenuInfo, Selected);
+            }
             else if ((KeyEvent == KEY_DOWN) && (Selected < Count))
             {
                 //
-                // Update the menu (deselect previous item)
+                // Deselect previous item and go down
                 //
                 MenuInfo->SelectedMenuItem++;
                 TuiDrawMenuItem(MenuInfo, Selected);
@@ -518,11 +575,20 @@ TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo,
 
                 // Skip past any separators
                 if ((Selected < Count) &&
-                    !(_stricmp(MenuInfo->MenuItemList[Selected], "SEPARATOR")))
+                    (MenuInfo->MenuItemList[Selected] == NULL))
                 {
                     MenuInfo->SelectedMenuItem++;
                 }
             }
+            else if ( ((KeyEvent == KEY_DOWN) && (Selected == Count)) ||
+                       (KeyEvent == KEY_HOME) )
+            {
+                //
+                // Go to the beginning
+                //
+                MenuInfo->SelectedMenuItem = 0;
+                TuiDrawMenuItem(MenuInfo, Selected);
+            }
 
             //
             // Select new item and update video buffer