]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Library/EdkGraphicsLib/Graphics.c
Merge GOP related code from r8->r9.
[mirror_edk2.git] / EdkModulePkg / Library / EdkGraphicsLib / Graphics.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 Graphics.c\r
15\r
16Abstract:\r
17\r
18 Support for Basic Graphics operations.\r
19\r
20 BugBug: Currently *.BMP files are supported. This will be replaced\r
21 when Tiano graphics format is supported.\r
22\r
23--*/\r
24\r
25EFI_STATUS\r
26GetGraphicsBitMapFromFV (\r
27 IN EFI_GUID *FileNameGuid,\r
28 OUT VOID **Image,\r
29 OUT UINTN *ImageSize\r
30 )\r
31/*++\r
32\r
33Routine Description:\r
34\r
35 Return the graphics image file named FileNameGuid into Image and return it's\r
36 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
37 file name.\r
38\r
39Arguments:\r
40\r
41 FileNameGuid - File Name of graphics file in the FV(s).\r
42\r
43 Image - Pointer to pointer to return graphics image. If NULL, a \r
44 buffer will be allocated.\r
45\r
46 ImageSize - Size of the graphics Image in bytes. Zero if no image found.\r
47\r
48\r
49Returns: \r
50\r
51 EFI_SUCCESS - Image and ImageSize are valid. \r
52 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
53 EFI_NOT_FOUND - FileNameGuid not found\r
54\r
55--*/\r
56{\r
57 EFI_STATUS Status;\r
58 UINTN FvProtocolCount;\r
59 EFI_HANDLE *FvHandles;\r
60 EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;\r
61 UINTN Index;\r
62 UINT32 AuthenticationStatus;\r
63\r
64\r
65 Status = gBS->LocateHandleBuffer (\r
66 ByProtocol,\r
67 &gEfiFirmwareVolumeProtocolGuid,\r
68 NULL,\r
69 &FvProtocolCount,\r
70 &FvHandles\r
71 );\r
72 if (EFI_ERROR (Status)) {\r
73 return EFI_NOT_FOUND;\r
74 }\r
75\r
76 for (Index = 0; Index < FvProtocolCount; Index++) {\r
77 Status = gBS->HandleProtocol (\r
78 FvHandles[Index],\r
79 &gEfiFirmwareVolumeProtocolGuid,\r
80 (VOID **) &Fv\r
81 );\r
82\r
83 //\r
84 // Assuming Image and ImageSize are correct on input.\r
85 //\r
86 Status = Fv->ReadSection (\r
87 Fv,\r
88 &gEfiDefaultBmpLogoGuid,\r
89 EFI_SECTION_RAW,\r
90 0,\r
91 Image,\r
92 ImageSize,\r
93 &AuthenticationStatus\r
94 );\r
95 if (!EFI_ERROR (Status)) {\r
96 return EFI_SUCCESS;\r
97 } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
98 //\r
99 // ImageSize updated to needed size so return\r
100 //\r
101 return EFI_BUFFER_TOO_SMALL;\r
102 }\r
103 }\r
104\r
105 return EFI_NOT_FOUND;\r
106}\r
107\r
108\r
109EFI_STATUS\r
406adcd1 110ConvertBmpToGopBlt (\r
878ddf1f 111 IN VOID *BmpImage,\r
112 IN UINTN BmpImageSize,\r
406adcd1 113 IN OUT VOID **GopBlt,\r
114 IN OUT UINTN *GopBltSize,\r
878ddf1f 115 OUT UINTN *PixelHeight,\r
116 OUT UINTN *PixelWidth\r
117 )\r
118/*++\r
119\r
120Routine Description:\r
121\r
122 Convert a *.BMP graphics image to a UGA blt buffer. If a NULL UgaBlt buffer\r
123 is passed in a UgaBlt buffer will be allocated by this routine. If a UgaBlt\r
124 buffer is passed in it will be used if it is big enough.\r
125\r
126Arguments:\r
127\r
128 BmpImage - Pointer to BMP file\r
129\r
130 BmpImageSize - Number of bytes in BmpImage\r
131\r
132 UgaBlt - Buffer containing UGA version of BmpImage.\r
133\r
134 UgaBltSize - Size of UgaBlt in bytes.\r
135\r
136 PixelHeight - Height of UgaBlt/BmpImage in pixels\r
137\r
138 PixelWidth - Width of UgaBlt/BmpImage in pixels\r
139\r
140\r
141Returns: \r
142\r
143 EFI_SUCCESS - UgaBlt and UgaBltSize are returned. \r
144 EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image\r
145 EFI_BUFFER_TOO_SMALL - The passed in UgaBlt buffer is not big enough.\r
146 UgaBltSize will contain the required size.\r
147 EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
148\r
149--*/\r
150{\r
151 UINT8 *Image;\r
152 UINT8 *ImageHeader;\r
153 BMP_IMAGE_HEADER *BmpHeader;\r
154 BMP_COLOR_MAP *BmpColorMap;\r
406adcd1 155 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
156 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
878ddf1f 157 UINTN BltBufferSize;\r
158 UINTN Index;\r
159 UINTN Height;\r
160 UINTN Width;\r
161 UINTN ImageIndex;\r
d4f397c0 162 BOOLEAN IsAllocated;\r
163 \r
878ddf1f 164 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
165 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
166 return EFI_UNSUPPORTED;\r
167 }\r
168\r
169 if (BmpHeader->CompressionType != 0) {\r
170 return EFI_UNSUPPORTED;\r
171 }\r
172\r
173 //\r
174 // Calculate Color Map offset in the image.\r
175 //\r
176 Image = BmpImage;\r
177 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
178\r
179 //\r
180 // Calculate graphics image data address in the image\r
181 //\r
182 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
183 ImageHeader = Image;\r
184\r
406adcd1 185 BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
d4f397c0 186 IsAllocated = FALSE;\r
406adcd1 187 if (*GopBlt == NULL) {\r
188 *GopBltSize = BltBufferSize;\r
189 *GopBlt = AllocatePool (*GopBltSize);\r
190 IsAllocated = TRUE;\r
191 if (*GopBlt == NULL) {\r
878ddf1f 192 return EFI_OUT_OF_RESOURCES;\r
193 }\r
194 } else {\r
406adcd1 195 if (*GopBltSize < BltBufferSize) {\r
196 *GopBltSize = BltBufferSize;\r
878ddf1f 197 return EFI_BUFFER_TOO_SMALL;\r
198 }\r
199 }\r
200\r
201 *PixelWidth = BmpHeader->PixelWidth;\r
202 *PixelHeight = BmpHeader->PixelHeight;\r
203\r
204 //\r
205 // Convert image from BMP to Blt buffer format\r
206 //\r
406adcd1 207 BltBuffer = *GopBlt;\r
878ddf1f 208 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
209 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
210 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
211 switch (BmpHeader->BitPerPixel) {\r
212 case 1:\r
213 //\r
214 // Convert 1bit BMP to 24-bit color\r
215 //\r
216 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
217 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
218 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
219 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
220 Blt++;\r
221 Width++;\r
222 }\r
223\r
224 Blt --;\r
225 Width --;\r
226 break;\r
227 \r
228 case 4:\r
229 //\r
230 // Convert BMP Palette to 24-bit color\r
231 //\r
232 Index = (*Image) >> 4;\r
233 Blt->Red = BmpColorMap[Index].Red;\r
234 Blt->Green = BmpColorMap[Index].Green;\r
235 Blt->Blue = BmpColorMap[Index].Blue;\r
236 if (Width < (BmpHeader->PixelWidth - 1)) {\r
237 Blt++;\r
238 Width++;\r
239 Index = (*Image) & 0x0f;\r
240 Blt->Red = BmpColorMap[Index].Red;\r
241 Blt->Green = BmpColorMap[Index].Green;\r
242 Blt->Blue = BmpColorMap[Index].Blue;\r
243 }\r
244 break;\r
245\r
246 case 8:\r
247 //\r
248 // Convert BMP Palette to 24-bit color\r
249 //\r
250 Blt->Red = BmpColorMap[*Image].Red;\r
251 Blt->Green = BmpColorMap[*Image].Green;\r
252 Blt->Blue = BmpColorMap[*Image].Blue;\r
253 break;\r
254\r
255 case 24:\r
256 Blt->Blue = *Image++;\r
257 Blt->Green = *Image++;\r
258 Blt->Red = *Image;\r
259 break;\r
260\r
261 default:\r
d4f397c0 262 if (IsAllocated) {\r
406adcd1 263 gBS->FreePool (*GopBlt);\r
264 *GopBlt = NULL;\r
d4f397c0 265 }\r
878ddf1f 266 return EFI_UNSUPPORTED;\r
267 break;\r
268 };\r
269\r
270 }\r
271\r
272 ImageIndex = (UINTN) (Image - ImageHeader);\r
273 if ((ImageIndex % 4) != 0) {\r
274 //\r
275 // Bmp Image starts each row on a 32-bit boundary!\r
276 //\r
277 Image = Image + (4 - (ImageIndex % 4));\r
278 }\r
279 }\r
280\r
281 return EFI_SUCCESS;\r
282}\r
283\r
284\r
285EFI_STATUS\r
286LockKeyboards (\r
287 IN CHAR16 *Password\r
288 )\r
289/*++\r
290\r
291Routine Description:\r
292 Use Console Control Protocol to lock the Console In Spliter virtual handle. \r
293 This is the ConInHandle and ConIn handle in the EFI system table. All key\r
294 presses will be ignored until the Password is typed in. The only way to\r
295 disable the password is to type it in to a ConIn device.\r
296\r
297Arguments:\r
298 Password - Password used to lock ConIn device\r
299\r
300\r
301Returns: \r
302\r
303 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
304 displayed.\r
305 EFI_UNSUPPORTED - Logo not found\r
306\r
307--*/\r
308{\r
309 EFI_STATUS Status;\r
310 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
311\r
312 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
313 if (EFI_ERROR (Status)) {\r
314 return EFI_UNSUPPORTED;\r
315 }\r
316\r
317 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
318 return Status;\r
319}\r
320\r
321\r
322EFI_STATUS\r
323EnableQuietBoot (\r
324 IN EFI_GUID *LogoFile\r
325 )\r
326/*++\r
327\r
328Routine Description:\r
329\r
330 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
331 to the UGA device. Put up LogoFile on every UGA device that is a console\r
332\r
333Arguments:\r
334\r
335 LogoFile - File name of logo to display on the center of the screen.\r
336\r
337\r
338Returns: \r
339\r
340 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
341 displayed.\r
342 EFI_UNSUPPORTED - Logo not found\r
343\r
344--*/\r
345{\r
346 EFI_STATUS Status;\r
347 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
878ddf1f 348 EFI_OEM_BADGING_PROTOCOL *Badging;\r
349 UINT32 SizeOfX;\r
350 UINT32 SizeOfY;\r
878ddf1f 351 INTN DestX;\r
352 INTN DestY;\r
878ddf1f 353 UINT8 *ImageData;\r
354 UINTN ImageSize;\r
406adcd1 355 UINTN BltSize;\r
878ddf1f 356 UINT32 Instance;\r
357 EFI_BADGING_FORMAT Format;\r
358 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
359 UINTN CoordinateX;\r
360 UINTN CoordinateY;\r
361 UINTN Height;\r
362 UINTN Width;\r
406adcd1 363 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
364 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
365 UINT32 ColorDepth;\r
366 UINT32 RefreshRate;\r
367 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 368\r
369 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
370 if (EFI_ERROR (Status)) {\r
371 return EFI_UNSUPPORTED;\r
372 }\r
373\r
406adcd1 374 UgaDraw = NULL;\r
375 //\r
376 // Try to open GOP first\r
377 //\r
378 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); \r
379 if (EFI_ERROR(Status)) {\r
380 GraphicsOutput = NULL;\r
381 //\r
382 // Open GOP failed, try to open UGA\r
383 //\r
384 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
385 if (EFI_ERROR (Status)) {\r
386 return EFI_UNSUPPORTED;\r
387 }\r
878ddf1f 388 }\r
389\r
390 Badging = NULL;\r
391 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
392\r
393 ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
394\r
406adcd1 395 if (GraphicsOutput != NULL) {\r
396 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
397 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
398 } else {\r
399 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
400 if (EFI_ERROR (Status)) {\r
401 return EFI_UNSUPPORTED;\r
402 }\r
878ddf1f 403 }\r
404\r
405 Instance = 0;\r
406 while (1) {\r
407 ImageData = NULL;\r
408 ImageSize = 0;\r
409\r
410 if (Badging != NULL) {\r
411 Status = Badging->GetImage (\r
412 Badging,\r
413 &Instance,\r
414 &Format,\r
415 &ImageData,\r
416 &ImageSize,\r
417 &Attribute,\r
418 &CoordinateX,\r
419 &CoordinateY\r
420 );\r
421 if (EFI_ERROR (Status)) {\r
422 return Status;\r
423 }\r
424\r
425 //\r
426 // Currently only support BMP format\r
427 //\r
428 if (Format != EfiBadgingFormatBMP) {\r
429 gBS->FreePool (ImageData);\r
430 continue;\r
431 }\r
432 } else {\r
433 Status = GetGraphicsBitMapFromFV (LogoFile, (VOID **) &ImageData, &ImageSize);\r
434 if (EFI_ERROR (Status)) {\r
435 return EFI_UNSUPPORTED;\r
436 }\r
437\r
438 CoordinateX = 0;\r
439 CoordinateY = 0;\r
440 Attribute = EfiBadgingDisplayAttributeCenter;\r
441 }\r
442\r
406adcd1 443 Blt = NULL;\r
444 Status = ConvertBmpToGopBlt (\r
878ddf1f 445 ImageData,\r
446 ImageSize,\r
406adcd1 447 (VOID**)&Blt,\r
448 &BltSize,\r
878ddf1f 449 &Height,\r
450 &Width\r
451 );\r
452 if (EFI_ERROR (Status)) {\r
453 gBS->FreePool (ImageData);\r
406adcd1 454 if (Badging == NULL) {\r
455 return Status;\r
456 } else {\r
457 continue;\r
458 }\r
878ddf1f 459 }\r
460\r
461 switch (Attribute) {\r
462 case EfiBadgingDisplayAttributeLeftTop:\r
463 DestX = CoordinateX;\r
464 DestY = CoordinateY;\r
465 break;\r
466\r
467 case EfiBadgingDisplayAttributeCenterTop:\r
468 DestX = (SizeOfX - Width) / 2;\r
469 DestY = CoordinateY;\r
470 break;\r
471\r
472 case EfiBadgingDisplayAttributeRightTop:\r
473 DestX = (SizeOfX - Width - CoordinateX);\r
474 DestY = CoordinateY;;\r
475 break;\r
476\r
477 case EfiBadgingDisplayAttributeCenterRight:\r
478 DestX = (SizeOfX - Width - CoordinateX);\r
479 DestY = (SizeOfY - Height) / 2;\r
480 break;\r
481\r
482 case EfiBadgingDisplayAttributeRightBottom:\r
483 DestX = (SizeOfX - Width - CoordinateX);\r
484 DestY = (SizeOfY - Height - CoordinateY);\r
485 break;\r
486\r
487 case EfiBadgingDisplayAttributeCenterBottom:\r
488 DestX = (SizeOfX - Width) / 2;\r
489 DestY = (SizeOfY - Height - CoordinateY);\r
490 break;\r
491\r
492 case EfiBadgingDisplayAttributeLeftBottom:\r
493 DestX = CoordinateX;\r
494 DestY = (SizeOfY - Height - CoordinateY);\r
495 break;\r
496\r
497 case EfiBadgingDisplayAttributeCenterLeft:\r
498 DestX = CoordinateX;\r
499 DestY = (SizeOfY - Height) / 2;\r
500 break;\r
501\r
502 case EfiBadgingDisplayAttributeCenter:\r
503 DestX = (SizeOfX - Width) / 2;\r
504 DestY = (SizeOfY - Height) / 2;\r
505 break;\r
506\r
507 default:\r
508 DestX = CoordinateX;\r
509 DestY = CoordinateY;\r
510 break;\r
511 }\r
512\r
513 if ((DestX >= 0) && (DestY >= 0)) {\r
406adcd1 514 if (GraphicsOutput != NULL) {\r
515 Status = GraphicsOutput->Blt (\r
516 GraphicsOutput,\r
517 Blt,\r
518 EfiBltBufferToVideo,\r
519 0,\r
520 0,\r
521 (UINTN) DestX,\r
522 (UINTN) DestY,\r
523 Width,\r
524 Height,\r
525 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
526 );\r
527 } else {\r
528 Status = UgaDraw->Blt (\r
529 UgaDraw,\r
530 (EFI_UGA_PIXEL *) Blt,\r
531 EfiUgaBltBufferToVideo,\r
532 0,\r
533 0,\r
534 (UINTN) DestX,\r
535 (UINTN) DestY,\r
536 Width,\r
537 Height,\r
538 Width * sizeof (EFI_UGA_PIXEL)\r
539 );\r
540 }\r
878ddf1f 541 }\r
542\r
543 gBS->FreePool (ImageData);\r
406adcd1 544 gBS->FreePool (Blt);\r
878ddf1f 545\r
546 if (Badging == NULL) {\r
547 break;\r
548 }\r
549 }\r
550\r
551 return Status;\r
552}\r
553\r
554\r
555EFI_STATUS\r
556DisableQuietBoot (\r
557 VOID\r
558 )\r
559/*++\r
560\r
561Routine Description:\r
562\r
563 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA \r
564 Simple Text Out screens will now be synced up with all non UGA output devices\r
565\r
566Arguments:\r
567\r
568 NONE\r
569\r
570Returns: \r
571\r
572 EFI_SUCCESS - UGA devices are back in text mode and synced up.\r
573 EFI_UNSUPPORTED - Logo not found\r
574\r
575--*/\r
576{\r
577 EFI_STATUS Status;\r
578 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
579\r
580 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
581 if (EFI_ERROR (Status)) {\r
582 return EFI_UNSUPPORTED;\r
583 }\r
584\r
585 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
586}\r
587\r
406adcd1 588static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
878ddf1f 589 { 0x00, 0x00, 0x00, 0x00 },\r
590 { 0x98, 0x00, 0x00, 0x00 },\r
591 { 0x00, 0x98, 0x00, 0x00 },\r
592 { 0x98, 0x98, 0x00, 0x00 },\r
593 { 0x00, 0x00, 0x98, 0x00 },\r
594 { 0x98, 0x00, 0x98, 0x00 },\r
595 { 0x00, 0x98, 0x98, 0x00 },\r
596 { 0x98, 0x98, 0x98, 0x00 },\r
597 { 0x10, 0x10, 0x10, 0x00 },\r
598 { 0xff, 0x10, 0x10, 0x00 },\r
599 { 0x10, 0xff, 0x10, 0x00 },\r
600 { 0xff, 0xff, 0x10, 0x00 },\r
601 { 0x10, 0x10, 0xff, 0x00 },\r
602 { 0xf0, 0x10, 0xff, 0x00 },\r
603 { 0x10, 0xff, 0xff, 0x00 },\r
604 { 0xff, 0xff, 0xff, 0x00 }\r
605};\r
606\r
607STATIC\r
608UINTN\r
609_IPrint (\r
406adcd1 610 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
878ddf1f 611 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,\r
612 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto,\r
613 IN UINTN X,\r
614 IN UINTN Y,\r
406adcd1 615 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
616 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,\r
878ddf1f 617 IN CHAR16 *fmt,\r
618 IN VA_LIST args\r
619 )\r
620/*++\r
621\r
622Routine Description:\r
623\r
624 Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
625\r
626Arguments:\r
627\r
406adcd1 628 GraphicsOutput - Graphics output protocol interface\r
629 \r
878ddf1f 630 UgaDraw - UGA draw protocol interface\r
631 \r
632 Sto - Simple text out protocol interface\r
633 \r
634 X - X coordinate to start printing\r
635 \r
636 Y - Y coordinate to start printing\r
637 \r
638 Foreground - Foreground color\r
639 \r
640 Background - Background color\r
641 \r
642 fmt - Format string\r
643 \r
644 args - Print arguments\r
645\r
646Returns: \r
647\r
648 EFI_SUCCESS - success\r
649 EFI_OUT_OF_RESOURCES - out of resources\r
650\r
651--*/\r
652{\r
653 VOID *Buffer;\r
654 EFI_STATUS Status;\r
655 UINT16 GlyphWidth;\r
656 UINT32 GlyphStatus;\r
657 UINT16 StringIndex;\r
658 UINTN Index;\r
659 CHAR16 *UnicodeWeight;\r
660 EFI_NARROW_GLYPH *Glyph;\r
661 EFI_HII_PROTOCOL *Hii;\r
406adcd1 662 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;\r
878ddf1f 663 UINT32 HorizontalResolution;\r
664 UINT32 VerticalResolution;\r
665 UINT32 ColorDepth;\r
666 UINT32 RefreshRate;\r
667\r
668 GlyphStatus = 0;\r
669\r
670 //\r
671 // For now, allocate an arbitrarily long buffer\r
672 //\r
673 Buffer = AllocateZeroPool (0x10000);\r
674 if (Buffer == NULL) {\r
675 return EFI_OUT_OF_RESOURCES;\r
676 }\r
406adcd1 677 \r
678 if (GraphicsOutput != NULL) {\r
679 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
680 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
681 } else {\r
682 //\r
683 // Get the current mode information from the UGA Draw Protocol\r
684 //\r
685 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
686 }\r
878ddf1f 687\r
406adcd1 688 LineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_WIDTH * GLYPH_HEIGHT);\r
878ddf1f 689 if (LineBuffer == NULL) {\r
690 gBS->FreePool (Buffer);\r
691 return EFI_OUT_OF_RESOURCES;\r
692 }\r
693\r
694 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID **) &Hii);\r
695 if (EFI_ERROR (Status)) {\r
696 goto Error;\r
697 }\r
698\r
699 UnicodeVSPrint (Buffer, 0x10000, fmt, args);\r
700\r
701 UnicodeWeight = (CHAR16 *) Buffer;\r
702\r
703 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
704 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
705 UnicodeWeight[Index] == CHAR_LINEFEED ||\r
706 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
707 UnicodeWeight[Index] = 0;\r
708 }\r
709 }\r
710\r
711 for (Index = 0; Index < StrLen (Buffer); Index++) {\r
712 StringIndex = (UINT16) Index;\r
713 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);\r
714 if (EFI_ERROR (Status)) {\r
715 goto Error;\r
716 }\r
717\r
718 if (Foreground == NULL || Background == NULL) {\r
719 Status = Hii->GlyphToBlt (\r
720 Hii,\r
721 (UINT8 *) Glyph,\r
722 mEfiColors[Sto->Mode->Attribute & 0x0f],\r
723 mEfiColors[Sto->Mode->Attribute >> 4],\r
724 StrLen (Buffer),\r
725 GlyphWidth,\r
726 GLYPH_HEIGHT,\r
727 &LineBuffer[Index * GLYPH_WIDTH]\r
728 );\r
729 } else {\r
730 Status = Hii->GlyphToBlt (\r
731 Hii,\r
732 (UINT8 *) Glyph,\r
733 *Foreground,\r
734 *Background,\r
735 StrLen (Buffer),\r
736 GlyphWidth,\r
737 GLYPH_HEIGHT,\r
738 &LineBuffer[Index * GLYPH_WIDTH]\r
739 );\r
740 }\r
741 }\r
742\r
743 //\r
744 // Blt a character to the screen\r
745 //\r
406adcd1 746 if (GraphicsOutput != NULL) {\r
747 Status = GraphicsOutput->Blt (\r
748 GraphicsOutput,\r
749 LineBuffer,\r
750 EfiBltBufferToVideo,\r
751 0,\r
752 0,\r
753 X,\r
754 Y,\r
755 GLYPH_WIDTH * StrLen (Buffer),\r
756 GLYPH_HEIGHT,\r
757 GLYPH_WIDTH * StrLen (Buffer) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
758 );\r
759 } else {\r
760 Status = UgaDraw->Blt (\r
761 UgaDraw,\r
762 (EFI_UGA_PIXEL *) (UINTN) LineBuffer,\r
763 EfiUgaBltBufferToVideo,\r
764 0,\r
765 0,\r
766 X,\r
767 Y,\r
768 GLYPH_WIDTH * StrLen (Buffer),\r
769 GLYPH_HEIGHT,\r
770 GLYPH_WIDTH * StrLen (Buffer) * sizeof (EFI_UGA_PIXEL)\r
771 );\r
772 }\r
878ddf1f 773\r
774Error:\r
775 gBS->FreePool (LineBuffer);\r
776 gBS->FreePool (Buffer);\r
777 return Status;\r
778}\r
779\r
780\r
781UINTN\r
782PrintXY (\r
783 IN UINTN X,\r
784 IN UINTN Y,\r
406adcd1 785 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL\r
786 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL\r
878ddf1f 787 IN CHAR16 *Fmt,\r
788 ...\r
789 )\r
790/*++\r
791\r
792Routine Description:\r
793\r
794 Prints a formatted unicode string to the default console\r
795\r
796Arguments:\r
797\r
798 X - X coordinate to start printing\r
799 \r
800 Y - Y coordinate to start printing\r
801 \r
802 ForeGround - Foreground color\r
803 \r
804 BackGround - Background color\r
805\r
806 Fmt - Format string\r
807\r
808 ... - Print arguments\r
809\r
810Returns:\r
811\r
812 Length of string printed to the console\r
813\r
814--*/\r
815{\r
816 EFI_HANDLE Handle;\r
406adcd1 817\r
818 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 819 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
820 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;\r
821 EFI_STATUS Status;\r
822 VA_LIST Args;\r
823\r
824 VA_START (Args, Fmt);\r
825\r
406adcd1 826 UgaDraw = NULL;\r
827\r
878ddf1f 828 Handle = gST->ConsoleOutHandle;\r
829\r
830 Status = gBS->HandleProtocol (\r
831 Handle,\r
406adcd1 832 &gEfiGraphicsOutputProtocolGuid,\r
833 (VOID **) &GraphicsOutput\r
878ddf1f 834 );\r
835\r
836 if (EFI_ERROR (Status)) {\r
406adcd1 837 GraphicsOutput = NULL;\r
838\r
839 Status = gBS->HandleProtocol (\r
840 Handle,\r
841 &gEfiUgaDrawProtocolGuid,\r
842 (VOID **) &UgaDraw\r
843 );\r
844\r
845 if (EFI_ERROR (Status)) {\r
846 return Status;\r
847 }\r
878ddf1f 848 }\r
849\r
850 Status = gBS->HandleProtocol (\r
851 Handle,\r
852 &gEfiSimpleTextOutProtocolGuid,\r
853 (VOID **) &Sto\r
854 );\r
855\r
856 if (EFI_ERROR (Status)) {\r
857 return Status;\r
858 }\r
859\r
406adcd1 860 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
878ddf1f 861}\r