There was a problem with the last merge :S
[blender.git] / intern / ghost / intern / GHOST_SystemWin32.cpp
index 3582554ba440a7e84866ac154a924c0d34709fdf..f5c7c08ebfe1d71ec5e68647413009b7485b65a5 100644 (file)
@@ -1,14 +1,11 @@
 /**
  * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -26,7 +23,7 @@
  *
  * Contributor(s): none yet.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
 /**
 #include <config.h>
 #endif
 
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+
 #include "GHOST_SystemWin32.h"
 
+// win64 doesn't define GWL_USERDATA
+#ifdef WIN32
+#ifndef GWL_USERDATA
+#define GWL_USERDATA GWLP_USERDATA
+#define GWL_WNDPROC GWLP_WNDPROC
+#endif
+#endif
+
+/*
+ * According to the docs the mouse wheel message is supported from windows 98 
+ * upwards. Leaving WINVER at default value, the WM_MOUSEWHEEL message and the 
+ * wheel detent value are undefined.
+ */
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x020A
+#endif // WM_MOUSEWHEEL
+#ifndef WHEEL_DELTA
+#define WHEEL_DELTA 120        /* Value for rolling one detent, (old convention! MS changed it) */
+#endif // WHEEL_DELTA
+
 
 #include "GHOST_Debug.h"
 #include "GHOST_DisplayManagerWin32.h"
 #include "GHOST_EventButton.h"
 #include "GHOST_EventCursor.h"
 #include "GHOST_EventKey.h"
+#include "GHOST_EventWheel.h"
+#include "GHOST_EventNDOF.h"
 #include "GHOST_TimerTask.h"
 #include "GHOST_TimerManager.h"
 #include "GHOST_WindowManager.h"
 #include "GHOST_WindowWin32.h"
+#include "GHOST_NDOFManager.h"
 
 // Key code values not found in winuser.h
 #ifndef VK_MINUS
 #ifndef VK_CLOSE_BRACKET
 #define VK_CLOSE_BRACKET 0xDD
 #endif // VK_CLOSE_BRACKET
+#ifndef VK_GR_LESS
+#define VK_GR_LESS 0xE2
+#endif // VK_GR_LESS
 
 
 GHOST_SystemWin32::GHOST_SystemWin32()
@@ -151,9 +176,9 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow(
        if (window) {
                if (window->getValid()) {
                        // Store the pointer to the window
-                       if (state != GHOST_kWindowStateFullScreen) {
+//                     if (state != GHOST_kWindowStateFullScreen) {
                                m_windowManager->addWindow(window);
-                       }
+//                     }
                }
                else {
                        delete window;
@@ -285,6 +310,15 @@ GHOST_TSuccess GHOST_SystemWin32::init()
 {
        GHOST_TSuccess success = GHOST_System::init();
 
+       /* Disable scaling on high DPI displays on Vista */
+       HMODULE user32 = ::LoadLibraryA("user32.dll");
+       typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)();
+       LPFNSETPROCESSDPIAWARE SetProcessDPIAware =
+               (LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware");
+       if (SetProcessDPIAware)
+               SetProcessDPIAware();
+       FreeLibrary(user32);
+
        // Determine whether this system has a high frequency performance counter. */
        m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE;
        if (m_hasPerformanceCounter) {
@@ -302,7 +336,8 @@ GHOST_TSuccess GHOST_SystemWin32::init()
                wc.cbClsExtra= 0;
                wc.cbWndExtra= 0;
                wc.hInstance= ::GetModuleHandle(0);
-               wc.hIcon = ::LoadIcon(wc.hInstance, "APPICON");
+               wc.hIcon = ::LoadIcon(wc.hInstance, "APPICON");
+               
                if (!wc.hIcon) {
                        ::LoadIcon(NULL, IDI_APPLICATION);
                }
@@ -391,6 +426,7 @@ GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
                case VK_BACK_SLASH:             key = GHOST_kKeyBackslash;              break;
                case VK_CLOSE_BRACKET:  key = GHOST_kKeyRightBracket;   break;
                case VK_QUOTE:                  key = GHOST_kKeyQuote;                  break;
+               case VK_GR_LESS:                key = GHOST_kKeyGrLess;                 break;
 
                // Process these keys separately because we need to distinguish right from left modifier keys
                case VK_SHIFT:
@@ -455,6 +491,21 @@ GHOST_EventCursor* GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type,
 }
 
 
+GHOST_EventWheel* GHOST_SystemWin32::processWheelEvent(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam)
+{
+       // short fwKeys = LOWORD(wParam);                       // key flags
+       int zDelta = (short) HIWORD(wParam);    // wheel rotation
+       
+       // zDelta /= WHEEL_DELTA;
+       // temporary fix below: microsoft now has added more precision, making the above division not work
+       if (zDelta <= 0 ) zDelta= -1; else zDelta= 1;   
+       
+       // short xPos = (short) LOWORD(lParam); // horizontal position of pointer
+       // short yPos = (short) HIWORD(lParam); // vertical position of pointer
+       return new GHOST_EventWheel (getSystem()->getMilliSeconds(), window, zDelta);
+}
+
+
 GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, bool keyDown, WPARAM wParam, LPARAM lParam)
 {
        GHOST_TKey key = ((GHOST_SystemWin32*)getSystem())->convertKey(wParam, lParam);
@@ -586,7 +637,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                         * specifies a character code generated by a dead key. A dead key is a key that 
                                         * generates a character, such as the umlaut (double-dot), that is combined with 
                                         * another character to form a composite character. For example, the umlaut-O 
-                                        * character (Ö) is generated by typing the dead key for the umlaut character, and 
+                                        * character (Ù) is generated by typing the dead key for the umlaut character, and 
                                         * then typing the O key.
                                         */
                                case WM_SYSDEADCHAR:
@@ -596,7 +647,16 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                         * a dead key that is pressed while holding down the alt key. 
                                         */
                                        break;
-
+                               ////////////////////////////////////////////////////////////////////////
+                               // Tablet events, processed
+                               ////////////////////////////////////////////////////////////////////////
+                               case WT_PACKET:
+                                       ((GHOST_WindowWin32*)window)->processWin32TabletEvent(wParam, lParam);
+                                       break;
+                               case WT_CSRCHANGE:
+                               case WT_PROXIMITY:
+                                       ((GHOST_WindowWin32*)window)->processWin32TabletInitEvent();
+                                       break;
                                ////////////////////////////////////////////////////////////////////////
                                // Mouse events, processed
                                ////////////////////////////////////////////////////////////////////////
@@ -627,6 +687,16 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                case WM_MOUSEMOVE:
                                        event = processCursorEvent(GHOST_kEventCursorMove, window);
                                        break;
+                               case WM_MOUSEWHEEL:
+                                       /* The WM_MOUSEWHEEL message is sent to the focus window 
+                                        * when the mouse wheel is rotated. The DefWindowProc 
+                                        * function propagates the message to the window's parent.
+                                        * There should be no internal forwarding of the message, 
+                                        * since DefWindowProc propagates it up the parent chain 
+                                        * until it finds a window that processes it.
+                                        */
+                                       event = processWheelEvent(window, wParam, lParam);
+                                       break;
                                case WM_SETCURSOR:
                                        /* The WM_SETCURSOR message is sent to a window if the mouse causes the cursor
                                         * to move within a window and mouse input is not captured.
@@ -791,6 +861,28 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                         * In GHOST, we let DefWindowProc call the timer callback.
                                         */
                                        break;
+                               case WM_BLND_NDOF_AXIS:
+                                       {
+                                               GHOST_TEventNDOFData ndofdata;
+                                               system->m_ndofManager->GHOST_NDOFGetDatas(ndofdata);
+                                               system->m_eventManager->
+                                                       pushEvent(new GHOST_EventNDOF(
+                                                               system->getMilliSeconds(), 
+                                                               GHOST_kEventNDOFMotion, 
+                                                               window, ndofdata));
+                                       }
+                                       break;
+                               case WM_BLND_NDOF_BTN:
+                                       {
+                                               GHOST_TEventNDOFData ndofdata;
+                                               system->m_ndofManager->GHOST_NDOFGetDatas(ndofdata);
+                                               system->m_eventManager->
+                                                       pushEvent(new GHOST_EventNDOF(
+                                                               system->getMilliSeconds(), 
+                                                               GHOST_kEventNDOFButton, 
+                                                               window, ndofdata));
+                                       }
+                                       break;
                        }
                }
                else {
@@ -819,3 +911,54 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
        }
        return lResult;
 }
+
+GHOST_TUns8* GHOST_SystemWin32::getClipboard(int flag) const 
+{
+       char *buffer;
+       char *temp_buff;
+       
+       if ( OpenClipboard(NULL) ) {
+               HANDLE hData = GetClipboardData( CF_TEXT );
+               buffer = (char*)GlobalLock( hData );
+               
+               temp_buff = (char*) malloc(strlen(buffer)+1);
+               strcpy(temp_buff, buffer);
+               
+               GlobalUnlock( hData );
+               CloseClipboard();
+               
+               temp_buff[strlen(buffer)] = '\0';
+               if (buffer) {
+                       return (GHOST_TUns8*)temp_buff;
+               } else {
+                       return NULL;
+               }
+       } else {
+               return NULL;
+       }
+}
+
+void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, int flag) const
+{
+       if(flag == 1) {return;} //If Flag is 1 means the selection and is used on X11
+       if (OpenClipboard(NULL)) {
+               HLOCAL clipbuffer;
+               char *data;
+               
+               if (buffer) {
+                       EmptyClipboard();
+                       
+                       clipbuffer = LocalAlloc(LMEM_FIXED,((strlen(buffer)+1)));
+                       data = (char*)GlobalLock(clipbuffer);
+
+                       strcpy(data, (char*)buffer);
+                       data[strlen(buffer)] = '\0';
+                       LocalUnlock(clipbuffer);
+                       SetClipboardData(CF_TEXT,clipbuffer);
+               }
+               CloseClipboard();
+       } else {
+               return;
+       }
+}
+