ReactOS 0.4.15-dev-5666-gc548b97
tuimenu.c File Reference
#include <freeldr.h>
Include dependency graph for tuimenu.c:

Go to the source code of this file.

Functions

static VOID TuiCalcMenuBoxSize (_In_ PUI_MENU_INFO MenuInfo)
 
static ULONG TuiProcessMenuKeyboardEvent (_In_ PUI_MENU_INFO MenuInfo, _In_ UiMenuKeyPressFilterCallback KeyPressFilter)
 
static VOID TuiDrawMenuTimeout (_In_ PUI_MENU_INFO MenuInfo)
 
BOOLEAN TuiDisplayMenu (IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, IN LONG MenuTimeOut, OUT PULONG SelectedMenuItem, IN BOOLEAN CanEscape, IN UiMenuKeyPressFilterCallback KeyPressFilter OPTIONAL, IN PVOID Context OPTIONAL)
 
VOID TuiDrawMenu (_In_ PUI_MENU_INFO MenuInfo)
 
VOID TuiDrawMenuBox (_In_ PUI_MENU_INFO MenuInfo)
 
VOID TuiDrawMenuItem (_In_ PUI_MENU_INFO MenuInfo, _In_ ULONG MenuItemNumber)
 

Function Documentation

◆ TuiCalcMenuBoxSize()

static VOID TuiCalcMenuBoxSize ( _In_ PUI_MENU_INFO  MenuInfo)
static

Definition at line 155 of file tuimenu.c.

157{
158 ULONG i;
159 ULONG Width = 0;
162
163 /* Height is the menu item count plus 2 (top border & bottom border) */
164 Height = MenuInfo->MenuItemCount + 2;
165 Height -= 1; // Height is zero-based
166
167 /* Loop every item */
168 for (i = 0; i < MenuInfo->MenuItemCount; ++i)
169 {
170 /* Get the string length and make it become the new width if necessary */
171 if (MenuInfo->MenuItemList[i])
172 {
173 Length = (ULONG)strlen(MenuInfo->MenuItemList[i]);
174 if (Length > Width) Width = Length;
175 }
176 }
177
178 /* Allow room for left & right borders, plus 8 spaces on each side */
179 Width += 18;
180
181#ifndef _M_ARM
182 /* Check if we're drawing a centered menu */
183 if (UiCenterMenu)
184 {
185 /* Calculate the menu box area for a centered menu */
186 MenuInfo->Left = (UiScreenWidth - Width) / 2;
189 }
190 else
191#endif
192 {
193 /* Put the menu in the default left-corner position */
194 MenuInfo->Left = -1;
195 MenuInfo->Top = 4;
196 }
197
198 /* The other margins are the same */
199 MenuInfo->Right = MenuInfo->Left + Width;
200 MenuInfo->Bottom = MenuInfo->Top + Height;
201}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int ULONG
Definition: retypes.h:1
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
menu info structure
Definition: window.h:276
#define TUI_TITLE_BOX_CHAR_HEIGHT
Definition: tui.h:33
ULONG UiScreenWidth
Definition: ui.c:56
BOOLEAN UiCenterMenu
Definition: ui.c:46
ULONG UiScreenHeight
Definition: ui.c:57
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:126
_In_ HFONT _Out_ PUINT Height
Definition: font.h:125

Referenced by TuiDisplayMenu().

◆ TuiDisplayMenu()

BOOLEAN TuiDisplayMenu ( IN PCSTR  MenuHeader,
IN PCSTR MenuFooter  OPTIONAL,
IN BOOLEAN  ShowBootOptions,
IN PCSTR  MenuItemList[],
IN ULONG  MenuItemCount,
IN ULONG  DefaultMenuItem,
IN LONG  MenuTimeOut,
OUT PULONG  SelectedMenuItem,
IN BOOLEAN  CanEscape,
IN UiMenuKeyPressFilterCallback KeyPressFilter  OPTIONAL,
IN PVOID Context  OPTIONAL 
)

Definition at line 30 of file tuimenu.c.

42{
43 UI_MENU_INFO MenuInformation;
44 ULONG LastClockSecond;
45 ULONG CurrentClockSecond;
46 ULONG KeyPress;
47
48 /*
49 * Before taking any default action if there is no timeout,
50 * check whether the supplied key filter callback function
51 * may handle a specific user keypress. If it does, the
52 * timeout is cancelled.
53 */
54 if (!MenuTimeOut && KeyPressFilter && MachConsKbHit())
55 {
56 /* Get the key (get the extended key if needed) */
57 KeyPress = MachConsGetCh();
58 if (KeyPress == KEY_EXTENDED)
59 KeyPress = MachConsGetCh();
60
61 /*
62 * Call the supplied key filter callback function to see
63 * if it is going to handle this keypress.
64 */
65 if (KeyPressFilter(KeyPress, DefaultMenuItem, Context))
66 {
67 /* It processed the key character, cancel the timeout */
68 MenuTimeOut = -1;
69 }
70 }
71
72 /* Check if there is no timeout */
73 if (!MenuTimeOut)
74 {
75 /* Return the default selected item */
76 if (SelectedMenuItem) *SelectedMenuItem = DefaultMenuItem;
77 return TRUE;
78 }
79
80 /* Setup the MENU_INFO structure */
81 MenuInformation.MenuHeader = MenuHeader;
82 MenuInformation.MenuFooter = MenuFooter;
83 MenuInformation.ShowBootOptions = ShowBootOptions;
84 MenuInformation.MenuItemList = MenuItemList;
85 MenuInformation.MenuItemCount = MenuItemCount;
86 MenuInformation.MenuTimeRemaining = MenuTimeOut;
87 MenuInformation.SelectedMenuItem = DefaultMenuItem;
88 MenuInformation.Context = Context;
89
90 /* Calculate the size of the menu box */
91 TuiCalcMenuBoxSize(&MenuInformation);
92
93 /* Draw the menu */
94#ifdef _M_ARM
95 UiDrawMenu(&MenuInformation);
96#else
97 UiVtbl.DrawMenu(&MenuInformation);
98#endif
99
100 /* Get the current second of time */
101 LastClockSecond = ArcGetTime()->Second;
102
103 /* Process keys */
104 while (TRUE)
105 {
106 /* Process key presses */
107 KeyPress = TuiProcessMenuKeyboardEvent(&MenuInformation, KeyPressFilter);
108
109 /* Check for ENTER or ESC */
110 if (KeyPress == KEY_ENTER) break;
111 if (CanEscape && KeyPress == KEY_ESC) return FALSE;
112
113 /* Get the updated time, and check if more than a second has elapsed */
114 CurrentClockSecond = ArcGetTime()->Second;
115 if (CurrentClockSecond != LastClockSecond)
116 {
117 /* Update the time information */
118 LastClockSecond = CurrentClockSecond;
119
120#ifndef _M_ARM // FIXME: Theme-specific
121 /* Update the date & time */
123#endif
124
125 /* If there is a countdown, update it */
126 if (MenuInformation.MenuTimeRemaining > 0)
127 {
128 MenuInformation.MenuTimeRemaining--;
129 TuiDrawMenuTimeout(&MenuInformation);
130 }
131 else if (MenuInformation.MenuTimeRemaining == 0)
132 {
133 /* A timeout occurred, exit this loop and return selection */
134#ifndef _M_ARM
136#endif
137 break;
138 }
139#ifndef _M_ARM
141#endif
142 }
143
144#ifndef _M_ARM
145 MachHwIdle();
146#endif
147 }
148
149 /* Return the selected item */
150 if (SelectedMenuItem) *SelectedMenuItem = MenuInformation.SelectedMenuItem;
151 return TRUE;
152}
TIMEINFO * ArcGetTime(VOID)
Definition: arcemul.c:27
#define MachHwIdle()
Definition: machine.h:137
#define MachConsKbHit()
Definition: machine.h:88
#define MachConsGetCh()
Definition: machine.h:90
VOID VideoCopyOffScreenBufferToVRAM(VOID)
Definition: video.c:39
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define KEY_EXTENDED
Definition: keycodes.h:38
#define KEY_ESC
Definition: keycodes.h:49
#define KEY_ENTER
Definition: keycodes.h:39
USHORT Second
Definition: fw.h:16
VOID(* DrawMenu)(PUI_MENU_INFO MenuInfo)
Definition: ui.h:297
PCSTR MenuHeader
Definition: ui.h:203
BOOLEAN ShowBootOptions
Definition: ui.h:205
LONG MenuTimeRemaining
Definition: ui.h:209
ULONG SelectedMenuItem
Definition: ui.h:210
PCSTR MenuFooter
Definition: ui.h:204
ULONG MenuItemCount
Definition: ui.h:208
PCSTR * MenuItemList
Definition: ui.h:207
PVOID Context
Definition: ui.h:211
VOID TuiUpdateDateTime(VOID)
Definition: tui.c:552
static ULONG TuiProcessMenuKeyboardEvent(_In_ PUI_MENU_INFO MenuInfo, _In_ UiMenuKeyPressFilterCallback KeyPressFilter)
Definition: tuimenu.c:527
static VOID TuiCalcMenuBoxSize(_In_ PUI_MENU_INFO MenuInfo)
Definition: tuimenu.c:155
static VOID TuiDrawMenuTimeout(_In_ PUI_MENU_INFO MenuInfo)
Definition: tuimenu.c:274
UIVTBL UiVtbl
Definition: ui.c:70

◆ TuiDrawMenu()

VOID TuiDrawMenu ( _In_ PUI_MENU_INFO  MenuInfo)

Definition at line 204 of file tuimenu.c.

206{
207 ULONG i;
208
209#ifndef _M_ARM // FIXME: Theme-specific
210 /* Draw the backdrop */
212#else
213
214 /* No GUI status bar text, just minimal text. Show the menu header. */
215 if (MenuInfo->MenuHeader)
216 {
217 UiDrawText(0,
218 MenuInfo->Top - 2,
219 MenuInfo->MenuHeader,
221 }
222
223#endif
224
225 /* Draw the menu box */
227
228 /* Draw each line of the menu */
229 for (i = 0; i < MenuInfo->MenuItemCount; ++i)
230 {
232 }
233
234#ifndef _M_ARM // FIXME: Theme-specific
235
236 /* Update the status bar */
237 UiVtbl.DrawStatusText("Use \x18 and \x19 to select, then press ENTER.");
238
239#else
240
241 /* Now tell the user how to choose */
242 UiDrawText(0,
243 MenuInfo->Bottom + 1,
244 "Use \x18 and \x19 to move the highlight to your choice.",
246 UiDrawText(0,
247 MenuInfo->Bottom + 2,
248 "Press ENTER to choose.",
250
251 /* And show the menu footer */
252 if (MenuInfo->MenuFooter)
253 {
254 UiDrawText(0,
255 UiScreenHeight - 4,
256 MenuInfo->MenuFooter,
258 }
259
260#endif
261
262 /* Display the boot options if needed */
263 if (MenuInfo->ShowBootOptions)
264 {
266 }
267
268#ifndef _M_ARM
270#endif
271}
VOID DisplayBootTimeOptions(VOID)
Definition: options.c:181
VOID(* DrawStatusText)(PCSTR StatusText)
Definition: ui.h:257
VOID TuiDrawMenuItem(_In_ PUI_MENU_INFO MenuInfo, _In_ ULONG MenuItemNumber)
Definition: tuimenu.c:426
VOID TuiDrawMenuBox(_In_ PUI_MENU_INFO MenuInfo)
Definition: tuimenu.c:400
VOID UiDrawText(_In_ ULONG X, _In_ ULONG Y, _In_ PCSTR Text, _In_ UCHAR Attr)
Definition: ui.c:260
UCHAR UiMenuBgColor
Definition: ui.c:37
#define ATTR(cFore, cBack)
Definition: ui.h:314
VOID UiDrawBackdrop(VOID)
Definition: ui.c:239
UCHAR UiMenuFgColor
Definition: ui.c:36

◆ TuiDrawMenuBox()

VOID TuiDrawMenuBox ( _In_ PUI_MENU_INFO  MenuInfo)

Definition at line 400 of file tuimenu.c.

402{
403#ifndef _M_ARM // FIXME: Theme-specific
404 /* Draw the menu box if requested */
405 if (UiMenuBox)
406 {
407 UiDrawBox(MenuInfo->Left,
408 MenuInfo->Top,
409 MenuInfo->Right,
410 MenuInfo->Bottom,
411 D_VERT,
412 D_HORZ,
413 FALSE, // Filled
414 TRUE, // Shadow
416 }
417
418 /* Update the date & time */
420#endif
421
423}
#define D_HORZ
Definition: ui.h:344
#define D_VERT
Definition: ui.h:346
BOOLEAN UiMenuBox
Definition: ui.c:45
VOID UiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOLEAN Fill, BOOLEAN Shadow, UCHAR Attr)
Definition: ui.c:254

Referenced by MiniTuiDrawMenu(), and TuiDrawMenu().

◆ TuiDrawMenuItem()

VOID TuiDrawMenuItem ( _In_ PUI_MENU_INFO  MenuInfo,
_In_ ULONG  MenuItemNumber 
)

Definition at line 426 of file tuimenu.c.

429{
430 ULONG SpaceLeft;
431 ULONG SpaceRight;
432 UCHAR Attribute;
433 CHAR MenuLineText[80];
434
435 /* If this is a separator */
436 if (MenuInfo->MenuItemList[MenuItemNumber] == NULL)
437 {
438#ifndef _M_ARM // FIXME: Theme-specific
439 /* Draw its left box corner */
440 if (UiMenuBox)
441 {
442 UiDrawText(MenuInfo->Left,
443 MenuInfo->Top + 1 + MenuItemNumber,
444 "\xC7",
446 }
447#endif
448
449 /* Make it a separator line and use menu colors */
450 RtlZeroMemory(MenuLineText, sizeof(MenuLineText));
451 RtlFillMemory(MenuLineText,
452 min(sizeof(MenuLineText), (MenuInfo->Right - MenuInfo->Left - 1)),
453 0xC4);
454
455 /* Draw the item */
456 UiDrawText(MenuInfo->Left + 1,
457 MenuInfo->Top + 1 + MenuItemNumber,
458 MenuLineText,
460
461#ifndef _M_ARM // FIXME: Theme-specific
462 /* Draw its right box corner */
463 if (UiMenuBox)
464 {
465 UiDrawText(MenuInfo->Right,
466 MenuInfo->Top + 1 + MenuItemNumber,
467 "\xB6",
469 }
470#endif
471
472 /* We are done */
473 return;
474 }
475
476 /* This is not a separator */
477 ASSERT(MenuInfo->MenuItemList[MenuItemNumber]);
478
479#ifndef _M_ARM
480 /* Check if using centered menu */
481 if (UiCenterMenu)
482 {
483 /*
484 * We will want the string centered so calculate
485 * how many spaces will be to the left and right.
486 */
487 ULONG SpaceTotal =
488 (MenuInfo->Right - MenuInfo->Left - 2) -
489 (ULONG)strlen(MenuInfo->MenuItemList[MenuItemNumber]);
490 SpaceLeft = (SpaceTotal / 2) + 1;
491 SpaceRight = (SpaceTotal - SpaceLeft) + 1;
492 }
493 else
494#endif
495 {
496 /* Simply left-align it */
497 SpaceLeft = 4;
498 SpaceRight = 0;
499 }
500
501 /* Format the item text string */
502 RtlStringCbPrintfA(MenuLineText, sizeof(MenuLineText),
503 "%*s%s%*s",
504 SpaceLeft, "", // Left padding
505 MenuInfo->MenuItemList[MenuItemNumber],
506 SpaceRight, ""); // Right padding
507
508 if (MenuItemNumber == MenuInfo->SelectedMenuItem)
509 {
510 /* If this is the selected item, use the selected colors */
512 }
513 else
514 {
515 /* Normal item colors */
516 Attribute = ATTR(UiTextColor, UiMenuBgColor);
517 }
518
519 /* Draw the item */
520 UiDrawText(MenuInfo->Left + 1,
521 MenuInfo->Top + 1 + MenuItemNumber,
522 MenuLineText,
523 Attribute);
524}
#define NULL
Definition: types.h:112
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define ASSERT(a)
Definition: mode.c:44
#define min(a, b)
Definition: monoChain.cc:55
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR UiTextColor
Definition: ui.c:38
UCHAR UiSelectedTextColor
Definition: ui.c:39
UCHAR UiSelectedTextBgColor
Definition: ui.c:40
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175

Referenced by MiniTuiDrawMenu(), TuiDrawMenu(), and TuiProcessMenuKeyboardEvent().

◆ TuiDrawMenuTimeout()

static VOID TuiDrawMenuTimeout ( _In_ PUI_MENU_INFO  MenuInfo)
static

How to pad/fill:

Center Box What to do: 0 0 or 1 Pad on the right with blanks. 1 0 Pad on the left with blanks. 1 1 Pad on the left with blanks + box bottom border.

Definition at line 274 of file tuimenu.c.

276{
278 CHAR MenuLineText[80];
279
280 /* If there is a timeout, draw the time remaining */
281 if (MenuInfo->MenuTimeRemaining >= 0)
282 {
283 /* Find whether the time text string is escaped
284 * with %d for specific countdown insertion. */
286 while ((ptr = strchr(ptr, '%')) && (ptr[1] != 'd'))
287 {
288 /* Ignore any following character (including a following
289 * '%' that would be escaped), thus skip two characters.
290 * If this is the last character, ignore it and stop. */
291 if (*++ptr)
292 ++ptr;
293 }
294 ASSERT(!ptr || (ptr[0] == '%' && ptr[1] == 'd'));
295
296 if (ptr)
297 {
298 /* Copy the time text string up to the '%d' insertion point and
299 * skip it, add the remaining time and the rest of the string. */
300 RtlStringCbPrintfA(MenuLineText, sizeof(MenuLineText),
301 "%.*s%d%s",
303 MenuInfo->MenuTimeRemaining,
304 ptr + 2);
305 }
306 else
307 {
308 /* Copy the time text string, append a separating blank,
309 * and add the remaining time. */
310 RtlStringCbPrintfA(MenuLineText, sizeof(MenuLineText),
311 "%s %d",
313 MenuInfo->MenuTimeRemaining);
314 }
315
316 Length = (ULONG)strlen(MenuLineText);
317 }
318 else
319 {
320 /* Erase the timeout with blanks */
321 Length = 0;
322 }
323
333#ifndef _M_ARM
334 if (UiCenterMenu)
335 {
336 /* In boxed menu mode, pad on the left with blanks and box border,
337 * otherwise, pad over all the box length until its right edge. */
338 TuiFillArea(0,
339 MenuInfo->Bottom,
341 ? MenuInfo->Left - 1 /* Left side of the box bottom */
342 : MenuInfo->Right, /* Left side + all box length */
343 MenuInfo->Bottom,
346
347 if (UiMenuBox)
348 {
349 /* Fill with box bottom border */
351 MenuInfo->Bottom,
352 MenuInfo->Right,
353 D_VERT,
354 D_HORZ,
356
357 /* In centered boxed menu mode, the timeout string
358 * does not go past the right border, in principle... */
359 }
360
361 if (Length > 0)
362 {
363 /* Display the timeout at the bottom-right part of the menu */
364 UiDrawText(MenuInfo->Right - Length - 1,
365 MenuInfo->Bottom,
366 MenuLineText,
368 }
369 }
370 else
371#endif
372 {
373 if (Length > 0)
374 {
375 /* Display the timeout under the menu directly */
376 UiDrawText(0,
377 MenuInfo->Bottom + 4,
378 MenuLineText,
380 }
381
382 /* Pad on the right with blanks, to erase
383 * characters when the string length decreases. */
385 MenuInfo->Bottom + 4,
386 Length ? (Length + 1) : (UiScreenWidth - 1),
387 MenuInfo->Bottom + 4,
388#ifndef _M_ARM
391#else
392 0, // ' '
393 ATTR(UiTextColor, COLOR_BLACK) // UiMenuBgColor
394#endif
395 );
396 }
397}
char * strchr(const char *String, int ch)
Definition: utclib.c:501
signed char * PCHAR
Definition: retypes.h:7
static PVOID ptr
Definition: dispmode.c:27
VOID TuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr)
Definition: tui.c:332
VOID TuiDrawBoxBottomLine(_In_ ULONG Left, _In_ ULONG Bottom, _In_ ULONG Right, _In_ UCHAR VertStyle, _In_ UCHAR HorzStyle, _In_ UCHAR Attr)
Definition: tui.c:463
CHAR UiTimeText[260]
Definition: ui.c:50
UCHAR UiBackdropFgColor
Definition: ui.c:29
UCHAR UiBackdropFillStyle
Definition: ui.c:31
UCHAR UiBackdropBgColor
Definition: ui.c:30
#define COLOR_BLACK
Definition: ui.h:319

Referenced by TuiDisplayMenu(), TuiDrawMenuBox(), and TuiProcessMenuKeyboardEvent().

◆ TuiProcessMenuKeyboardEvent()

static ULONG TuiProcessMenuKeyboardEvent ( _In_ PUI_MENU_INFO  MenuInfo,
_In_ UiMenuKeyPressFilterCallback  KeyPressFilter 
)
static

Definition at line 527 of file tuimenu.c.

530{
531 ULONG KeyEvent = 0;
532 ULONG Selected, Count;
533
534 /* Check for a keypress */
535 if (!MachConsKbHit())
536 return 0; // None, bail out
537
538 /* Check if the timeout is not already complete */
539 if (MenuInfo->MenuTimeRemaining != -1)
540 {
541 /* Cancel it and remove it */
542 MenuInfo->MenuTimeRemaining = -1;
544 }
545
546 /* Get the key (get the extended key if needed) */
547 KeyEvent = MachConsGetCh();
548 if (KeyEvent == KEY_EXTENDED)
549 KeyEvent = MachConsGetCh();
550
551 /*
552 * Call the supplied key filter callback function to see
553 * if it is going to handle this keypress.
554 */
555 if (KeyPressFilter &&
556 KeyPressFilter(KeyEvent, MenuInfo->SelectedMenuItem, MenuInfo->Context))
557 {
558 /* It processed the key character, so redraw and exit */
559#ifdef _M_ARM
560 UiDrawMenu(MenuInfo);
561#else
563#endif
564 return 0;
565 }
566
567 /* Process the key */
568 if ((KeyEvent == KEY_UP ) || (KeyEvent == KEY_DOWN) ||
569 (KeyEvent == KEY_HOME) || (KeyEvent == KEY_END ))
570 {
571 /* Get the current selected item and count */
572 Selected = MenuInfo->SelectedMenuItem;
573 Count = MenuInfo->MenuItemCount - 1;
574
575 /* Check the key and change the selected menu item */
576 if ((KeyEvent == KEY_UP) && (Selected > 0))
577 {
578 /* Deselect previous item and go up */
579 MenuInfo->SelectedMenuItem--;
580 TuiDrawMenuItem(MenuInfo, Selected);
581 Selected--;
582
583 /* Skip past any separators */
584 if ((Selected > 0) &&
585 (MenuInfo->MenuItemList[Selected] == NULL))
586 {
587 MenuInfo->SelectedMenuItem--;
588 }
589 }
590 else if ( ((KeyEvent == KEY_UP) && (Selected == 0)) ||
591 (KeyEvent == KEY_END) )
592 {
593 /* Go to the end */
594 MenuInfo->SelectedMenuItem = Count;
595 TuiDrawMenuItem(MenuInfo, Selected);
596 }
597 else if ((KeyEvent == KEY_DOWN) && (Selected < Count))
598 {
599 /* Deselect previous item and go down */
600 MenuInfo->SelectedMenuItem++;
601 TuiDrawMenuItem(MenuInfo, Selected);
602 Selected++;
603
604 /* Skip past any separators */
605 if ((Selected < Count) &&
606 (MenuInfo->MenuItemList[Selected] == NULL))
607 {
608 MenuInfo->SelectedMenuItem++;
609 }
610 }
611 else if ( ((KeyEvent == KEY_DOWN) && (Selected == Count)) ||
612 (KeyEvent == KEY_HOME) )
613 {
614 /* Go to the beginning */
615 MenuInfo->SelectedMenuItem = 0;
616 TuiDrawMenuItem(MenuInfo, Selected);
617 }
618
619 /* Select new item and update video buffer */
620 TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem);
621#ifndef _M_ARM
623#endif
624 }
625
626 /* Return the pressed key */
627 return KeyEvent;
628}
#define KEY_DOWN
Definition: keycodes.h:46
#define KEY_END
Definition: keycodes.h:64
#define KEY_HOME
Definition: keycodes.h:44
#define KEY_UP
Definition: keycodes.h:45
int Count
Definition: noreturn.cpp:7

Referenced by TuiDisplayMenu().