]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/SetupBrowser.c
HII Library Class interface refine.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / SetupBrowser.c
CommitLineData
0368663f 1/**@file\r
2Framework to UEFI 2.1 Setup Browser Thunk. The file consume EFI_FORM_BROWSER2_PROTOCOL\r
3to produce a EFI_FORM_BROWSER_PROTOCOL.\r
4\r
5Copyright (c) 2008, Intel Corporation\r
6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "HiiDatabase.h"\r
a235abd2 17#include "SetupBrowser.h"\r
18\r
19EFI_GUID gFrameworkBdsFrontPageFormsetGuid = FRAMEWORK_BDS_FRONTPAGE_FORMSET_GUID;\r
20EFI_HII_HANDLE gStringPackHandle = NULL;\r
21BOOLEAN mFrontPageDisplayed = FALSE;\r
22//\r
23// 106F3545-B788-4cb5-9D2A-CE0CDB208DF5\r
24//\r
25EFI_GUID gEfiHiiThunkProducerGuid = { 0x106f3545, 0xb788, 0x4cb5, { 0x9d, 0x2a, 0xce, 0xc, 0xdb, 0x20, 0x8d, 0xf5 } }; \r
26\r
27\r
28/**\r
29 Get string by string id from HII Interface\r
30\r
31\r
32 @param Id String ID.\r
33\r
34 @retval CHAR16 * String from ID.\r
35 @retval NULL If error occurs.\r
36\r
37**/\r
38CHAR16 *\r
39GetStringById (\r
40 IN EFI_STRING_ID Id\r
41 )\r
42{\r
cb7d01c0 43 return HiiGetString (gStringPackHandle, Id, NULL);\r
a235abd2 44}\r
cb7d01c0 45\r
a235abd2 46/**\r
47\r
48 Show progress bar with title above it. It only works in Graphics mode.\r
49\r
50\r
51 @param TitleForeground Foreground color for Title.\r
52 @param TitleBackground Background color for Title.\r
53 @param Title Title above progress bar.\r
54 @param ProgressColor Progress bar color.\r
55 @param Progress Progress (0-100)\r
56 @param PreviousValue The previous value of the progress.\r
57\r
58 @retval EFI_STATUS Success update the progress bar\r
59\r
60**/\r
61EFI_STATUS\r
62PlatformBdsShowProgress (\r
63 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,\r
64 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,\r
65 IN CHAR16 *Title,\r
66 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,\r
67 IN UINTN Progress,\r
68 IN UINTN PreviousValue\r
69 )\r
70{\r
71 EFI_STATUS Status;\r
72 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
73 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
74 UINT32 SizeOfX;\r
75 UINT32 SizeOfY;\r
76 UINT32 ColorDepth;\r
77 UINT32 RefreshRate;\r
78 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
79 UINTN BlockHeight;\r
80 UINTN BlockWidth;\r
81 UINTN BlockNum;\r
82 UINTN PosX;\r
83 UINTN PosY;\r
84 UINTN Index;\r
85\r
86 if (Progress > 100) {\r
87 return EFI_INVALID_PARAMETER;\r
88 }\r
89\r
90 UgaDraw = NULL;\r
91 Status = gBS->HandleProtocol (\r
92 gST->ConsoleOutHandle,\r
93 &gEfiGraphicsOutputProtocolGuid,\r
94 (VOID **) &GraphicsOutput\r
95 );\r
96 if (EFI_ERROR (Status)) {\r
97 GraphicsOutput = NULL;\r
98\r
99 Status = gBS->HandleProtocol (\r
100 gST->ConsoleOutHandle,\r
101 &gEfiUgaDrawProtocolGuid,\r
102 (VOID **) &UgaDraw\r
103 );\r
104 }\r
105 if (EFI_ERROR (Status)) {\r
106 return EFI_UNSUPPORTED;\r
107 }\r
108\r
109 SizeOfX = 0;\r
110 SizeOfY = 0;\r
111 if (GraphicsOutput != NULL) {\r
112 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
113 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
114 } else {\r
115 Status = UgaDraw->GetMode (\r
116 UgaDraw,\r
117 &SizeOfX,\r
118 &SizeOfY,\r
119 &ColorDepth,\r
120 &RefreshRate\r
121 );\r
122 if (EFI_ERROR (Status)) {\r
123 return EFI_UNSUPPORTED;\r
124 }\r
125 }\r
126\r
127 BlockWidth = SizeOfX / 100;\r
128 BlockHeight = SizeOfY / 50;\r
129\r
130 BlockNum = Progress;\r
131\r
132 PosX = 0;\r
133 PosY = SizeOfY * 48 / 50;\r
134\r
135 if (BlockNum == 0) {\r
136 //\r
137 // Clear progress area\r
138 //\r
139 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
140\r
141 if (GraphicsOutput != NULL) {\r
142 Status = GraphicsOutput->Blt (\r
143 GraphicsOutput,\r
144 &Color,\r
145 EfiBltVideoFill,\r
146 0,\r
147 0,\r
148 0,\r
149 PosY - EFI_GLYPH_HEIGHT - 1,\r
150 SizeOfX,\r
151 SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),\r
152 SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
153 );\r
154 } else {\r
155 Status = UgaDraw->Blt (\r
156 UgaDraw,\r
157 (EFI_UGA_PIXEL *) &Color,\r
158 EfiUgaVideoFill,\r
159 0,\r
160 0,\r
161 0,\r
162 PosY - EFI_GLYPH_HEIGHT - 1,\r
163 SizeOfX,\r
164 SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),\r
165 SizeOfX * sizeof (EFI_UGA_PIXEL)\r
166 );\r
167 }\r
168 }\r
169 //\r
170 // Show progress by drawing blocks\r
171 //\r
172 for (Index = PreviousValue; Index < BlockNum; Index++) {\r
173 PosX = Index * BlockWidth;\r
174 if (GraphicsOutput != NULL) {\r
175 Status = GraphicsOutput->Blt (\r
176 GraphicsOutput,\r
177 &ProgressColor,\r
178 EfiBltVideoFill,\r
179 0,\r
180 0,\r
181 PosX,\r
182 PosY,\r
183 BlockWidth - 1,\r
184 BlockHeight,\r
185 (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
186 );\r
187 } else {\r
188 Status = UgaDraw->Blt (\r
189 UgaDraw,\r
190 (EFI_UGA_PIXEL *) &ProgressColor,\r
191 EfiUgaVideoFill,\r
192 0,\r
193 0,\r
194 PosX,\r
195 PosY,\r
196 BlockWidth - 1,\r
197 BlockHeight,\r
198 (BlockWidth) * sizeof (EFI_UGA_PIXEL)\r
199 );\r
200 }\r
201 }\r
202\r
203 PrintXY (\r
204 (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,\r
205 PosY - EFI_GLYPH_HEIGHT - 1,\r
206 &TitleForeground,\r
207 &TitleBackground,\r
208 Title\r
209 );\r
210\r
211 return EFI_SUCCESS;\r
212}\r
213\r
214/**\r
215 Function waits for a given event to fire, or for an optional timeout to expire.\r
216\r
217\r
218 @param Event The event to wait for\r
219 \r
220 @param Timeout An optional timeout value in 100 ns units.\r
221\r
222 @retval EFI_SUCCESS Event fired before Timeout expired.\r
223 @retval EFI_TIME_OUT Timout expired before Event fired..\r
224\r
225**/\r
226EFI_STATUS\r
227WaitForSingleEvent (\r
228 IN EFI_EVENT Event,\r
229 IN UINT64 Timeout OPTIONAL\r
230 )\r
231{\r
232 EFI_STATUS Status;\r
233 UINTN Index;\r
234 EFI_EVENT TimerEvent;\r
235 EFI_EVENT WaitList[2];\r
236\r
237 if (Timeout != 0) {\r
238 //\r
239 // Create a timer event\r
240 //\r
241 Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
242 if (!EFI_ERROR (Status)) {\r
243 //\r
244 // Set the timer event\r
245 //\r
246 gBS->SetTimer (\r
247 TimerEvent,\r
248 TimerRelative,\r
249 Timeout\r
250 );\r
251\r
252 //\r
253 // Wait for the original event or the timer\r
254 //\r
255 WaitList[0] = Event;\r
256 WaitList[1] = TimerEvent;\r
257 Status = gBS->WaitForEvent (2, WaitList, &Index);\r
258 gBS->CloseEvent (TimerEvent);\r
259\r
260 //\r
261 // If the timer expired, change the return to timed out\r
262 //\r
263 if (!EFI_ERROR (Status) && Index == 1) {\r
264 Status = EFI_TIMEOUT;\r
265 }\r
266 }\r
267 } else {\r
268 //\r
269 // No timeout... just wait on the event\r
270 //\r
271 Status = gBS->WaitForEvent (1, &Event, &Index);\r
272 ASSERT (!EFI_ERROR (Status));\r
273 ASSERT (Index == 0);\r
274 }\r
275\r
276 return Status;\r
277}\r
278\r
279/**\r
280 Function show progress bar to wait for user input.\r
281\r
282\r
283 @param TimeoutDefault - The fault time out value before the system\r
284 continue to boot.\r
285\r
286 @retval EFI_SUCCESS User pressed some key except "Enter"\r
287 @retval EFI_TIME_OUT Timout expired or user press "Enter"\r
288\r
289**/\r
290EFI_STATUS\r
291ShowProgress (\r
292 IN UINT16 TimeoutDefault\r
293 )\r
294{\r
295 EFI_STATUS Status;\r
296 CHAR16 *TmpStr;\r
297 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
298 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
299 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
300 EFI_INPUT_KEY Key;\r
301 UINT16 TimeoutRemain;\r
302\r
303 if (TimeoutDefault == 0) {\r
304 return EFI_TIMEOUT;\r
305 }\r
306\r
307 DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));\r
308 \r
309 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
310 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
311 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
312\r
313 //\r
314 // Clear the progress status bar first\r
315 //\r
316 TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
317 if (TmpStr != NULL) {\r
318 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\r
319 }\r
320\r
321 TimeoutRemain = TimeoutDefault;\r
322 while (TimeoutRemain != 0) {\r
323 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));\r
324 \r
325 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);\r
326 if (Status != EFI_TIMEOUT) {\r
327 break;\r
328 }\r
329 TimeoutRemain--;\r
330\r
331 //\r
332 // Show progress\r
333 //\r
334 if (TmpStr != NULL) {\r
335 PlatformBdsShowProgress (\r
336 Foreground,\r
337 Background,\r
338 TmpStr,\r
339 Color,\r
340 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),\r
341 0\r
342 );\r
343 }\r
344 }\r
345 gBS->FreePool (TmpStr);\r
346\r
347 //\r
348 // Timeout expired\r
349 //\r
350 if (TimeoutRemain == 0) {\r
351 return EFI_TIMEOUT;\r
352 }\r
353\r
354 //\r
355 // User pressed some key\r
356 //\r
357 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
358 if (EFI_ERROR (Status)) {\r
359 return Status;\r
360 }\r
361\r
362 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
363 //\r
364 // User pressed enter, equivalent to select "continue"\r
365 //\r
366 return EFI_TIMEOUT;\r
367 }\r
368\r
369 return EFI_SUCCESS;\r
370}\r
371\r
372/**\r
373 Return the default value for system Timeout variable.\r
374\r
375 @return Timeout value.\r
376\r
377**/\r
378UINT16\r
379EFIAPI\r
380GetTimeout (\r
381 VOID\r
382 )\r
383{\r
78b719ae 384 return PcdGet16 (PcdPlatformBootTimeOut);\r
a235abd2 385}\r
386\r
0368663f 387\r
a9d85320 388/**\r
389 This is the Framework Setup Browser interface which displays a FormSet.\r
390\r
391 @param This The EFI_FORM_BROWSER_PROTOCOL context.\r
392 @param UseDatabase TRUE if the FormSet is from HII database. The Thunk implementation\r
393 only support UseDatabase is TRUE.\r
394 @param Handle The Handle buffer.\r
395 @param HandleCount The number of Handle in the Handle Buffer. It must be 1 for this implementation.\r
396 @param Packet The pointer to data buffer containing IFR and String package. Not supported.\r
397 @param CallbackHandle Not supported.\r
398 @param NvMapOverride The buffer is used only when there is no NV variable to define the \r
399 current settings and the caller needs to provide to the browser the\r
400 current settings for the the "fake" NV variable. If used, no saving of\r
401 an NV variable is possbile. This parameter is also ignored if Handle is NULL.\r
402\r
403 @retval EFI_SUCCESS If the Formset is displayed correctly.\r
404 @retval EFI_UNSUPPORTED If UseDatabase is FALSE or HandleCount is not 1.\r
405 @retval EFI_INVALID_PARAMETER If the *Handle passed in is not found in the database.\r
406**/\r
407\r
0368663f 408EFI_STATUS\r
409EFIAPI \r
410ThunkSendForm (\r
411 IN EFI_FORM_BROWSER_PROTOCOL *This,\r
412 IN BOOLEAN UseDatabase,\r
413 IN FRAMEWORK_EFI_HII_HANDLE *Handle,\r
414 IN UINTN HandleCount,\r
415 IN FRAMEWORK_EFI_IFR_PACKET *Packet, OPTIONAL\r
416 IN EFI_HANDLE CallbackHandle, OPTIONAL\r
417 IN UINT8 *NvMapOverride, OPTIONAL\r
418 IN FRAMEWORK_EFI_SCREEN_DESCRIPTOR *ScreenDimensions, OPTIONAL\r
419 OUT BOOLEAN *ResetRequired OPTIONAL\r
420 )\r
421{\r
422 EFI_STATUS Status;\r
423 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
424 HII_THUNK_CONTEXT *ThunkContext;\r
425 HII_THUNK_PRIVATE_DATA *Private;\r
426 EFI_FORMBROWSER_THUNK_PRIVATE_DATA *BrowserPrivate;\r
427\r
428 if (!UseDatabase) {\r
429 //\r
a3318eaf 430 // ThunkSendForm only support displays forms registered into the HII database.\r
0368663f 431 //\r
432 return EFI_UNSUPPORTED;\r
433 }\r
434\r
435 if (HandleCount != 1 ) {\r
436 return EFI_UNSUPPORTED;\r
437 }\r
438\r
439 BrowserPrivate = EFI_FORMBROWSER_THUNK_PRIVATE_DATA_FROM_THIS (This);\r
440 Private = BrowserPrivate->ThunkPrivate;\r
441\r
442 ThunkContext = FwHiiHandleToThunkContext (Private, *Handle);\r
443 if (ThunkContext == NULL) {\r
444 return EFI_INVALID_PARAMETER;\r
445 }\r
446\r
a235abd2 447 //\r
448 // Following UEFI spec to do auto booting after a time-out. This feature is implemented \r
449 // in Framework Setup Browser and moved to MdeModulePkg/Universal/BdsDxe. The auto booting is\r
450 // moved here in HII Thunk module. \r
451 //\r
452 if (CompareGuid (&gFrameworkBdsFrontPageFormsetGuid, &ThunkContext->FormSet->Guid) && !mFrontPageDisplayed) {\r
453 //\r
454 // Send form is called before entering the \r
455 //\r
456 mFrontPageDisplayed = TRUE;\r
457 Status = ShowProgress (GetTimeout ());\r
458\r
459 if (EFI_ERROR (Status)) {\r
460 return Status;\r
461 }\r
462 }\r
463 \r
0368663f 464 if (NvMapOverride != NULL) {\r
465 ThunkContext->NvMapOverride = NvMapOverride;\r
466 }\r
467\r
468 Status = mFormBrowser2Protocol->SendForm (\r
469 mFormBrowser2Protocol,\r
470 &ThunkContext->UefiHiiHandle,\r
471 1,\r
472 NULL,\r
473 0,\r
474 (EFI_SCREEN_DESCRIPTOR *) ScreenDimensions,\r
475 &ActionRequest\r
476 );\r
477\r
478 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
479 *ResetRequired = TRUE;\r
480 }\r
481 \r
482 return Status;\r
483}\r
484\r
a9d85320 485/** \r
486\r
487 Rountine used to display a generic dialog interface and return \r
488 the Key or Input from user input.\r
489\r
490 @param NumberOfLines The number of lines for the dialog box.\r
491 @param HotKey Defines if a single character is parsed (TRUE) and returned in KeyValue\r
492 or if a string is returned in StringBuffer.\r
493 @param MaximumStringSize The maximum size in bytes of a typed-in string.\r
494 @param StringBuffer On return contains the typed-in string if HotKey\r
495 is FALSE.\r
496 @param KeyValue The EFI_INPUT_KEY value returned if HotKey is TRUE.\r
497 @param String The pointer to the first string in the list of strings\r
498 that comprise the dialog box.\r
499 @param ... A series of NumberOfLines text strings that will be used\r
500 to construct the dialog box.\r
501 @retval EFI_SUCCESS The dialog is created successfully and user interaction was received.\r
502 @retval EFI_DEVICE_ERROR The user typed in an ESC.\r
503 @retval EFI_INVALID_PARAMETER One of the parameters was invalid.(StringBuffer == NULL && HotKey == FALSE).\r
504**/\r
0368663f 505EFI_STATUS\r
506EFIAPI \r
507ThunkCreatePopUp (\r
508 IN UINTN NumberOfLines,\r
509 IN BOOLEAN HotKey,\r
510 IN UINTN MaximumStringSize,\r
511 OUT CHAR16 *StringBuffer,\r
512 OUT EFI_INPUT_KEY *KeyValue,\r
513 IN CHAR16 *String,\r
514 ...\r
515 )\r
516{\r
517 EFI_STATUS Status;\r
518 VA_LIST Marker;\r
519\r
520 if (HotKey != TRUE) {\r
521 return EFI_UNSUPPORTED;\r
522 }\r
523\r
70d72ba9 524 VA_START (Marker, String);\r
0368663f 525 \r
70d72ba9 526 Status = IfrLibCreatePopUp2 (NumberOfLines, KeyValue, String, Marker);\r
0368663f 527\r
528 VA_END (Marker);\r
529 \r
530 return Status;\r
531}\r
532\r
a235abd2 533/** \r
534\r
535 Initialize string packages in HII database.\r
536\r
537**/\r
538VOID\r
539InitSetBrowserStrings (\r
540 VOID\r
541 )\r
542{\r
a235abd2 543 //\r
544 // Initialize strings to HII database\r
545 //\r
cb7d01c0 546 gStringPackHandle = HiiAddPackages (\r
547 &gEfiHiiThunkProducerGuid,\r
548 NULL,\r
549 STRING_ARRAY_NAME,\r
550 NULL\r
551 );\r
552 ASSERT (gStringPackHandle != NULL);\r
a235abd2 553}\r