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:
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp68
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h11
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp110
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h67
4 files changed, 218 insertions, 38 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index bf12f049283..ebec5a773a0 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -116,6 +116,9 @@
#define WM_POINTERUPDATE 0x0245
#endif // WM_POINTERUPDATE
+#define WM_POINTERDOWN 0x0246
+#define WM_POINTERUP 0x0247
+
/* 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
@@ -791,9 +794,55 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(
GHOST_WindowWin32 *window,
GHOST_TButtonMask mask)
{
- return new GHOST_EventButton(getSystem()->getMilliSeconds(), type, window, mask);
+ GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem();
+ if (window->useTabletAPI(GHOST_kTabletNative)) {
+ window->setTabletData(NULL);
+ }
+ return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask);
}
+GHOST_Event *GHOST_SystemWin32::processPointerEvent(
+ GHOST_TEventType type,
+ GHOST_WindowWin32 *window,
+ WPARAM wParam,
+ LPARAM lParam,
+ bool& eventHandled)
+{
+ GHOST_PointerInfoWin32 pointerInfo;
+ GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem();
+
+ if (!window->useTabletAPI(GHOST_kTabletNative)) {
+ return NULL;
+ }
+
+ if (window->getPointerInfo(&pointerInfo, wParam, lParam) != GHOST_kSuccess) {
+ return NULL;
+ }
+
+ if (!pointerInfo.isPrimary) {
+ eventHandled = true;
+ return NULL; // For multi-touch displays we ignore these events
+ }
+
+ system->setCursorPosition(pointerInfo.pixelLocation.x, pointerInfo.pixelLocation.y);
+
+ switch (type) {
+ case GHOST_kEventButtonDown:
+ window->setTabletData(&pointerInfo.tabletData);
+ eventHandled = true;
+ return new GHOST_EventButton(system->getMilliSeconds(), GHOST_kEventButtonDown, window, pointerInfo.buttonMask);
+ case GHOST_kEventButtonUp:
+ eventHandled = true;
+ return new GHOST_EventButton(system->getMilliSeconds(), GHOST_kEventButtonUp, window, pointerInfo.buttonMask);
+ case GHOST_kEventCursorMove:
+ window->setTabletData(&pointerInfo.tabletData);
+ eventHandled = true;
+ return new GHOST_EventCursor(system->getMilliSeconds(), GHOST_kEventCursorMove, window,
+ pointerInfo.pixelLocation.x, pointerInfo.pixelLocation.y);
+ default:
+ return NULL;
+ }
+}
GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window)
{
@@ -1220,8 +1269,23 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WT_PROXIMITY:
window->processWin32TabletInitEvent();
break;
+ ////////////////////////////////////////////////////////////////////////
+ // Pointer events, processed
+ ////////////////////////////////////////////////////////////////////////
+ case WM_POINTERDOWN:
+ event = processPointerEvent(GHOST_kEventButtonDown, window, wParam, lParam, eventHandled);
+ if (event && eventHandled) {
+ window->registerMouseClickEvent(0);
+ }
+ break;
+ case WM_POINTERUP:
+ event = processPointerEvent(GHOST_kEventButtonUp, window, wParam, lParam, eventHandled);
+ if (event && eventHandled) {
+ window->registerMouseClickEvent(1);
+ }
+ break;
case WM_POINTERUPDATE:
- window->processWin32PointerEvent(wParam);
+ event = processPointerEvent(GHOST_kEventCursorMove, window, wParam, lParam, eventHandled);
break;
////////////////////////////////////////////////////////////////////////
// Mouse events, processed
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index edf7c3fb695..62492e8d8b7 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -261,6 +261,17 @@ protected:
static GHOST_EventButton *processButtonEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TButtonMask mask);
/**
+ * Creates pointer event.
+ * \param type The type of event to create.
+ * \param window The window receiving the event (the active window).
+ * \param wParam The wParam from the wndproc
+ * \param lParam The lParam from the wndproc
+ * \param eventhandled true if the method handled the event
+ * \return The event created.
+ */
+ static GHOST_Event *processPointerEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool & eventhandled);
+
+ /**
* Creates cursor event.
* \param type The type of event to create.
* \param window The window receiving the event (the active window).
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index b119a32e002..ed5e0798643 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -39,6 +39,7 @@
#include <Dwmapi.h>
#endif
+#include <windowsx.h>
#include <math.h>
#include <string.h>
#include <assert.h>
@@ -82,9 +83,10 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_customCursor(0),
m_wantAlphaBackground(alphaBackground),
m_normal_state(GHOST_kWindowStateNormal),
- m_user32(NULL),
+ m_user32(NULL),
m_fpGetPointerInfo(NULL),
m_fpGetPointerPenInfo(NULL),
+ m_fpGetPointerTouchInfo(NULL),
m_parentWindowHwnd(parentwindowhwnd),
m_debug_context(is_debug)
{
@@ -284,6 +286,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
if (m_user32) {
m_fpGetPointerInfo = (GHOST_WIN32_GetPointerInfo) ::GetProcAddress(m_user32, "GetPointerInfo");
m_fpGetPointerPenInfo = (GHOST_WIN32_GetPointerPenInfo) ::GetProcAddress(m_user32, "GetPointerPenInfo");
+ m_fpGetPointerTouchInfo = (GHOST_WIN32_GetPointerTouchInfo) ::GetProcAddress(m_user32, "GetPointerTouchInfo");
}
// Initialize Wintab
@@ -372,6 +375,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
m_user32 = NULL;
m_fpGetPointerInfo = NULL;
m_fpGetPointerPenInfo = NULL;
+ m_fpGetPointerTouchInfo = NULL;
}
if (m_customCursor) {
@@ -396,11 +400,6 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
::DestroyWindow(m_hWnd);
m_hWnd = 0;
}
-
- if (m_user32) {
- FreeLibrary(m_user32);
- m_user32 = NULL;
- }
}
bool GHOST_WindowWin32::getValid() const
@@ -878,54 +877,93 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cur
return GHOST_kSuccess;
}
-void GHOST_WindowWin32::processWin32PointerEvent(WPARAM wParam)
+GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo, WPARAM wParam, LPARAM lParam)
{
- if (!useTabletAPI(GHOST_kTabletNative)) {
- return; // Other tablet API specified by user
- }
+ ZeroMemory(pointerInfo, sizeof(GHOST_PointerInfoWin32));
+
+ // Obtain the basic information from the event
+ pointerInfo->pointerId = GET_POINTERID_WPARAM(wParam);
+ pointerInfo->isInContact = IS_POINTER_INCONTACT_WPARAM(wParam);
+ pointerInfo->isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam);
- if (!m_fpGetPointerInfo || !m_fpGetPointerPenInfo) {
- return; // OS version does not support pointer API
+ // Obtain more accurate and predicted information from the Pointer API
+ POINTER_INFO pointerApiInfo;
+ if (!(m_fpGetPointerInfo && m_fpGetPointerInfo(pointerInfo->pointerId, &pointerApiInfo))) {
+ return GHOST_kFailure;
}
- UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
- POINTER_INFO pointerInfo;
- if (!m_fpGetPointerInfo(pointerId, &pointerInfo)) {
- return; // Invalid pointer info
+ pointerInfo->hasButtonMask = GHOST_kSuccess;
+ switch (pointerApiInfo.ButtonChangeType) {
+ case POINTER_CHANGE_FIRSTBUTTON_DOWN:
+ case POINTER_CHANGE_FIRSTBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskLeft;
+ break;
+ case POINTER_CHANGE_SECONDBUTTON_DOWN:
+ case POINTER_CHANGE_SECONDBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskRight;
+ break;
+ case POINTER_CHANGE_THIRDBUTTON_DOWN:
+ case POINTER_CHANGE_THIRDBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskMiddle;
+ break;
+ case POINTER_CHANGE_FOURTHBUTTON_DOWN:
+ case POINTER_CHANGE_FOURTHBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskButton4;
+ break;
+ case POINTER_CHANGE_FIFTHBUTTON_DOWN:
+ case POINTER_CHANGE_FIFTHBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskButton5;
+ break;
+ default:
+ pointerInfo->hasButtonMask = GHOST_kFailure;
+ break;
+ }
+
+ pointerInfo->pixelLocation = pointerApiInfo.ptPixelLocation;
+ pointerInfo->tabletData.Active = GHOST_kTabletModeNone;
+ pointerInfo->tabletData.Pressure = 1.0f;
+ pointerInfo->tabletData.Xtilt = 0.0f;
+ pointerInfo->tabletData.Ytilt = 0.0f;
+
+ if (pointerApiInfo.pointerType != PT_PEN) {
+ return GHOST_kFailure;
}
- 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;
- }
+ POINTER_PEN_INFO pointerPenInfo;
+ if (m_fpGetPointerPenInfo && m_fpGetPointerPenInfo(pointerInfo->pointerId, &pointerPenInfo)) {
+ pointerInfo->tabletData.Active = GHOST_kTabletModeStylus;
- // 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.penMask & PEN_MASK_PRESSURE) {
+ pointerInfo->tabletData.Pressure = pointerPenInfo.pressure / 1024.0f;
}
if (pointerPenInfo.penFlags & PEN_FLAG_ERASER) {
- m_tabletData.Active = GHOST_kTabletModeEraser;
+ pointerInfo->tabletData.Active = GHOST_kTabletModeEraser;
}
if (pointerPenInfo.penFlags & PEN_MASK_TILT_X) {
- m_tabletData.Xtilt = fmin(fabs(pointerPenInfo.tiltX / 90), 1.0f);
+ pointerInfo->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);
+ pointerInfo->tabletData.Ytilt = fmin(fabs(pointerPenInfo.tiltY / 90), 1.0f);
}
}
+
+ return GHOST_kSuccess;
+}
+
+void GHOST_WindowWin32::setTabletData(GHOST_TabletData * pTabletData)
+{
+ if (pTabletData) {
+ m_tabletData = *pTabletData;
+ }
+ else {
+ m_tabletData.Active = GHOST_kTabletModeNone;
+ m_tabletData.Pressure = 1.0f;
+ m_tabletData.Xtilt = 0.0f;
+ m_tabletData.Ytilt = 0.0f;
+ }
}
void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 41874579f73..5de6a62380a 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -130,8 +130,70 @@ typedef struct tagPOINTER_PEN_INFO {
INT32 tiltY;
} POINTER_PEN_INFO;
+/*
+ * Flags that appear in pointer input message parameters
+ */
+#define POINTER_MESSAGE_FLAG_NEW 0x00000001 // New pointer
+#define POINTER_MESSAGE_FLAG_INRANGE 0x00000002 // Pointer has not departed
+#define POINTER_MESSAGE_FLAG_INCONTACT 0x00000004 // Pointer is in contact
+#define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010 // Primary action
+#define POINTER_MESSAGE_FLAG_SECONDBUTTON 0x00000020 // Secondary action
+#define POINTER_MESSAGE_FLAG_THIRDBUTTON 0x00000040 // Third button
+#define POINTER_MESSAGE_FLAG_FOURTHBUTTON 0x00000080 // Fourth button
+#define POINTER_MESSAGE_FLAG_FIFTHBUTTON 0x00000100 // Fifth button
+#define POINTER_MESSAGE_FLAG_PRIMARY 0x00002000 // Pointer is primary
+#define POINTER_MESSAGE_FLAG_CONFIDENCE 0x00004000 // Pointer is considered unlikely to be accidental
+#define POINTER_MESSAGE_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner
+
+typedef UINT32 TOUCH_FLAGS;
+#define TOUCH_FLAG_NONE 0x00000000 // Default
+
+typedef UINT32 TOUCH_MASK;
+#define TOUCH_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
+#define TOUCH_MASK_CONTACTAREA 0x00000001 // The rcContact field is valid
+#define TOUCH_MASK_ORIENTATION 0x00000002 // The orientation field is valid
+#define TOUCH_MASK_PRESSURE 0x00000004 // The pressure field is valid
+
+typedef struct tagPOINTER_TOUCH_INFO {
+ POINTER_INFO pointerInfo;
+ TOUCH_FLAGS touchFlags;
+ TOUCH_MASK touchMask;
+ RECT rcContact;
+ RECT rcContactRaw;
+ UINT32 orientation;
+ UINT32 pressure;
+} POINTER_TOUCH_INFO;
+
+ /*
+ * Macros to retrieve information from pointer input message parameters
+ */
+#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
+#define IS_POINTER_FLAG_SET_WPARAM(wParam, flag) (((DWORD)HIWORD(wParam) & (flag)) == (flag))
+#define IS_POINTER_NEW_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_NEW)
+#define IS_POINTER_INRANGE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INRANGE)
+#define IS_POINTER_INCONTACT_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INCONTACT)
+#define IS_POINTER_FIRSTBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIRSTBUTTON)
+#define IS_POINTER_SECONDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_SECONDBUTTON)
+#define IS_POINTER_THIRDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_THIRDBUTTON)
+#define IS_POINTER_FOURTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FOURTHBUTTON)
+#define IS_POINTER_FIFTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIFTHBUTTON)
+#define IS_POINTER_PRIMARY_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_PRIMARY)
+#define HAS_POINTER_CONFIDENCE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CONFIDENCE)
+#define IS_POINTER_CANCELED_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CANCELED)
+
typedef BOOL (API * GHOST_WIN32_GetPointerInfo)(UINT32 pointerId, POINTER_INFO *pointerInfo);
typedef BOOL (API * GHOST_WIN32_GetPointerPenInfo)(UINT32 pointerId, POINTER_PEN_INFO *penInfo);
+typedef BOOL (API * GHOST_WIN32_GetPointerTouchInfo)(UINT32 pointerId, POINTER_TOUCH_INFO *penInfo);
+
+struct GHOST_PointerInfoWin32 {
+ GHOST_TInt32 pointerId;
+ GHOST_TInt32 isInContact;
+ GHOST_TInt32 isPrimary;
+ GHOST_TSuccess hasButtonMask;
+ GHOST_TButtonMask buttonMask;
+ POINT pixelLocation;
+ GHOST_TabletData tabletData;
+};
/**
* GHOST window on M$ Windows OSs.
@@ -316,7 +378,9 @@ public:
return &m_tabletData;
}
+ void setTabletData(GHOST_TabletData * tabletData);
bool useTabletAPI(GHOST_TTabletAPI api) const;
+ void getPointerInfo(WPARAM wParam);
void processWin32PointerEvent(WPARAM wParam);
void processWin32TabletActivateEvent(WORD state);
@@ -330,6 +394,8 @@ public:
GHOST_TUns16 getDPIHint() override;
+ GHOST_TSuccess getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo, WPARAM wParam, LPARAM lParam);
+
/** if the window currently resizing */
bool m_inLiveResize;
@@ -445,6 +511,7 @@ private:
HMODULE m_user32;
GHOST_WIN32_GetPointerInfo m_fpGetPointerInfo;
GHOST_WIN32_GetPointerPenInfo m_fpGetPointerPenInfo;
+ GHOST_WIN32_GetPointerTouchInfo m_fpGetPointerTouchInfo;
/** Hwnd to parent window */
GHOST_TEmbedderWindowID m_parentWindowHwnd;