vsg  1.0.4
VulkanSceneGraph library
Win32_Window.h
1 #pragma once
2 
3 /* <editor-fold desc="MIT License">
4 
5 Copyright(c) 2018 Robert Osfield
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8 
9 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12 
13 </editor-fold> */
14 
15 #define VK_USE_PLATFORM_WIN32_KHR
16 
17 #ifndef NOMINMAX
18 # define NOMINMAX
19 #endif
20 
21 #include <vsg/app/Window.h>
22 #include <vsg/ui/KeyEvent.h>
23 #include <vsg/ui/PointerEvent.h>
24 
25 #include <windows.h>
26 #include <windowsx.h>
27 
28 #include <vulkan/vulkan_win32.h>
29 
30 namespace vsgWin32
31 {
32  class KeyboardMap : public vsg::Object
33  {
34  public:
35  KeyboardMap();
36 
37  using VirtualKeyToKeySymbolMap = std::map<uint16_t, vsg::KeySymbol>;
38 
39  bool getKeySymbol(WPARAM wParam, LPARAM lParam, vsg::KeySymbol& keySymbol, vsg::KeySymbol& modifiedKeySymbol, vsg::KeyModifier& keyModifier)
40  {
41  uint16_t modifierMask = 0;
42  uint32_t virtualKey = ::MapVirtualKeyEx((lParam >> 16) & 0xff, MAPVK_VSC_TO_VK_EX, ::GetKeyboardLayout(0));
43  auto itr = _vk2vsg.find(virtualKey);
44 
45  if (itr == _vk2vsg.end())
46  {
47  // What ever the code was in lParam should translate to a Virtual Key that we know of in _vk2vsg
48  // If we cannot find it, we simply return.
49  return false;
50  }
51 
52  // This is the base-key that was pressed. (i.e., the VSG enum of the physical key pressed).
53  keySymbol = itr->second;
54 
55  // Look for any modifiers that may be active.
56  BYTE keyState[256];
57  if (virtualKey == 0 || !::GetKeyboardState(keyState))
58  {
59  // if virtualKey was undefined or we could not get the keyboard state, simply return.
60  return false;
61  }
62 
63  // If any of the specific left/right modifier keys are active
64  // add the side-independent vsg modifier to the modifier Mask
65  switch (virtualKey)
66  {
67  case VK_LSHIFT:
68  case VK_RSHIFT:
69  modifierMask |= vsg::KeyModifier::MODKEY_Shift;
70  break;
71 
72  case VK_LCONTROL:
73  case VK_RCONTROL:
74  modifierMask |= vsg::KeyModifier::MODKEY_Control;
75  break;
76 
77  case VK_LMENU:
78  case VK_RMENU:
79  modifierMask |= vsg::KeyModifier::MODKEY_Alt;
80  break;
81 
82  default:
83  virtualKey = static_cast<int>(wParam);
84  break;
85  }
86 
87  // Check if caps lock or numlock is toggled.
88  if (keyState[VK_CAPITAL] & 0x01) modifierMask |= vsg::KeyModifier::MODKEY_CapsLock;
89  if (keyState[VK_NUMLOCK] & 0x01) modifierMask |= vsg::KeyModifier::MODKEY_NumLock;
90 
91  // This is the final keyModifier
92  keyModifier = static_cast<vsg::KeyModifier>(modifierMask);
93 
94  // The actual keystroke is what we get after the ::ToAscii call
95  char asciiKey[2];
96  int32_t numChars = ::ToAscii(static_cast<UINT>(wParam), (lParam >> 16) & 0xff, keyState, reinterpret_cast<WORD*>(asciiKey), 0);
97  if (numChars == 1)
98  {
99  // it is indeed an ascii character. 0-127
100  modifiedKeySymbol = static_cast<vsg::KeySymbol>(asciiKey[0]);
101  }
102  else
103  {
104  // otherwise treat the modifiedKeySymbol as the same as the keySymbol.
105  modifiedKeySymbol = keySymbol;
106  }
107 
108  return true;
109  }
110 
111  protected:
112  VirtualKeyToKeySymbolMap _vk2vsg;
113  };
114 
115  vsg::ButtonMask getButtonMask(WPARAM wParam)
116  {
117  auto mask = (wParam & MK_LBUTTON ? vsg::ButtonMask::BUTTON_MASK_1 : 0) | (wParam & MK_MBUTTON ? vsg::ButtonMask::BUTTON_MASK_2 : 0) | (wParam & MK_RBUTTON ? vsg::ButtonMask::BUTTON_MASK_3 : 0) |
118  (wParam & MK_XBUTTON1 ? vsg::ButtonMask::BUTTON_MASK_4 : 0) | (wParam & MK_XBUTTON2 ? vsg::ButtonMask::BUTTON_MASK_5 : 0);
119  return static_cast<vsg::ButtonMask>(mask);
120  }
121 
122  uint32_t getButtonDownEventDetail(UINT buttonMsg)
123  {
124  return buttonMsg == WM_LBUTTONDOWN ? 1 : (buttonMsg == WM_MBUTTONDOWN ? 2 : buttonMsg == WM_RBUTTONDOWN ? 3
125  : (buttonMsg == WM_XBUTTONDOWN ? 4 : 0)); // need to determine x1, x2
126  }
127 
128  uint32_t getButtonUpEventDetail(UINT buttonMsg)
129  {
130  return buttonMsg == WM_LBUTTONUP ? 1 : (buttonMsg == WM_MBUTTONUP ? 2 : buttonMsg == WM_RBUTTONUP ? 3
131  : (buttonMsg == WM_XBUTTONUP ? 4 : 0));
132  }
133 
135  class Win32_Window : public vsg::Inherit<vsg::Window, Win32_Window>
136  {
137  public:
139  Win32_Window() = delete;
140  Win32_Window(const Win32_Window&) = delete;
141  Win32_Window operator=(const Win32_Window&) = delete;
142 
143  const char* instanceExtensionSurfaceName() const override { return VK_KHR_WIN32_SURFACE_EXTENSION_NAME; }
144 
145  bool valid() const override { return _window; }
146 
147  bool visible() const override;
148 
149  bool pollEvents(vsg::UIEvents& events) override;
150 
151  void resize() override;
152 
153  operator HWND() { return _window; }
154  operator const HWND() const { return _window; }
155 
156  LRESULT handleWin32Messages(UINT msg, WPARAM wParam, LPARAM lParam);
157 
158  protected:
159  virtual ~Win32_Window();
160 
161  void _initSurface() override;
162 
163  HWND _window;
164  bool _windowMapped = false;
165 
166  vsg::ref_ptr<KeyboardMap> _keyboard;
167  };
168 
169 } // namespace vsgWin32
170 
171 EVSG_type_name(vsgWin32::Win32_Window);
Definition: Win32_Window.h:33
Win32_Window implements Win32 specific window creation, event handling and vulkan Surface setup.
Definition: Win32_Window.h:136
bool pollEvents(vsg::UIEvents &events) override
get the list of events since the last poolEvents() call by splicing bufferEvents with polled windowin...
Definition: Inherit.h:28
Definition: Object.h:42