]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Dxe/GraphicsLite/Graphics.c
GCC cleanup for all EDK I DXE libraries.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / GraphicsLite / Graphics.c
CommitLineData
3eb9473e 1/*++\r
2\r
3Copyright (c) 2004 - 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
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
161 UINTN BltBufferSize;\r
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
189 BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
190 IsAllocated = FALSE;\r
191 if (*GopBlt == NULL) {\r
192 *GopBltSize = BltBufferSize;\r
193 *GopBlt = EfiLibAllocatePool (*GopBltSize);\r
194 IsAllocated = TRUE;\r
195 if (*GopBlt == NULL) {\r
196 return EFI_OUT_OF_RESOURCES;\r
197 }\r
198 } else {\r
199 if (*GopBltSize < BltBufferSize) {\r
200 *GopBltSize = BltBufferSize;\r
201 return EFI_BUFFER_TOO_SMALL;\r
202 }\r
203 }\r
204\r
205 *PixelWidth = BmpHeader->PixelWidth;\r
206 *PixelHeight = BmpHeader->PixelHeight;\r
207\r
208 //\r
209 // Convert image from BMP to Blt buffer format\r
210 //\r
211 BltBuffer = *GopBlt;\r
212 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
213 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
214 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
215 switch (BmpHeader->BitPerPixel) {\r
216 case 1:\r
217 //\r
218 // Convert 1bit BMP to 24-bit color\r
219 //\r
220 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
221 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
222 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
223 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
224 Blt++;\r
225 Width++;\r
226 }\r
227\r
228 Blt --;\r
229 Width --;\r
230 break;\r
231\r
232 case 4:\r
233 //\r
234 // Convert BMP Palette to 24-bit color\r
235 //\r
236 Index = (*Image) >> 4;\r
237 Blt->Red = BmpColorMap[Index].Red;\r
238 Blt->Green = BmpColorMap[Index].Green;\r
239 Blt->Blue = BmpColorMap[Index].Blue;\r
240 if (Width < (BmpHeader->PixelWidth - 1)) {\r
241 Blt++;\r
242 Width++;\r
243 Index = (*Image) & 0x0f;\r
244 Blt->Red = BmpColorMap[Index].Red;\r
245 Blt->Green = BmpColorMap[Index].Green;\r
246 Blt->Blue = BmpColorMap[Index].Blue;\r
247 }\r
248 break;\r
249\r
250 case 8:\r
251 //\r
252 // Convert BMP Palette to 24-bit color\r
253 //\r
254 Blt->Red = BmpColorMap[*Image].Red;\r
255 Blt->Green = BmpColorMap[*Image].Green;\r
256 Blt->Blue = BmpColorMap[*Image].Blue;\r
257 break;\r
258\r
259 case 24:\r
260 Blt->Blue = *Image++;\r
261 Blt->Green = *Image++;\r
262 Blt->Red = *Image;\r
263 break;\r
264\r
265 default:\r
266 if (IsAllocated) {\r
267 gBS->FreePool (*GopBlt);\r
268 *GopBlt = NULL;\r
269 }\r
270 return EFI_UNSUPPORTED;\r
271 break;\r
272 };\r
273\r
274 }\r
275\r
276 ImageIndex = (UINTN) (Image - ImageHeader);\r
277 if ((ImageIndex % 4) != 0) {\r
278 //\r
279 // Bmp Image starts each row on a 32-bit boundary!\r
280 //\r
281 Image = Image + (4 - (ImageIndex % 4));\r
282 }\r
283 }\r
284\r
285 return EFI_SUCCESS;\r
286}\r
287\r
288\r
289EFI_STATUS\r
290LockKeyboards (\r
291 IN CHAR16 *Password\r
292 )\r
293/*++\r
294\r
295Routine Description:\r
296 Use Console Control Protocol to lock the Console In Spliter virtual handle. \r
297 This is the ConInHandle and ConIn handle in the EFI system table. All key\r
298 presses will be ignored until the Password is typed in. The only way to\r
299 disable the password is to type it in to a ConIn device.\r
300\r
301Arguments:\r
302 Password - Password used to lock ConIn device\r
303\r
304\r
305Returns: \r
306\r
307 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
308 displayed.\r
309 EFI_UNSUPPORTED - Logo not found\r
310\r
311--*/\r
312{\r
313 EFI_STATUS Status;\r
314 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
315\r
57d40fe2 316 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
3eb9473e 317 if (EFI_ERROR (Status)) {\r
318 return EFI_UNSUPPORTED;\r
319 }\r
320\r
321 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
322 return Status;\r
323}\r
324\r
325EFI_STATUS\r
326EnableQuietBoot (\r
327 IN EFI_GUID *LogoFile\r
328 )\r
329/*++\r
330\r
331Routine Description:\r
332\r
333 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
334 to the UGA device. Put up LogoFile on every UGA device that is a console\r
335\r
336Arguments:\r
337\r
338 LogoFile - File name of logo to display on the center of the screen.\r
339\r
340\r
341Returns: \r
342\r
343 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
344 displayed.\r
345 EFI_UNSUPPORTED - Logo not found\r
346\r
347--*/\r
348{\r
349 return EnableQuietBootEx (LogoFile, NULL);\r
350}\r
351\r
352\r
353EFI_STATUS\r
354EnableQuietBootEx (\r
355 IN EFI_GUID *LogoFile,\r
356 IN EFI_HANDLE ImageHandle\r
357 )\r
358/*++\r
359\r
360Routine Description:\r
361\r
362 Use Console Control to turn off GOP/UGA based Simple Text Out consoles from going\r
363 to the GOP/UGA device. Put up LogoFile on every GOP/UGA device that is a console\r
364\r
365Arguments:\r
366\r
367 LogoFile - File name of logo to display on the center of the screen.\r
368\r
369\r
370Returns: \r
371\r
372 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
373 displayed.\r
374 EFI_UNSUPPORTED - Logo not found\r
375\r
376--*/\r
377{\r
378 EFI_STATUS Status;\r
379 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
380 EFI_OEM_BADGING_PROTOCOL *Badging;\r
381 UINT32 SizeOfX;\r
382 UINT32 SizeOfY;\r
383 INTN DestX;\r
384 INTN DestY;\r
385 UINT8 *ImageData;\r
386 UINTN ImageSize;\r
387 UINTN BltSize;\r
388 UINT32 Instance;\r
389 EFI_BADGING_FORMAT Format;\r
390 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
391 UINTN CoordinateX;\r
392 UINTN CoordinateY;\r
393 UINTN Height;\r
394 UINTN Width;\r
395 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
396 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
397 UINT32 ColorDepth;\r
398 UINT32 RefreshRate;\r
399 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
400\r
57d40fe2 401 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
3eb9473e 402 if (EFI_ERROR (Status)) {\r
403 return EFI_UNSUPPORTED;\r
404 }\r
405\r
406 UgaDraw = NULL;\r
407 //\r
408 // Try to open GOP first\r
409 //\r
57d40fe2 410 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
3eb9473e 411 if (EFI_ERROR (Status)) {\r
412 GraphicsOutput = NULL;\r
413 //\r
414 // Open GOP failed, try to open UGA\r
415 //\r
57d40fe2 416 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
3eb9473e 417 if (EFI_ERROR (Status)) {\r
418 return EFI_UNSUPPORTED;\r
419 }\r
420 }\r
421\r
422 Badging = NULL;\r
57d40fe2 423 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
3eb9473e 424\r
425 ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
426\r
427 if (GraphicsOutput != NULL) {\r
428 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
429 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
430 } else {\r
431 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
432 if (EFI_ERROR (Status)) {\r
433 return EFI_UNSUPPORTED;\r
434 }\r
435 }\r
436\r
437 Instance = 0;\r
438 while (1) {\r
439 ImageData = NULL;\r
440 ImageSize = 0;\r
441\r
442 if (Badging != NULL) {\r
443 Status = Badging->GetImage (\r
444 Badging,\r
445 &Instance,\r
446 &Format,\r
447 &ImageData,\r
448 &ImageSize,\r
449 &Attribute,\r
450 &CoordinateX,\r
451 &CoordinateY\r
452 );\r
453 if (EFI_ERROR (Status)) {\r
454 return Status;\r
455 }\r
456\r
457 //\r
458 // Currently only support BMP format\r
459 //\r
460 if (Format != EfiBadgingFormatBMP) {\r
461 gBS->FreePool (ImageData);\r
462 continue;\r
463 }\r
464 } else {\r
57d40fe2 465 Status = GetGraphicsBitMapFromFVEx (ImageHandle, LogoFile, (VOID **) &ImageData, &ImageSize);\r
3eb9473e 466 if (EFI_ERROR (Status)) {\r
467 return EFI_UNSUPPORTED;\r
468 }\r
469\r
470 CoordinateX = 0;\r
471 CoordinateY = 0;\r
472 Attribute = EfiBadgingDisplayAttributeCenter;\r
473 }\r
474\r
475 Blt = NULL;\r
476 Status = ConvertBmpToGopBlt (\r
477 ImageData,\r
478 ImageSize,\r
57d40fe2 479 (VOID **) &Blt,\r
3eb9473e 480 &BltSize,\r
481 &Height,\r
482 &Width\r
483 );\r
484 if (EFI_ERROR (Status)) {\r
485 gBS->FreePool (ImageData);\r
486 if (Badging == NULL) {\r
487 return Status;\r
488 } else {\r
489 continue;\r
490 }\r
491 }\r
492\r
493 switch (Attribute) {\r
494 case EfiBadgingDisplayAttributeLeftTop:\r
495 DestX = CoordinateX;\r
496 DestY = CoordinateY;\r
497 break;\r
498\r
499 case EfiBadgingDisplayAttributeCenterTop:\r
500 DestX = (SizeOfX - Width) / 2;\r
501 DestY = CoordinateY;\r
502 break;\r
503\r
504 case EfiBadgingDisplayAttributeRightTop:\r
505 DestX = (SizeOfX - Width - CoordinateX);\r
506 DestY = CoordinateY;;\r
507 break;\r
508\r
509 case EfiBadgingDisplayAttributeCenterRight:\r
510 DestX = (SizeOfX - Width - CoordinateX);\r
511 DestY = (SizeOfY - Height) / 2;\r
512 break;\r
513\r
514 case EfiBadgingDisplayAttributeRightBottom:\r
515 DestX = (SizeOfX - Width - CoordinateX);\r
516 DestY = (SizeOfY - Height - CoordinateY);\r
517 break;\r
518\r
519 case EfiBadgingDisplayAttributeCenterBottom:\r
520 DestX = (SizeOfX - Width) / 2;\r
521 DestY = (SizeOfY - Height - CoordinateY);\r
522 break;\r
523\r
524 case EfiBadgingDisplayAttributeLeftBottom:\r
525 DestX = CoordinateX;\r
526 DestY = (SizeOfY - Height - CoordinateY);\r
527 break;\r
528\r
529 case EfiBadgingDisplayAttributeCenterLeft:\r
530 DestX = CoordinateX;\r
531 DestY = (SizeOfY - Height) / 2;\r
532 break;\r
533\r
534 case EfiBadgingDisplayAttributeCenter:\r
535 DestX = (SizeOfX - Width) / 2;\r
536 DestY = (SizeOfY - Height) / 2;\r
537 break;\r
538\r
539 default:\r
540 DestX = CoordinateX;\r
541 DestY = CoordinateY;\r
542 break;\r
543 }\r
544\r
545 if ((DestX >= 0) && (DestY >= 0)) {\r
546 if (GraphicsOutput != NULL) {\r
547 Status = GraphicsOutput->Blt (\r
548 GraphicsOutput,\r
549 Blt,\r
550 EfiBltBufferToVideo,\r
551 0,\r
552 0,\r
553 (UINTN) DestX,\r
554 (UINTN) DestY,\r
555 Width,\r
556 Height,\r
557 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
558 );\r
559 } else {\r
560 Status = UgaDraw->Blt (\r
561 UgaDraw,\r
562 (EFI_UGA_PIXEL *) Blt,\r
563 EfiUgaBltBufferToVideo,\r
564 0,\r
565 0,\r
566 (UINTN) DestX,\r
567 (UINTN) DestY,\r
568 Width,\r
569 Height,\r
570 Width * sizeof (EFI_UGA_PIXEL)\r
571 );\r
572 }\r
573 }\r
574\r
575 gBS->FreePool (ImageData);\r
576 gBS->FreePool (Blt);\r
577\r
578 if (Badging == NULL) {\r
579 break;\r
580 }\r
581 }\r
582\r
583 return Status;\r
584}\r
585\r
586\r
587EFI_STATUS\r
588DisableQuietBoot (\r
589 VOID\r
590 )\r
591/*++\r
592\r
593Routine Description:\r
594\r
595 Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA \r
596 Simple Text Out screens will now be synced up with all non GOP/UGA output devices\r
597\r
598Arguments:\r
599\r
600 NONE\r
601\r
602Returns: \r
603\r
604 EFI_SUCCESS - GOP/UGA devices are back in text mode and synced up.\r
605 EFI_UNSUPPORTED - Logo not found\r
606\r
607--*/\r
608{\r
609 EFI_STATUS Status;\r
610 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
611\r
57d40fe2 612 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
3eb9473e 613 if (EFI_ERROR (Status)) {\r
614 return EFI_UNSUPPORTED;\r
615 }\r
616\r
617 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
618}\r