]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Nt32Pkg/WinNtGopDxe/WinNtGopScreen.c
OvmfPkg/CsmSupportLib: list "LegacyPlatform.h" in the INF file
[mirror_edk2.git] / Nt32Pkg / WinNtGopDxe / WinNtGopScreen.c
index 9124e26eddf63d0f8a86dec85e4fdf9eaca3bf61..b15d621b3b2c28fe8ef2174deda2ab6788925d9c 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\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
@@ -52,105 +52,154 @@ KillNtGopThread (
   IN VOID       *Context\r
   );\r
 \r
-VOID\r
+BOOLEAN\r
 WinNtGopConvertParamToEfiKeyShiftState (\r
   IN  GOP_PRIVATE_DATA  *Private,\r
   IN  WPARAM            *wParam,\r
+  IN  LPARAM            *lParam,\r
   IN  BOOLEAN           Flag\r
   )\r
 {\r
   switch (*wParam) {\r
   //\r
   // BUGBUG: Only GetAsyncKeyState() and GetKeyState() can distinguish\r
-  // left and right Ctrl, and Shift key. \r
-  // Neither of the two is defined in EFI_WIN_NT_THUNK_PROTOCOL. \r
+  // left and right Ctrl, and Shift key.\r
+  // Neither of the two is defined in EFI_WIN_NT_THUNK_PROTOCOL.\r
   // Therefor, we can not set the correct Shift state here.\r
-  // \r
-  case VK_SHIFT:  \r
-    Private->LeftShift  = Flag;\r
-    break;  \r
+  //\r
+  case VK_SHIFT:\r
+    if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+        Private->RightShift = Flag;\r
+      } else {\r
+        Private->LeftShift = Flag;\r
+      }\r
+    return TRUE;\r
+\r
+  case VK_LSHIFT:\r
+    Private->LeftShift = Flag;\r
+    return TRUE;\r
+\r
+  case VK_RSHIFT:\r
+    Private->RightShift = Flag;\r
+    return TRUE;\r
+\r
   case VK_CONTROL:\r
-    Private->LeftCtrl   = Flag;\r
-    break;\r
-  case VK_LWIN:      \r
+    if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+        Private->RightCtrl= Flag;\r
+      } else {\r
+        Private->LeftCtrl = Flag;\r
+      }\r
+    return TRUE;\r
+\r
+  case VK_LCONTROL:\r
+    Private->LeftCtrl = Flag;\r
+    return TRUE;\r
+\r
+  case VK_RCONTROL:\r
+    Private->RightCtrl = Flag;\r
+    return TRUE;\r
+\r
+  case VK_LWIN:\r
     Private->LeftLogo   = Flag;\r
-    break;\r
-  case VK_RWIN:      \r
+    return TRUE;\r
+\r
+  case VK_RWIN:\r
     Private->RightLogo  = Flag;\r
-    break;\r
-  case VK_APPS:      \r
+    return TRUE;\r
+\r
+  case VK_APPS:\r
     Private->Menu       = Flag;\r
-    break;\r
+    return TRUE;\r
   //\r
   // BUGBUG: PrintScreen/SysRq can not trigger WM_KEYDOWN message,\r
   // so SySReq shift state is not supported here.\r
   //\r
-  case VK_PRINT:  \r
+  case VK_PRINT:\r
     Private->SysReq     = Flag;\r
-    break;\r
+    return TRUE;\r
+  //\r
+  // For Alt Keystroke.\r
+  //\r
+  case VK_MENU:\r
+    if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+        Private->RightAlt = Flag;\r
+      } else {\r
+        Private->LeftAlt = Flag;\r
+      }\r
+    return TRUE;\r
+\r
+  default:\r
+    return FALSE;\r
   }\r
 }\r
 \r
-VOID\r
+BOOLEAN\r
 WinNtGopConvertParamToEfiKey (\r
   IN  GOP_PRIVATE_DATA  *Private,\r
   IN  WPARAM            *wParam,\r
+  IN  LPARAM            *lParam,\r
   IN  EFI_INPUT_KEY     *Key\r
   )\r
 {\r
+  BOOLEAN Flag;\r
+  Flag = FALSE;\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
-  case VK_F13:        Key->ScanCode = SCAN_F13;        break;\r
-  case VK_F14:        Key->ScanCode = SCAN_F14;        break;\r
-  case VK_F15:        Key->ScanCode = SCAN_F15;        break;\r
-  case VK_F16:        Key->ScanCode = SCAN_F16;        break;\r
-  case VK_F17:        Key->ScanCode = SCAN_F17;        break;\r
-  case VK_F18:        Key->ScanCode = SCAN_F18;        break;\r
-  case VK_F19:        Key->ScanCode = SCAN_F19;        break;\r
-  case VK_F20:        Key->ScanCode = SCAN_F20;        break;\r
-  case VK_F21:        Key->ScanCode = SCAN_F21;        break;\r
-  case VK_F22:        Key->ScanCode = SCAN_F22;        break;\r
-  case VK_F23:        Key->ScanCode = SCAN_F23;        break;\r
-  case VK_F24:        Key->ScanCode = SCAN_F24;        break;\r
+  case VK_HOME:       Key->ScanCode = SCAN_HOME;      Flag = TRUE; break;\r
+  case VK_END:        Key->ScanCode = SCAN_END;       Flag = TRUE; break;\r
+  case VK_LEFT:       Key->ScanCode = SCAN_LEFT;      Flag = TRUE; break;\r
+  case VK_RIGHT:      Key->ScanCode = SCAN_RIGHT;     Flag = TRUE; break;\r
+  case VK_UP:         Key->ScanCode = SCAN_UP;        Flag = TRUE; break;\r
+  case VK_DOWN:       Key->ScanCode = SCAN_DOWN;      Flag = TRUE; break;\r
+  case VK_DELETE:     Key->ScanCode = SCAN_DELETE;    Flag = TRUE; break;\r
+  case VK_INSERT:     Key->ScanCode = SCAN_INSERT;    Flag = TRUE; break;\r
+  case VK_PRIOR:      Key->ScanCode = SCAN_PAGE_UP;   Flag = TRUE; break;\r
+  case VK_NEXT:       Key->ScanCode = SCAN_PAGE_DOWN; Flag = TRUE; break;\r
+  case VK_ESCAPE:     Key->ScanCode = SCAN_ESC;       Flag = TRUE; break;\r
+\r
+  case VK_F1:         Key->ScanCode = SCAN_F1;    Flag = TRUE;     break;\r
+  case VK_F2:         Key->ScanCode = SCAN_F2;    Flag = TRUE;     break;\r
+  case VK_F3:         Key->ScanCode = SCAN_F3;    Flag = TRUE;     break;\r
+  case VK_F4:         Key->ScanCode = SCAN_F4;    Flag = TRUE;     break;\r
+  case VK_F5:         Key->ScanCode = SCAN_F5;    Flag = TRUE;     break;\r
+  case VK_F6:         Key->ScanCode = SCAN_F6;    Flag = TRUE;     break;\r
+  case VK_F7:         Key->ScanCode = SCAN_F7;    Flag = TRUE;     break;\r
+  case VK_F8:         Key->ScanCode = SCAN_F8;    Flag = TRUE;     break;\r
+  case VK_F9:         Key->ScanCode = SCAN_F9;    Flag = TRUE;     break;\r
+  case VK_F11:        Key->ScanCode = SCAN_F11;   Flag = TRUE;     break;\r
+  case VK_F12:        Key->ScanCode = SCAN_F12;   Flag = TRUE;     break;\r
+\r
+  case VK_F13:        Key->ScanCode = SCAN_F13;   Flag = TRUE;     break;\r
+  case VK_F14:        Key->ScanCode = SCAN_F14;   Flag = TRUE;     break;\r
+  case VK_F15:        Key->ScanCode = SCAN_F15;   Flag = TRUE;     break;\r
+  case VK_F16:        Key->ScanCode = SCAN_F16;   Flag = TRUE;     break;\r
+  case VK_F17:        Key->ScanCode = SCAN_F17;   Flag = TRUE;     break;\r
+  case VK_F18:        Key->ScanCode = SCAN_F18;   Flag = TRUE;     break;\r
+  case VK_F19:        Key->ScanCode = SCAN_F19;   Flag = TRUE;     break;\r
+  case VK_F20:        Key->ScanCode = SCAN_F20;   Flag = TRUE;     break;\r
+  case VK_F21:        Key->ScanCode = SCAN_F21;   Flag = TRUE;     break;\r
+  case VK_F22:        Key->ScanCode = SCAN_F22;   Flag = TRUE;     break;\r
+  case VK_F23:        Key->ScanCode = SCAN_F23;   Flag = TRUE;     break;\r
+  case VK_F24:        Key->ScanCode = SCAN_F24;   Flag = TRUE;     break;\r
+  case VK_PAUSE:      Key->ScanCode = SCAN_PAUSE; Flag = TRUE;     break;\r
 \r
   //\r
   // Set toggle state\r
-  //    \r
-  case VK_NUMLOCK:     \r
+  //\r
+  case VK_NUMLOCK:\r
     Private->NumLock    = (BOOLEAN)(!Private->NumLock);\r
+    Flag = TRUE;\r
     break;\r
   case VK_SCROLL:\r
     Private->ScrollLock = (BOOLEAN)(!Private->ScrollLock);\r
-    break;  \r
+    Flag = TRUE;\r
+    break;\r
   case VK_CAPITAL:\r
     Private->CapsLock   = (BOOLEAN)(!Private->CapsLock);\r
-    break;  \r
+    Flag = TRUE;\r
+    break;\r
   }\r
   \r
-  WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, TRUE);  \r
+  return (WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, lParam, TRUE)) == TRUE ? TRUE : Flag;\r
 }\r
 \r
 \r
@@ -330,7 +379,7 @@ WinNtGopSetMode (
     //\r
     // Adjust the window size\r
     //\r
-    Private->WinNtThunk->MoveWindow (Private->WindowHandle, Rect.left, Rect.top, Width, Height, TRUE);\r
+    Private->WinNtThunk->MoveWindow (Private->WindowHandle, Rect.left, Rect.top, (INT32)Width, (INT32)Height, TRUE);\r
 \r
   }\r
 \r
@@ -533,10 +582,10 @@ WinNtGopBlt (
     //\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
+    Rect.left   = (LONG)DestinationX;\r
+    Rect.top    = (LONG)DestinationY;\r
+    Rect.right  = (LONG)(DestinationX + Width);\r
+    Rect.bottom = (LONG)(DestinationY + Height);\r
     Private->WinNtThunk->InvalidateRect (Private->WindowHandle, &Rect, FALSE);\r
 \r
     //\r
@@ -615,6 +664,7 @@ WinNtGopThreadWindowProc (
   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
@@ -629,6 +679,7 @@ WinNtGopThreadWindowProc (
   // This works since each Gop protocol has a unique Private data instance and\r
   // a unique thread.\r
   //\r
+  AltIsPress = FALSE;\r
   Private = mWinNt->TlsGetValue (mTlsIndex);\r
   ASSERT (NULL != Private);\r
 \r
@@ -688,92 +739,98 @@ WinNtGopThreadWindowProc (
 \r
   //\r
   // F10 and the ALT key do not create a WM_KEYDOWN message, thus this special case\r
-  // WM_SYSKEYDOWN is posted when F10 is pressed or \r
+  // WM_SYSKEYDOWN is posted when F10 is pressed or\r
   // holds down ALT key and then presses another key.\r
   //\r
   case WM_SYSKEYDOWN:\r
-    Key.ScanCode = 0;\r
+\r
+    Key.ScanCode    = 0;\r
+    Key.UnicodeChar = CHAR_NULL;\r
     switch (wParam) {\r
     case VK_F10:\r
       Key.ScanCode    = SCAN_F10;\r
-      Key.UnicodeChar = 0;\r
+      Key.UnicodeChar = CHAR_NULL;\r
       GopPrivateAddKey (Private, Key);\r
       return 0;\r
     }\r
 \r
-    if ((lParam & GOP_ALT_KEY_PRESSED) == GOP_ALT_KEY_PRESSED) {\r
-      //\r
-      // ALT is pressed with another key pressed\r
-      //\r
-      WinNtGopConvertParamToEfiKey (Private, &wParam, &Key);\r
-\r
-      if ((lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
-        Private->RightAlt = TRUE;\r
-      } else {\r
+    //\r
+    // If ALT or ALT + modifier key is pressed.\r
+    //\r
+    if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) {\r
+      if (Key.ScanCode != 0){\r
+        //\r
+        // If ALT is pressed with other ScanCode.\r
+        // Always revers the left Alt for simple.\r
+        //\r
         Private->LeftAlt = TRUE;\r
       }\r
-\r
-      if (Private->RightAlt && Private->LeftAlt) {\r
-        Private->LeftAlt = FALSE;\r
-      }\r
-    }\r
-\r
-    if (Key.ScanCode != 0) {\r
-      Key.UnicodeChar = 0;\r
       GopPrivateAddKey (Private, Key);\r
+      //\r
+      // When Alt is released there is no windoes message, so \r
+      // clean it after using it.\r
+      //\r
+      Private->RightAlt = FALSE;\r
+      Private->LeftAlt  = FALSE;\r
+      return 0;\r
     }\r
+    AltIsPress = TRUE;\r
 \r
-    return 0;\r
+  case WM_CHAR:    \r
+    //\r
+    // The ESC key also generate WM_CHAR.\r
+    //\r
+    if (wParam == 0x1B) {\r
+           return 0;\r
+    }    \r
 \r
-  case WM_SYSKEYUP:\r
-    if ((lParam & GOP_ALT_KEY_PRESSED) == GOP_ALT_KEY_PRESSED) {\r
+    if (AltIsPress == TRUE) {\r
       //\r
-      // ALT is pressed with another key released\r
+      // If AltIsPress is true that means the Alt key is pressed.\r
       //\r
-      WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE);  \r
+      Private->LeftAlt = TRUE;\r
+    }\r
+    for (Index = 0; Index < (lParam & 0xffff); Index++) {\r
+      if (wParam != 0) {\r
+        Key.UnicodeChar = (CHAR16) wParam;\r
+        Key.ScanCode    = SCAN_NULL;     \r
+        GopPrivateAddKey (Private, Key);    \r
+      }\r
+    }\r
+    if (AltIsPress == TRUE) {\r
       //\r
-      // Actually ALT key is still held down here.\r
-      // Change the ALT key state when another key is released\r
-      // by user because we did not find a better solution to\r
-      // get a released ALT key. \r
+      // When Alt is released there is no windoes message, so \r
+      // clean it after using it.\r
       //\r
+      Private->LeftAlt  = FALSE;\r
       Private->RightAlt = FALSE;\r
-      Private->LeftAlt = FALSE;\r
     }\r
-\r
     return 0;\r
 \r
+  case WM_SYSKEYUP:\r
+    //\r
+    // ALT is pressed with another key released\r
+    //\r
+    WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE);\r
+    return 0;\r
 \r
   case WM_KEYDOWN:\r
-    Key.ScanCode = 0;\r
-    WinNtGopConvertParamToEfiKey (Private, &wParam, &Key);\r
-    if (Key.ScanCode != 0) {\r
-      Key.UnicodeChar = 0;\r
+    Key.ScanCode    = SCAN_NULL;\r
+    Key.UnicodeChar = CHAR_NULL;\r
+    //\r
+    // A value key press will cause a WM_KEYDOWN first, then cause a WM_CHAR\r
+    // So if there is no modifier key updated, skip the WM_KEYDOWN even.\r
+    //\r
+    if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) {\r
+      //\r
+      // Support the partial keystroke, add all keydown event into the queue.\r
+      //\r
       GopPrivateAddKey (Private, Key);\r
     }\r
-\r
     return 0;\r
 \r
   case WM_KEYUP:\r
-    WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE);  \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
-        GopPrivateAddKey (Private, Key);\r
-      }\r
-    }\r
-\r
+    WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE);\r
     return 0;\r
 \r
   case WM_CLOSE:\r
@@ -843,7 +900,7 @@ WinNtGopThreadWinMain (
   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.hbrBackground = (HBRUSH)(UINTN)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
@@ -906,7 +963,7 @@ WinNtGopThreadWinMain (
     Private->WinNtThunk->DispatchMessage (&Message);\r
   }\r
 \r
-  return Message.wParam;\r
+  return (DWORD)Message.wParam;\r
 }\r
 \r
 \r