]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmulatorPkg/Win/Host/WinGopScreen.c
EmulatorPkg/Win: Fix various typos
[mirror_edk2.git] / EmulatorPkg / Win / Host / WinGopScreen.c
index 2ca51d23d017f6409f33ca794e46017b96071df2..74011e225e3094f2e05a78e5db86e47c481b0ccb 100644 (file)
@@ -1,13 +1,7 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 Module Name:\r
 \r
@@ -193,64 +187,85 @@ WinNtWndSize (
   IN  UINT32                        Height\r
 )\r
 {\r
-  UINT32                            Size;\r
-  GRAPHICS_PRIVATE_DATA             *Private;\r
-  RECT                              Rect;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     *NewFillLine;\r
+  RETURN_STATUS                        RStatus;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION Info;\r
+  GRAPHICS_PRIVATE_DATA                *Private;\r
+  RECT                                 Rect;\r
+  BITMAPV4HEADER                       *VirtualScreenInfo;\r
+  FRAME_BUFFER_CONFIGURE               *FrameBufferConfigure;\r
+  UINTN                                FrameBufferConfigureSize;\r
 \r
   Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);\r
-  Private->Width  = Width;\r
-  Private->Height = Height;\r
-\r
-\r
-  //\r
-  // Free the old buffer. We do not save the content of the old buffer since the\r
-  // screen is to be cleared anyway. Clearing the screen is required by the EFI spec.\r
-  // See UEFI spec -EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode()\r
-  //\r
-  if (Private->VirtualScreenInfo != NULL) {\r
-    HeapFree (GetProcessHeap (), 0, Private->VirtualScreenInfo);\r
-  }\r
 \r
   //\r
   // Allocate DIB frame buffer directly from NT for performance enhancement\r
-  // This buffer is the virtual screen/frame buffer. This buffer is not the\r
-  // same a a frame buffer. The first row of this buffer will be the bottom\r
-  // line of the image. This is an artifact of the way we draw to the screen.\r
+  // This buffer is the virtual screen/frame buffer.\r
   //\r
-  Size = Private->Width * Private->Height * sizeof (RGBQUAD) + sizeof (BITMAPV4HEADER);\r
-  Private->VirtualScreenInfo = HeapAlloc (\r
+  VirtualScreenInfo = HeapAlloc (\r
     GetProcessHeap (),\r
     HEAP_ZERO_MEMORY,\r
-    Size\r
+    Width * Height * sizeof (RGBQUAD) + sizeof (BITMAPV4HEADER)\r
   );\r
+  if (VirtualScreenInfo == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
 \r
   //\r
   // Update the virtual screen info data structure\r
+  // Use negative Height to make sure screen/buffer are using the same coordinate.\r
   //\r
-  Private->VirtualScreenInfo->bV4Size = sizeof (BITMAPV4HEADER);\r
-  Private->VirtualScreenInfo->bV4Width = Private->Width;\r
-  Private->VirtualScreenInfo->bV4Height = Private->Height;\r
-  Private->VirtualScreenInfo->bV4Planes = 1;\r
-  Private->VirtualScreenInfo->bV4BitCount = 32;\r
+  VirtualScreenInfo->bV4Size = sizeof (BITMAPV4HEADER);\r
+  VirtualScreenInfo->bV4Width = Width;\r
+  VirtualScreenInfo->bV4Height = -(LONG)Height;\r
+  VirtualScreenInfo->bV4Planes = 1;\r
+  VirtualScreenInfo->bV4BitCount = 32;\r
   //\r
   // uncompressed\r
   //\r
-  Private->VirtualScreenInfo->bV4V4Compression = BI_RGB;\r
+  VirtualScreenInfo->bV4V4Compression = BI_RGB;\r
+\r
+  Info.HorizontalResolution = Width;\r
+  Info.VerticalResolution   = Height;\r
+  Info.PixelFormat          = PixelBlueGreenRedReserved8BitPerColor;\r
+  Info.PixelsPerScanLine    = Width;\r
+  FrameBufferConfigureSize  = 0;\r
+  RStatus = FrameBufferBltConfigure (VirtualScreenInfo + 1, &Info, NULL, &FrameBufferConfigureSize);\r
+  ASSERT (RStatus == EFI_BUFFER_TOO_SMALL);\r
+  FrameBufferConfigure = AllocatePool (FrameBufferConfigureSize);\r
+  if (FrameBufferConfigure == NULL) {\r
+    HeapFree (GetProcessHeap (), 0, VirtualScreenInfo);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  RStatus = FrameBufferBltConfigure (VirtualScreenInfo + 1, &Info, FrameBufferConfigure, &FrameBufferConfigureSize);\r
+  ASSERT_RETURN_ERROR (RStatus);\r
+\r
+\r
+  if (Private->FrameBufferConfigure != NULL) {\r
+    FreePool (Private->FrameBufferConfigure);\r
+  }\r
+  Private->FrameBufferConfigure = FrameBufferConfigure;\r
 \r
   //\r
-  // The rest of the allocated memory block is the virtual screen buffer\r
+  // Free the old buffer. We do not save the content of the old buffer since the\r
+  // screen is to be cleared anyway. Clearing the screen is required by the EFI spec.\r
+  // See UEFI spec -EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode()\r
   //\r
-  Private->VirtualScreen = (RGBQUAD *)(Private->VirtualScreenInfo + 1);\r
+  if (Private->VirtualScreenInfo != NULL) {\r
+    HeapFree (GetProcessHeap (), 0, Private->VirtualScreenInfo);\r
+  }\r
+  Private->VirtualScreenInfo = VirtualScreenInfo;\r
+\r
+  Private->Width  = Width;\r
+  Private->Height = Height;\r
 \r
   //\r
   // Use the AdjuctWindowRect fuction to calculate the real width and height\r
   // of the new window including the border and caption\r
   //\r
-  Rect.left = 0;\r
-  Rect.top = 0;\r
-  Rect.right = Private->Width;\r
-  Rect.bottom = Private->Height;\r
+  Rect.left   = 0;\r
+  Rect.top    = 0;\r
+  Rect.right  = Width;\r
+  Rect.bottom = Height;\r
 \r
   AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0);\r
 \r
@@ -267,16 +282,6 @@ WinNtWndSize (
   //\r
   MoveWindow (Private->WindowHandle, Rect.left, Rect.top, (INT32)Width, (INT32)Height, TRUE);\r
 \r
-  NewFillLine = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * Private->Width);\r
-  if (NewFillLine == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (Private->FillLine != NULL) {\r
-    FreePool (Private->FillLine);\r
-  }\r
-\r
-  Private->FillLine = NewFillLine;\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -292,7 +297,7 @@ WinNtWndSize (
   @param  X                      X location on graphics screen.\r
   @param  Y                      Y location on the graphics screen.\r
   @param  Width                  Width of BltBuffer.\r
-  @param  Height                 Hight of BltBuffer\r
+  @param  Height                 Height of BltBuffer\r
   @param  BltOperation           Operation to perform on BltBuffer and video memory\r
   @param  BltBuffer              Buffer containing data to blt into video buffer.\r
                                  This  buffer has a size of\r
@@ -306,7 +311,7 @@ WinNtWndSize (
 \r
   @retval EFI_SUCCESS            The palette is updated with PaletteArray.\r
   @retval EFI_INVALID_PARAMETER  BltOperation is not valid.\r
-  @retval EFI_DEVICE_ERROR       A hardware error occured writting to the video\r
+  @retval EFI_DEVICE_ERROR       A hardware error occurred writing to the video\r
                                  buffer.\r
 \r
 **/\r
@@ -322,68 +327,22 @@ WinNtWndBlt (
   IN  EMU_GRAPHICS_WINDOWS__BLT_ARGS          *Args\r
 )\r
 {\r
+  RETURN_STATUS                 RStatus;\r
   GRAPHICS_PRIVATE_DATA         *Private;\r
-  UINTN                         DstY;\r
-  UINTN                         SrcY;\r
-  RGBQUAD                       *VScreen;\r
-  RGBQUAD                       *VScreenSrc;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
-  UINTN                         Index;\r
   RECT                          Rect;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *FillPixel;\r
-  UINT32                        VerticalResolution;\r
-  UINT32                        HorizontalResolution;\r
 \r
   Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);\r
-\r
-  //\r
-  // We need to fill the Virtual Screen buffer with the blt data.\r
-  // The virtual screen is upside down, as the first row is the bootom row of\r
-  // the image.\r
-  //\r
-  VerticalResolution = Private->VirtualScreenInfo->bV4Height;\r
-  HorizontalResolution = Private->VirtualScreenInfo->bV4Width;\r
-  if (BltOperation == EfiBltVideoToBltBuffer) {\r
-\r
-    for (SrcY = Args->SourceY, DstY = Args->DestinationY; DstY < (Args->Height + Args->DestinationY); SrcY++, DstY++) {\r
-      Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Args->Delta) + Args->DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
-      VScreen = &Private->VirtualScreen[(VerticalResolution - SrcY - 1) * HorizontalResolution + Args->SourceX];\r
-      CopyMem (Blt, VScreen, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * Args->Width);\r
-    }\r
-  } else {\r
-    if (BltOperation == EfiBltVideoFill) {\r
-      FillPixel = BltBuffer;\r
-      for (Index = 0; Index < Args->Width; Index++) {\r
-        Private->FillLine[Index] = *FillPixel;\r
-      }\r
-    }\r
-\r
-    for (Index = 0; Index < Args->Height; Index++) {\r
-      if (Args->DestinationY <= Args->SourceY) {\r
-        SrcY  = Args->SourceY + Index;\r
-        DstY  = Args->DestinationY + Index;\r
-      } else {\r
-        SrcY  = Args->SourceY + Args->Height - Index - 1;\r
-        DstY  = Args->DestinationY + Args->Height - Index - 1;\r
-      }\r
-\r
-      VScreen = &Private->VirtualScreen[(VerticalResolution - DstY - 1) * HorizontalResolution + Args->DestinationX];\r
-      switch (BltOperation) {\r
-      case EfiBltBufferToVideo:\r
-        Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Args->Delta) + Args->SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
-        CopyMem (VScreen, Blt, Args->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
-        break;\r
-\r
-      case EfiBltVideoToVideo:\r
-        VScreenSrc = &Private->VirtualScreen[(VerticalResolution - SrcY - 1) * HorizontalResolution + Args->SourceX];\r
-        CopyMem (VScreen, VScreenSrc, Args->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
-        break;\r
-\r
-      case EfiBltVideoFill:\r
-        CopyMem (VScreen, Private->FillLine, Args->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
-        break;\r
-      }\r
-    }\r
+  RStatus = FrameBufferBlt (\r
+              Private->FrameBufferConfigure,\r
+              BltBuffer,\r
+              BltOperation,\r
+              Args->SourceX, Args->SourceY,\r
+              Args->DestinationX, Args->DestinationY,\r
+              Args->Width, Args->Height,\r
+              Args->Delta\r
+              );\r
+  if (RETURN_ERROR (RStatus)) {\r
+    return (EFI_STATUS)RStatus;\r
   }\r
 \r
   if (BltOperation != EfiBltVideoToBltBuffer) {\r
@@ -435,20 +394,13 @@ WinNtGopThreadWindowProc (
   )\r
 {\r
   GRAPHICS_PRIVATE_DATA *Private;\r
-  UINTN                 Size;\r
   HDC                   Handle;\r
   PAINTSTRUCT           PaintStruct;\r
   LPARAM                Index;\r
   EFI_INPUT_KEY         Key;\r
   BOOLEAN               AltIsPress;\r
-\r
-  //\r
-  // BugBug - if there are two instances of this DLL in memory (such as is\r
-  // the case for ERM), the correct instance of this function may not be called.\r
-  // This also means that the address of the mTlsIndex value will be wrong, and\r
-  // the value may be wrong too.\r
-  //\r
-\r
+  INT32                 PosX;\r
+  INT32                 PosY;\r
 \r
   //\r
   // Use mTlsIndex global to get a Thread Local Storage version of Private.\r
@@ -460,39 +412,7 @@ WinNtGopThreadWindowProc (
   ASSERT (NULL != Private);\r
 \r
   switch (iMsg) {\r
-  case WM_CREATE:\r
-    Size = Private->Width * Private->Height * sizeof (RGBQUAD);\r
-\r
-    //\r
-    // Allocate DIB frame buffer directly from NT for performance enhancement\r
-    // This buffer is the virtual screen/frame buffer. This buffer is not the\r
-    // same a a frame buffer. The first fow of this buffer will be the bottom\r
-    // line of the image. This is an artifact of the way we draw to the screen.\r
-    //\r
-    Private->VirtualScreenInfo = HeapAlloc (\r
-                                   GetProcessHeap (),\r
-                                   HEAP_ZERO_MEMORY,\r
-                                   Size\r
-                                   );\r
-\r
-    Private->VirtualScreenInfo->bV4Size           = sizeof (BITMAPV4HEADER);\r
-    Private->VirtualScreenInfo->bV4Width          = Private->Width;\r
-    Private->VirtualScreenInfo->bV4Height         = Private->Height;\r
-    Private->VirtualScreenInfo->bV4Planes         = 1;\r
-    Private->VirtualScreenInfo->bV4BitCount       = 32;\r
-    //\r
-    // uncompressed\r
-    //\r
-    Private->VirtualScreenInfo->bV4V4Compression  = BI_RGB;\r
-    Private->VirtualScreen = (RGBQUAD *) (Private->VirtualScreenInfo + 1);\r
-    return 0;\r
-\r
   case WM_PAINT:\r
-    //\r
-    // I have not found a way to convert hwnd into a Private context. So for\r
-    // now we use this API to convert hwnd to Private data.\r
-    //\r
-\r
     Handle = BeginPaint (hwnd, &PaintStruct);\r
 \r
     SetDIBitsToDevice (\r
@@ -505,7 +425,7 @@ WinNtGopThreadWindowProc (
       0,                                          // Source Y\r
       0,                                          // DIB Start Scan Line\r
       Private->Height,                            // Number of scan lines\r
-      Private->VirtualScreen,                     // Address of array of DIB bits\r
+      Private->VirtualScreenInfo + 1,             // Address of array of DIB bits\r
       (BITMAPINFO *) Private->VirtualScreenInfo,  // Address of structure with bitmap info\r
       DIB_RGB_COLORS                              // RGB or palette indexes\r
       );\r
@@ -609,6 +529,45 @@ WinNtGopThreadWindowProc (
     WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE);\r
     return 0;\r
 \r
+  case WM_MOUSEMOVE:\r
+    PosX = GET_X_LPARAM (lParam);\r
+    PosY = GET_Y_LPARAM (lParam);\r
+\r
+    if (Private->PointerPreviousX != PosX) {\r
+      Private->PointerState.RelativeMovementX += (PosX - Private->PointerPreviousX);\r
+      Private->PointerPreviousX                = PosX;\r
+      Private->PointerStateChanged             = TRUE;\r
+    }\r
+\r
+    if (Private->PointerPreviousY != PosY) {\r
+      Private->PointerState.RelativeMovementY += (PosY - Private->PointerPreviousY);\r
+      Private->PointerPreviousY                = PosY;\r
+      Private->PointerStateChanged             = TRUE;\r
+    }\r
+\r
+    Private->PointerState.RelativeMovementZ  = 0;\r
+    return 0;\r
+\r
+  case WM_LBUTTONDOWN:\r
+    Private->PointerState.LeftButton = TRUE;\r
+    Private->PointerStateChanged     = TRUE;\r
+    return 0;\r
+\r
+  case WM_LBUTTONUP:\r
+    Private->PointerState.LeftButton = FALSE;\r
+    Private->PointerStateChanged     = TRUE;\r
+    return 0;\r
+\r
+  case WM_RBUTTONDOWN:\r
+    Private->PointerState.RightButton = TRUE;\r
+    Private->PointerStateChanged      = TRUE;\r
+    return 0;\r
+\r
+  case WM_RBUTTONUP:\r
+    Private->PointerState.RightButton = FALSE;\r
+    Private->PointerStateChanged      = TRUE;\r
+    return 0;\r
+\r
   case WM_CLOSE:\r
     //\r
     // This close message is issued by user, core is not aware of this,\r
@@ -634,11 +593,11 @@ WinNtGopThreadWindowProc (
 \r
 \r
 /**\r
-  This thread simulates the end of WinMain () aplication. Each Winow nededs\r
-  to process it's events. The messages are dispatched to\r
+  This thread simulates the end of WinMain () application. Each Window needs\r
+  to process its events. The messages are dispatched to\r
   WinNtGopThreadWindowProc ().\r
-  Be very careful sine WinNtGopThreadWinMain () and WinNtGopThreadWindowProc ()\r
-  are running in a seperate thread. We have to do this to process the events.\r
+  Be very careful since WinNtGopThreadWinMain () and WinNtGopThreadWindowProc ()\r
+  are running in a separate thread. We have to do this to process the events.\r
 \r
   @param  lpParameter            Handle of window to manage.\r
 \r
@@ -691,10 +650,6 @@ WinNtGopThreadWinMain (
   // This call will fail after the first time, but thats O.K. since we only need\r
   // WIN_NT_GOP_CLASS_NAME to exist to create the window.\r
   //\r
-  // Note: Multiple instances of this DLL will use the same instance of this\r
-  // Class, including the callback function, unless the Class is unregistered and\r
-  // successfully registered again.\r
-  //\r
   RegisterClassEx (&Private->WindowsClass);\r
 \r
   //\r
@@ -724,7 +679,7 @@ WinNtGopThreadWinMain (
                             );\r
 \r
   //\r
-  // The reset of this thread is the standard winows program. We need a sperate\r
+  // The reset of this thread is the standard windows program. We need a separate\r
   // thread since we must process the message loop to make windows act like\r
   // windows.\r
   //\r