Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/GHOST_C-api.h7
-rw-r--r--intern/ghost/GHOST_ISystem.h6
-rw-r--r--intern/ghost/GHOST_Types.h6
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp7
-rw-r--r--intern/ghost/intern/GHOST_System.cpp15
-rw-r--r--intern/ghost/intern/GHOST_System.h13
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp9
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp90
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h76
9 files changed, 223 insertions, 6 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 1ce051d2660..45ec41f63a0 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -743,6 +743,13 @@ extern GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthan
extern GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle);
/**
+ * Set which tablet API to use. Only affects Windows, other platforms have a single API.
+ * \param systemhandle The handle to the system
+ * \param api Enum indicating which API to use.
+ */
+extern void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api);
+
+/**
* Returns the status of the tablet
* \param windowhandle The handle to the window
* \return Status of tablet
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 42ae750e20a..39686c56719 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -397,6 +397,12 @@ public:
*/
virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const = 0;
+ /**
+ * Set which tablet API to use. Only affects Windows, other platforms have a single API.
+ * \param api Enum indicating which API to use.
+ */
+ virtual void setTabletAPI(GHOST_TTabletAPI api) = 0;
+
#ifdef WITH_INPUT_NDOF
/**
* Sets 3D mouse deadzone
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 1fc1d1a3e56..f786c99342b 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -90,6 +90,12 @@ typedef enum {
GHOST_kTabletModeEraser
} GHOST_TTabletMode;
+typedef enum {
+ GHOST_kTabletAutomatic = 0,
+ GHOST_kTabletNative,
+ GHOST_kTabletWintab,
+} GHOST_TTabletAPI;
+
typedef struct GHOST_TabletData {
GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */
float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index ab0e7b724b8..d3fb7d6f043 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -750,8 +750,13 @@ GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle)
return window->invalidate();
}
+void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api)
+{
+ GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ system->setTabletAPI(api);
+}
-extern const GHOST_TabletData *GHOST_GetTabletData(GHOST_WindowHandle windowhandle)
+const GHOST_TabletData *GHOST_GetTabletData(GHOST_WindowHandle windowhandle)
{
return ((GHOST_IWindow *)windowhandle)->GetTabletData();
}
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index fc69900acdf..149649f11d1 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -52,10 +52,11 @@ GHOST_System::GHOST_System()
m_displayManager(NULL),
m_timerManager(NULL),
m_windowManager(NULL),
- m_eventManager(NULL)
+ m_eventManager(NULL),
#ifdef WITH_INPUT_NDOF
- , m_ndofManager(0)
+ m_ndofManager(0),
#endif
+ m_tabletAPI(GHOST_kTabletAutomatic)
{
}
@@ -297,6 +298,16 @@ GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButtonMask mask, bool& isDown
return success;
}
+void GHOST_System::setTabletAPI(GHOST_TTabletAPI api)
+{
+ m_tabletAPI = api;
+}
+
+bool GHOST_System::useTabletAPI(GHOST_TTabletAPI api) const
+{
+ return (m_tabletAPI == GHOST_kTabletAutomatic || m_tabletAPI == api);
+}
+
#ifdef WITH_INPUT_NDOF
void GHOST_System::setNDOFDeadZone(float deadzone)
{
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index ee3c30c35b4..7660ddc947e 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -247,6 +247,17 @@ public:
*/
GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const;
+ /**
+ * Set which tablet API to use. Only affects Windows, other platforms have a single API.
+ * \param api Enum indicating which API to use.
+ */
+ void setTabletAPI(GHOST_TTabletAPI api);
+
+ /**
+ * Test if given tablet API should be used by event handling.
+ */
+ bool useTabletAPI(GHOST_TTabletAPI api) const;
+
#ifdef WITH_INPUT_NDOF
/***************************************************************************************
* Access to 3D mouse.
@@ -380,6 +391,8 @@ protected:
/** Settings of the display before the display went fullscreen. */
GHOST_DisplaySetting m_preFullScreenSetting;
+ /** Which tablet API to use. */
+ GHOST_TTabletAPI m_tabletAPI;
};
inline GHOST_TimerManager *GHOST_System::getTimerManager() const
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 00852c1ad05..70010f8b558 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -122,6 +122,10 @@
#define WM_DPICHANGED 0x02E0
#endif // WM_DPICHANGED
+#ifndef WM_POINTERUPDATE
+#define WM_POINTERUPDATE 0x0245
+#endif // WM_POINTERUPDATE
+
/* Workaround for some laptop touchpads, some of which seems to
* have driver issues which makes it so window function receives
* the message, but PeekMessage doesn't pick those messages for
@@ -1233,6 +1237,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WT_PROXIMITY:
window->processWin32TabletInitEvent();
break;
+ case WM_POINTERUPDATE:
+ window->processWin32PointerEvent(wParam);
+ break;
////////////////////////////////////////////////////////////////////////
// Mouse events, processed
////////////////////////////////////////////////////////////////////////
@@ -1450,8 +1457,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* change such as when the window is moved to a monitor with a different DPI.
*/
{
- WORD newYAxisDPI = HIWORD(wParam);
- WORD newXAxisDPI = LOWORD(wParam);
// The suggested new size and position of the window.
RECT* const suggestedWindowRect = (RECT*)lParam;
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 7027c2af368..da23baa3111 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -51,7 +51,9 @@
#include <string.h>
#include <assert.h>
-
+#ifndef GET_POINTERID_WPARAM
+#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
+#endif // GET_POINTERID_WPARAM
const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass";
const int GHOST_WindowWin32::s_maxTitleLength = 128;
@@ -89,6 +91,8 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_wantAlphaBackground(alphaBackground),
m_normal_state(GHOST_kWindowStateNormal),
m_user32(NULL),
+ m_fpGetPointerInfo(NULL),
+ m_fpGetPointerPenInfo(NULL),
m_parentWindowHwnd(parentwindowhwnd),
m_debug_context(is_debug)
{
@@ -284,6 +288,12 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
RegisterRawInputDevices(&device, 1, sizeof(device));
}
+ // Initialize Windows Ink
+ if (m_user32) {
+ m_fpGetPointerInfo = (GHOST_WIN32_GetPointerInfo) ::GetProcAddress(m_user32, "GetPointerInfo");
+ m_fpGetPointerPenInfo = (GHOST_WIN32_GetPointerPenInfo) ::GetProcAddress(m_user32, "GetPointerPenInfo");
+ }
+
// Initialize Wintab
m_wintab.handle = ::LoadLibrary("Wintab32.dll");
if (m_wintab.handle) {
@@ -353,6 +363,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
if (m_Bar) {
m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS);
m_Bar->Release();
+ m_Bar = NULL;
}
if (m_wintab.handle) {
@@ -364,6 +375,13 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
memset(&m_wintab, 0, sizeof(m_wintab));
}
+ if (m_user32) {
+ FreeLibrary(m_user32);
+ m_user32 = NULL;
+ m_fpGetPointerInfo = NULL;
+ m_fpGetPointerPenInfo = NULL;
+ }
+
if (m_customCursor) {
DestroyCursor(m_customCursor);
m_customCursor = NULL;
@@ -371,6 +389,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
if (m_hWnd != NULL && m_hDC != NULL && releaseNativeHandles()) {
::ReleaseDC(m_hWnd, m_hDC);
+ m_hDC = NULL;
}
if (m_hWnd) {
@@ -379,6 +398,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
RevokeDragDrop(m_hWnd);
// Release our reference of the DropTarget and it will delete itself eventually.
m_dropTarget->Release();
+ m_dropTarget = NULL;
}
::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL);
::DestroyWindow(m_hWnd);
@@ -866,8 +886,62 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cur
return GHOST_kSuccess;
}
+void GHOST_WindowWin32::processWin32PointerEvent(WPARAM wParam)
+{
+ if (!m_system->useTabletAPI(GHOST_kTabletNative)) {
+ return; // Other tablet API specified by user
+ }
+
+ if (!m_fpGetPointerInfo || !m_fpGetPointerPenInfo) {
+ return; // OS version does not support pointer API
+ }
+
+ UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
+ POINTER_INFO pointerInfo;
+ if (!m_fpGetPointerInfo(pointerId, &pointerInfo)) {
+ return; // Invalid pointer info
+ }
+
+ m_tabletData.Active = GHOST_kTabletModeNone;
+ m_tabletData.Pressure = 1.0f;
+ m_tabletData.Xtilt = 0.0f;
+ m_tabletData.Ytilt = 0.0f;
+
+ if (pointerInfo.pointerType & PT_POINTER) {
+ POINTER_PEN_INFO pointerPenInfo;
+ if (!m_fpGetPointerPenInfo(pointerId, &pointerPenInfo)) {
+ return;
+ }
+
+ // With the Microsoft Surface Pen if you hover the within 1cm of the screen the WM_POINTERUPDATE
+ // event will fire with PEN_MASK_PRESSURE mask set and zero pressure. In this case we disable
+ // tablet mode until the pen is physically touching. This enables the user to switch to the
+ // mouse and draw at full pressure.
+ if (pointerPenInfo.penMask & PEN_MASK_PRESSURE && pointerPenInfo.pressure > 0) {
+ m_tabletData.Active = GHOST_kTabletModeStylus;
+ m_tabletData.Pressure = pointerPenInfo.pressure / 1024.0f;
+ }
+
+ if (pointerPenInfo.penFlags & PEN_FLAG_ERASER) {
+ m_tabletData.Active = GHOST_kTabletModeEraser;
+ }
+
+ if (pointerPenInfo.penFlags & PEN_MASK_TILT_X) {
+ m_tabletData.Xtilt = fmin(fabs(pointerPenInfo.tiltX / 90), 1.0f);
+ }
+
+ if (pointerPenInfo.penFlags & PEN_MASK_TILT_Y) {
+ m_tabletData.Ytilt = fmin(fabs(pointerPenInfo.tiltY / 90), 1.0f);
+ }
+ }
+}
+
void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
{
+ if (!m_system->useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
if (m_wintab.enable && m_wintab.tablet) {
m_wintab.enable(m_wintab.tablet, state);
@@ -879,6 +953,10 @@ void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
void GHOST_WindowWin32::processWin32TabletInitEvent()
{
+ if (!m_system->useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
// Let's see if we can initialize tablet here
if (m_wintab.info && m_wintab.tablet) {
AXIS Pressure, Orientation[3]; /* The maximum tablet size */
@@ -903,10 +981,16 @@ void GHOST_WindowWin32::processWin32TabletInitEvent()
m_tabletData.Active = GHOST_kTabletModeNone;
}
+
+ m_tabletData.Active = GHOST_kTabletModeNone;
}
void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
{
+ if (!m_system->useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
if (m_wintab.packet && m_wintab.tablet) {
PACKET pkt;
if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) {
@@ -972,6 +1056,10 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
void GHOST_WindowWin32::bringTabletContextToFront()
{
+ if (!m_system->useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
if (m_wintab.overlap && m_wintab.tablet) {
m_wintab.overlap(m_wintab.tablet, TRUE);
}
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index d790d5c3d24..4efcac53c85 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -68,6 +68,79 @@ typedef UINT(API * GHOST_WIN32_GetDpiForWindow)(HWND);
#define USER_DEFAULT_SCREEN_DPI 96
#endif // USER_DEFAULT_SCREEN_DPI
+// typedefs for user32 functions to allow pointer functions
+enum tagPOINTER_INPUT_TYPE {
+ PT_POINTER = 1, // Generic pointer
+ PT_TOUCH = 2, // Touch
+ PT_PEN = 3, // Pen
+ PT_MOUSE = 4, // Mouse
+#if(WINVER >= 0x0603)
+ PT_TOUCHPAD = 5, // Touchpad
+#endif /* WINVER >= 0x0603 */
+};
+
+typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
+ POINTER_CHANGE_NONE,
+ POINTER_CHANGE_FIRSTBUTTON_DOWN,
+ POINTER_CHANGE_FIRSTBUTTON_UP,
+ POINTER_CHANGE_SECONDBUTTON_DOWN,
+ POINTER_CHANGE_SECONDBUTTON_UP,
+ POINTER_CHANGE_THIRDBUTTON_DOWN,
+ POINTER_CHANGE_THIRDBUTTON_UP,
+ POINTER_CHANGE_FOURTHBUTTON_DOWN,
+ POINTER_CHANGE_FOURTHBUTTON_UP,
+ POINTER_CHANGE_FIFTHBUTTON_DOWN,
+ POINTER_CHANGE_FIFTHBUTTON_UP,
+} POINTER_BUTTON_CHANGE_TYPE;
+
+typedef DWORD POINTER_INPUT_TYPE;
+typedef UINT32 POINTER_FLAGS;
+
+typedef struct tagPOINTER_INFO {
+ POINTER_INPUT_TYPE pointerType;
+ UINT32 pointerId;
+ UINT32 frameId;
+ POINTER_FLAGS pointerFlags;
+ HANDLE sourceDevice;
+ HWND hwndTarget;
+ POINT ptPixelLocation;
+ POINT ptHimetricLocation;
+ POINT ptPixelLocationRaw;
+ POINT ptHimetricLocationRaw;
+ DWORD dwTime;
+ UINT32 historyCount;
+ INT32 InputData;
+ DWORD dwKeyStates;
+ UINT64 PerformanceCount;
+ POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
+} POINTER_INFO;
+
+typedef UINT32 PEN_FLAGS;
+#define PEN_FLAG_NONE 0x00000000 // Default
+#define PEN_FLAG_BARREL 0x00000001 // The barrel button is pressed
+#define PEN_FLAG_INVERTED 0x00000002 // The pen is inverted
+#define PEN_FLAG_ERASER 0x00000004 // The eraser button is pressed
+
+typedef UINT32 PEN_MASK;
+#define PEN_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
+#define PEN_MASK_PRESSURE 0x00000001 // The pressure field is valid
+#define PEN_MASK_ROTATION 0x00000002 // The rotation field is valid
+#define PEN_MASK_TILT_X 0x00000004 // The tiltX field is valid
+#define PEN_MASK_TILT_Y 0x00000008 // The tiltY field is valid
+
+typedef struct tagPOINTER_PEN_INFO {
+ POINTER_INFO pointerInfo;
+ PEN_FLAGS penFlags;
+ PEN_MASK penMask;
+ UINT32 pressure;
+ UINT32 rotation;
+ INT32 tiltX;
+ INT32 tiltY;
+} POINTER_PEN_INFO;
+
+typedef BOOL (API * GHOST_WIN32_GetPointerInfo)(UINT32 pointerId, POINTER_INFO *pointerInfo);
+typedef BOOL (API * GHOST_WIN32_GetPointerPenInfo)(UINT32 pointerId, POINTER_PEN_INFO *penInfo);
+
/**
* GHOST window on M$ Windows OSs.
* \author Maarten Gribnau
@@ -253,6 +326,7 @@ public:
return &m_tabletData;
}
+ void processWin32PointerEvent(WPARAM wParam);
void processWin32TabletActivateEvent(WORD state);
void processWin32TabletInitEvent();
void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
@@ -377,6 +451,8 @@ private:
/** user32 dll handle*/
HMODULE m_user32;
+ GHOST_WIN32_GetPointerInfo m_fpGetPointerInfo;
+ GHOST_WIN32_GetPointerPenInfo m_fpGetPointerPenInfo;
/** Hwnd to parent window */
GHOST_TEmbedderWindowID m_parentWindowHwnd;