]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Graphics.c
Update the copyright notice format
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / Graphics / Graphics.c
CommitLineData
3eb9473e 1/*++\r
2\r
4ea9375a
HT
3Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>\r
4This program and the accompanying materials \r
3eb9473e 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
25#include "Tiano.h"\r
26#include "EfiDriverLib.h"\r
27#include "GraphicsLib.h"\r
28\r
29EFI_STATUS\r
30GetGraphicsBitMapFromFV (\r
31 IN EFI_GUID *FileNameGuid,\r
32 OUT VOID **Image,\r
33 OUT UINTN *ImageSize\r
34 )\r
35/*++\r
36\r
37Routine Description:\r
38\r
39 Return the graphics image file named FileNameGuid into Image and return it's\r
40 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
41 file name.\r
42\r
43Arguments:\r
44\r
45 FileNameGuid - File Name of graphics file in the FV(s).\r
46\r
47 Image - Pointer to pointer to return graphics image. If NULL, a \r
48 buffer will be allocated.\r
49\r
50 ImageSize - Size of the graphics Image in bytes. Zero if no image found.\r
51\r
52\r
53Returns: \r
54\r
55 EFI_SUCCESS - Image and ImageSize are valid. \r
56 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
57 EFI_NOT_FOUND - FileNameGuid not found\r
58\r
59--*/\r
60{\r
61 return GetGraphicsBitMapFromFVEx (NULL, FileNameGuid, Image, ImageSize);\r
62}\r
63\r
64EFI_STATUS\r
65GetGraphicsBitMapFromFVEx (\r
66 IN EFI_HANDLE ImageHandle,\r
67 IN EFI_GUID *FileNameGuid,\r
68 OUT VOID **Image,\r
69 OUT UINTN *ImageSize\r
70 )\r
71/*++\r
72\r
73Routine Description:\r
74\r
75 Return the graphics image file named FileNameGuid into Image and return it's\r
76 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
77 file name.\r
78\r
79Arguments:\r
80\r
81 ImageHandle - The driver image handle of the caller. The parameter is used to\r
82 optimize the loading of the image file so that the FV from which\r
83 the driver image is loaded will be tried first. \r
84\r
85 FileNameGuid - File Name of graphics file in the FV(s).\r
86\r
87 Image - Pointer to pointer to return graphics image. If NULL, a \r
88 buffer will be allocated.\r
89\r
90 ImageSize - Size of the graphics Image in bytes. Zero if no image found.\r
91\r
92\r
93Returns: \r
94\r
95 EFI_SUCCESS - Image and ImageSize are valid. \r
96 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
97 EFI_NOT_FOUND - FileNameGuid not found\r
98\r
99--*/\r
100{\r
101 return GetImageEx (\r
102 ImageHandle,\r
c7f33ca4 103 FileNameGuid,\r
3eb9473e 104 EFI_SECTION_RAW,\r
105 Image,\r
106 ImageSize,\r
107 FALSE\r
108 );\r
109}\r
110\r
111\r
112EFI_STATUS\r
113ConvertBmpToGopBlt (\r
114 IN VOID *BmpImage,\r
115 IN UINTN BmpImageSize,\r
116 IN OUT VOID **GopBlt,\r
117 IN OUT UINTN *GopBltSize,\r
118 OUT UINTN *PixelHeight,\r
119 OUT UINTN *PixelWidth\r
120 )\r
121/*++\r
122\r
123Routine Description:\r
124\r
125 Convert a *.BMP graphics image to a GOP/UGA blt buffer. If a NULL Blt buffer\r
126 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
127 buffer is passed in it will be used if it is big enough.\r
128\r
129Arguments:\r
130\r
131 BmpImage - Pointer to BMP file\r
132\r
133 BmpImageSize - Number of bytes in BmpImage\r
134\r
135 GopBlt - Buffer containing GOP version of BmpImage.\r
136\r
137 GopBltSize - Size of GopBlt in bytes.\r
138\r
139 PixelHeight - Height of GopBlt/BmpImage in pixels\r
140\r
141 PixelWidth - Width of GopBlt/BmpImage in pixels\r
142\r
143\r
144Returns: \r
145\r
146 EFI_SUCCESS - GopBlt and GopBltSize are returned. \r
147 EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image\r
148 EFI_BUFFER_TOO_SMALL - The passed in GopBlt buffer is not big enough.\r
149 GopBltSize will contain the required size.\r
150 EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
151\r
152--*/\r
153{\r
154 UINT8 *Image;\r
155 UINT8 *ImageHeader;\r
156 BMP_IMAGE_HEADER *BmpHeader;\r
157 BMP_COLOR_MAP *BmpColorMap;\r
158 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
159 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
99f67594 160 UINT64 BltBufferSize;\r
3eb9473e 161 UINTN Index;\r
162 UINTN Height;\r
163 UINTN Width;\r
164 UINTN ImageIndex;\r
165 BOOLEAN IsAllocated;\r
166\r
167 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
168 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
169 return EFI_UNSUPPORTED;\r
170 }\r
171\r
172 if (BmpHeader->CompressionType != 0) {\r
173 return EFI_UNSUPPORTED;\r
174 }\r
175\r
176 //\r
177 // Calculate Color Map offset in the image.\r
178 //\r
179 Image = BmpImage;\r
180 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
181\r
182 //\r
183 // Calculate graphics image data address in the image\r
184 //\r
185 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
186 ImageHeader = Image;\r
187\r
99f67594 188 BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);\r
189 //\r
190 // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
191 //\r
192 if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), NULL)) {\r
193 return EFI_UNSUPPORTED;\r
194 }\r
195 BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
196\r
3eb9473e 197 IsAllocated = FALSE;\r
198 if (*GopBlt == NULL) {\r
99f67594 199 *GopBltSize = (UINTN) BltBufferSize;\r
3eb9473e 200 *GopBlt = EfiLibAllocatePool (*GopBltSize);\r
201 IsAllocated = TRUE;\r
202 if (*GopBlt == NULL) {\r
203 return EFI_OUT_OF_RESOURCES;\r
204 }\r
205 } else {\r
99f67594 206 if (*GopBltSize < (UINTN) BltBufferSize) {\r
207 *GopBltSize = (UINTN) BltBufferSize;\r
3eb9473e 208 return EFI_BUFFER_TOO_SMALL;\r
209 }\r
210 }\r
211\r
212 *PixelWidth = BmpHeader->PixelWidth;\r
213 *PixelHeight = BmpHeader->PixelHeight;\r
214\r
215 //\r
216 // Convert image from BMP to Blt buffer format\r
217 //\r
218 BltBuffer = *GopBlt;\r
219 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
220 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
221 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
222 switch (BmpHeader->BitPerPixel) {\r
223 case 1:\r
224 //\r
225 // Convert 1bit BMP to 24-bit color\r
226 //\r
227 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
228 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
229 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
230 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
231 Blt++;\r
232 Width++;\r
233 }\r
234\r
235 Blt --;\r
236 Width --;\r
237 break;\r
238\r
239 case 4:\r
240 //\r
241 // Convert BMP Palette to 24-bit color\r
242 //\r
243 Index = (*Image) >> 4;\r
244 Blt->Red = BmpColorMap[Index].Red;\r
245 Blt->Green = BmpColorMap[Index].Green;\r
246 Blt->Blue = BmpColorMap[Index].Blue;\r
247 if (Width < (BmpHeader->PixelWidth - 1)) {\r
248 Blt++;\r
249 Width++;\r
250 Index = (*Image) & 0x0f;\r
251 Blt->Red = BmpColorMap[Index].Red;\r
252 Blt->Green = BmpColorMap[Index].Green;\r
253 Blt->Blue = BmpColorMap[Index].Blue;\r
254 }\r
255 break;\r
256\r
257 case 8:\r
258 //\r
259 // Convert BMP Palette to 24-bit color\r
260 //\r
261 Blt->Red = BmpColorMap[*Image].Red;\r
262 Blt->Green = BmpColorMap[*Image].Green;\r
263 Blt->Blue = BmpColorMap[*Image].Blue;\r
264 break;\r
265\r
266 case 24:\r
267 Blt->Blue = *Image++;\r
268 Blt->Green = *Image++;\r
269 Blt->Red = *Image;\r
270 break;\r
271\r
272 default:\r
273 if (IsAllocated) {\r
274 gBS->FreePool (*GopBlt);\r
275 *GopBlt = NULL;\r
276 }\r
277 return EFI_UNSUPPORTED;\r
278 break;\r
279 };\r
280\r
281 }\r
282\r
283 ImageIndex = (UINTN) (Image - ImageHeader);\r
284 if ((ImageIndex % 4) != 0) {\r
285 //\r
286 // Bmp Image starts each row on a 32-bit boundary!\r
287 //\r
288 Image = Image + (4 - (ImageIndex % 4));\r
289 }\r
290 }\r
291\r
292 return EFI_SUCCESS;\r
293}\r
294\r
295\r
296EFI_STATUS\r
297LockKeyboards (\r
298 IN CHAR16 *Password\r
299 )\r
300/*++\r
301\r
302Routine Description:\r
303 Use Console Control Protocol to lock the Console In Spliter virtual handle. \r
304 This is the ConInHandle and ConIn handle in the EFI system table. All key\r
305 presses will be ignored until the Password is typed in. The only way to\r
306 disable the password is to type it in to a ConIn device.\r
307\r
308Arguments:\r
309 Password - Password used to lock ConIn device\r
310\r
311\r
312Returns: \r
313\r
314 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
315 displayed.\r
316 EFI_UNSUPPORTED - Logo not found\r
317\r
318--*/\r
319{\r
320 EFI_STATUS Status;\r
321 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
322\r
323 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);\r
324 if (EFI_ERROR (Status)) {\r
325 return EFI_UNSUPPORTED;\r
326 }\r
327\r
328 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
329 return Status;\r
330}\r
331\r
332EFI_STATUS\r
333EnableQuietBoot (\r
334 IN EFI_GUID *LogoFile\r
335 )\r
336/*++\r
337\r
338Routine Description:\r
339\r
340 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
341 to the UGA device. Put up LogoFile on every UGA device that is a console\r
342\r
343Arguments:\r
344\r
345 LogoFile - File name of logo to display on the center of the screen.\r
346\r
347\r
348Returns: \r
349\r
350 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
351 displayed.\r
352 EFI_UNSUPPORTED - Logo not found\r
353\r
354--*/\r
355{\r
356 return EnableQuietBootEx (LogoFile, NULL);\r
357}\r
358\r
359EFI_STATUS\r
360EnableQuietBootEx (\r
361 IN EFI_GUID *LogoFile,\r
362 IN EFI_HANDLE ImageHandle\r
363 )\r
364/*++\r
365\r
366Routine Description:\r
367\r
368 Use Console Control to turn off GOP/UGA based Simple Text Out consoles from going\r
369 to the GOP/UGA device. Put up LogoFile on every GOP/UGA device that is a console\r
370\r
371Arguments:\r
372\r
373 LogoFile - File name of logo to display on the center of the screen.\r
374 ImageHandle - The driver image handle of the caller. The parameter is used to\r
375 optimize the loading of the logo file so that the FV from which\r
376 the driver image is loaded will be tried first.\r
377\r
378\r
379Returns: \r
380\r
381 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
382 displayed.\r
383 EFI_UNSUPPORTED - Logo not found\r
384\r
385--*/\r
386{\r
387 EFI_STATUS Status;\r
388 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
389 EFI_OEM_BADGING_PROTOCOL *Badging;\r
390 UINT32 SizeOfX;\r
391 UINT32 SizeOfY;\r
392 INTN DestX;\r
393 INTN DestY;\r
394 UINT8 *ImageData;\r
395 UINTN ImageSize;\r
396 UINTN BltSize;\r
397 UINT32 Instance;\r
398 EFI_BADGING_FORMAT Format;\r
399 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
400 UINTN CoordinateX;\r
401 UINTN CoordinateY;\r
402 UINTN Height;\r
403 UINTN Width;\r
404 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
405 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
406 UINT32 ColorDepth;\r
407 UINT32 RefreshRate;\r
408 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
409\r
410 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);\r
411 if (EFI_ERROR (Status)) {\r
412 return EFI_UNSUPPORTED;\r
413 }\r
414\r
415 UgaDraw = NULL;\r
416 //\r
417 // Try to open GOP first\r
418 //\r
419 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID**)&GraphicsOutput);\r
420 if (EFI_ERROR (Status)) {\r
421 GraphicsOutput = NULL;\r
422 //\r
423 // Open GOP failed, try to open UGA\r
424 //\r
425 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID**)&UgaDraw);\r
426 if (EFI_ERROR (Status)) {\r
427 return EFI_UNSUPPORTED;\r
428 }\r
429 }\r
430\r
431 Badging = NULL;\r
432 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID**)&Badging);\r
433\r
434 ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
435\r
436 if (GraphicsOutput != NULL) {\r
437 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
438 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
439 } else {\r
440 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
441 if (EFI_ERROR (Status)) {\r
442 return EFI_UNSUPPORTED;\r
443 }\r
444 }\r
445\r
446 Instance = 0;\r
447 while (1) {\r
448 ImageData = NULL;\r
449 ImageSize = 0;\r
450\r
451 if (Badging != NULL) {\r
452 Status = Badging->GetImage (\r
453 Badging,\r
454 &Instance,\r
455 &Format,\r
456 &ImageData,\r
457 &ImageSize,\r
458 &Attribute,\r
459 &CoordinateX,\r
460 &CoordinateY\r
461 );\r
462 if (EFI_ERROR (Status)) {\r
463 return Status;\r
464 }\r
465\r
466 //\r
467 // Currently only support BMP format\r
468 //\r
469 if (Format != EfiBadgingFormatBMP) {\r
470 gBS->FreePool (ImageData);\r
471 continue;\r
472 }\r
473 } else {\r
57d40fe2 474 Status = GetGraphicsBitMapFromFVEx (ImageHandle, LogoFile, (VOID **) &ImageData, &ImageSize);\r
3eb9473e 475 if (EFI_ERROR (Status)) {\r
476 return EFI_UNSUPPORTED;\r
477 }\r
478\r
479 CoordinateX = 0;\r
480 CoordinateY = 0;\r
481 Attribute = EfiBadgingDisplayAttributeCenter;\r
482 }\r
483\r
484 Blt = NULL;\r
485 Status = ConvertBmpToGopBlt (\r
486 ImageData,\r
487 ImageSize,\r
488 (VOID**)&Blt,\r
489 &BltSize,\r
490 &Height,\r
491 &Width\r
492 );\r
493 if (EFI_ERROR (Status)) {\r
494 gBS->FreePool (ImageData);\r
495 if (Badging == NULL) {\r
496 return Status;\r
497 } else {\r
498 continue;\r
499 }\r
500 }\r
501\r
502 switch (Attribute) {\r
503 case EfiBadgingDisplayAttributeLeftTop:\r
504 DestX = CoordinateX;\r
505 DestY = CoordinateY;\r
506 break;\r
507\r
508 case EfiBadgingDisplayAttributeCenterTop:\r
509 DestX = (SizeOfX - Width) / 2;\r
510 DestY = CoordinateY;\r
511 break;\r
512\r
513 case EfiBadgingDisplayAttributeRightTop:\r
514 DestX = (SizeOfX - Width - CoordinateX);\r
515 DestY = CoordinateY;;\r
516 break;\r
517\r
518 case EfiBadgingDisplayAttributeCenterRight:\r
519 DestX = (SizeOfX - Width - CoordinateX);\r
520 DestY = (SizeOfY - Height) / 2;\r
521 break;\r
522\r
523 case EfiBadgingDisplayAttributeRightBottom:\r
524 DestX = (SizeOfX - Width - CoordinateX);\r
525 DestY = (SizeOfY - Height - CoordinateY);\r
526 break;\r
527\r
528 case EfiBadgingDisplayAttributeCenterBottom:\r
529 DestX = (SizeOfX - Width) / 2;\r
530 DestY = (SizeOfY - Height - CoordinateY);\r
531 break;\r
532\r
533 case EfiBadgingDisplayAttributeLeftBottom:\r
534 DestX = CoordinateX;\r
535 DestY = (SizeOfY - Height - CoordinateY);\r
536 break;\r
537\r
538 case EfiBadgingDisplayAttributeCenterLeft:\r
539 DestX = CoordinateX;\r
540 DestY = (SizeOfY - Height) / 2;\r
541 break;\r
542\r
543 case EfiBadgingDisplayAttributeCenter:\r
544 DestX = (SizeOfX - Width) / 2;\r
545 DestY = (SizeOfY - Height) / 2;\r
546 break;\r
547\r
548 default:\r
549 DestX = CoordinateX;\r
550 DestY = CoordinateY;\r
551 break;\r
552 }\r
553\r
554 if ((DestX >= 0) && (DestY >= 0)) {\r
555 if (GraphicsOutput != NULL) {\r
556 Status = GraphicsOutput->Blt (\r
557 GraphicsOutput,\r
558 Blt,\r
559 EfiBltBufferToVideo,\r
560 0,\r
561 0,\r
562 (UINTN) DestX,\r
563 (UINTN) DestY,\r
564 Width,\r
565 Height,\r
566 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
567 );\r
568 } else {\r
569 Status = UgaDraw->Blt (\r
570 UgaDraw,\r
571 (EFI_UGA_PIXEL *) Blt,\r
572 EfiUgaBltBufferToVideo,\r
573 0,\r
574 0,\r
575 (UINTN) DestX,\r
576 (UINTN) DestY,\r
577 Width,\r
578 Height,\r
579 Width * sizeof (EFI_UGA_PIXEL)\r
580 );\r
581 }\r
582 }\r
583\r
584 gBS->FreePool (ImageData);\r
585 gBS->FreePool (Blt);\r
586\r
587 if (Badging == NULL) {\r
588 break;\r
589 }\r
590 }\r
591\r
592 return Status;\r
593}\r
594\r
595\r
596EFI_STATUS\r
597DisableQuietBoot (\r
598 VOID\r
599 )\r
600/*++\r
601\r
602Routine Description:\r
603\r
604 Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA \r
605 Simple Text Out screens will now be synced up with all non GOP/UGA output devices\r
606\r
607Arguments:\r
608\r
609 NONE\r
610\r
611Returns: \r
612\r
613 EFI_SUCCESS - GOP/UGA devices are back in text mode and synced up.\r
614 EFI_UNSUPPORTED - Logo not found\r
615\r
616--*/\r
617{\r
618 EFI_STATUS Status;\r
619 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
620\r
621 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);\r
622 if (EFI_ERROR (Status)) {\r
623 return EFI_UNSUPPORTED;\r
624 }\r
625\r
626 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
627}\r