consplittergraphics.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,003 行 · 第 1/3 页

C
1,003
字号
    }
    if ( ( SourceX + Width ) > HorizontalResolution ) {
      return EFI_INVALID_PARAMETER;
    }

    BltPtr      = (EFI_UGA_PIXEL *) ((UINT8 *)BltBuffer + DestinationY * Delta + DestinationX * sizeof (EFI_UGA_PIXEL));
    ScreenPtr   = &Private->UgaBlt[SourceY * HorizontalResolution + SourceX];
    while ( Height ) {
      EfiCopyMem (BltPtr, ScreenPtr, Width * sizeof (EFI_UGA_PIXEL) );
      BltPtr    = (EFI_UGA_PIXEL *) ((UINT8 *)BltPtr + Delta);
      ScreenPtr += HorizontalResolution;
      Height --;
    }
  } else {
    //
    // BltBuffer to Video: Source is BltBuffer, destination is Video
    //
    if (DestinationY + Height > VerticalResolution) {
      return EFI_INVALID_PARAMETER;
    }
    if (DestinationX + Width > HorizontalResolution) {
      return EFI_INVALID_PARAMETER;
    }

    ScreenPtr   = &Private->UgaBlt[DestinationY * HorizontalResolution + DestinationX];
    SrcY        = SourceY;
    while ( Height ) {
      if ( BltOperation == EfiUgaVideoFill ) {
        for (Index = 0; Index < Width; Index++) {
          ScreenPtr[Index] = *(EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + SourceY * Delta + SourceX * sizeof (EFI_UGA_PIXEL));
        }
      } else {
        if ( BltOperation == EfiUgaBltBufferToVideo ) {
          BltPtr = (EFI_UGA_PIXEL *) ((UINT8 *)BltBuffer + SrcY * Delta + SourceX * sizeof (EFI_UGA_PIXEL));
        } else  {
          BltPtr = &Private->UgaBlt[SrcY * HorizontalResolution + SourceX];
        }
        EfiCopyMem (ScreenPtr, BltPtr, Width * sizeof (EFI_UGA_PIXEL));
      }
      ScreenPtr += HorizontalResolution;
      SrcY ++;
      Height --;
    }
  }

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
ConSpliterUgaDrawBlt (
  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
  )
/*++

  Routine Description:
    The following table defines actions for BltOperations:
    EfiUgaVideoFill - Write data from the  BltBuffer pixel (SourceX, SourceY) 
      directly to every pixel of the video display rectangle 
      (DestinationX, DestinationY) 
      (DestinationX + Width, DestinationY + Height).
      Only one pixel will be used from the BltBuffer. Delta is NOT used.
    EfiUgaVideoToBltBuffer - Read data from the video display rectangle 
      (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in 
      the BltBuffer rectangle (DestinationX, DestinationY ) 
      (DestinationX + Width, DestinationY + Height). If DestinationX or 
      DestinationY is not zero then Delta must be set to the length in bytes 
      of a row in the BltBuffer.
    EfiUgaBltBufferToVideo - Write data from the  BltBuffer rectangle 
      (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the 
      video display rectangle (DestinationX, DestinationY) 
      (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is 
      not zero then Delta must be set to the length in bytes of a row in the 
      BltBuffer.
    EfiUgaVideoToVideo - Copy from the video display rectangle 
      (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
      to the video display rectangle (DestinationX, DestinationY) 
      (DestinationX + Width, DestinationY + Height). 
     The BltBuffer and Delta  are not used in this mode.

  Arguments:
    This          - Protocol instance pointer.
    BltBuffer     - Buffer containing data to blit into video buffer. This 
                    buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
    BltOperation  - Operation to perform on BlitBuffer and video memory
    SourceX       - X coordinate of source for the BltBuffer.
    SourceY       - Y coordinate of source for the BltBuffer.
    DestinationX  - X coordinate of destination for the BltBuffer.
    DestinationY  - Y coordinate of destination for the BltBuffer.
    Width         - Width of rectangle in BltBuffer in pixels.
    Height        - Hight of rectangle in BltBuffer in pixels.
    Delta         -
  
  Returns:
    EFI_SUCCES            - The Blt operation completed.
    EFI_INVALID_PARAMETER - BltOperation is not valid.
    EFI_DEVICE_ERROR      - A hardware error occured writting to the video 
                             buffer.

--*/
{
  EFI_STATUS                          Status;
  TEXT_OUT_SPLITTER_PRIVATE_DATA      *Private;
  UINTN                               Index;
  EFI_STATUS                          ReturnStatus;

  Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  if( ( BltOperation >= EfiUgaBltMax ) || ( BltOperation < 0 ) ) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Sync up DevNull UGA device
  //  
  ReturnStatus = DevNullUgaBlt (
                    Private, 
                    BltBuffer,
                    BltOperation,
                    SourceX,
                    SourceY,
                    DestinationX,
                    DestinationY,
                    Width,
                    Height,
                    Delta 
                    );
  if (Private->UgaMode != EfiScreenGraphics) {
    return ReturnStatus;
  }
  
  //
  // return the worst status met
  //
  for ( Index = 0; Index < Private->CurrentNumberOfConsoles; Index++ ) {
    if ( Private->TextOutList[Index].UgaDraw ) {
      Status = Private->TextOutList[Index].UgaDraw->Blt (
                                      Private->TextOutList[Index].UgaDraw,
                                      BltBuffer,
                                      BltOperation,
                                      SourceX,
                                      SourceY,
                                      DestinationX,
                                      DestinationY,
                                      Width,
                                      Height,
                                      Delta 
                                      );
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      } else if (BltOperation == EfiUgaVideoToBltBuffer) {
        //
        // Only need to read the data into buffer one time
        //
        return EFI_SUCCESS;
      }
    }
  }
   
  return ReturnStatus;
}

EFI_STATUS
DevNullUgaSync (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw
  )
{
  return UgaDraw->Blt (
           UgaDraw, 
           Private->UgaBlt,
           EfiUgaBltBufferToVideo,
           0,
           0,
           0,
           0,
           Private->UgaHorizontalResolution,
           Private->UgaVerticalResolution,
           Private->UgaHorizontalResolution * sizeof (EFI_UGA_PIXEL) 
           );
}

EFI_STATUS
DevNullTextOutOutputString (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  CHAR16                          *WString
  )
/*++

  Routine Description:
    Write a Unicode string to the output device.

  Arguments:
    This    - Protocol instance pointer.
    String  - The NULL-terminated Unicode string to be displayed on the output
              device(s). All output devices must also support the Unicode 
              drawing defined in this file.

  Returns:
    EFI_SUCCES        - The string was output to the device.
    EFI_DEVICE_ERROR  - The device reported an error while attempting to output
                         the text.
    EFI_UNSUPPORTED        - The output device's mode is not currently in a 
                              defined text mode.
    EFI_WARN_UNKNOWN_GLYPH - This warning code indicates that some of the 
                              characters in the Unicode string could not be 
                              rendered and were skipped.

--*/
{
  UINTN                               SizeScreen;
  UINTN                               SizeAttribute;
  UINTN                               Index;
  EFI_SIMPLE_TEXT_OUTPUT_MODE         *Mode;
  CHAR16                              *Screen, *NullScreen;
  INT32                               *Attribute, *NullAttributes;
  UINTN                               LastRow, MaxColumn;

  Mode            = &Private->TextOutMode;
  NullScreen      = Private->DevNullScreen;
  NullAttributes  = Private->DevNullAttributes;
  LastRow         = Private->DevNullRows - 1;
  MaxColumn       = Private->DevNullColumns;
  
  while ( *WString ) {

    if ( *WString == CHAR_BACKSPACE ) {

      //  
      // If the cursor is not at the left edge of the display, 
      // then move the cursor left one column.
      //
      if ( Mode->CursorColumn > 0 ) {
        Mode->CursorColumn --;
      }
      WString++;

    } else if ( *WString == CHAR_LINEFEED ) {
      //
      // If the cursor is at the bottom of the display, 
      // then scroll the display one row, and do not update 
      // the cursor position. Otherwise, move the cursor down one row.
      //
      if ( Mode->CursorRow == (INT32) (LastRow) ) {
        //
        // Scroll Screen Up One Row 
        //
        SizeAttribute = LastRow * MaxColumn;
        EfiCopyMem (
          NullAttributes,
          NullAttributes + MaxColumn,
          SizeAttribute * sizeof (INT32)
          );

        //
        // Each row has an ending CHAR_NULL. So one more character each line
        // for DevNullScreen than DevNullAttributes
        //
        SizeScreen = SizeAttribute + LastRow;
        EfiCopyMem (
          NullScreen,
          NullScreen + (MaxColumn + 1),
          SizeScreen * sizeof (CHAR16)
          );

        //
        // Print Blank Line at last line
        //
        Screen = NullScreen + SizeScreen;
        Attribute = NullAttributes + SizeAttribute;

        for ( Index = 0; Index < MaxColumn; Index++, Screen++, Attribute++ ) {
          *Screen = ' ';
          *Attribute = Mode->Attribute;
        }
      } else {
        Mode->CursorRow ++;
      }
      WString++;
    } else if ( *WString == CHAR_CARRIAGE_RETURN ) {
      //
      // Move the cursor to the beginning of the current row.
      //
      Mode->CursorColumn = 0;
      WString++;
    } else {
      //  
      // Print the character at the current cursor position and 
      // move the cursor right one column. If this moves the cursor 
      // past the right edge of the display, then the line should wrap to 
      // the beginning of the next line. This is equivalent to inserting 
      // a CR and an LF. Note that if the cursor is at the bottom of the 
      // display, and the line wraps, then the display will be scrolled
      // one line.
      //
      Index = Mode->CursorRow * MaxColumn + Mode->CursorColumn;

      while ( Mode->CursorColumn < (INT32)MaxColumn ) {
        if ( *WString == CHAR_NULL ) {
          break;
        }
        if ( *WString == CHAR_BACKSPACE ) {
          break;
        }
        if ( *WString == CHAR_LINEFEED ) {
          break;
        }
        if ( *WString == CHAR_CARRIAGE_RETURN ) {
          break;
        }

        NullScreen[Index + Mode->CursorRow] = *WString;
        NullAttributes[Index]               = Mode->Attribute;
        Index ++;
        WString ++;
        Mode->CursorColumn ++;
      }

      //
      // At the end of line, output carriage return and line feed
      //
      if ( Mode->CursorColumn >= (INT32) (MaxColumn) ) {
        DevNullTextOutOutputString (Private, mCrLfString);
      } 
    }
  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?