1 /** @file
2   Support for Graphics output spliter.
3 
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 
14 **/
15 
16 #include "ConSplitter.h"
17 
18 
19 CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
20 
21 /**
22   Returns information for an available graphics mode that the graphics device
23   and the set of active video output devices supports.
24 
25   @param  This                  The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
26   @param  ModeNumber            The mode number to return information on.
27   @param  SizeOfInfo            A pointer to the size, in bytes, of the Info buffer.
28   @param  Info                  A pointer to callee allocated buffer that returns information about ModeNumber.
29 
30   @retval EFI_SUCCESS           Mode information returned.
31   @retval EFI_BUFFER_TOO_SMALL  The Info buffer was too small.
32   @retval EFI_DEVICE_ERROR      A hardware error occurred trying to retrieve the video mode.
33   @retval EFI_INVALID_PARAMETER One of the input args was NULL.
34   @retval EFI_OUT_OF_RESOURCES  No resource available.
35 
36 **/
37 EFI_STATUS
38 EFIAPI
ConSplitterGraphicsOutputQueryMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,IN UINT32 ModeNumber,OUT UINTN * SizeOfInfo,OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ** Info)39 ConSplitterGraphicsOutputQueryMode (
40   IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
41   IN  UINT32                                ModeNumber,
42   OUT UINTN                                 *SizeOfInfo,
43   OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
44   )
45 {
46   TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
47   EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
48   EFI_STATUS                      Status;
49   UINTN                           Index;
50 
51   if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
52     return EFI_INVALID_PARAMETER;
53   }
54 
55   //
56   // retrieve private data
57   //
58   Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
59 
60   GraphicsOutput = NULL;
61 
62   if (Private->CurrentNumberOfGraphicsOutput == 1) {
63     //
64     // Find the only one GraphicsOutput.
65     //
66     for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
67       GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
68       if (GraphicsOutput != NULL) {
69         break;
70       }
71     }
72   }
73 
74   if (GraphicsOutput != NULL) {
75     //
76     // If only one physical GOP device exist, return its information.
77     //
78     Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) ModeNumber, SizeOfInfo, Info);
79     return Status;
80   } else {
81     //
82     // If 2 more phyiscal GOP device exist or GOP protocol does not exist,
83     // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
84     //
85     *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
86     if (*Info == NULL) {
87       return EFI_OUT_OF_RESOURCES;
88     }
89     *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
90     CopyMem (*Info, &Private->GraphicsOutputModeBuffer[ModeNumber], *SizeOfInfo);
91   }
92 
93   return EFI_SUCCESS;
94 }
95 
96 
97 /**
98   Set the video device into the specified mode and clears the visible portions of
99   the output display to black.
100 
101   @param  This                  The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
102   @param  ModeNumber            Abstraction that defines the current video mode.
103 
104   @retval EFI_SUCCESS           The graphics mode specified by ModeNumber was selected.
105   @retval EFI_DEVICE_ERROR      The device had an error and could not complete the request.
106   @retval EFI_UNSUPPORTED       ModeNumber is not supported by this device.
107   @retval EFI_OUT_OF_RESOURCES  No resource available.
108 
109 **/
110 EFI_STATUS
111 EFIAPI
ConSplitterGraphicsOutputSetMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,IN UINT32 ModeNumber)112 ConSplitterGraphicsOutputSetMode (
113   IN  EFI_GRAPHICS_OUTPUT_PROTOCOL * This,
114   IN  UINT32                       ModeNumber
115   )
116 {
117   EFI_STATUS                             Status;
118   TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;
119   UINTN                                  Index;
120   EFI_STATUS                             ReturnStatus;
121   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Mode;
122   EFI_GRAPHICS_OUTPUT_PROTOCOL           *GraphicsOutput;
123   EFI_GRAPHICS_OUTPUT_PROTOCOL           *PhysicalGraphicsOutput;
124   UINTN                                  NumberIndex;
125   UINTN                                  SizeOfInfo;
126   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;
127   EFI_UGA_DRAW_PROTOCOL                  *UgaDraw;
128 
129   if (ModeNumber >= This->Mode->MaxMode) {
130     return EFI_UNSUPPORTED;
131   }
132 
133   Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
134   Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];
135 
136   ReturnStatus = EFI_SUCCESS;
137   GraphicsOutput = NULL;
138   PhysicalGraphicsOutput = NULL;
139   //
140   // return the worst status met
141   //
142   for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
143     GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
144     if (GraphicsOutput != NULL) {
145       PhysicalGraphicsOutput = GraphicsOutput;
146       //
147       // Find corresponding ModeNumber of this GraphicsOutput instance
148       //
149       for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex ++) {
150         Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);
151         if (EFI_ERROR (Status)) {
152           return Status;
153         }
154         if ((Info->HorizontalResolution == Mode->HorizontalResolution) && (Info->VerticalResolution == Mode->VerticalResolution)) {
155           FreePool (Info);
156           break;
157         }
158         FreePool (Info);
159       }
160 
161       Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);
162       if (EFI_ERROR (Status)) {
163         ReturnStatus = Status;
164       }
165     } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
166       UgaDraw = Private->TextOutList[Index].UgaDraw;
167       if (UgaDraw != NULL) {
168         Status = UgaDraw->SetMode (
169                             UgaDraw,
170                             Mode->HorizontalResolution,
171                             Mode->VerticalResolution,
172                             32,
173                             60
174                             );
175         if (EFI_ERROR (Status)) {
176           ReturnStatus = Status;
177         }
178       }
179     }
180   }
181 
182   This->Mode->Mode = ModeNumber;
183 
184   if ((Private->CurrentNumberOfGraphicsOutput == 1) && (PhysicalGraphicsOutput != NULL)) {
185     //
186     // If only one physical GOP device exist, copy physical information to consplitter.
187     //
188     CopyMem (This->Mode->Info, PhysicalGraphicsOutput->Mode->Info, PhysicalGraphicsOutput->Mode->SizeOfInfo);
189     This->Mode->SizeOfInfo = PhysicalGraphicsOutput->Mode->SizeOfInfo;
190     This->Mode->FrameBufferBase = PhysicalGraphicsOutput->Mode->FrameBufferBase;
191     This->Mode->FrameBufferSize = PhysicalGraphicsOutput->Mode->FrameBufferSize;
192   } else {
193     //
194     // If 2 more phyiscal GOP device exist or GOP protocol does not exist,
195     // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
196     //
197     CopyMem (This->Mode->Info, &Private->GraphicsOutputModeBuffer[ModeNumber], This->Mode->SizeOfInfo);
198   }
199 
200   return ReturnStatus;
201 }
202 
203 
204 
205 /**
206   The following table defines actions for BltOperations.
207 
208   EfiBltVideoFill - Write data from the  BltBuffer pixel (SourceX, SourceY)
209   directly to every pixel of the video display rectangle
210   (DestinationX, DestinationY)
211   (DestinationX + Width, DestinationY + Height).
212   Only one pixel will be used from the BltBuffer. Delta is NOT used.
213   EfiBltVideoToBltBuffer - Read data from the video display rectangle
214   (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
215   the BltBuffer rectangle (DestinationX, DestinationY )
216   (DestinationX + Width, DestinationY + Height). If DestinationX or
217   DestinationY is not zero then Delta must be set to the length in bytes
218   of a row in the BltBuffer.
219   EfiBltBufferToVideo - Write data from the  BltBuffer rectangle
220   (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
221   video display rectangle (DestinationX, DestinationY)
222   (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
223   not zero then Delta must be set to the length in bytes of a row in the
224   BltBuffer.
225   EfiBltVideoToVideo - Copy from the video display rectangle
226   (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
227   to the video display rectangle (DestinationX, DestinationY)
228   (DestinationX + Width, DestinationY + Height).
229   The BltBuffer and Delta  are not used in this mode.
230 
231   @param  This                    Protocol instance pointer.
232   @param  BltBuffer               Buffer containing data to blit into video buffer.
233                                   This buffer has a size of
234                                   Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
235   @param  BltOperation            Operation to perform on BlitBuffer and video
236                                   memory
237   @param  SourceX                 X coordinate of source for the BltBuffer.
238   @param  SourceY                 Y coordinate of source for the BltBuffer.
239   @param  DestinationX            X coordinate of destination for the BltBuffer.
240   @param  DestinationY            Y coordinate of destination for the BltBuffer.
241   @param  Width                   Width of rectangle in BltBuffer in pixels.
242   @param  Height                  Hight of rectangle in BltBuffer in pixels.
243   @param  Delta                   OPTIONAL.
244 
245   @retval EFI_SUCCESS             The Blt operation completed.
246   @retval EFI_INVALID_PARAMETER   BltOperation is not valid.
247   @retval EFI_DEVICE_ERROR        A hardware error occured writting to the video
248                                   buffer.
249 
250 **/
251 EFI_STATUS
252 EFIAPI
ConSplitterGraphicsOutputBlt(IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL * BltBuffer,OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,IN UINTN SourceX,IN UINTN SourceY,IN UINTN DestinationX,IN UINTN DestinationY,IN UINTN Width,IN UINTN Height,IN UINTN Delta OPTIONAL)253 ConSplitterGraphicsOutputBlt (
254   IN  EFI_GRAPHICS_OUTPUT_PROTOCOL                  *This,
255   IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL                 *BltBuffer, OPTIONAL
256   IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION             BltOperation,
257   IN  UINTN                                         SourceX,
258   IN  UINTN                                         SourceY,
259   IN  UINTN                                         DestinationX,
260   IN  UINTN                                         DestinationY,
261   IN  UINTN                                         Width,
262   IN  UINTN                                         Height,
263   IN  UINTN                                         Delta         OPTIONAL
264   )
265 {
266   EFI_STATUS                      Status;
267   EFI_STATUS                      ReturnStatus;
268   TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
269   UINTN                           Index;
270   EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
271   EFI_UGA_DRAW_PROTOCOL           *UgaDraw;
272 
273   if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {
274     return EFI_INVALID_PARAMETER;
275   }
276 
277   Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
278 
279   ReturnStatus = EFI_SUCCESS;
280 
281   //
282   // return the worst status met
283   //
284   for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
285     GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
286     if (GraphicsOutput != NULL) {
287       Status = GraphicsOutput->Blt (
288                               GraphicsOutput,
289                               BltBuffer,
290                               BltOperation,
291                               SourceX,
292                               SourceY,
293                               DestinationX,
294                               DestinationY,
295                               Width,
296                               Height,
297                               Delta
298                               );
299       if (EFI_ERROR (Status)) {
300         ReturnStatus = Status;
301       } else if (BltOperation == EfiBltVideoToBltBuffer) {
302         //
303         // Only need to read the data into buffer one time
304         //
305         return EFI_SUCCESS;
306       }
307     }
308 
309     UgaDraw = Private->TextOutList[Index].UgaDraw;
310     if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
311       Status = UgaDraw->Blt (
312                               UgaDraw,
313                               (EFI_UGA_PIXEL *) BltBuffer,
314                               (EFI_UGA_BLT_OPERATION) BltOperation,
315                               SourceX,
316                               SourceY,
317                               DestinationX,
318                               DestinationY,
319                               Width,
320                               Height,
321                               Delta
322                               );
323       if (EFI_ERROR (Status)) {
324         ReturnStatus = Status;
325       } else if (BltOperation == EfiBltVideoToBltBuffer) {
326         //
327         // Only need to read the data into buffer one time
328         //
329         return EFI_SUCCESS;
330       }
331     }
332   }
333 
334   return ReturnStatus;
335 }
336 
337 /**
338   Return the current video mode information.
339 
340   @param  This                  The EFI_UGA_DRAW_PROTOCOL instance.
341   @param  HorizontalResolution  The size of video screen in pixels in the X dimension.
342   @param  VerticalResolution    The size of video screen in pixels in the Y dimension.
343   @param  ColorDepth            Number of bits per pixel, currently defined to be 32.
344   @param  RefreshRate           The refresh rate of the monitor in Hertz.
345 
346   @retval EFI_SUCCESS           Mode information returned.
347   @retval EFI_NOT_STARTED       Video display is not initialized. Call SetMode ()
348   @retval EFI_INVALID_PARAMETER One of the input args was NULL.
349 
350 **/
351 EFI_STATUS
352 EFIAPI
ConSplitterUgaDrawGetMode(IN EFI_UGA_DRAW_PROTOCOL * This,OUT UINT32 * HorizontalResolution,OUT UINT32 * VerticalResolution,OUT UINT32 * ColorDepth,OUT UINT32 * RefreshRate)353 ConSplitterUgaDrawGetMode (
354   IN  EFI_UGA_DRAW_PROTOCOL           *This,
355   OUT UINT32                          *HorizontalResolution,
356   OUT UINT32                          *VerticalResolution,
357   OUT UINT32                          *ColorDepth,
358   OUT UINT32                          *RefreshRate
359   )
360 {
361   TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
362 
363   if ((HorizontalResolution == NULL) ||
364       (VerticalResolution   == NULL) ||
365       (RefreshRate          == NULL) ||
366       (ColorDepth           == NULL)) {
367     return EFI_INVALID_PARAMETER;
368   }
369   //
370   // retrieve private data
371   //
372   Private               = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
373 
374   *HorizontalResolution = Private->UgaHorizontalResolution;
375   *VerticalResolution   = Private->UgaVerticalResolution;
376   *ColorDepth           = Private->UgaColorDepth;
377   *RefreshRate          = Private->UgaRefreshRate;
378 
379   return EFI_SUCCESS;
380 }
381 
382 
383 /**
384   Set the current video mode information.
385 
386   @param  This                 The EFI_UGA_DRAW_PROTOCOL instance.
387   @param  HorizontalResolution The size of video screen in pixels in the X dimension.
388   @param  VerticalResolution   The size of video screen in pixels in the Y dimension.
389   @param  ColorDepth           Number of bits per pixel, currently defined to be 32.
390   @param  RefreshRate          The refresh rate of the monitor in Hertz.
391 
392   @retval EFI_SUCCESS          Mode information returned.
393   @retval EFI_NOT_STARTED      Video display is not initialized. Call SetMode ()
394   @retval EFI_OUT_OF_RESOURCES Out of resources.
395 
396 **/
397 EFI_STATUS
398 EFIAPI
ConSplitterUgaDrawSetMode(IN EFI_UGA_DRAW_PROTOCOL * This,IN UINT32 HorizontalResolution,IN UINT32 VerticalResolution,IN UINT32 ColorDepth,IN UINT32 RefreshRate)399 ConSplitterUgaDrawSetMode (
400   IN  EFI_UGA_DRAW_PROTOCOL           *This,
401   IN UINT32                           HorizontalResolution,
402   IN UINT32                           VerticalResolution,
403   IN UINT32                           ColorDepth,
404   IN UINT32                           RefreshRate
405   )
406 {
407   EFI_STATUS                             Status;
408   TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;
409   UINTN                                  Index;
410   EFI_STATUS                             ReturnStatus;
411   EFI_GRAPHICS_OUTPUT_PROTOCOL           *GraphicsOutput;
412   UINTN                                  NumberIndex;
413   UINTN                                  SizeOfInfo;
414   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;
415   EFI_UGA_DRAW_PROTOCOL                  *UgaDraw;
416 
417   Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
418 
419   ReturnStatus = EFI_SUCCESS;
420 
421   //
422   // Update the Mode data
423   //
424   Private->UgaHorizontalResolution  = HorizontalResolution;
425   Private->UgaVerticalResolution    = VerticalResolution;
426   Private->UgaColorDepth            = ColorDepth;
427   Private->UgaRefreshRate           = RefreshRate;
428 
429   //
430   // return the worst status met
431   //
432   for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
433 
434     GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
435     if (GraphicsOutput != NULL) {
436       //
437       // Find corresponding ModeNumber of this GraphicsOutput instance
438       //
439       for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex ++) {
440         Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);
441         if (EFI_ERROR (Status)) {
442           return Status;
443         }
444         if ((Info->HorizontalResolution == HorizontalResolution) && (Info->VerticalResolution == VerticalResolution)) {
445           FreePool (Info);
446           break;
447         }
448         FreePool (Info);
449       }
450 
451       Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);
452       if (EFI_ERROR (Status)) {
453         ReturnStatus = Status;
454       }
455     } else if (FeaturePcdGet (PcdUgaConsumeSupport)){
456       UgaDraw = Private->TextOutList[Index].UgaDraw;
457       if (UgaDraw != NULL) {
458         Status = UgaDraw->SetMode (
459                           UgaDraw,
460                           HorizontalResolution,
461                           VerticalResolution,
462                           ColorDepth,
463                           RefreshRate
464                           );
465         if (EFI_ERROR (Status)) {
466           ReturnStatus = Status;
467         }
468       }
469     }
470   }
471 
472   return ReturnStatus;
473 }
474 
475 
476 /**
477   Blt a rectangle of pixels on the graphics screen.
478 
479   The following table defines actions for BltOperations.
480 
481   EfiUgaVideoFill:
482     Write data from the  BltBuffer pixel (SourceX, SourceY)
483     directly to every pixel of the video display rectangle
484     (DestinationX, DestinationY)
485     (DestinationX + Width, DestinationY + Height).
486     Only one pixel will be used from the BltBuffer. Delta is NOT used.
487   EfiUgaVideoToBltBuffer:
488     Read data from the video display rectangle
489     (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
490     the BltBuffer rectangle (DestinationX, DestinationY )
491     (DestinationX + Width, DestinationY + Height). If DestinationX or
492     DestinationY is not zero then Delta must be set to the length in bytes
493     of a row in the BltBuffer.
494   EfiUgaBltBufferToVideo:
495     Write data from the  BltBuffer rectangle
496     (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
497     video display rectangle (DestinationX, DestinationY)
498     (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
499     not zero then Delta must be set to the length in bytes of a row in the
500     BltBuffer.
501   EfiUgaVideoToVideo:
502     Copy from the video display rectangle
503     (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
504     to the video display rectangle (DestinationX, DestinationY)
505     (DestinationX + Width, DestinationY + Height).
506     The BltBuffer and Delta  are not used in this mode.
507 
508   @param  This           Protocol instance pointer.
509   @param  BltBuffer      Buffer containing data to blit into video buffer. This
510                          buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
511   @param  BltOperation   Operation to perform on BlitBuffer and video memory
512   @param  SourceX        X coordinate of source for the BltBuffer.
513   @param  SourceY        Y coordinate of source for the BltBuffer.
514   @param  DestinationX   X coordinate of destination for the BltBuffer.
515   @param  DestinationY   Y coordinate of destination for the BltBuffer.
516   @param  Width          Width of rectangle in BltBuffer in pixels.
517   @param  Height         Hight of rectangle in BltBuffer in pixels.
518   @param  Delta          OPTIONAL
519 
520   @retval EFI_SUCCESS            The Blt operation completed.
521   @retval EFI_INVALID_PARAMETER  BltOperation is not valid.
522   @retval EFI_DEVICE_ERROR       A hardware error occured writting to the video buffer.
523 
524 **/
525 EFI_STATUS
526 EFIAPI
ConSplitterUgaDrawBlt(IN EFI_UGA_DRAW_PROTOCOL * This,IN EFI_UGA_PIXEL * BltBuffer,OPTIONAL IN EFI_UGA_BLT_OPERATION BltOperation,IN UINTN SourceX,IN UINTN SourceY,IN UINTN DestinationX,IN UINTN DestinationY,IN UINTN Width,IN UINTN Height,IN UINTN Delta OPTIONAL)527 ConSplitterUgaDrawBlt (
528   IN  EFI_UGA_DRAW_PROTOCOL                         *This,
529   IN  EFI_UGA_PIXEL                                 *BltBuffer, OPTIONAL
530   IN  EFI_UGA_BLT_OPERATION                         BltOperation,
531   IN  UINTN                                         SourceX,
532   IN  UINTN                                         SourceY,
533   IN  UINTN                                         DestinationX,
534   IN  UINTN                                         DestinationY,
535   IN  UINTN                                         Width,
536   IN  UINTN                                         Height,
537   IN  UINTN                                         Delta         OPTIONAL
538   )
539 {
540   EFI_STATUS                      Status;
541   TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
542   UINTN                           Index;
543   EFI_STATUS                      ReturnStatus;
544   EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
545 
546   Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
547 
548   ReturnStatus = EFI_SUCCESS;
549   //
550   // return the worst status met
551   //
552   for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
553     GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
554     if (GraphicsOutput != NULL) {
555       Status = GraphicsOutput->Blt (
556                               GraphicsOutput,
557                               (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltBuffer,
558                               (EFI_GRAPHICS_OUTPUT_BLT_OPERATION) BltOperation,
559                               SourceX,
560                               SourceY,
561                               DestinationX,
562                               DestinationY,
563                               Width,
564                               Height,
565                               Delta
566                               );
567       if (EFI_ERROR (Status)) {
568         ReturnStatus = Status;
569       } else if (BltOperation == EfiUgaVideoToBltBuffer) {
570         //
571         // Only need to read the data into buffer one time
572         //
573         return EFI_SUCCESS;
574       }
575     }
576 
577     if (Private->TextOutList[Index].UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
578       Status = Private->TextOutList[Index].UgaDraw->Blt (
579                                                       Private->TextOutList[Index].UgaDraw,
580                                                       BltBuffer,
581                                                       BltOperation,
582                                                       SourceX,
583                                                       SourceY,
584                                                       DestinationX,
585                                                       DestinationY,
586                                                       Width,
587                                                       Height,
588                                                       Delta
589                                                       );
590       if (EFI_ERROR (Status)) {
591         ReturnStatus = Status;
592       } else if (BltOperation == EfiUgaVideoToBltBuffer) {
593         //
594         // Only need to read the data into buffer one time
595         //
596         return EFI_SUCCESS;
597       }
598     }
599   }
600 
601   return ReturnStatus;
602 }
603 
604 /**
605   Sets the output device(s) to a specified mode.
606 
607   @param  Private                 Text Out Splitter pointer.
608   @param  ModeNumber              The mode number to set.
609 
610 **/
611 VOID
TextOutSetMode(IN TEXT_OUT_SPLITTER_PRIVATE_DATA * Private,IN UINTN ModeNumber)612 TextOutSetMode (
613   IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
614   IN  UINTN                           ModeNumber
615   )
616 {
617   //
618   // No need to do extra check here as whether (Column, Row) is valid has
619   // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
620   // always be supported.
621   //
622   Private->TextOutMode.Mode          = (INT32) ModeNumber;
623   Private->TextOutMode.CursorColumn  = 0;
624   Private->TextOutMode.CursorRow     = 0;
625   Private->TextOutMode.CursorVisible = TRUE;
626 
627   return;
628 }
629