]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add WinNtGop driver into Nt32Pkg
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 27 Jun 2007 06:48:58 +0000 (06:48 +0000)
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 27 Jun 2007 06:48:58 +0000 (06:48 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2784 6f19259b-4bc3-4df7-8a09-765794883524

Nt32Pkg/Nt32.dsc
Nt32Pkg/WinNtGopDxe/ComponentName.c [new file with mode: 0644]
Nt32Pkg/WinNtGopDxe/WinNtGop.h [new file with mode: 0644]
Nt32Pkg/WinNtGopDxe/WinNtGop.inf [new file with mode: 0644]
Nt32Pkg/WinNtGopDxe/WinNtGopDriver.c [new file with mode: 0644]
Nt32Pkg/WinNtGopDxe/WinNtGopInput.c [new file with mode: 0644]
Nt32Pkg/WinNtGopDxe/WinNtGopScreen.c [new file with mode: 0644]

index 61b2d83713cdcc9499c99a93a1f59d432b8f2394..28e046fcd20cc57c64a8b7d2129eb2d071d4de7f 100644 (file)
   $(WORKSPACE)\Nt32Pkg\WinNtBusDriverDxe\WinNtBusDriver.inf\r
   $(WORKSPACE)\Nt32Pkg\WinNtConsoleDxe\WinNtConsole.inf\r
   $(WORKSPACE)\Nt32Pkg\WinNtSimpleFileSystemDxe\WinNtSimpleFileSystem.inf\r
   $(WORKSPACE)\Nt32Pkg\WinNtBusDriverDxe\WinNtBusDriver.inf\r
   $(WORKSPACE)\Nt32Pkg\WinNtConsoleDxe\WinNtConsole.inf\r
   $(WORKSPACE)\Nt32Pkg\WinNtSimpleFileSystemDxe\WinNtSimpleFileSystem.inf\r
+  $(WORKSPACE)\Nt32Pkg\WinNtGopDxe\WinNtGop.inf\r
diff --git a/Nt32Pkg/WinNtGopDxe/ComponentName.c b/Nt32Pkg/WinNtGopDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..952db00
--- /dev/null
@@ -0,0 +1,224 @@
+/** @file\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. 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
+\r
+Module Name:\r
+\r
+  ComponentName.c\r
+\r
+Abstract:\r
+\r
+\r
+**/\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <Uefi.h>\r
+#include <WinNtDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/EventGroup.h>\r
+#include <Protocol/WinNtIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/SimpleTextIn.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include "WinNtGop.h"\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  );\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL     gWinNtGopComponentName = {\r
+  WinNtGopComponentNameGetDriverName,\r
+  WinNtGopComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+static EFI_UNICODE_STRING_TABLE mWinNtGopDriverNameTable[] = {\r
+  { "eng", L"Windows GOP Driver" },\r
+  { NULL , NULL }\r
+};\r
+\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+  @param  This                   A pointer to the EFI_COMPONENT_NAME_PROTOCOL\r
+                                 instance.\r
+  @param  Language               A pointer to a three character ISO 639-2 language\r
+                                 identifier. This is the language of the driver\r
+                                 name that that the caller  is requesting, and it\r
+                                 must match one of the languages specified in\r
+                                 SupportedLanguages.  The number of languages\r
+                                 supported by a  driver is up to the driver writer.\r
+  @param  DriverName             A pointer to the Unicode string to return.  This\r
+                                 Unicode string is the name of the driver specified\r
+                                 by This in the language  specified by Language.\r
+\r
+  @retval EFI_SUCCESS            The Unicode string for the Driver specified by\r
+                                 This and the language specified by Language was\r
+                                 returned  in DriverName.\r
+  @retval EFI_INVALID_PARAMETER  Language is NULL.\r
+  @retval EFI_INVALID_PARAMETER  DriverName is NULL.\r
+  @retval EFI_UNSUPPORTED        The driver specified by This does not support the\r
+                                 language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  )\r
+{\r
+  return LookupUnicodeString (\r
+          Language,\r
+          gWinNtGopComponentName.SupportedLanguages,\r
+          mWinNtGopDriverNameTable,\r
+          DriverName\r
+          );\r
+}\r
+\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by an EFI Driver.\r
+\r
+  @param  This                   A pointer to the EFI_COMPONENT_NAME_PROTOCOL\r
+                                 instance.\r
+  @param  ControllerHandle       The handle of a controller that the driver\r
+                                 specified by  This is managing.  This handle\r
+                                 specifies the controller  whose name is to be\r
+                                 returned.\r
+  @param  ChildHandle            The handle of the child controller to retrieve the\r
+                                 name  of.  This is an optional parameter that may\r
+                                 be NULL.  It  will be NULL for device drivers.  It\r
+                                 will also be NULL  for a bus drivers that wish to\r
+                                 retrieve the name of the  bus controller.  It will\r
+                                 not be NULL for a bus driver  that wishes to\r
+                                 retrieve the name of a child controller.\r
+  @param  Language               A pointer to a three character ISO 639-2 language\r
+                                 identifier.  This is the language of the\r
+                                 controller name  that that the caller is\r
+                                 requesting, and it must match one of the languages\r
+                                 specified in SupportedLanguages.  The  number of\r
+                                 languages supported by a driver is up to the\r
+                                 driver writer.\r
+  @param  ControllerName         A pointer to the Unicode string to return.  This\r
+                                 Unicode string is the name of the controller\r
+                                 specified by  ControllerHandle and ChildHandle in\r
+                                 the language specified by Language from the point\r
+                                 of view of the driver specified by This.\r
+\r
+  @retval EFI_SUCCESS            The Unicode string for the user readable name in\r
+                                 the  language specified by Language for the driver\r
+                                  specified by This was returned in DriverName.\r
+  @retval EFI_INVALID_PARAMETER  ControllerHandle is not a valid EFI_HANDLE.\r
+  @retval EFI_INVALID_PARAMETER  ChildHandle is not NULL and it is not a valid\r
+                                 EFI_HANDLE.\r
+  @retval EFI_INVALID_PARAMETER  Language is NULL.\r
+  @retval EFI_INVALID_PARAMETER  ControllerName is NULL.\r
+  @retval EFI_UNSUPPORTED        The driver specified by This is not currently\r
+                                 managing  the controller specified by\r
+                                 ControllerHandle and  ChildHandle.\r
+  @retval EFI_UNSUPPORTED        The driver specified by This does not support the\r
+                                 language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+  GOP_PRIVATE_DATA             *Private;\r
+\r
+  //\r
+  // This is a device driver, so ChildHandle must be NULL.\r
+  //\r
+  if (ChildHandle != NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Make sure this driver is currently managing ControllerHandle\r
+  //\r
+  Status = EfiTestManagedDevice (\r
+             ControllerHandle,\r
+             gWinNtGopDriverBinding.DriverBindingHandle,\r
+             &gEfiWinNtIoProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Get our context back\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  &GraphicsOutput,\r
+                  gWinNtGopDriverBinding.DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput);\r
+\r
+  return LookupUnicodeString (\r
+          Language,\r
+          gWinNtGopComponentName.SupportedLanguages,\r
+          Private->ControllerNameTable,\r
+          ControllerName\r
+          );\r
+}\r
diff --git a/Nt32Pkg/WinNtGopDxe/WinNtGop.h b/Nt32Pkg/WinNtGopDxe/WinNtGop.h
new file mode 100644 (file)
index 0000000..cc7283e
--- /dev/null
@@ -0,0 +1,326 @@
+/** @file\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. 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
+\r
+Module Name:\r
+\r
+  WinNtGop.h\r
+\r
+Abstract:\r
+\r
+  Private data for the Gop driver that is bound to the WinNt Thunk protocol\r
+\r
+\r
+**/\r
+\r
+#ifndef _WIN_NT_GOP_H_\r
+#define _WIN_NT_GOP_H_\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+//@MT:#include "EfiWinNT.h"\r
+//@MT:#include "Tiano.h"\r
+//@MT:#include "EfiDriverLib.h"\r
+\r
+//\r
+// Driver Consumed Protocols\r
+//\r
+//@MT:#include EFI_PROTOCOL_DEFINITION (DevicePath)\r
+//@MT:#include EFI_PROTOCOL_DEFINITION (WinNtIo)\r
+\r
+//\r
+// Driver Produced Protocols\r
+//\r
+//@MT:#include EFI_PROTOCOL_DEFINITION (DriverBinding)\r
+//@MT:#include EFI_PROTOCOL_DEFINITION (ComponentName)\r
+//@MT:#include EFI_PROTOCOL_DEFINITION (GraphicsOutput)\r
+//@MT:#include "LinkedList.h"\r
+\r
+#define MAX_Q 256\r
+\r
+typedef struct {\r
+  UINTN         Front;\r
+  UINTN         Rear;\r
+  UINTN         Count;\r
+  EFI_INPUT_KEY Q[MAX_Q];\r
+} GOP_QUEUE_FIXED;\r
+\r
+#define WIN_NT_GOP_CLASS_NAME       L"WinNtGopWindow"\r
+\r
+#define GOP_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('S', 'g', 'o', 'N')\r
+\r
+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff\r
+\r
+typedef struct {\r
+  UINT32                     HorizontalResolution;\r
+  UINT32                     VerticalResolution;\r
+  UINT32                     ColorDepth;\r
+  UINT32                     RefreshRate;\r
+} GOP_MODE_DATA;\r
+\r
+typedef struct {\r
+  UINT64                        Signature;\r
+\r
+  EFI_HANDLE                    Handle;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  GraphicsOutput;\r
+  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   SimpleTextIn;\r
+\r
+  EFI_WIN_NT_THUNK_PROTOCOL     *WinNtThunk;\r
+\r
+  EFI_UNICODE_STRING_TABLE      *ControllerNameTable;\r
+\r
+  //\r
+  // GOP Private Data for QueryMode ()\r
+  //\r
+  GOP_MODE_DATA                 *ModeData;\r
+\r
+  //\r
+  // GOP Private Data knowing when to start hardware\r
+  //\r
+  BOOLEAN                       HardwareNeedsStarting;\r
+\r
+  CHAR16                        *WindowName;\r
+  CHAR16                        Buffer[160];\r
+\r
+  HANDLE                        ThreadInited; // Semaphore\r
+  HANDLE                        ThreadHandle; // Thread\r
+  DWORD                         ThreadId;\r
+\r
+  HWND                          WindowHandle;\r
+  WNDCLASSEX                    WindowsClass;\r
+\r
+  //\r
+  // This screen is used to redraw the scree when windows events happen. It's\r
+  // updated in the main thread and displayed in the windows thread.\r
+  //\r
+  BITMAPV4HEADER                *VirtualScreenInfo;\r
+  RGBQUAD                       *VirtualScreen;\r
+\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *FillLine;\r
+\r
+  //\r
+  // Keyboard Queue used by Simple Text In. WinProc thread adds, and main\r
+  // thread removes.\r
+  //\r
+  CRITICAL_SECTION              QCriticalSection;\r
+  GOP_QUEUE_FIXED               Queue;\r
+\r
+} GOP_PRIVATE_DATA;\r
+\r
+#define GOP_PRIVATE_DATA_FROM_THIS(a)  \\r
+         CR(a, GOP_PRIVATE_DATA, GraphicsOutput, GOP_PRIVATE_DATA_SIGNATURE)\r
+\r
+#define GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS(a)  \\r
+         CR(a, GOP_PRIVATE_DATA, SimpleTextIn, GOP_PRIVATE_DATA_SIGNATURE)\r
+\r
+//\r
+// Global Protocol Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL  gWinNtGopDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL  gWinNtGopComponentName;\r
+\r
+//\r
+// Gop Hardware abstraction internal worker functions\r
+//\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  WinNtIo              TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtGopSupported (\r
+  IN  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private              TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtGopConstructor (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private              TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtGopDestructor (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  )\r
+;\r
+\r
+//\r
+// EFI 1.1 driver model prototypes for Win NT GOP\r
+//\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  ImageHandle          TODO: add argument description\r
+  @param  SystemTable          TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopInitialize (\r
+  IN EFI_HANDLE            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE      *SystemTable\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  This                 TODO: add argument description\r
+  @param  Handle               TODO: add argument description\r
+  @param  RemainingDevicePath  TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopDriverBindingSupported (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      Handle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  This                 TODO: add argument description\r
+  @param  Handle               TODO: add argument description\r
+  @param  RemainingDevicePath  TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopDriverBindingStart (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      Handle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  This                 TODO: add argument description\r
+  @param  Handle               TODO: add argument description\r
+  @param  NumberOfChildren     TODO: add argument description\r
+  @param  ChildHandleBuffer    TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  UINTN                        NumberOfChildren,\r
+  IN  EFI_HANDLE                   *ChildHandleBuffer\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private              TODO: add argument description\r
+  @param  Key                  TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+GopPrivateAddQ (\r
+  IN  GOP_PRIVATE_DATA    *Private,\r
+  IN  EFI_INPUT_KEY       Key\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private              TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtGopInitializeSimpleTextInForWindow (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private              TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtGopDestroySimpleTextInForWindow (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  String               TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+UINTN\r
+Atoi (\r
+  IN  CHAR16  *String\r
+  )\r
+;\r
+\r
+#endif\r
diff --git a/Nt32Pkg/WinNtGopDxe/WinNtGop.inf b/Nt32Pkg/WinNtGopDxe/WinNtGop.inf
new file mode 100644 (file)
index 0000000..7130ba3
--- /dev/null
@@ -0,0 +1,119 @@
+#/** @file\r
+# Gop Driver\r
+#\r
+# GOP is short hand for UEFI Graphics Output protocol.\r
+#  This file is a verision of GopIo the uses WinNtThunk system calls as an IO\r
+#  abstraction. For a PCI device WinNtIo would be replaced with\r
+#  a PCI IO abstraction that abstracted a specific PCI device.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. 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
+#  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
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = WinNtGop\r
+  FILE_GUID                      = 29b3c4c6-e5aa-49e4-8ce0-2772f782ddc2\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = InitializeWinNtGop\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32\r
+#\r
+#  DRIVER_BINDING                =  gWinNtGopDriverBinding                       \r
+#  COMPONENT_NAME                =  gWinNtGopComponentName                       \r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  WinNtGopDriver.c\r
+  ComponentName.c\r
+  WinNtGop.h\r
+  WinNtGopInput.c\r
+  WinNtGopScreen.c\r
+\r
+################################################################################\r
+#\r
+# Includes Section - list of Include locations that are required for\r
+#                    this module.\r
+#\r
+################################################################################\r
+\r
+[Includes]\r
+  $(WORKSPACE)/MdePkg/Include/Library\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  Nt32Pkg/Nt32Pkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  UefiLib\r
+  UefiDriverEntryPoint\r
+  BaseLib\r
+  DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+  gEfiEventExitBootServicesGuid                 # SOMETIMES_CONSUMED  Create Event: EVENT_GROUP_GUID\r
+  gEfiWinNtGopGuid                              # ALWAYS_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiGraphicsOutputProtocolGuid                # PROTOCOL BY_START\r
+  gEfiSimpleTextInProtocolGuid                  # PROTOCOL BY_START\r
+  gEfiWinNtIoProtocolGuid                       # PROTOCOL TO_START\r
+\r
diff --git a/Nt32Pkg/WinNtGopDxe/WinNtGopDriver.c b/Nt32Pkg/WinNtGopDxe/WinNtGopDriver.c
new file mode 100644 (file)
index 0000000..86b6d19
--- /dev/null
@@ -0,0 +1,378 @@
+/** @file\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. 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
+\r
+Module Name:\r
+\r
+  WinNtGopDriver.c\r
+\r
+Abstract:\r
+\r
+  This file implements the UEFI Device Driver model requirements for GOP\r
+\r
+  GOP is short hand for Graphics Output Protocol.\r
+\r
+\r
+**/\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <Uefi.h>\r
+#include <WinNtDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/EventGroup.h>\r
+#include <Protocol/WinNtIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/SimpleTextIn.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include "WinNtGop.h"\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gWinNtGopDriverBinding = {\r
+  WinNtGopDriverBindingSupported,\r
+  WinNtGopDriverBindingStart,\r
+  WinNtGopDriverBindingStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+/**\r
+  The user Entry Point for module WinNtGop. The user code starts with this function.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeWinNtGop(\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+\r
+  //\r
+  // Install driver model protocol(s).\r
+  //\r
+  Status = EfiLibInstallAllDriverProtocols (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gWinNtGopDriverBinding,\r
+             ImageHandle,\r
+             &gWinNtGopComponentName,\r
+             NULL,\r
+             NULL\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+\r
+\r
+  @return None\r
+\r
+**/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Handle - add argument and description to function comment\r
+// TODO:    RemainingDevicePath - add argument and description to function comment\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopDriverBindingSupported (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      Handle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;\r
+\r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Handle,\r
+                  &gEfiWinNtIoProtocolGuid,\r
+                  &WinNtIo,\r
+                  This->DriverBindingHandle,\r
+                  Handle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WinNtGopSupported (WinNtIo);\r
+\r
+  //\r
+  // Close the I/O Abstraction(s) used to perform the supported test\r
+  //\r
+  gBS->CloseProtocol (\r
+        Handle,\r
+        &gEfiWinNtIoProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Handle\r
+        );\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+\r
+\r
+  @return None\r
+\r
+**/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Handle - add argument and description to function comment\r
+// TODO:    RemainingDevicePath - add argument and description to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopDriverBindingStart (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      Handle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
+  )\r
+{\r
+  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;\r
+  EFI_STATUS              Status;\r
+  GOP_PRIVATE_DATA        *Private;\r
+\r
+  //\r
+  // Grab the protocols we need\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Handle,\r
+                  &gEfiWinNtIoProtocolGuid,\r
+                  &WinNtIo,\r
+                  This->DriverBindingHandle,\r
+                  Handle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Allocate Private context data for SGO inteface.\r
+  //\r
+  Private = NULL;\r
+  Private = AllocatePool (sizeof (GOP_PRIVATE_DATA));\r
+  if (Private == NULL) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // Set up context record\r
+  //\r
+  Private->Signature            = GOP_PRIVATE_DATA_SIGNATURE;\r
+  Private->Handle               = Handle;\r
+  Private->WinNtThunk           = WinNtIo->WinNtThunk;\r
+\r
+  Private->ControllerNameTable  = NULL;\r
+\r
+  AddUnicodeString (\r
+    "eng",\r
+    gWinNtGopComponentName.SupportedLanguages,\r
+    &Private->ControllerNameTable,\r
+    WinNtIo->EnvString\r
+    );\r
+\r
+  Private->WindowName = WinNtIo->EnvString;\r
+\r
+  Status              = WinNtGopConstructor (Private);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // Publish the Gop interface to the world\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Private->Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  &Private->GraphicsOutput,\r
+                  &gEfiSimpleTextInProtocolGuid,\r
+                  &Private->SimpleTextIn,\r
+                  NULL\r
+                  );\r
+\r
+Done:\r
+  if (EFI_ERROR (Status)) {\r
+\r
+    gBS->CloseProtocol (\r
+          Handle,\r
+          &gEfiWinNtIoProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          Handle\r
+          );\r
+\r
+    if (Private != NULL) {\r
+      //\r
+      // On Error Free back private data\r
+      //\r
+      if (Private->ControllerNameTable != NULL) {\r
+        FreeUnicodeStringTable (Private->ControllerNameTable);\r
+      }\r
+\r
+      FreePool (Private);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+\r
+\r
+  @return None\r
+\r
+**/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Handle - add argument and description to function comment\r
+// TODO:    NumberOfChildren - add argument and description to function comment\r
+// TODO:    ChildHandleBuffer - add argument and description to function comment\r
+// TODO:    EFI_NOT_STARTED - add return value to function comment\r
+// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  UINTN                        NumberOfChildren,\r
+  IN  EFI_HANDLE                   *ChildHandleBuffer\r
+  )\r
+{\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+  EFI_STATUS                   Status;\r
+  GOP_PRIVATE_DATA             *Private;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  &GraphicsOutput,\r
+                  This->DriverBindingHandle,\r
+                  Handle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // If the GOP interface does not exist the driver is not started\r
+    //\r
+    return EFI_NOT_STARTED;\r
+  }\r
+\r
+  //\r
+  // Get our private context information\r
+  //\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput);\r
+\r
+  //\r
+  // Remove the SGO interface from the system\r
+  //\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  Private->Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  &Private->GraphicsOutput,\r
+                  &gEfiSimpleTextInProtocolGuid,\r
+                  &Private->SimpleTextIn,\r
+                  NULL\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Shutdown the hardware\r
+    //\r
+    Status = WinNtGopDestructor (Private);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    gBS->CloseProtocol (\r
+          Handle,\r
+          &gEfiWinNtIoProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          Handle\r
+          );\r
+\r
+    //\r
+    // Free our instance data\r
+    //\r
+    FreeUnicodeStringTable (Private->ControllerNameTable);\r
+\r
+    FreePool (Private);\r
+\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Convert a unicode string to a UINTN\r
+\r
+  @param  String  Unicode string.\r
+\r
+  @return UINTN of the number represented by String.\r
+\r
+**/\r
+UINTN\r
+Atoi (\r
+  CHAR16  *String\r
+  )\r
+{\r
+  UINTN   Number;\r
+  CHAR16  *Str;\r
+\r
+  //\r
+  // skip preceeding white space\r
+  //\r
+  Str = String;\r
+  while ((*Str) && (*Str == ' ' || *Str == '"')) {\r
+    Str++;\r
+  }\r
+\r
+  //\r
+  // Convert ot a Number\r
+  //\r
+  Number = 0;\r
+  while (*Str != '\0') {\r
+    if ((*Str >= '0') && (*Str <= '9')) {\r
+      Number = (Number * 10) +*Str - '0';\r
+    } else {\r
+      break;\r
+    }\r
+\r
+    Str++;\r
+  }\r
+\r
+  return Number;\r
+}\r
diff --git a/Nt32Pkg/WinNtGopDxe/WinNtGopInput.c b/Nt32Pkg/WinNtGopDxe/WinNtGopInput.c
new file mode 100644 (file)
index 0000000..a604dad
--- /dev/null
@@ -0,0 +1,377 @@
+/** @file\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. 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
+\r
+Module Name:\r
+\r
+  WinNtGopInput.c\r
+\r
+Abstract:\r
+\r
+  This file produces the Simple Text In for an Gop window.\r
+\r
+  This stuff is linked at the hip to the Window, since the window\r
+  processing is done in a thread kicked off in WinNtGopImplementation.c\r
+\r
+  Since the window information is processed in an other thread we need\r
+  a keyboard Queue to pass data about. The Simple Text In code just\r
+  takes data off the Queue. The WinProc message loop takes keyboard input\r
+  and places it in the Queue.\r
+\r
+\r
+**/\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <Uefi.h>\r
+#include <WinNtDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/EventGroup.h>\r
+#include <Protocol/WinNtIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/SimpleTextIn.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include "WinNtGop.h"\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private               TODO: add argument description\r
+\r
+  @retval EFI_SUCCESS           TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+GopPrivateCreateQ (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  Private->WinNtThunk->InitializeCriticalSection (&Private->QCriticalSection);\r
+\r
+  Private->Queue.Front  = 0;\r
+  Private->Queue.Rear   = MAX_Q - 1;\r
+  Private->Queue.Count  = 0;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private               TODO: add argument description\r
+\r
+  @retval EFI_SUCCESS           TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+GopPrivateDestroyQ (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  Private->Queue.Count = 0;\r
+  Private->WinNtThunk->DeleteCriticalSection (&Private->QCriticalSection);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private               TODO: add argument description\r
+  @param  Key                   TODO: add argument description\r
+\r
+  @retval EFI_NOT_READY         TODO: Add description for return value\r
+  @retval EFI_SUCCESS           TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+GopPrivateAddQ (\r
+  IN  GOP_PRIVATE_DATA    *Private,\r
+  IN  EFI_INPUT_KEY       Key\r
+  )\r
+{\r
+  Private->WinNtThunk->EnterCriticalSection (&Private->QCriticalSection);\r
+\r
+  if (Private->Queue.Count == MAX_Q) {\r
+    Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  Private->Queue.Rear                   = (Private->Queue.Rear + 1) % MAX_Q;\r
+  Private->Queue.Q[Private->Queue.Rear] = Key;\r
+  Private->Queue.Count++;\r
+\r
+  Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private               TODO: add argument description\r
+  @param  Key                   TODO: add argument description\r
+\r
+  @retval EFI_NOT_READY         TODO: Add description for return value\r
+  @retval EFI_SUCCESS           TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+GopPrivateDeleteQ (\r
+  IN  GOP_PRIVATE_DATA    *Private,\r
+  OUT EFI_INPUT_KEY       *Key\r
+  )\r
+{\r
+  Private->WinNtThunk->EnterCriticalSection (&Private->QCriticalSection);\r
+\r
+  if (Private->Queue.Count == 0) {\r
+    Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  *Key                  = Private->Queue.Q[Private->Queue.Front];\r
+  Private->Queue.Front  = (Private->Queue.Front + 1) % MAX_Q;\r
+  Private->Queue.Count--;\r
+\r
+  Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private               TODO: add argument description\r
+\r
+  @retval EFI_NOT_READY         TODO: Add description for return value\r
+  @retval EFI_SUCCESS           TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+GopPrivateCheckQ (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  if (Private->Queue.Count == 0) {\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// Simple Text In implementation.\r
+//\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  This                  TODO: add argument description\r
+  @param  ExtendedVerification  TODO: add argument description\r
+\r
+  @retval EFI_SUCCESS           TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInReset (\r
+  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL          *This,\r
+  IN BOOLEAN                              ExtendedVerification\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+  EFI_INPUT_KEY     Key;\r
+  EFI_TPL           OldTpl;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
+\r
+  //\r
+  // Enter critical section\r
+  //\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+  //\r
+  // A reset is draining the Queue\r
+  //\r
+  while (GopPrivateDeleteQ (Private, &Key) == EFI_SUCCESS)\r
+    ;\r
+\r
+  //\r
+  // Leave critical section and return\r
+  //\r
+  gBS->RestoreTPL (OldTpl);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  This                  TODO: add argument description\r
+  @param  Key                   TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInReadKeyStroke (\r
+  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL          *This,\r
+  OUT EFI_INPUT_KEY                       *Key\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+  EFI_STATUS        Status;\r
+  EFI_TPL           OldTpl;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
+\r
+  //\r
+  // Enter critical section\r
+  //\r
+  OldTpl  = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+  Status  = GopPrivateCheckQ (Private);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // If a Key press exists try and read it.\r
+    //\r
+    Status = GopPrivateDeleteQ (Private, Key);\r
+  }\r
+\r
+  //\r
+  // Leave critical section and return\r
+  //\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Event                 TODO: add argument description\r
+  @param  Context               TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+WinNtGopSimpleTextInWaitForKey (\r
+  IN EFI_EVENT          Event,\r
+  IN VOID               *Context\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+  EFI_STATUS        Status;\r
+  EFI_TPL           OldTpl;\r
+\r
+  Private = (GOP_PRIVATE_DATA *) Context;\r
+\r
+  //\r
+  // Enter critical section\r
+  //\r
+  OldTpl  = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+  Status  = GopPrivateCheckQ (Private);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // If a there is a key in the queue signal our event.\r
+    //\r
+    gBS->SignalEvent (Event);\r
+  } else {\r
+    //\r
+    // We need to sleep or NT will schedule this thread with such high\r
+    // priority that WinProc thread will never run and we will not see\r
+    // keyboard input. This Sleep makes the syste run 10x faster, so don't\r
+    // remove it.\r
+    //\r
+    Private->WinNtThunk->Sleep (1);\r
+  }\r
+\r
+  //\r
+  // Leave critical section and return\r
+  //\r
+  gBS->RestoreTPL (OldTpl);\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private               TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtGopInitializeSimpleTextInForWindow (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  GopPrivateCreateQ (Private);\r
+\r
+  //\r
+  // Initialize Simple Text In protoocol\r
+  //\r
+  Private->SimpleTextIn.Reset         = WinNtGopSimpleTextInReset;\r
+  Private->SimpleTextIn.ReadKeyStroke = WinNtGopSimpleTextInReadKeyStroke;\r
+\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_WAIT,\r
+                  TPL_NOTIFY,\r
+                  WinNtGopSimpleTextInWaitForKey,\r
+                  Private,\r
+                  &Private->SimpleTextIn.WaitForKey\r
+                  );\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private               TODO: add argument description\r
+\r
+  @retval EFI_SUCCESS           TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtGopDestroySimpleTextInForWindow (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  GopPrivateDestroyQ (Private);\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/Nt32Pkg/WinNtGopDxe/WinNtGopScreen.c b/Nt32Pkg/WinNtGopDxe/WinNtGopScreen.c
new file mode 100644 (file)
index 0000000..e027071
--- /dev/null
@@ -0,0 +1,1020 @@
+/** @file\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. 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
+\r
+Module Name:\r
+\r
+    WinNtGopScreen.c\r
+\r
+Abstract:\r
+\r
+  This file produces the graphics abstration of GOP. It is called by\r
+  WinNtGopDriver.c file which deals with the EFI 1.1 driver model.\r
+  This file just does graphics.\r
+\r
+\r
+**/\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <Uefi.h>\r
+#include <WinNtDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/EventGroup.h>\r
+#include <Protocol/WinNtIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/SimpleTextIn.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include "WinNtGop.h"\r
+\r
+EFI_WIN_NT_THUNK_PROTOCOL *mWinNt;\r
+DWORD                     mTlsIndex         = TLS_OUT_OF_INDEXES;\r
+DWORD                     mTlsIndexUseCount = 0;  // lets us know when we can free mTlsIndex.\r
+static EFI_EVENT          mGopScreenExitBootServicesEvent;\r
+GOP_MODE_DATA mGopModeData[] = {\r
+    {800, 600, 0, 0},\r
+    {640, 480, 0, 0},\r
+    {720, 400, 0, 0},\r
+    {1024, 768, 0, 0},\r
+    {1280, 1024, 0, 0}\r
+    };\r
+\r
+EFI_STATUS\r
+WinNtGopStartWindow (\r
+  IN  GOP_PRIVATE_DATA    *Private,\r
+  IN  UINT32              HorizontalResolution,\r
+  IN  UINT32              VerticalResolution,\r
+  IN  UINT32              ColorDepth,\r
+  IN  UINT32              RefreshRate\r
+  );\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+KillNtGopThread (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  );\r
+\r
+//\r
+// GOP Protocol Member Functions\r
+//\r
+\r
+\r
+/**\r
+  Graphics Output protocol interface to get video mode\r
+\r
+  @param  This                   Protocol instance pointer.\r
+  @param  ModeNumber             The mode number to return information on.\r
+  @param  Info                   Caller allocated buffer that returns information\r
+                                 about ModeNumber.\r
+  @param  SizeOfInfo             A pointer to the size, in bytes, of the Info\r
+                                 buffer.\r
+\r
+  @retval EFI_SUCCESS            Mode information returned.\r
+  @retval EFI_BUFFER_TOO_SMALL   The Info buffer was too small.\r
+  @retval EFI_DEVICE_ERROR       A hardware error occurred trying to retrieve the\r
+                                 video mode.\r
+  @retval EFI_NOT_STARTED        Video display is not initialized. Call SetMode ()\r
+  @retval EFI_INVALID_PARAMETER  One of the input args was NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopQuerytMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,\r
+  IN  UINT32                                ModeNumber,\r
+  OUT UINTN                                 *SizeOfInfo,\r
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (Info == NULL || SizeOfInfo == NULL || (UINTN) ModeNumber >= This->Mode->MaxMode) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+  if (*Info == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+\r
+  (*Info)->Version = 0;\r
+  (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;\r
+  (*Info)->VerticalResolution   = Private->ModeData[ModeNumber].VerticalResolution;\r
+  (*Info)->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
+  (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Graphics Output protocol interface to set video mode\r
+\r
+  @param  This                   Protocol instance pointer.\r
+  @param  ModeNumber             The mode number to be set.\r
+\r
+  @retval EFI_SUCCESS            Graphics mode was changed.\r
+  @retval EFI_DEVICE_ERROR       The device had an error and could not complete the\r
+                                 request.\r
+  @retval EFI_UNSUPPORTED        ModeNumber is not supported by this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSetMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL * This,\r
+  IN  UINT32                       ModeNumber\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  GOP_PRIVATE_DATA              *Private;\r
+  GOP_MODE_DATA *ModeData;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewFillLine;\r
+  RECT                          Rect;\r
+  UINTN                         Size;\r
+  UINTN                         Width;\r
+  UINTN                         Height;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (ModeNumber >= This->Mode->MaxMode) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (ModeNumber == This->Mode->Mode) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  ModeData = &Private->ModeData[ModeNumber];\r
+  This->Mode->Mode = ModeNumber;\r
+  Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
+  Private->GraphicsOutput.Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
+  Private->GraphicsOutput.Mode->Info->PixelsPerScanLine = ModeData->HorizontalResolution;\r
+\r
+  if (Private->HardwareNeedsStarting) {\r
+    Status = WinNtGopStartWindow (\r
+              Private,\r
+              ModeData->HorizontalResolution,\r
+              ModeData->VerticalResolution,\r
+              ModeData->ColorDepth,\r
+              ModeData->RefreshRate\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    Private->HardwareNeedsStarting = FALSE;\r
+  } else {\r
+    //\r
+    // Change the resolution and resize of the window\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
+    Private->WinNtThunk->HeapFree (Private->WinNtThunk->GetProcessHeap (), 0, Private->VirtualScreenInfo);\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
+    //\r
+    Size = ModeData->HorizontalResolution * ModeData->VerticalResolution * sizeof (RGBQUAD) + sizeof (BITMAPV4HEADER);\r
+    Private->VirtualScreenInfo = Private->WinNtThunk->HeapAlloc (\r
+                                                        Private->WinNtThunk->GetProcessHeap (),\r
+                                                        HEAP_ZERO_MEMORY,\r
+                                                        Size\r
+                                                        );\r
+\r
+    //\r
+    // Update the virtual screen info data structure\r
+    //\r
+    Private->VirtualScreenInfo->bV4Size           = sizeof (BITMAPV4HEADER);\r
+    Private->VirtualScreenInfo->bV4Width          = ModeData->HorizontalResolution;\r
+    Private->VirtualScreenInfo->bV4Height         = ModeData->VerticalResolution;\r
+    Private->VirtualScreenInfo->bV4Planes         = 1;\r
+    Private->VirtualScreenInfo->bV4BitCount       = 32;\r
+    //\r
+    // uncompressed\r
+    //\r
+    Private->VirtualScreenInfo->bV4V4Compression  = BI_RGB;\r
+\r
+    //\r
+    // The rest of the allocated memory block is the virtual screen buffer\r
+    //\r
+    Private->VirtualScreen = (RGBQUAD *) (Private->VirtualScreenInfo + 1);\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  = ModeData->HorizontalResolution;\r
+    Rect.bottom = ModeData->VerticalResolution;\r
+\r
+    Private->WinNtThunk->AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0);\r
+\r
+    Width   = Rect.right - Rect.left;\r
+    Height  = Rect.bottom - Rect.top;\r
+\r
+    //\r
+    // Retrieve the original window position information\r
+    //\r
+    Private->WinNtThunk->GetWindowRect (Private->WindowHandle, &Rect);\r
+\r
+    //\r
+    // Adjust the window size\r
+    //\r
+    Private->WinNtThunk->MoveWindow (Private->WindowHandle, Rect.left, Rect.top, Width, Height, TRUE);\r
+\r
+  }\r
+\r
+  NewFillLine = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->HorizontalResolution);\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
+\r
+  Fill.Red                      = 0x00;\r
+  Fill.Green                    = 0x00;\r
+  Fill.Blue                     = 0x00;\r
+  This->Blt (\r
+          This,\r
+          &Fill,\r
+          EfiBltVideoFill,\r
+          0,\r
+          0,\r
+          0,\r
+          0,\r
+          ModeData->HorizontalResolution,\r
+          ModeData->VerticalResolution,\r
+          ModeData->HorizontalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+          );\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Blt pixels from the rectangle (Width X Height) formed by the BltBuffer\r
+  onto the graphics screen starting a location (X, Y). (0, 0) is defined as\r
+  the upper left hand side of the screen. (X, Y) can be outside of the\r
+  current screen geometry and the BltBuffer will be cliped when it is\r
+  displayed. X and Y can be negative or positive. If Width or Height is\r
+  bigger than the current video screen the image will be clipped.\r
+\r
+  @param  This                   Protocol instance pointer.\r
+  @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  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
+                                 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+  @param  SourceX                If the BltOperation is a EfiCopyBlt this is the\r
+                                 source of the copy. For other BLT operations this\r
+                                 argument is not used.\r
+  @param  SourceX                If the BltOperation is a EfiCopyBlt this is the\r
+                                 source of the copy. For other BLT operations this\r
+                                 argument is not used.\r
+\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
+                                 buffer.\r
+\r
+**/\r
+// TODO:    SourceY - add argument and description to function comment\r
+// TODO:    DestinationX - add argument and description to function comment\r
+// TODO:    DestinationY - add argument and description to function comment\r
+// TODO:    Delta - add argument and description to function comment\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopBlt (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL                   *This,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL                           *BltBuffer, OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION                   BltOperation,\r
+  IN  UINTN                                   SourceX,\r
+  IN  UINTN                                   SourceY,\r
+  IN  UINTN                                   DestinationX,\r
+  IN  UINTN                                   DestinationY,\r
+  IN  UINTN                                   Width,\r
+  IN  UINTN                                   Height,\r
+  IN  UINTN                                   Delta         OPTIONAL\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA              *Private;\r
+  EFI_TPL                       OriginalTPL;\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 = GOP_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if ((BltOperation < 0) || (BltOperation >= EfiGraphicsOutputBltOperationMax)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,\r
+  // the number of bytes in each row can be computed.\r
+  //\r
+  if (Delta == 0) {\r
+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
+  }\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 = This->Mode->Info->VerticalResolution;\r
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
+  if (BltOperation == EfiBltVideoToBltBuffer) {\r
+\r
+    //\r
+    // Video to BltBuffer: Source is Video, destination is BltBuffer\r
+    //\r
+    if (SourceY + Height > VerticalResolution) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (SourceX + Width > HorizontalResolution) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    //\r
+    // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
+    // We would not want a timer based event (Cursor, ...) to come in while we are\r
+    // doing this operation.\r
+    //\r
+    OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+    for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {\r
+      Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+      VScreen = &Private->VirtualScreen[(VerticalResolution - SrcY - 1) * HorizontalResolution + SourceX];\r
+      CopyMem (Blt, VScreen, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * Width);\r
+    }\r
+  } else {\r
+    //\r
+    // BltBuffer to Video: Source is BltBuffer, destination is Video\r
+    //\r
+    if (DestinationY + Height > VerticalResolution) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (DestinationX + Width > HorizontalResolution) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    //\r
+    // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
+    // We would not want a timer based event (Cursor, ...) to come in while we are\r
+    // doing this operation.\r
+    //\r
+    OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+    if (BltOperation == EfiBltVideoFill) {\r
+      FillPixel = BltBuffer;\r
+      for (Index = 0; Index < Width; Index++) {\r
+        Private->FillLine[Index] = *FillPixel;\r
+      }\r
+    }\r
+\r
+    for (Index = 0; Index < Height; Index++) {\r
+      if (DestinationY <= SourceY) {\r
+        SrcY  = SourceY + Index;\r
+        DstY  = DestinationY + Index;\r
+      } else {\r
+        SrcY  = SourceY + Height - Index - 1;\r
+        DstY  = DestinationY + Height - Index - 1;\r
+      }\r
+\r
+      VScreen = &Private->VirtualScreen[(VerticalResolution - DstY - 1) * HorizontalResolution + DestinationX];\r
+      switch (BltOperation) {\r
+      case EfiBltBufferToVideo:\r
+        Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+        CopyMem (VScreen, Blt, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+        break;\r
+\r
+      case EfiBltVideoToVideo:\r
+        VScreenSrc = &Private->VirtualScreen[(VerticalResolution - SrcY - 1) * HorizontalResolution + SourceX];\r
+        CopyMem (VScreen, VScreenSrc, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+        break;\r
+\r
+      case EfiBltVideoFill:\r
+        CopyMem (VScreen, Private->FillLine, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (BltOperation != EfiBltVideoToBltBuffer) {\r
+    //\r
+    // Mark the area we just blted as Invalid so WM_PAINT will update.\r
+    //\r
+    Rect.left   = DestinationX;\r
+    Rect.top    = DestinationY;\r
+    Rect.right  = DestinationX + Width;\r
+    Rect.bottom = DestinationY + Height;\r
+    Private->WinNtThunk->InvalidateRect (Private->WindowHandle, &Rect, FALSE);\r
+\r
+    //\r
+    // Send the WM_PAINT message to the thread that is drawing the window. We\r
+    // are in the main thread and the window drawing is in a child thread.\r
+    // There is a child thread per window. We have no CriticalSection or Mutex\r
+    // since we write the data and the other thread displays the data. While\r
+    // we may miss some data for a short period of time this is no different than\r
+    // a write combining on writes to a frame buffer.\r
+    //\r
+\r
+    Private->WinNtThunk->UpdateWindow (Private->WindowHandle);\r
+  }\r
+\r
+  gBS->RestoreTPL (OriginalTPL);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// Construction and Destruction functions\r
+//\r
+\r
+\r
+/**\r
+\r
+\r
+  @return None\r
+\r
+**/\r
+// TODO:    WinNtIo - add argument and description to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+EFI_STATUS\r
+WinNtGopSupported (\r
+  IN  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo\r
+  )\r
+{\r
+  //\r
+  // Check to see if the IO abstraction represents a device type we support.\r
+  //\r
+  // This would be replaced a check of PCI subsystem ID, etc.\r
+  //\r
+  if (!CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtGopGuid)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Win32 Windows event handler.\r
+\r
+  See Win32 Book\r
+\r
+  @return See Win32 Book\r
+\r
+**/\r
+// TODO:    hwnd - add argument and description to function comment\r
+// TODO:    iMsg - add argument and description to function comment\r
+// TODO:    wParam - add argument and description to function comment\r
+// TODO:    lParam - add argument and description to function comment\r
+LRESULT\r
+CALLBACK\r
+WinNtGopThreadWindowProc (\r
+  IN  HWND    hwnd,\r
+  IN  UINT    iMsg,\r
+  IN  WPARAM  wParam,\r
+  IN  LPARAM  lParam\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+  UINTN             Size;\r
+  HDC               Handle;\r
+  PAINTSTRUCT       PaintStruct;\r
+  LPARAM            Index;\r
+  EFI_INPUT_KEY     Key;\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
+\r
+  //\r
+  // Use mTlsIndex global to get a Thread Local Storage version of Private.\r
+  // This works since each Gop protocol has a unique Private data instance and\r
+  // a unique thread.\r
+  //\r
+  Private = mWinNt->TlsGetValue (mTlsIndex);\r
+  ASSERT (NULL != Private);\r
+\r
+  switch (iMsg) {\r
+  case WM_CREATE:\r
+    Size = Private->GraphicsOutput.Mode->Info->HorizontalResolution * Private->GraphicsOutput.Mode->Info->VerticalResolution * 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 = Private->WinNtThunk->HeapAlloc (\r
+                                                        Private->WinNtThunk->GetProcessHeap (),\r
+                                                        HEAP_ZERO_MEMORY,\r
+                                                        Size\r
+                                                        );\r
+\r
+    Private->VirtualScreenInfo->bV4Size           = sizeof (BITMAPV4HEADER);\r
+    Private->VirtualScreenInfo->bV4Width          = Private->GraphicsOutput.Mode->Info->HorizontalResolution;\r
+    Private->VirtualScreenInfo->bV4Height         = Private->GraphicsOutput.Mode->Info->VerticalResolution;\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 = mWinNt->BeginPaint (hwnd, &PaintStruct);\r
+\r
+    mWinNt->SetDIBitsToDevice (\r
+              Handle,                                     // Destination Device Context\r
+              0,                                          // Destination X - 0\r
+              0,                                          // Destination Y - 0\r
+              Private->GraphicsOutput.Mode->Info->HorizontalResolution,              // Width\r
+              Private->GraphicsOutput.Mode->Info->VerticalResolution,                // Height\r
+              0,                                          // Source X\r
+              0,                                          // Source Y\r
+              0,                                          // DIB Start Scan Line\r
+              Private->GraphicsOutput.Mode->Info->VerticalResolution,                // Number of scan lines\r
+              Private->VirtualScreen,                     // 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
+\r
+    mWinNt->EndPaint (hwnd, &PaintStruct);\r
+    return 0;\r
+\r
+  //\r
+  // F10 and the ALT key do not create a WM_KEYDOWN message, thus this special case\r
+  //\r
+  case WM_SYSKEYDOWN:\r
+    Key.ScanCode = 0;\r
+    switch (wParam) {\r
+    case VK_F10:\r
+      Key.ScanCode    = SCAN_F10;\r
+      Key.UnicodeChar = 0;\r
+      GopPrivateAddQ (Private, Key);\r
+      return 0;\r
+    }\r
+    break;\r
+\r
+  case WM_KEYDOWN:\r
+    Key.ScanCode = 0;\r
+    switch (wParam) {\r
+    case VK_HOME:       Key.ScanCode = SCAN_HOME;       break;\r
+    case VK_END:        Key.ScanCode = SCAN_END;        break;\r
+    case VK_LEFT:       Key.ScanCode = SCAN_LEFT;       break;\r
+    case VK_RIGHT:      Key.ScanCode = SCAN_RIGHT;      break;\r
+    case VK_UP:         Key.ScanCode = SCAN_UP;         break;\r
+    case VK_DOWN:       Key.ScanCode = SCAN_DOWN;       break;\r
+    case VK_DELETE:     Key.ScanCode = SCAN_DELETE;     break;\r
+    case VK_INSERT:     Key.ScanCode = SCAN_INSERT;     break;\r
+    case VK_PRIOR:      Key.ScanCode = SCAN_PAGE_UP;    break;\r
+    case VK_NEXT:       Key.ScanCode = SCAN_PAGE_DOWN;  break;\r
+    case VK_ESCAPE:     Key.ScanCode = SCAN_ESC;        break;\r
+\r
+    case VK_F1:   Key.ScanCode = SCAN_F1;   break;\r
+    case VK_F2:   Key.ScanCode = SCAN_F2;   break;\r
+    case VK_F3:   Key.ScanCode = SCAN_F3;   break;\r
+    case VK_F4:   Key.ScanCode = SCAN_F4;   break;\r
+    case VK_F5:   Key.ScanCode = SCAN_F5;   break;\r
+    case VK_F6:   Key.ScanCode = SCAN_F6;   break;\r
+    case VK_F7:   Key.ScanCode = SCAN_F7;   break;\r
+    case VK_F8:   Key.ScanCode = SCAN_F8;   break;\r
+    case VK_F9:   Key.ScanCode = SCAN_F9;   break;\r
+    case VK_F11:  Key.ScanCode = SCAN_F11;  break;\r
+    case VK_F12:  Key.ScanCode = SCAN_F12;  break;\r
+    }\r
+\r
+    if (Key.ScanCode != 0) {\r
+      Key.UnicodeChar = 0;\r
+      GopPrivateAddQ (Private, Key);\r
+    }\r
+\r
+    return 0;\r
+\r
+  case WM_CHAR:\r
+    //\r
+    // The ESC key also generate WM_CHAR.\r
+    //\r
+    if (wParam == 0x1B) {\r
+      return 0;\r
+    }\r
+\r
+    for (Index = 0; Index < (lParam & 0xffff); Index++) {\r
+      if (wParam != 0) {\r
+        Key.UnicodeChar = (CHAR16) wParam;\r
+        Key.ScanCode    = 0;\r
+        GopPrivateAddQ (Private, Key);\r
+      }\r
+    }\r
+\r
+    return 0;\r
+\r
+  case WM_CLOSE:\r
+    //\r
+    // This close message is issued by user, core is not aware of this,\r
+    // so don't release the window display resource, just hide the window.\r
+    //\r
+    Private->WinNtThunk->ShowWindow (Private->WindowHandle, SW_HIDE);\r
+    return 0;\r
+\r
+  case WM_DESTROY:\r
+    mWinNt->DestroyWindow (hwnd);\r
+    mWinNt->PostQuitMessage (0);\r
+\r
+    mWinNt->HeapFree (Private->WinNtThunk->GetProcessHeap (), 0, Private->VirtualScreenInfo);\r
+\r
+    mWinNt->ExitThread (0);\r
+    return 0;\r
+\r
+  default:\r
+    break;\r
+  };\r
+\r
+  return mWinNt->DefWindowProc (hwnd, iMsg, wParam, lParam);\r
+}\r
+\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
+  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
+\r
+  @param  lpParameter            Handle of window to manage.\r
+\r
+  @return if a WM_QUIT message is returned exit.\r
+\r
+**/\r
+DWORD\r
+WINAPI\r
+WinNtGopThreadWinMain (\r
+  LPVOID    lpParameter\r
+  )\r
+{\r
+  MSG               Message;\r
+  GOP_PRIVATE_DATA  *Private;\r
+  ATOM              Atom;\r
+  RECT              Rect;\r
+\r
+  Private = (GOP_PRIVATE_DATA *) lpParameter;\r
+  ASSERT (NULL != Private);\r
+\r
+  //\r
+  // Since each thread has unique private data, save the private data in Thread\r
+  // Local Storage slot. Then the shared global mTlsIndex can be used to get\r
+  // thread specific context.\r
+  //\r
+  Private->WinNtThunk->TlsSetValue (mTlsIndex, Private);\r
+\r
+  Private->ThreadId                   = Private->WinNtThunk->GetCurrentThreadId ();\r
+\r
+  Private->WindowsClass.cbSize        = sizeof (WNDCLASSEX);\r
+  Private->WindowsClass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;\r
+  Private->WindowsClass.lpfnWndProc   = WinNtGopThreadWindowProc;\r
+  Private->WindowsClass.cbClsExtra    = 0;\r
+  Private->WindowsClass.cbWndExtra    = 0;\r
+  Private->WindowsClass.hInstance     = NULL;\r
+  Private->WindowsClass.hIcon         = Private->WinNtThunk->LoadIcon (NULL, IDI_APPLICATION);\r
+  Private->WindowsClass.hCursor       = Private->WinNtThunk->LoadCursor (NULL, IDC_ARROW);\r
+  Private->WindowsClass.hbrBackground = (HBRUSH) COLOR_WINDOW;\r
+  Private->WindowsClass.lpszMenuName  = NULL;\r
+  Private->WindowsClass.lpszClassName = WIN_NT_GOP_CLASS_NAME;\r
+  Private->WindowsClass.hIconSm       = Private->WinNtThunk->LoadIcon (NULL, IDI_APPLICATION);\r
+\r
+  //\r
+  // 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
+  Atom = Private->WinNtThunk->RegisterClassEx (&Private->WindowsClass);\r
+\r
+  //\r
+  // Setting Rect values to allow for the AdjustWindowRect to provide\r
+  // us the correct sizes for the client area when doing the CreateWindowEx\r
+  //\r
+  Rect.top    = 0;\r
+  Rect.bottom = Private->GraphicsOutput.Mode->Info->VerticalResolution;\r
+  Rect.left   = 0;\r
+  Rect.right  = Private->GraphicsOutput.Mode->Info->HorizontalResolution;\r
+\r
+  Private->WinNtThunk->AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0);\r
+\r
+  Private->WindowHandle = Private->WinNtThunk->CreateWindowEx (\r
+                                                0,\r
+                                                WIN_NT_GOP_CLASS_NAME,\r
+                                                Private->WindowName,\r
+                                                WS_OVERLAPPEDWINDOW,\r
+                                                CW_USEDEFAULT,\r
+                                                CW_USEDEFAULT,\r
+                                                Rect.right - Rect.left,\r
+                                                Rect.bottom - Rect.top,\r
+                                                NULL,\r
+                                                NULL,\r
+                                                NULL,\r
+                                                &Private\r
+                                                );\r
+\r
+  //\r
+  // The reset of this thread is the standard winows program. We need a sperate\r
+  // thread since we must process the message loop to make windows act like\r
+  // windows.\r
+  //\r
+\r
+  Private->WinNtThunk->ShowWindow (Private->WindowHandle, SW_SHOW);\r
+  Private->WinNtThunk->UpdateWindow (Private->WindowHandle);\r
+\r
+  //\r
+  // Let the main thread get some work done\r
+  //\r
+  Private->WinNtThunk->ReleaseSemaphore (Private->ThreadInited, 1, NULL);\r
+\r
+  //\r
+  // This is the message loop that all Windows programs need.\r
+  //\r
+  while (Private->WinNtThunk->GetMessage (&Message, Private->WindowHandle, 0, 0)) {\r
+    Private->WinNtThunk->TranslateMessage (&Message);\r
+    Private->WinNtThunk->DispatchMessage (&Message);\r
+  }\r
+\r
+  return Message.wParam;\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  Private                TODO: add argument description\r
+  @param  HorizontalResolution   TODO: add argument description\r
+  @param  VerticalResolution     TODO: add argument description\r
+  @param  ColorDepth             TODO: add argument description\r
+  @param  RefreshRate            TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtGopStartWindow (\r
+  IN  GOP_PRIVATE_DATA    *Private,\r
+  IN  UINT32              HorizontalResolution,\r
+  IN  UINT32              VerticalResolution,\r
+  IN  UINT32              ColorDepth,\r
+  IN  UINT32              RefreshRate\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  DWORD               NewThreadId;\r
+\r
+  mWinNt  = Private->WinNtThunk;\r
+\r
+  //\r
+  // Initialize a Thread Local Storge variable slot. We use TLS to get the\r
+  // correct Private data instance into the windows thread.\r
+  //\r
+  if (mTlsIndex == TLS_OUT_OF_INDEXES) {\r
+    ASSERT (0 == mTlsIndexUseCount);\r
+    mTlsIndex = Private->WinNtThunk->TlsAlloc ();\r
+  }\r
+\r
+  //\r
+  // always increase the use count!\r
+  //\r
+  mTlsIndexUseCount++;\r
+\r
+  //\r
+  // Register to be notified on exit boot services so we can destroy the window.\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+                  TPL_CALLBACK,\r
+                  KillNtGopThread,\r
+                  Private,\r
+                  &mGopScreenExitBootServicesEvent\r
+                  );\r
+\r
+  Private->ThreadInited = Private->WinNtThunk->CreateSemaphore (NULL, 0, 1, NULL);\r
+  Private->ThreadHandle = Private->WinNtThunk->CreateThread (\r
+                                                NULL,\r
+                                                0,\r
+                                                WinNtGopThreadWinMain,\r
+                                                (VOID *) Private,\r
+                                                0,\r
+                                                &NewThreadId\r
+                                                );\r
+\r
+  //\r
+  // The other thread has entered the windows message loop so we can\r
+  // continue our initialization.\r
+  //\r
+  Private->WinNtThunk->WaitForSingleObject (Private->ThreadInited, INFINITE);\r
+  Private->WinNtThunk->CloseHandle (Private->ThreadInited);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+\r
+\r
+  @return None\r
+\r
+**/\r
+// TODO:    Private - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+EFI_STATUS\r
+WinNtGopConstructor (\r
+  GOP_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  Private->ModeData = mGopModeData;\r
+\r
+  Private->GraphicsOutput.QueryMode = WinNtGopQuerytMode;\r
+  Private->GraphicsOutput.SetMode = WinNtGopSetMode;\r
+  Private->GraphicsOutput.Blt            = WinNtGopBlt;\r
+\r
+  //\r
+  // Allocate buffer for Graphics Output Protocol mode information\r
+  //\r
+  Private->GraphicsOutput.Mode = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));\r
+  if (Private->GraphicsOutput.Mode == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  Private->GraphicsOutput.Mode->Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+  if (Private->GraphicsOutput.Mode->Info == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Private->GraphicsOutput.Mode->MaxMode = sizeof(mGopModeData) / sizeof(GOP_MODE_DATA);\r
+  //\r
+  // Till now, we have no idea about the window size.\r
+  //\r
+  Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
+  Private->GraphicsOutput.Mode->Info->Version = 0;\r
+  Private->GraphicsOutput.Mode->Info->HorizontalResolution = 0;\r
+  Private->GraphicsOutput.Mode->Info->VerticalResolution = 0;\r
+  Private->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;\r
+  Private->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+  Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
+  Private->GraphicsOutput.Mode->FrameBufferSize = 0;\r
+\r
+  Private->HardwareNeedsStarting  = TRUE;\r
+  Private->FillLine               = NULL;\r
+\r
+  WinNtGopInitializeSimpleTextInForWindow (Private);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+\r
+\r
+  @return None\r
+\r
+**/\r
+// TODO:    Private - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+EFI_STATUS\r
+WinNtGopDestructor (\r
+  GOP_PRIVATE_DATA     *Private\r
+  )\r
+{\r
+  UINT32  UnregisterReturn;\r
+\r
+  if (!Private->HardwareNeedsStarting) {\r
+    //\r
+    // BugBug: Shutdown GOP Hardware and any child devices.\r
+    //\r
+    Private->WinNtThunk->SendMessage (Private->WindowHandle, WM_DESTROY, 0, 0);\r
+    Private->WinNtThunk->CloseHandle (Private->ThreadHandle);\r
+\r
+    mTlsIndexUseCount--;\r
+\r
+    //\r
+    // The callback function for another window could still be called,\r
+    // so we need to make sure there are no more users of mTlsIndex.\r
+    //\r
+    if (0 == mTlsIndexUseCount) {\r
+      ASSERT (TLS_OUT_OF_INDEXES != mTlsIndex);\r
+\r
+      Private->WinNtThunk->TlsFree (mTlsIndex);\r
+      mTlsIndex = TLS_OUT_OF_INDEXES;\r
+\r
+      UnregisterReturn = Private->WinNtThunk->UnregisterClass (\r
+                                                Private->WindowsClass.lpszClassName,\r
+                                                Private->WindowsClass.hInstance\r
+                                                );\r
+    }\r
+\r
+    WinNtGopDestroySimpleTextInForWindow (Private);\r
+  }\r
+\r
+  //\r
+  // Free graphics output protocol occupied resource\r
+  //\r
+  if (Private->GraphicsOutput.Mode != NULL) {\r
+    if (Private->GraphicsOutput.Mode->Info != NULL) {\r
+      FreePool (Private->GraphicsOutput.Mode->Info);\r
+    }\r
+    FreePool (Private->GraphicsOutput.Mode);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This is the GOP screen's callback notification function for exit-boot-services.\r
+  All we do here is call WinNtGopDestructor().\r
+\r
+  @param  Event                  not used\r
+  @param  Context                pointer to the Private structure.\r
+\r
+  @return None.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+KillNtGopThread (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  Status = WinNtGopDestructor (Context);\r
+}\r