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