]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/SetupBrowser.c
Remove unwanted svn properties added by tool.
[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
388 UINT16 Timeout;\r
389 UINTN Size;\r
390 EFI_STATUS Status;\r
391\r
392 //\r
393 // Return Timeout variable or 0xffff if no valid\r
394 // Timeout variable exists.\r
395 //\r
396 Size = sizeof (UINT16);\r
397 Status = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout);\r
398 if (EFI_ERROR (Status)) {\r
399 //\r
400 // According to UEFI 2.0 spec, it should treat the Timeout value as 0xffff\r
401 // (default value PcdPlatformBootTimeOutDefault) when L"Timeout" variable is not present.\r
402 // To make the current EFI Automatic-Test activity possible, platform can choose other value\r
403 // for automatic boot when the variable is not present.\r
404 //\r
405 Timeout = PcdGet16 (PcdPlatformBootTimeOutDefault);\r
406 }\r
407\r
408 return Timeout;\r
409}\r
410\r
0368663f 411\r
a9d85320 412/**\r
413 This is the Framework Setup Browser interface which displays a FormSet.\r
414\r
415 @param This The EFI_FORM_BROWSER_PROTOCOL context.\r
416 @param UseDatabase TRUE if the FormSet is from HII database. The Thunk implementation\r
417 only support UseDatabase is TRUE.\r
418 @param Handle The Handle buffer.\r
419 @param HandleCount The number of Handle in the Handle Buffer. It must be 1 for this implementation.\r
420 @param Packet The pointer to data buffer containing IFR and String package. Not supported.\r
421 @param CallbackHandle Not supported.\r
422 @param NvMapOverride The buffer is used only when there is no NV variable to define the \r
423 current settings and the caller needs to provide to the browser the\r
424 current settings for the the "fake" NV variable. If used, no saving of\r
425 an NV variable is possbile. This parameter is also ignored if Handle is NULL.\r
426\r
427 @retval EFI_SUCCESS If the Formset is displayed correctly.\r
428 @retval EFI_UNSUPPORTED If UseDatabase is FALSE or HandleCount is not 1.\r
429 @retval EFI_INVALID_PARAMETER If the *Handle passed in is not found in the database.\r
430**/\r
431\r
0368663f 432EFI_STATUS\r
433EFIAPI \r
434ThunkSendForm (\r
435 IN EFI_FORM_BROWSER_PROTOCOL *This,\r
436 IN BOOLEAN UseDatabase,\r
437 IN FRAMEWORK_EFI_HII_HANDLE *Handle,\r
438 IN UINTN HandleCount,\r
439 IN FRAMEWORK_EFI_IFR_PACKET *Packet, OPTIONAL\r
440 IN EFI_HANDLE CallbackHandle, OPTIONAL\r
441 IN UINT8 *NvMapOverride, OPTIONAL\r
442 IN FRAMEWORK_EFI_SCREEN_DESCRIPTOR *ScreenDimensions, OPTIONAL\r
443 OUT BOOLEAN *ResetRequired OPTIONAL\r
444 )\r
445{\r
446 EFI_STATUS Status;\r
447 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
448 HII_THUNK_CONTEXT *ThunkContext;\r
449 HII_THUNK_PRIVATE_DATA *Private;\r
450 EFI_FORMBROWSER_THUNK_PRIVATE_DATA *BrowserPrivate;\r
451\r
452 if (!UseDatabase) {\r
453 //\r
a3318eaf 454 // ThunkSendForm only support displays forms registered into the HII database.\r
0368663f 455 //\r
456 return EFI_UNSUPPORTED;\r
457 }\r
458\r
459 if (HandleCount != 1 ) {\r
460 return EFI_UNSUPPORTED;\r
461 }\r
462\r
463 BrowserPrivate = EFI_FORMBROWSER_THUNK_PRIVATE_DATA_FROM_THIS (This);\r
464 Private = BrowserPrivate->ThunkPrivate;\r
465\r
466 ThunkContext = FwHiiHandleToThunkContext (Private, *Handle);\r
467 if (ThunkContext == NULL) {\r
468 return EFI_INVALID_PARAMETER;\r
469 }\r
470\r
a235abd2 471 //\r
472 // Following UEFI spec to do auto booting after a time-out. This feature is implemented \r
473 // in Framework Setup Browser and moved to MdeModulePkg/Universal/BdsDxe. The auto booting is\r
474 // moved here in HII Thunk module. \r
475 //\r
476 if (CompareGuid (&gFrameworkBdsFrontPageFormsetGuid, &ThunkContext->FormSet->Guid) && !mFrontPageDisplayed) {\r
477 //\r
478 // Send form is called before entering the \r
479 //\r
480 mFrontPageDisplayed = TRUE;\r
481 Status = ShowProgress (GetTimeout ());\r
482\r
483 if (EFI_ERROR (Status)) {\r
484 return Status;\r
485 }\r
486 }\r
487 \r
0368663f 488 if (NvMapOverride != NULL) {\r
489 ThunkContext->NvMapOverride = NvMapOverride;\r
490 }\r
491\r
492 Status = mFormBrowser2Protocol->SendForm (\r
493 mFormBrowser2Protocol,\r
494 &ThunkContext->UefiHiiHandle,\r
495 1,\r
496 NULL,\r
497 0,\r
498 (EFI_SCREEN_DESCRIPTOR *) ScreenDimensions,\r
499 &ActionRequest\r
500 );\r
501\r
502 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
503 *ResetRequired = TRUE;\r
504 }\r
505 \r
506 return Status;\r
507}\r
508\r
a9d85320 509/** \r
510\r
511 Rountine used to display a generic dialog interface and return \r
512 the Key or Input from user input.\r
513\r
514 @param NumberOfLines The number of lines for the dialog box.\r
515 @param HotKey Defines if a single character is parsed (TRUE) and returned in KeyValue\r
516 or if a string is returned in StringBuffer.\r
517 @param MaximumStringSize The maximum size in bytes of a typed-in string.\r
518 @param StringBuffer On return contains the typed-in string if HotKey\r
519 is FALSE.\r
520 @param KeyValue The EFI_INPUT_KEY value returned if HotKey is TRUE.\r
521 @param String The pointer to the first string in the list of strings\r
522 that comprise the dialog box.\r
523 @param ... A series of NumberOfLines text strings that will be used\r
524 to construct the dialog box.\r
525 @retval EFI_SUCCESS The dialog is created successfully and user interaction was received.\r
526 @retval EFI_DEVICE_ERROR The user typed in an ESC.\r
527 @retval EFI_INVALID_PARAMETER One of the parameters was invalid.(StringBuffer == NULL && HotKey == FALSE).\r
528**/\r
0368663f 529EFI_STATUS\r
530EFIAPI \r
531ThunkCreatePopUp (\r
532 IN UINTN NumberOfLines,\r
533 IN BOOLEAN HotKey,\r
534 IN UINTN MaximumStringSize,\r
535 OUT CHAR16 *StringBuffer,\r
536 OUT EFI_INPUT_KEY *KeyValue,\r
537 IN CHAR16 *String,\r
538 ...\r
539 )\r
540{\r
541 EFI_STATUS Status;\r
542 VA_LIST Marker;\r
543\r
544 if (HotKey != TRUE) {\r
545 return EFI_UNSUPPORTED;\r
546 }\r
547\r
70d72ba9 548 VA_START (Marker, String);\r
0368663f 549 \r
70d72ba9 550 Status = IfrLibCreatePopUp2 (NumberOfLines, KeyValue, String, Marker);\r
0368663f 551\r
552 VA_END (Marker);\r
553 \r
554 return Status;\r
555}\r
556\r
a235abd2 557/** \r
558\r
559 Initialize string packages in HII database.\r
560\r
561**/\r
562VOID\r
563InitSetBrowserStrings (\r
564 VOID\r
565 )\r
566{\r
567 EFI_STATUS Status;\r
568 \r
569 //\r
570 // Initialize strings to HII database\r
571 //\r
572 Status = HiiLibAddPackages (1, &gEfiHiiThunkProducerGuid, NULL, &gStringPackHandle, STRING_ARRAY_NAME);\r
573 ASSERT_EFI_ERROR (Status);\r
574\r
575}\r