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