Merge branch 'master' into blender2.8
[blender.git] / intern / ghost / intern / GHOST_SystemWin32.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file ghost/intern/GHOST_SystemWin32.h
29  *  \ingroup GHOST
30  * Declaration of GHOST_SystemWin32 class.
31  */
32
33 #ifndef __GHOST_SYSTEMWIN32_H__
34 #define __GHOST_SYSTEMWIN32_H__
35
36 #ifndef WIN32
37 #error WIN32 only!
38 #endif // WIN32
39
40 /* require Windows XP or newer */
41 #undef _WIN32_WINNT
42 #define _WIN32_WINNT 0x501
43
44 #define WIN32_LEAN_AND_MEAN
45 #include <windows.h>
46 #include <ole2.h> // for drag-n-drop
47
48 #include "GHOST_System.h"
49
50 class GHOST_EventButton;
51 class GHOST_EventCursor;
52 class GHOST_EventKey;
53 class GHOST_EventWheel;
54 class GHOST_EventWindow;
55 class GHOST_EventDragnDrop;
56
57 class GHOST_WindowWin32;
58
59 /**
60  * WIN32 Implementation of GHOST_System class.
61  * \see GHOST_System.
62  * \author      Maarten Gribnau
63  * \date        May 10, 2001
64  */
65 class GHOST_SystemWin32 : public GHOST_System {
66 public:
67         /**
68          * Constructor.
69          */
70         GHOST_SystemWin32();
71
72         /**
73          * Destructor.
74          */
75         ~GHOST_SystemWin32();
76
77         /***************************************************************************************
78          ** Time(r) functionality
79          ***************************************************************************************/
80
81         /**
82          * Returns the system time.
83          * Returns the number of milliseconds since the start of the system process.
84          * This overloaded method uses the high frequency timer if available.
85          * \return The number of milliseconds.
86          */
87         GHOST_TUns64 getMilliSeconds() const;
88
89         /***************************************************************************************
90          ** Display/window management functionality
91          ***************************************************************************************/
92
93         /**
94          * Returns the number of displays on this system.
95          * \return The number of displays.
96          */
97         GHOST_TUns8 getNumDisplays() const;
98
99         /**
100          * Returns the dimensions of the main display on this system.
101          * \return The dimension of the main display.
102          */
103         void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
104
105         /**
106          * Returns the dimensions of all displays on this system.
107          * \return The dimension of the main display.
108          */
109         void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
110
111         /**
112          * Create a new window.
113          * The new window is added to the list of windows managed.
114          * Never explicitly delete the window, use disposeWindow() instead.
115          * \param       title   The name of the window (displayed in the title bar of the window if the OS supports it).
116          * \param       left    The coordinate of the left edge of the window.
117          * \param       top             The coordinate of the top edge of the window.
118          * \param       width   The width the window.
119          * \param       height  The height the window.
120          * \param       state   The state of the window when opened.
121          * \param       type    The type of drawing context installed in this window.
122          * \param glSettings: Misc OpenGL settings.
123          * \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
124          * \param       parentWindow    Parent (embedder) window
125          * \return      The new window (or 0 if creation failed).
126          */
127         GHOST_IWindow *createWindow(
128             const STR_String& title,
129             GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
130             GHOST_TWindowState state, GHOST_TDrawingContextType type,
131             GHOST_GLSettings glSettings,
132             const bool exclusive = false,
133             const GHOST_TEmbedderWindowID parentWindow = 0);
134
135
136         /**
137          * Create a new offscreen context.
138          * Never explicitly delete the window, use disposeContext() instead.
139          * \return  The new context (or 0 if creation failed).
140          */
141         GHOST_IContext *createOffscreenContext();
142
143         /**
144          * Dispose of a context.
145          * \param   context Pointer to the context to be disposed.
146          * \return  Indication of success.
147          */
148         GHOST_TSuccess disposeContext(GHOST_IContext *context);
149
150         /***************************************************************************************
151          ** Event management functionality
152          ***************************************************************************************/
153
154         /**
155          * Gets events from the system and stores them in the queue.
156          * \param waitForEvent Flag to wait for an event (or return immediately).
157          * \return Indication of the presence of events.
158          */
159         bool processEvents(bool waitForEvent);
160
161
162         /***************************************************************************************
163          ** Cursor management functionality
164          ***************************************************************************************/
165
166         /**
167          * Returns the current location of the cursor (location in screen coordinates)
168          * \param x                     The x-coordinate of the cursor.
169          * \param y                     The y-coordinate of the cursor.
170          * \return                      Indication of success.
171          */
172         GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
173
174         /**
175          * Updates the location of the cursor (location in screen coordinates).
176          * \param x                     The x-coordinate of the cursor.
177          * \param y                     The y-coordinate of the cursor.
178          * \return                      Indication of success.
179          */
180         GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
181
182         /***************************************************************************************
183          ** Access to mouse button and keyboard states.
184          ***************************************************************************************/
185
186         /**
187          * Returns the state of all modifier keys.
188          * \param keys  The state of all modifier keys (true == pressed).
189          * \return              Indication of success.
190          */
191         GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
192
193         /**
194          * Returns the state of the mouse buttons (ouside the message queue).
195          * \param buttons       The state of the buttons.
196          * \return                      Indication of success.
197          */
198         GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
199
200         /**
201          * Returns unsigned char from CUT_BUFFER0
202          * \param selection             Used by X11 only
203          * \return                              Returns the Clipboard
204          */
205         GHOST_TUns8 *getClipboard(bool selection) const;
206
207         /**
208          * Puts buffer to system clipboard
209          * \param selection             Used by X11 only
210          * \return                              No return
211          */
212         void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
213
214         /**
215          * Creates a drag'n'drop event and pushes it immediately onto the event queue.
216          * Called by GHOST_DropTargetWin32 class.
217          * \param eventType The type of drag'n'drop event
218          * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap)
219          * \param mouseX x mouse coordinate (in window coordinates)
220          * \param mouseY y mouse coordinate
221          * \param window The window on which the event occurred
222          * \return Indication whether the event was handled.
223          */
224         static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_WindowWin32 *window, int mouseX, int mouseY, void *data);
225
226         /**
227          * Confirms quitting he program when there is just one window left open
228          * in the application
229          */
230         int confirmQuit(GHOST_IWindow *window) const;
231
232 protected:
233         /**
234          * Initializes the system.
235          * For now, it just registers the window class (WNDCLASS).
236          * \return A success value.
237          */
238         GHOST_TSuccess init();
239
240         /**
241          * Closes the system down.
242          * \return A success value.
243          */
244         GHOST_TSuccess exit();
245
246         /**
247          * Converts raw WIN32 key codes from the wndproc to GHOST keys.
248          * \param vKey          The virtual key from hardKey
249          * \param ScanCode      The ScanCode of pressed key (similar to PS/2 Set 1)
250          * \param extend        Flag if key is not primly (left or right)
251          * \return The GHOST key (GHOST_kKeyUnknown if no match).
252          */
253         GHOST_TKey convertKey(short vKey, short ScanCode, short extend) const;
254
255         /**
256          * Catches raw WIN32 key codes from WM_INPUT in the wndproc.
257          * \param raw           RawInput structure with detailed info about the key event
258          * \param keyDown       Pointer flag that specify if a key is down
259          * \param vk            Pointer to virtual key
260          * \return The GHOST key (GHOST_kKeyUnknown if no match).
261          */
262         GHOST_TKey hardKey(RAWINPUT const& raw, int *keyDown, char *vk);
263
264         /**
265          * Creates mouse button event.
266          * \param type          The type of event to create.
267          * \param window        The window receiving the event (the active window).
268          * \param mask          The button mask of this event.
269          * \return The event created.
270          */
271         static GHOST_EventButton *processButtonEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TButtonMask mask);
272
273         /**
274          * Creates cursor event.
275          * \param type          The type of event to create.
276          * \param window        The window receiving the event (the active window).
277          * \return The event created.
278          */
279         static GHOST_EventCursor *processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window);
280
281         /**
282          * Handles a mouse wheel event.
283          * \param window        The window receiving the event (the active window).
284          * \param wParam        The wParam from the wndproc
285          * \param lParam        The lParam from the wndproc
286          */
287         static void processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam);
288
289         /**
290          * Creates a key event and updates the key data stored locally (m_modifierKeys).
291          * In most cases this is a straightforward conversion of key codes.
292          * For the modifier keys however, we want to distinguish left and right keys.
293          * \param window        The window receiving the event (the active window).
294          * \param raw           RawInput structure with detailed info about the key event
295          */
296         static GHOST_EventKey *processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const& raw);
297
298         /**
299          * Process special keys (VK_OEM_*), to see if current key layout
300          * gives us anything special, like ! on french AZERTY.
301          * \param vKey          The virtual key from hardKey
302          * \param scanCode      The ScanCode of pressed key (simular to PS/2 Set 1)
303          */
304         GHOST_TKey processSpecialKey(short vKey, short scanCode) const;
305
306         /**
307          * Creates a window event.
308          * \param type          The type of event to create.
309          * \param window        The window receiving the event (the active window).
310          * \return The event created.
311          */
312         static GHOST_Event *processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window);
313
314 #ifdef WITH_INPUT_IME
315         /**
316          * Creates a IME event.
317          * \param type          The type of event to create.
318          * \param window                The window receiving the event (the active window).
319          * \param data          IME data.
320          * \return The event created.
321          */
322         static GHOST_Event *processImeEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TEventImeData *data);
323 #endif // WITH_INPUT_IME
324
325         /**
326          * Handles minimum window size.
327          * \param minmax        The MINMAXINFO structure.
328          */
329         static void processMinMaxInfo(MINMAXINFO *minmax);
330
331 #ifdef WITH_INPUT_NDOF
332         /**
333          * Handles Motion and Button events from a SpaceNavigator or related device.
334          * Instead of returning an event object, this function communicates directly
335          * with the GHOST_NDOFManager.
336          * \param raw           RawInput structure with detailed info about the NDOF event
337          * \return Whether an event was generated and sent.
338          */
339         bool processNDOF(RAWINPUT const& raw);
340 #endif
341
342         /**
343          * Returns the local state of the modifier keys (from the message queue).
344          * \param keys The state of the keys.
345          */
346         inline void retrieveModifierKeys(GHOST_ModifierKeys& keys) const;
347
348         /**
349          * Stores the state of the modifier keys locally.
350          * For internal use only!
351          * param keys The new state of the modifier keys.
352          */
353         inline void storeModifierKeys(const GHOST_ModifierKeys& keys);
354
355         /**
356          * Check current key layout for AltGr
357          */
358         inline void handleKeyboardChange(void);
359
360         /**
361          * Windows call back routine for our window class.
362          */
363         static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
364
365         /**
366          * Toggles console
367          * \param action
368          * - 0 - Hides
369          * - 1 - Shows
370          * - 2 - Toggles
371          * - 3 - Hides if it runs not from  command line
372          * - * - Does nothing
373          * \return current status (1 -visible, 0 - hidden)
374          */
375         int toggleConsole(int action);
376
377         /** The current state of the modifier keys. */
378         GHOST_ModifierKeys m_modifierKeys;
379         /** State variable set at initialization. */
380         bool m_hasPerformanceCounter;
381         /** High frequency timer variable. */
382         __int64 m_freq;
383         /** High frequency timer variable. */
384         __int64 m_start;
385         /** AltGr on current keyboard layout. */
386         bool m_hasAltGr;
387         /** language identifier. */
388         WORD m_langId;
389         /** stores keyboard layout. */
390         HKL m_keylayout;
391
392         /** Console status */
393         int m_consoleStatus;
394
395         /** Wheel delta accumulator **/
396         int m_wheelDeltaAccum;
397 };
398
399 inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const
400 {
401         keys = m_modifierKeys;
402 }
403
404 inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys& keys)
405 {
406         m_modifierKeys = keys;
407 }
408
409 inline void GHOST_SystemWin32::handleKeyboardChange(void)
410 {
411         m_keylayout = GetKeyboardLayout(0); // get keylayout for current thread
412         int i;
413         SHORT s;
414
415         // save the language identifier.
416         m_langId = LOWORD(m_keylayout);
417
418         for (m_hasAltGr = false, i = 32; i < 256; ++i) {
419                 s = VkKeyScanEx((char)i, m_keylayout);
420                 // s == -1 means no key that translates passed char code
421                 // high byte contains shift state. bit 2 ctrl pressed, bit 4 alt pressed
422                 // if both are pressed, we have AltGr keycombo on keylayout
423                 if (s != -1 && (s & 0x600) == 0x600) {
424                         m_hasAltGr = true;
425                         break;
426                 }
427         }
428 }
429 #endif // __GHOST_SYSTEMWIN32_H__