/** @file

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

Module Name:

  WinGop.h

Abstract:

  Private data for the Gop driver that is bound to the WinNt Thunk protocol


**/

#ifndef _WIN_GOP_H_
#define _WIN_GOP_H_

#include "WinHost.h"

#include <Protocol/EmuIoThunk.h>
#include <Protocol/EmuGraphicsWindow.h>
#include <Protocol/SimplePointer.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/SimpleTextInEx.h>
#include <Protocol/GraphicsOutput.h>
#include <Library/FrameBufferBltLib.h>

//
// WM_SYSKEYDOWN/WM_SYSKEYUP Notification
// lParam
// bit 24: Specifies whether the key is an extended key,
// such as the right-hand ALT and CTRL keys that appear on
// an enhanced 101- or 102-key keyboard.
// The value is 1 if it is an extended key; otherwise, it is 0.
// bit 29:Specifies the context code.
// The value is 1 if the ALT key is down while the key is pressed/released;
// it is 0 if the WM_SYSKEYDOWN message is posted to the active window
// because no window has the keyboard focus.
#define GOP_EXTENDED_KEY     (0x1 << 24)
#define GOP_ALT_KEY_PRESSED  (0x1 << 29)

#define KEYBOARD_TIMER_INTERVAL  200000         // 0.02s

#define MAX_Q  256

typedef struct {
  UINTN               Front;
  UINTN               Rear;
  EFI_KEY_DATA        Q[MAX_Q];
  CRITICAL_SECTION    Cs;
} GOP_QUEUE_FIXED;

#define WIN_NT_GOP_CLASS_NAME  L"WinNtGopWindow"

typedef struct {
  UINT64                                              Signature;
  EMU_GRAPHICS_WINDOW_PROTOCOL                        GraphicsWindowIo;

  //
  // GOP Private Data knowing when to start hardware
  //
  BOOLEAN                                             HardwareNeedsStarting;

  CHAR16                                              *WindowName;
  CHAR16                                              Buffer[160];

  HANDLE                                              ThreadInited; // Semaphore
  HANDLE                                              ThreadHandle; // Thread
  DWORD                                               ThreadId;

  HWND                                                WindowHandle;
  WNDCLASSEX                                          WindowsClass;

  UINT32                                              Width;
  UINT32                                              Height;
  //
  // This screen is used to redraw the screen when windows events happen. It's
  // updated in the main thread and displayed in the windows thread.
  //
  BITMAPV4HEADER                                      *VirtualScreenInfo;

  FRAME_BUFFER_CONFIGURE                              *FrameBufferConfigure;

  //
  // Keyboard Queue used by Simple Text In.
  // QueueForRead:   WinProc thread adds, and main thread removes.
  //
  GOP_QUEUE_FIXED                                     QueueForRead;

  EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK    MakeRegisterdKeyCallback;
  EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK    BreakRegisterdKeyCallback;
  VOID                                                *RegisterdKeyCallbackContext;

  EFI_KEY_STATE                                       KeyState;
  BOOLEAN                                             LeftShift;
  BOOLEAN                                             RightShift;
  BOOLEAN                                             LeftAlt;
  BOOLEAN                                             RightAlt;
  BOOLEAN                                             LeftCtrl;
  BOOLEAN                                             RightCtrl;
  BOOLEAN                                             LeftLogo;
  BOOLEAN                                             RightLogo;
  BOOLEAN                                             Menu;
  BOOLEAN                                             SysReq;
  BOOLEAN                                             NumLock;
  BOOLEAN                                             ScrollLock;
  BOOLEAN                                             CapsLock;
  BOOLEAN                                             IsPartialKeySupport;
  INT32                                               PointerPreviousX;
  INT32                                               PointerPreviousY;
  BOOLEAN                                             PointerStateChanged;
  EFI_SIMPLE_POINTER_STATE                            PointerState;
} GRAPHICS_PRIVATE_DATA;
#define GRAPHICS_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('g', 'f', 'x', 'd')
#define GRAPHICS_PRIVATE_DATA_FROM_THIS(a)  \
         CR(a, GRAPHICS_PRIVATE_DATA, GraphicsWindowIo, GRAPHICS_PRIVATE_DATA_SIGNATURE)

//
// Gop Hardware abstraction internal worker functions
//

/**
  TODO: Add function description

  @param  Private              TODO: add argument description
  @param  Key                  TODO: add argument description

  @return TODO: add return values

**/
EFI_STATUS
GopPrivateAddKey (
  IN  GRAPHICS_PRIVATE_DATA  *Private,
  IN  EFI_INPUT_KEY          Key
  );

EFI_STATUS
EFIAPI
WinNtWndGetKey (
  IN  EMU_GRAPHICS_WINDOW_PROTOCOL  *GraphicsIo,
  IN  EFI_KEY_DATA                  *KeyData
  );

EFI_STATUS
EFIAPI
WinNtWndCheckKey (
  IN  EMU_GRAPHICS_WINDOW_PROTOCOL  *GraphicsIo
  );

EFI_STATUS
EFIAPI
WinNtWndKeySetState (
  IN EMU_GRAPHICS_WINDOW_PROTOCOL  *GraphicsIo,
  IN EFI_KEY_TOGGLE_STATE          *KeyToggleState
  );

EFI_STATUS
EFIAPI
WinNtWndRegisterKeyNotify (
  IN EMU_GRAPHICS_WINDOW_PROTOCOL                      *GraphicsIo,
  IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK  MakeCallBack,
  IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK  BreakCallBack,
  IN VOID                                              *Context
  );

EFI_STATUS
EFIAPI
WinNtWndCheckPointer (
  IN  EMU_GRAPHICS_WINDOW_PROTOCOL  *GraphicsIo
  );

EFI_STATUS
EFIAPI
WinNtWndGetPointerState (
  IN  EMU_GRAPHICS_WINDOW_PROTOCOL  *GraphicsIo,
  IN  EFI_SIMPLE_POINTER_STATE      *State
  );

EFI_STATUS
GopPrivateCreateQ (
  IN  GRAPHICS_PRIVATE_DATA  *Private,
  IN GOP_QUEUE_FIXED         *Queue
  );

/**
  TODO: Add function description

  @param  Private               TODO: add argument description

  @retval EFI_SUCCESS           TODO: Add description for return value

**/
EFI_STATUS
GopPrivateDestroyQ (
  IN  GRAPHICS_PRIVATE_DATA  *Private,
  IN GOP_QUEUE_FIXED         *Queue
  );

#endif
