]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Library/EdkGraphicsLib/Graphics.c
Partially make EdkModulePkg pass intel IPF compiler with /W4 /WX switched on.
[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
1cc8ee78 108STATIC\r
878ddf1f 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
1cc8ee78 667 UINTN BufferGlyphWidth;\r
878ddf1f 668\r
669 GlyphStatus = 0;\r
670\r
671 //\r
672 // For now, allocate an arbitrarily long buffer\r
673 //\r
674 Buffer = AllocateZeroPool (0x10000);\r
675 if (Buffer == NULL) {\r
676 return EFI_OUT_OF_RESOURCES;\r
677 }\r
406adcd1 678 \r
679 if (GraphicsOutput != NULL) {\r
680 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
681 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
682 } else {\r
683 //\r
684 // Get the current mode information from the UGA Draw Protocol\r
685 //\r
686 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
687 }\r
878ddf1f 688\r
406adcd1 689 LineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_WIDTH * GLYPH_HEIGHT);\r
878ddf1f 690 if (LineBuffer == NULL) {\r
691 gBS->FreePool (Buffer);\r
692 return EFI_OUT_OF_RESOURCES;\r
693 }\r
694\r
695 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID **) &Hii);\r
696 if (EFI_ERROR (Status)) {\r
697 goto Error;\r
698 }\r
699\r
700 UnicodeVSPrint (Buffer, 0x10000, fmt, args);\r
701\r
702 UnicodeWeight = (CHAR16 *) Buffer;\r
703\r
704 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
705 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
706 UnicodeWeight[Index] == CHAR_LINEFEED ||\r
707 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
708 UnicodeWeight[Index] = 0;\r
709 }\r
710 }\r
711\r
712 for (Index = 0; Index < StrLen (Buffer); Index++) {\r
713 StringIndex = (UINT16) Index;\r
714 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);\r
715 if (EFI_ERROR (Status)) {\r
716 goto Error;\r
717 }\r
718\r
719 if (Foreground == NULL || Background == NULL) {\r
720 Status = Hii->GlyphToBlt (\r
721 Hii,\r
722 (UINT8 *) Glyph,\r
723 mEfiColors[Sto->Mode->Attribute & 0x0f],\r
724 mEfiColors[Sto->Mode->Attribute >> 4],\r
725 StrLen (Buffer),\r
726 GlyphWidth,\r
727 GLYPH_HEIGHT,\r
728 &LineBuffer[Index * GLYPH_WIDTH]\r
729 );\r
730 } else {\r
731 Status = Hii->GlyphToBlt (\r
732 Hii,\r
733 (UINT8 *) Glyph,\r
734 *Foreground,\r
735 *Background,\r
736 StrLen (Buffer),\r
737 GlyphWidth,\r
738 GLYPH_HEIGHT,\r
739 &LineBuffer[Index * GLYPH_WIDTH]\r
740 );\r
741 }\r
742 }\r
743\r
744 //\r
745 // Blt a character to the screen\r
746 //\r
1cc8ee78 747 BufferGlyphWidth = GLYPH_WIDTH * StrLen (Buffer);\r
406adcd1 748 if (GraphicsOutput != NULL) {\r
749 Status = GraphicsOutput->Blt (\r
750 GraphicsOutput,\r
751 LineBuffer,\r
752 EfiBltBufferToVideo,\r
753 0,\r
754 0,\r
755 X,\r
756 Y,\r
1cc8ee78 757 BufferGlyphWidth,\r
406adcd1 758 GLYPH_HEIGHT,\r
1cc8ee78 759 BufferGlyphWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
406adcd1 760 );\r
761 } else {\r
762 Status = UgaDraw->Blt (\r
763 UgaDraw,\r
764 (EFI_UGA_PIXEL *) (UINTN) LineBuffer,\r
765 EfiUgaBltBufferToVideo,\r
766 0,\r
767 0,\r
768 X,\r
769 Y,\r
1cc8ee78 770 BufferGlyphWidth,\r
406adcd1 771 GLYPH_HEIGHT,\r
1cc8ee78 772 BufferGlyphWidth * sizeof (EFI_UGA_PIXEL)\r
406adcd1 773 );\r
774 }\r
878ddf1f 775\r
776Error:\r
777 gBS->FreePool (LineBuffer);\r
778 gBS->FreePool (Buffer);\r
779 return Status;\r
780}\r
781\r
782\r
783UINTN\r
784PrintXY (\r
785 IN UINTN X,\r
786 IN UINTN Y,\r
406adcd1 787 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL\r
788 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL\r
878ddf1f 789 IN CHAR16 *Fmt,\r
790 ...\r
791 )\r
792/*++\r
793\r
794Routine Description:\r
795\r
796 Prints a formatted unicode string to the default console\r
797\r
798Arguments:\r
799\r
800 X - X coordinate to start printing\r
801 \r
802 Y - Y coordinate to start printing\r
803 \r
804 ForeGround - Foreground color\r
805 \r
806 BackGround - Background color\r
807\r
808 Fmt - Format string\r
809\r
810 ... - Print arguments\r
811\r
812Returns:\r
813\r
814 Length of string printed to the console\r
815\r
816--*/\r
817{\r
818 EFI_HANDLE Handle;\r
406adcd1 819\r
820 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 821 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
822 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;\r
823 EFI_STATUS Status;\r
824 VA_LIST Args;\r
825\r
826 VA_START (Args, Fmt);\r
827\r
406adcd1 828 UgaDraw = NULL;\r
829\r
878ddf1f 830 Handle = gST->ConsoleOutHandle;\r
831\r
832 Status = gBS->HandleProtocol (\r
833 Handle,\r
406adcd1 834 &gEfiGraphicsOutputProtocolGuid,\r
835 (VOID **) &GraphicsOutput\r
878ddf1f 836 );\r
837\r
838 if (EFI_ERROR (Status)) {\r
406adcd1 839 GraphicsOutput = NULL;\r
840\r
841 Status = gBS->HandleProtocol (\r
842 Handle,\r
843 &gEfiUgaDrawProtocolGuid,\r
844 (VOID **) &UgaDraw\r
845 );\r
846\r
847 if (EFI_ERROR (Status)) {\r
848 return Status;\r
849 }\r
878ddf1f 850 }\r
851\r
852 Status = gBS->HandleProtocol (\r
853 Handle,\r
854 &gEfiSimpleTextOutProtocolGuid,\r
855 (VOID **) &Sto\r
856 );\r
857\r
858 if (EFI_ERROR (Status)) {\r
859 return Status;\r
860 }\r
861\r
406adcd1 862 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
878ddf1f 863}\r