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