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:
authorNicholas Rishel <rishel.nick@gmail.com>2021-02-16 09:47:52 +0300
committerNicholas Rishel <rishel.nick@gmail.com>2021-02-16 10:06:00 +0300
commit2e81f2c01abd21fdbc79625f3f7a0778103fa199 (patch)
tree2b8edd142af13c920223e0ec676e50fbd8dd0778 /intern/ghost
parentc63df3b33f011d524fc8dd1b8fc28f896e876a99 (diff)
Revert Wintab High Frequency Input.
This revert removes handling of cursor move and button press events during Wintab's WT_PACKET event, instead storing pressure and tilt information to be combined with Window's WM_MOUSEMOVE events. This also reverts dynamic enabling and disabling of Wintab, dependent on the chosen Tablet API. If the Tablet API is not explictly Windows Ink during startup, Wintab is loaded and enabled. Left in place is a fallback to Windows Ink when the Tablet API is set to Automatic and no Wintab devices are present. This allows devices with Wintab installed but not active to fallback to Windows Ink. Using position provided by Wintab was found to have too many regressions to include in Blender 2.93. The primary source of regressions was tablets which mapped coordinates incorrectly on multi- monitor and scaled displays. This resulted in an offset between what the driver controlled Win32 cursor position and the Wintab reported position. A special case of this included tablets set to mouse mode, where Wintab reported absolute position while the system cursor moved as a relative mouse with mouse acceleration.
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/intern/GHOST_System.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp226
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h19
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp448
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h124
5 files changed, 237 insertions, 582 deletions
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 279f90b9641..2a7123b293e 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -239,7 +239,7 @@ class GHOST_System : public GHOST_ISystem {
* 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);
+ void setTabletAPI(GHOST_TTabletAPI api);
GHOST_TTabletAPI getTabletAPI(void);
#ifdef WITH_INPUT_NDOF
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 718ace9db4a..c86b332d228 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -237,11 +237,6 @@ GHOST_SystemWin32::~GHOST_SystemWin32()
toggleConsole(1);
}
-GHOST_TUns64 GHOST_SystemWin32::millisSinceStart(__int64 ms) const
-{
- return (GHOST_TUns64)(ms - m_start * 1000 / m_freq);
-}
-
GHOST_TUns64 GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const
{
// Calculate the time passed since system initialization.
@@ -955,101 +950,25 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
{
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- GHOST_TabletData td = window->m_tabletInRange ? window->getLastTabletData() :
- GHOST_TABLET_DATA_NONE;
+ GHOST_TabletData td = GHOST_TABLET_DATA_NONE;
- /* Move mouse to button event position. */
- if (!window->m_tabletInRange) {
- processCursorEvent(window);
- }
- else {
- /* Tablet should be hadling inbetween mouse moves, only move to event position. */
+ if (window->m_tabletInRange) {
+ td = window->getTabletData();
+
+ /* Check if tablet cursor position is in sync with Win32 cursor position, if not then move
+ * cursor to position where button event occurred. */
DWORD msgPos = ::GetMessagePos();
int msgPosX = GET_X_LPARAM(msgPos);
int msgPosY = GET_Y_LPARAM(msgPos);
- system->pushEvent(new GHOST_EventCursor(
- ::GetMessageTime(), GHOST_kEventCursorMove, window, msgPosX, msgPosY, td));
+ if (msgPosX != system->m_mousePosX || msgPosY != system->m_mousePosY) {
+ system->pushEvent(new GHOST_EventCursor(
+ ::GetMessageTime(), GHOST_kEventCursorMove, window, msgPosX, msgPosY, td));
+ }
}
- window->updateMouseCapture(type == GHOST_kEventButtonDown ? MousePressed : MouseReleased);
return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask, td);
}
-void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
-{
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
-
- std::vector<GHOST_WintabInfoWin32> wintabInfo;
- if (!window->getWintabInfo(wintabInfo)) {
- return;
- }
-
- for (auto info : wintabInfo) {
- switch (info.type) {
- case GHOST_kEventCursorMove: {
- system->pushEvent(new GHOST_EventCursor(
- info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
- break;
- }
- case GHOST_kEventButtonDown: {
- system->pushEvent(new GHOST_EventCursor(
- info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
-
- UINT message;
- switch (info.button) {
- case GHOST_kButtonMaskLeft:
- message = WM_LBUTTONDOWN;
- break;
- case GHOST_kButtonMaskRight:
- message = WM_RBUTTONDOWN;
- break;
- case GHOST_kButtonMaskMiddle:
- message = WM_MBUTTONDOWN;
- break;
- default:
- continue;
- }
-
- MSG msg;
- if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
- WM_QUIT != msg.message) {
- window->updateMouseCapture(MousePressed);
- system->pushEvent(
- new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
- }
- break;
- }
- case GHOST_kEventButtonUp: {
- UINT message;
- switch (info.button) {
- case GHOST_kButtonMaskLeft:
- message = WM_LBUTTONUP;
- break;
- case GHOST_kButtonMaskRight:
- message = WM_RBUTTONUP;
- break;
- case GHOST_kButtonMaskMiddle:
- message = WM_MBUTTONUP;
- break;
- default:
- continue;
- }
-
- MSG msg;
- if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
- WM_QUIT != msg.message) {
- window->updateMouseCapture(MouseReleased);
- system->pushEvent(
- new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
- }
- break;
- }
- default:
- break;
- }
- }
-}
-
void GHOST_SystemWin32::processPointerEvent(
UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventHandled)
{
@@ -1129,12 +1048,15 @@ void GHOST_SystemWin32::processPointerEvent(
void GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window)
{
- /* Cursor moves handled by tablets while active. */
- if (window->m_tabletInRange) {
+ if (window->m_tabletInRange && window->useTabletAPI(GHOST_kTabletNative)) {
+ /* Tablet input handled in WM_POINTER* events. WM_MOUSEMOVE events in response to tablet
+ * input aren't normally generated when using WM_POINTER events, but manually moving the
+ * system cursor as we do in WM_POINTER handling does. */
return;
}
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ GHOST_TabletData td = window->getTabletData();
DWORD msgPos = ::GetMessagePos();
LONG msgTime = ::GetMessageTime();
@@ -1185,13 +1107,13 @@ void GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window)
window,
points[i].x + x_accum,
points[i].y + y_accum,
- GHOST_TABLET_DATA_NONE));
+ td));
}
DWORD lastTimestamp = points[0].time;
/* Check if we need to wrap the cursor. */
- if (window->getCursorGrabModeIsWarp()) {
+ if (window->getCursorGrabModeIsWarp() && !window->m_tabletInRange) {
/* Wrap based on current cursor position in case Win32 mouse move queue is out of order due to
* prior wrap. */
POINT point;
@@ -1334,23 +1256,6 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
return event;
}
-GHOST_Event *GHOST_SystemWin32::processWindowSizeEvent(GHOST_WindowWin32 *window)
-{
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- GHOST_Event *sizeEvent = new GHOST_Event(
- system->getMilliSeconds(), GHOST_kEventWindowSize, window);
-
- /* We get WM_SIZE before we fully init. Do not dispatch before we are continuously resizing. */
- if (window->m_inLiveResize) {
- system->pushEvent(sizeEvent);
- system->dispatchEvents();
- return NULL;
- }
- else {
- return sizeEvent;
- }
-}
-
GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type,
GHOST_WindowWin32 *window)
{
@@ -1358,6 +1263,7 @@ GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type,
if (type == GHOST_kEventWindowActivate) {
system->getWindowManager()->setActiveWindow(window);
+ window->bringTabletContextToFront();
}
return new GHOST_Event(system->getMilliSeconds(), type, window);
@@ -1385,18 +1291,6 @@ GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType,
system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data));
}
-void GHOST_SystemWin32::setTabletAPI(GHOST_TTabletAPI api)
-{
- GHOST_System::setTabletAPI(api);
-
- GHOST_WindowManager *wm = getWindowManager();
-
- for (GHOST_IWindow *win : wm->getWindows()) {
- GHOST_WindowWin32 *windowWin32 = (GHOST_WindowWin32 *)win;
- windowWin32->setWintabEnabled(windowWin32->useTabletAPI(GHOST_kTabletWintab));
- }
-}
-
void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax)
{
minmax->ptMinTrackSize.x = 320;
@@ -1636,30 +1530,16 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
////////////////////////////////////////////////////////////////////////
// Wintab events, processed
////////////////////////////////////////////////////////////////////////
- case WT_INFOCHANGE: {
+ case WT_INFOCHANGE:
window->processWintabInfoChangeEvent(lParam);
eventHandled = true;
break;
- }
- case WT_CSRCHANGE:
- window->updateWintabCursorInfo();
- eventHandled = true;
- break;
- case WT_PROXIMITY: {
- if (window->useTabletAPI(GHOST_kTabletWintab)) {
- if (LOWORD(lParam)) {
- window->m_tabletInRange = true;
- }
- else {
- window->processWintabLeave();
- }
- }
- eventHandled = true;
- break;
- }
case WT_PACKET:
- processWintabEvent(window);
- eventHandled = true;
+ window->processWin32TabletEvent(wParam, lParam);
+ break;
+ case WT_CSRCHANGE:
+ case WT_PROXIMITY:
+ window->processWin32TabletInitEvent();
break;
////////////////////////////////////////////////////////////////////////
// Pointer events, processed
@@ -1675,53 +1555,52 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
// Mouse events, processed
////////////////////////////////////////////////////////////////////////
case WM_LBUTTONDOWN:
+ window->updateMouseCapture(MousePressed);
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft);
break;
case WM_MBUTTONDOWN:
+ window->updateMouseCapture(MousePressed);
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle);
break;
case WM_RBUTTONDOWN:
+ window->updateMouseCapture(MousePressed);
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight);
break;
case WM_XBUTTONDOWN:
if ((short)HIWORD(wParam) == XBUTTON1) {
+ window->updateMouseCapture(MousePressed);
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4);
}
else if ((short)HIWORD(wParam) == XBUTTON2) {
+ window->updateMouseCapture(MousePressed);
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5);
}
break;
case WM_LBUTTONUP:
+ window->updateMouseCapture(MouseReleased);
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
break;
case WM_MBUTTONUP:
+ window->updateMouseCapture(MouseReleased);
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle);
break;
case WM_RBUTTONUP:
+ window->updateMouseCapture(MouseReleased);
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight);
break;
case WM_XBUTTONUP:
if ((short)HIWORD(wParam) == XBUTTON1) {
+ window->updateMouseCapture(MouseReleased);
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4);
}
else if ((short)HIWORD(wParam) == XBUTTON2) {
+ window->updateMouseCapture(MouseReleased);
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5);
}
break;
case WM_MOUSEMOVE:
- if (!window->m_mousePresent) {
- TRACKMOUSEEVENT tme = {sizeof(tme)};
- tme.dwFlags = TME_LEAVE;
- tme.hwndTrack = hwnd;
- TrackMouseEvent(&tme);
- window->m_mousePresent = true;
- window->setWintabOverlap(true);
- }
-
- if (!window->m_tabletInRange) {
- processCursorEvent(window);
- eventHandled = true;
- }
+ processCursorEvent(window);
+ eventHandled = true;
break;
case WM_MOUSEWHEEL: {
/* The WM_MOUSEWHEEL message is sent to the focus window
@@ -1763,13 +1642,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
window->loadCursor(true, GHOST_kStandardCursorDefault);
}
break;
- case WM_MOUSELEAVE:
- window->m_mousePresent = false;
- window->setWintabOverlap(false);
- if (!window->m_tabletInRange) {
- processCursorEvent(window);
- }
- break;
+
////////////////////////////////////////////////////////////////////////
// Mouse events, ignored
////////////////////////////////////////////////////////////////////////
@@ -1785,6 +1658,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* is sent to the window that has captured the mouse.
*/
break;
+
////////////////////////////////////////////////////////////////////////
// Window events, processed
////////////////////////////////////////////////////////////////////////
@@ -1816,7 +1690,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* will not be dispatched to OUR active window if we minimize one of OUR windows. */
if (LOWORD(wParam) == WA_INACTIVE)
window->lostMouseCapture();
-
+ window->processWin32TabletActivateEvent(GET_WM_ACTIVATE_STATE(wParam, lParam));
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
@@ -1858,8 +1732,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
/* Let DefWindowProc handle it. */
break;
case WM_SIZING:
- event = processWindowSizeEvent(window);
- break;
case WM_SIZE:
/* The WM_SIZE message is sent to a window after its size has changed.
* The WM_SIZE and WM_MOVE messages are not sent if an application handles the
@@ -1867,15 +1739,15 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* to perform any move or size change processing during the WM_WINDOWPOSCHANGED
* message without calling DefWindowProc.
*/
- event = processWindowSizeEvent(window);
-
- if (wParam == SIZE_MINIMIZED) {
- window->setWintabEnabled(false);
+ /* we get first WM_SIZE before we fully init.
+ * So, do not dispatch before we continuously resizing. */
+ if (window->m_inLiveResize) {
+ system->pushEvent(processWindowEvent(GHOST_kEventWindowSize, window));
+ system->dispatchEvents();
}
- else if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED) {
- window->setWintabEnabled(true);
+ else {
+ event = processWindowEvent(GHOST_kEventWindowSize, window);
}
-
break;
case WM_CAPTURECHANGED:
window->lostMouseCapture();
@@ -1926,12 +1798,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
SWP_NOZORDER | SWP_NOACTIVATE);
}
break;
- case WM_DISPLAYCHANGE:
- for (GHOST_IWindow *iter_win : system->getWindowManager()->getWindows()) {
- GHOST_WindowWin32 *iter_win32win = (GHOST_WindowWin32 *)iter_win;
- iter_win32win->processWintabDisplayChangeEvent();
- }
- break;
////////////////////////////////////////////////////////////////////////
// Window events, ignored
////////////////////////////////////////////////////////////////////////
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 8ae0b0927c3..86c443bb1c7 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -64,8 +64,6 @@ class GHOST_SystemWin32 : public GHOST_System {
** Time(r) functionality
***************************************************************************************/
- GHOST_TUns64 millisSinceStart(__int64 ms) const;
-
/**
* This method converts performance counter measurements into milliseconds since the start of the
* system process.
@@ -267,16 +265,6 @@ class GHOST_SystemWin32 : public GHOST_System {
int mouseY,
void *data);
- /***************************************************************************************
- ** Modify tablet API
- ***************************************************************************************/
-
- /**
- * Set which tablet API to use.
- * \param api: Enum indicating which API to use.
- */
- void setTabletAPI(GHOST_TTabletAPI api) override;
-
protected:
/**
* Initializes the system.
@@ -369,13 +357,6 @@ class GHOST_SystemWin32 : public GHOST_System {
GHOST_TKey processSpecialKey(short vKey, short scanCode) const;
/**
- * Creates a window size event.
- * \param window: The window receiving the event (the active window).
- * \return The event created.
- */
- static GHOST_Event *processWindowSizeEvent(GHOST_WindowWin32 *window);
-
- /**
* Creates a window 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 255d487649b..f443fc3153f 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -72,7 +72,6 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
bool is_debug,
bool dialog)
: GHOST_Window(width, height, state, wantStereoVisual, false),
- m_mousePresent(false),
m_tabletInRange(false),
m_inLiveResize(false),
m_system(system),
@@ -82,7 +81,6 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_nPressedButtons(0),
m_customCursor(0),
m_wantAlphaBackground(alphaBackground),
- m_wintab(),
m_normal_state(GHOST_kWindowStateNormal),
m_user32(NULL),
m_fpGetPointerInfoHistory(NULL),
@@ -91,6 +89,10 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : NULL),
m_debug_context(is_debug)
{
+ // Initialize tablet variables
+ memset(&m_wintab, 0, sizeof(m_wintab));
+ m_tabletData = GHOST_TABLET_DATA_NONE;
+
// Create window
if (state != GHOST_kWindowStateFullScreen) {
RECT rect;
@@ -295,24 +297,68 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_user32, "GetPointerTouchInfoHistory");
}
- if ((m_wintab.handle = ::LoadLibrary("Wintab32.dll")) &&
- (m_wintab.info = (GHOST_WIN32_WTInfo)::GetProcAddress(m_wintab.handle, "WTInfoA")) &&
- (m_wintab.open = (GHOST_WIN32_WTOpen)::GetProcAddress(m_wintab.handle, "WTOpenA")) &&
- (m_wintab.get = (GHOST_WIN32_WTGet)::GetProcAddress(m_wintab.handle, "WTGetA")) &&
- (m_wintab.set = (GHOST_WIN32_WTSet)::GetProcAddress(m_wintab.handle, "WTSetA")) &&
- (m_wintab.close = (GHOST_WIN32_WTClose)::GetProcAddress(m_wintab.handle, "WTClose")) &&
- (m_wintab.packetsGet = (GHOST_WIN32_WTPacketsGet)::GetProcAddress(m_wintab.handle,
- "WTPacketsGet")) &&
- (m_wintab.queueSizeGet = (GHOST_WIN32_WTQueueSizeGet)::GetProcAddress(m_wintab.handle,
- "WTQueueSizeGet")) &&
- (m_wintab.queueSizeSet = (GHOST_WIN32_WTQueueSizeSet)::GetProcAddress(m_wintab.handle,
- "WTQueueSizeSet")) &&
- (m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable")) &&
- (m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap"))) {
- initializeWintab();
- setWintabEnabled(true);
- }
+ // Initialize Wintab
+ m_wintab.handle = ::LoadLibrary("Wintab32.dll");
+ if (m_wintab.handle && m_system->getTabletAPI() != GHOST_kTabletNative) {
+ // Get API functions
+ m_wintab.info = (GHOST_WIN32_WTInfo)::GetProcAddress(m_wintab.handle, "WTInfoA");
+ m_wintab.open = (GHOST_WIN32_WTOpen)::GetProcAddress(m_wintab.handle, "WTOpenA");
+ m_wintab.close = (GHOST_WIN32_WTClose)::GetProcAddress(m_wintab.handle, "WTClose");
+ m_wintab.packet = (GHOST_WIN32_WTPacket)::GetProcAddress(m_wintab.handle, "WTPacket");
+ m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable");
+ m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap");
+
+ // Let's see if we can initialize tablet here.
+ // Check if WinTab available by getting system context info.
+ LOGCONTEXT lc = {0};
+ lc.lcOptions |= CXO_SYSTEM;
+ if (m_wintab.open && m_wintab.info && m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) {
+ // Now init the tablet
+ /* The maximum tablet size, pressure and orientation (tilt) */
+ AXIS TabletX, TabletY, Pressure, Orientation[3];
+
+ // Open a Wintab context
+
+ // Open the context
+ lc.lcPktData = PACKETDATA;
+ lc.lcPktMode = PACKETMODE;
+ lc.lcOptions |= CXO_MESSAGES;
+ lc.lcMoveMask = PACKETDATA;
+
+ /* Set the entire tablet as active */
+ m_wintab.info(WTI_DEVICES, DVC_X, &TabletX);
+ m_wintab.info(WTI_DEVICES, DVC_Y, &TabletY);
+
+ /* get the max pressure, to divide into a float */
+ BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
+ if (pressureSupport)
+ m_wintab.maxPressure = Pressure.axMax;
+ else
+ m_wintab.maxPressure = 0;
+
+ /* get the max tilt axes, to divide into floats */
+ BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
+ if (tiltSupport) {
+ /* does the tablet support azimuth ([0]) and altitude ([1]) */
+ if (Orientation[0].axResolution && Orientation[1].axResolution) {
+ /* all this assumes the minimum is 0 */
+ m_wintab.maxAzimuth = Orientation[0].axMax;
+ m_wintab.maxAltitude = Orientation[1].axMax;
+ }
+ else { /* no so dont do tilt stuff */
+ m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
+ }
+ }
+
+ // The Wintab spec says we must open the context disabled if we are using cursor masks.
+ m_wintab.tablet = m_wintab.open(m_hWnd, &lc, FALSE);
+ if (m_wintab.enable && m_wintab.tablet) {
+ m_wintab.enable(m_wintab.tablet, TRUE);
+ }
+ m_wintab.info(WTI_INTERFACE, IFC_NDEVICES, &m_wintab.numDevices);
+ }
+ }
CoCreateInstance(
CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar);
}
@@ -326,12 +372,12 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
}
if (m_wintab.handle) {
- setWintabEnabled(false);
- if (m_wintab.close && m_wintab.context) {
- m_wintab.close(m_wintab.context);
+ if (m_wintab.close && m_wintab.tablet) {
+ m_wintab.close(m_wintab.tablet);
}
FreeLibrary(m_wintab.handle);
+ memset(&m_wintab, 0, sizeof(m_wintab));
}
if (m_user32) {
@@ -973,62 +1019,6 @@ GHOST_TSuccess GHOST_WindowWin32::hasCursorShape(GHOST_TStandardCursor cursorSha
return (getStandardCursor(cursorShape)) ? GHOST_kSuccess : GHOST_kFailure;
}
-void GHOST_WindowWin32::initializeWintab()
-{
- /* Return if wintab library handle doesn't exist or wintab is already initialized. */
- if (!m_wintab.handle || m_wintab.context) {
- return;
- }
-
- /* Check if WinTab available by getting system context info. */
- LOGCONTEXT lc = {0};
- if (m_wintab.open && m_wintab.info && m_wintab.queueSizeGet && m_wintab.queueSizeSet &&
- m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) {
-
- lc.lcPktData = PACKETDATA;
- lc.lcPktMode = PACKETMODE;
- lc.lcMoveMask = PACKETDATA;
- lc.lcOptions |= CXO_CSRMESSAGES | CXO_MESSAGES;
- /* Wacom maps y origin to the tablet's bottom. Invert to match Windows y origin mapping to the
- * screen top. */
- lc.lcOutExtY = -lc.lcOutExtY;
-
- m_wintab.info(WTI_INTERFACE, IFC_NDEVICES, &m_wintab.numDevices);
-
- updateWintabCursorInfo();
-
- /* The Wintab spec says we must open the context disabled if we are using cursor masks. */
- m_wintab.context = m_wintab.open(m_hWnd, &lc, FALSE);
-
- /* Wintab provides no way to determine the maximum queue size aside from checking if attempts
- * to change the queue size are successful. */
- const int maxQueue = 500;
- int queueSize = m_wintab.queueSizeGet(m_wintab.context);
-
- while (queueSize < maxQueue) {
- int testSize = min(queueSize + 16, maxQueue);
- if (m_wintab.queueSizeSet(m_wintab.context, testSize)) {
- queueSize = testSize;
- }
- else {
- /* From Windows Wintab Documentation for WTQueueSizeSet:
- * "If the return value is zero, the context has no queue because the function deletes the
- * original queue before attempting to create a new one. The application must continue
- * calling the function with a smaller queue size until the function returns a non - zero
- * value."
- *
- * In our case we start with a known valid queue size and in the event of failure roll
- * back to the last valid queue size. The Wintab spec dates back to 16 bit Windows, thus
- * assumes memory recently deallocated may not be available, which is no longer a practical
- * concern. */
- m_wintab.queueSizeSet(m_wintab.context, queueSize);
- break;
- }
- }
- m_wintab.pkts.resize(queueSize);
- }
-}
-
GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
std::vector<GHOST_PointerInfoWin32> &outPointerInfo, WPARAM wParam, LPARAM lParam)
{
@@ -1108,85 +1098,24 @@ GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
}
}
- if (!outPointerInfo.empty()) {
- lastTabletData = outPointerInfo.back().tabletData;
- }
-
return GHOST_kSuccess;
}
-void GHOST_WindowWin32::setWintabEnabled(bool enable)
+void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
{
- if (m_wintab.enable && m_wintab.get && m_wintab.context) {
- LOGCONTEXT context = {0};
-
- if (m_wintab.get(m_wintab.context, &context)) {
- if (enable && context.lcStatus & CXS_DISABLED && useTabletAPI(GHOST_kTabletWintab)) {
- m_wintab.enable(m_wintab.context, true);
-
- POINT cursorPos;
- ::GetCursorPos(&cursorPos);
- GHOST_Rect bounds;
- getClientBounds(bounds);
- if (bounds.isInside(cursorPos.x, cursorPos.y)) {
- setWintabOverlap(true);
- }
- }
- else if (!enable && !(context.lcStatus & CXS_DISABLED)) {
- setWintabOverlap(false);
- m_wintab.enable(m_wintab.context, false);
- }
- }
+ if (!useTabletAPI(GHOST_kTabletWintab)) {
+ return;
}
-}
-void GHOST_WindowWin32::setWintabOverlap(bool overlap)
-{
- if (m_wintab.overlap && m_wintab.get && m_wintab.packetsGet && m_wintab.context) {
- LOGCONTEXT context = {0};
+ if (m_wintab.enable && m_wintab.tablet) {
+ m_wintab.enable(m_wintab.tablet, state);
- if (m_wintab.get(m_wintab.context, &context)) {
- if (overlap && context.lcStatus & CXS_OBSCURED && useTabletAPI(GHOST_kTabletWintab)) {
- m_wintab.overlap(m_wintab.context, true);
- }
- else if (!overlap && context.lcStatus & CXS_ONTOP) {
- m_wintab.overlap(m_wintab.context, false);
-
- /* If context is disabled, Windows Ink may be active and managing m_tabletInRange. Don't
- * modify it. */
- if (!(context.lcStatus & CXS_DISABLED)) {
- processWintabLeave();
- }
- }
+ if (m_wintab.overlap && state) {
+ m_wintab.overlap(m_wintab.tablet, TRUE);
}
}
}
-void GHOST_WindowWin32::processWintabLeave()
-{
- m_tabletInRange = false;
- m_wintab.buttons = 0;
- /* Clear the packet queue. */
- m_wintab.packetsGet(m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
-}
-
-void GHOST_WindowWin32::processWintabDisplayChangeEvent()
-{
- LOGCONTEXT lc_sys = {0}, lc_curr = {0};
-
- if (m_wintab.info && m_wintab.get && m_wintab.set && m_wintab.info(WTI_DEFSYSCTX, 0, &lc_sys)) {
-
- m_wintab.get(m_wintab.context, &lc_curr);
-
- lc_curr.lcOutOrgX = lc_sys.lcOutOrgX;
- lc_curr.lcOutOrgY = lc_sys.lcOutOrgY;
- lc_curr.lcOutExtX = lc_sys.lcOutExtX;
- lc_curr.lcOutExtY = -lc_sys.lcOutExtY;
-
- m_wintab.set(m_wintab.context, &lc_curr);
- }
-}
-
bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const
{
if (m_system->getTabletAPI() == api) {
@@ -1203,24 +1132,36 @@ bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const
}
}
-void GHOST_WindowWin32::updateWintabCursorInfo()
+void GHOST_WindowWin32::processWin32TabletInitEvent()
{
- if (m_wintab.info && m_wintab.context) {
- AXIS Pressure, Orientation[3];
+ if (!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 */
BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
- m_wintab.maxPressure = pressureSupport ? Pressure.axMax : 0;
+ if (pressureSupport)
+ m_wintab.maxPressure = Pressure.axMax;
+ else
+ m_wintab.maxPressure = 0;
BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
- /* Does the tablet support azimuth ([0]) and altitude ([1]). */
- if (tiltSupport && Orientation[0].axResolution && Orientation[1].axResolution) {
- m_wintab.maxAzimuth = Orientation[0].axMax;
- m_wintab.maxAltitude = Orientation[1].axMax;
- }
- else {
- m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
+ if (tiltSupport) {
+ /* does the tablet support azimuth ([0]) and altitude ([1]) */
+ if (Orientation[0].axResolution && Orientation[1].axResolution) {
+ m_wintab.maxAzimuth = Orientation[0].axMax;
+ m_wintab.maxAltitude = Orientation[1].axMax;
+ }
+ else { /* no so dont do tilt stuff */
+ m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
+ }
}
}
+
+ m_tabletData.Active = GHOST_kTabletModeNone;
}
void GHOST_WindowWin32::processWintabInfoChangeEvent(LPARAM lParam)
@@ -1228,151 +1169,86 @@ void GHOST_WindowWin32::processWintabInfoChangeEvent(LPARAM lParam)
/* Update number of connected Wintab digitizers */
if (LOWORD(lParam) == WTI_INTERFACE && HIWORD(lParam) == IFC_NDEVICES) {
m_wintab.info(WTI_INTERFACE, IFC_NDEVICES, &m_wintab.numDevices);
- if (useTabletAPI(GHOST_kTabletWintab)) {
- setWintabEnabled(true);
- }
- }
-}
-
-GHOST_TButtonMask GHOST_WindowWin32::wintabMouseToGhost(UINT cursor, WORD physicalButton)
-{
- const WORD numButtons = 32;
- BYTE logicalButtons[numButtons] = {0};
- BYTE systemButtons[numButtons] = {0};
-
- m_wintab.info(WTI_CURSORS + cursor, CSR_BUTTONMAP, &logicalButtons);
- m_wintab.info(WTI_CURSORS + cursor, CSR_SYSBTNMAP, &systemButtons);
-
- if (physicalButton >= numButtons) {
- return GHOST_kButtonMaskNone;
- }
- BYTE lb = logicalButtons[physicalButton];
-
- if (lb >= numButtons) {
- return GHOST_kButtonMaskNone;
- }
- switch (systemButtons[lb]) {
- case SBN_LCLICK:
- return GHOST_kButtonMaskLeft;
- case SBN_RCLICK:
- return GHOST_kButtonMaskRight;
- case SBN_MCLICK:
- return GHOST_kButtonMaskMiddle;
- default:
- return GHOST_kButtonMaskNone;
}
}
-GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
+void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
{
- if (!(useTabletAPI(GHOST_kTabletWintab) && m_wintab.packetsGet && m_wintab.context)) {
- return GHOST_kFailure;
+ if (!useTabletAPI(GHOST_kTabletWintab)) {
+ return;
}
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
-
- const int numPackets = m_wintab.packetsGet(
- m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
- outWintabInfo.resize(numPackets);
-
- for (int i = 0; i < numPackets; i++) {
- PACKET pkt = m_wintab.pkts[i];
- GHOST_WintabInfoWin32 &out = outWintabInfo[i];
-
- out.tabletData = GHOST_TABLET_DATA_NONE;
- /* % 3 for multiple devices ("DualTrack"). */
- switch (pkt.pkCursor % 3) {
- case 0:
- /* Puck - processed as mouse. */
- out.tabletData.Active = GHOST_kTabletModeNone;
- break;
- case 1:
- out.tabletData.Active = GHOST_kTabletModeStylus;
- break;
- case 2:
- out.tabletData.Active = GHOST_kTabletModeEraser;
- break;
- }
-
- out.x = pkt.pkX;
- out.y = pkt.pkY;
-
- if (m_wintab.maxPressure > 0) {
- out.tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
- }
-
- if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) {
- ORIENTATION ort = pkt.pkOrientation;
- float vecLen;
- float altRad, azmRad; /* In radians. */
-
- /*
- * From the wintab spec:
- * orAzimuth: Specifies the clockwise rotation of the cursor about the z axis through a
- * full circular range.
- * orAltitude: Specifies the angle with the x-y plane through a signed, semicircular range.
- * Positive values specify an angle upward toward the positive z axis; negative values
- * specify an angle downward toward the negative z axis.
- *
- * wintab.h defines orAltitude as a UINT but documents orAltitude as positive for upward
- * angles and negative for downward angles. WACOM uses negative altitude values to show that
- * the pen is inverted; therefore we cast orAltitude as an (int) and then use the absolute
- * value.
- */
-
- /* Convert raw fixed point data to radians. */
- altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0);
- azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0);
-
- /* Find length of the stylus' projected vector on the XY plane. */
- vecLen = cos(altRad);
-
- /* From there calculate X and Y components based on azimuth. */
- out.tabletData.Xtilt = sin(azmRad) * vecLen;
- out.tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
- }
+ if (m_wintab.packet && m_wintab.tablet) {
+ PACKET pkt;
+ if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) {
+ switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */
+ case 0:
+ m_tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */
+ break;
+ case 1:
+ m_tabletData.Active = GHOST_kTabletModeStylus; /* stylus */
+ break;
+ case 2:
+ m_tabletData.Active = GHOST_kTabletModeEraser; /* eraser */
+ break;
+ }
- /* Some Wintab libraries don't handle relative button input, so we track button presses
- * manually. */
- out.button = GHOST_kButtonMaskNone;
- out.type = GHOST_kEventCursorMove;
-
- DWORD buttonsChanged = m_wintab.buttons ^ pkt.pkButtons;
- if (buttonsChanged) {
- /* Find the index for the changed button from the button map. */
- WORD physicalButton = 0;
- for (DWORD diff = (unsigned)buttonsChanged >> 1; diff > 0; diff = (unsigned)diff >> 1) {
- physicalButton++;
+ if (m_wintab.maxPressure > 0) {
+ m_tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
+ }
+ else {
+ m_tabletData.Pressure = 1.0f;
}
- out.button = wintabMouseToGhost(pkt.pkCursor, physicalButton);
+ if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) {
+ ORIENTATION ort = pkt.pkOrientation;
+ float vecLen;
+ float altRad, azmRad; /* in radians */
- if (out.button != GHOST_kButtonMaskNone) {
- if (buttonsChanged & pkt.pkButtons) {
- out.type = GHOST_kEventButtonDown;
- }
- else {
- out.type = GHOST_kEventButtonUp;
- }
+ /*
+ * from the wintab spec:
+ * orAzimuth Specifies the clockwise rotation of the
+ * cursor about the z axis through a full circular range.
+ *
+ * orAltitude Specifies the angle with the x-y plane
+ * through a signed, semicircular range. Positive values
+ * specify an angle upward toward the positive z axis;
+ * negative values specify an angle downward toward the negative z axis.
+ *
+ * wintab.h defines .orAltitude as a UINT but documents .orAltitude
+ * as positive for upward angles and negative for downward angles.
+ * WACOM uses negative altitude values to show that the pen is inverted;
+ * therefore we cast .orAltitude as an (int) and then use the absolute value.
+ */
+
+ /* convert raw fixed point data to radians */
+ altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0);
+ azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0);
+
+ /* find length of the stylus' projected vector on the XY plane */
+ vecLen = cos(altRad);
+
+ /* from there calculate X and Y components based on azimuth */
+ m_tabletData.Xtilt = sin(azmRad) * vecLen;
+ m_tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
+ }
+ else {
+ m_tabletData.Xtilt = 0.0f;
+ m_tabletData.Ytilt = 0.0f;
}
-
- /* Only update handled button, in case multiple button events arrived simultaneously. */
- m_wintab.buttons ^= 1 << physicalButton;
}
-
- out.time = system->tickCountToMillis(pkt.pkTime);
- }
-
- if (!outWintabInfo.empty()) {
- lastTabletData = outWintabInfo.back().tabletData;
}
-
- return GHOST_kSuccess;
}
-GHOST_TabletData GHOST_WindowWin32::getLastTabletData()
+void GHOST_WindowWin32::bringTabletContextToFront()
{
- return lastTabletData;
+ if (!useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
+ if (m_wintab.overlap && m_wintab.tablet) {
+ m_wintab.overlap(m_wintab.tablet, TRUE);
+ }
}
GHOST_TUns16 GHOST_WindowWin32::getDPIHint()
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index a7e7cdc6602..c65f6a3319f 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -34,14 +34,12 @@
# include "GHOST_ImeWin32.h"
#endif
-#include <queue>
#include <vector>
#include <wintab.h>
// PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first
-#define PACKETDATA \
- (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_X | PK_Y | PK_TIME)
-#define PACKETMODE 0
+#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
+#define PACKETMODE PK_BUTTONS
#include <pktdef.h>
class GHOST_SystemWin32;
@@ -49,13 +47,9 @@ class GHOST_DropTargetWin32;
// typedefs for WinTab functions to allow dynamic loading
typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
-typedef BOOL(API *GHOST_WIN32_WTGet)(HCTX, LPLOGCONTEXTA);
-typedef BOOL(API *GHOST_WIN32_WTSet)(HCTX, LPLOGCONTEXTA);
typedef HCTX(API *GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
typedef BOOL(API *GHOST_WIN32_WTClose)(HCTX);
-typedef int(API *GHOST_WIN32_WTPacketsGet)(HCTX, int, LPVOID);
-typedef int(API *GHOST_WIN32_WTQueueSizeGet)(HCTX);
-typedef BOOL(API *GHOST_WIN32_WTQueueSizeSet)(HCTX, int);
+typedef BOOL(API *GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
typedef BOOL(API *GHOST_WIN32_WTEnable)(HCTX, BOOL);
typedef BOOL(API *GHOST_WIN32_WTOverlap)(HCTX, BOOL);
@@ -236,14 +230,7 @@ struct GHOST_PointerInfoWin32 {
GHOST_TButtonMask buttonMask;
POINT pixelLocation;
GHOST_TUns64 time;
- GHOST_TabletData tabletData;
-};
-struct GHOST_WintabInfoWin32 {
- GHOST_TInt32 x, y;
- GHOST_TEventType type;
- GHOST_TButtonMask button;
- GHOST_TUns64 time;
GHOST_TabletData tabletData;
};
@@ -437,6 +424,11 @@ class GHOST_WindowWin32 : public GHOST_Window {
HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const;
void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
+ const GHOST_TabletData &getTabletData()
+ {
+ return m_tabletData;
+ }
+
/**
* Query whether given tablet API should be used.
* \param api: Tablet API to test.
@@ -455,50 +447,15 @@ class GHOST_WindowWin32 : public GHOST_Window {
LPARAM lParam);
/**
- * Enables or disables Wintab context.
- * \param enable: Whether the context should be enabled.
- */
- void setWintabEnabled(bool enable);
-
- /**
- * Changes Wintab context overlap.
- * \param overlap: Whether context should be brought to top of overlap order.
- */
- void setWintabOverlap(bool overlap);
-
- /**
- * Resets Wintab state.
- */
- void processWintabLeave();
-
- /**
- * Handle Wintab coordinate changes when DisplayChange events occur.
- */
- void processWintabDisplayChangeEvent();
-
- /**
- * Updates cached Wintab properties for current cursor.
- */
- void updateWintabCursorInfo();
-
- /**
* Handle Wintab info changes such as change in number of connected tablets.
* \param lParam: LPARAM of the event.
*/
void processWintabInfoChangeEvent(LPARAM lParam);
- /**
- * Translate Wintab packets into GHOST_WintabInfoWin32 structs.
- * \param outWintabInfo: Storage to return resulting GHOST_WintabInfoWin32 structs.
- * \return Success if able to read packets, even if there are none.
- */
- GHOST_TSuccess getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo);
-
- /**
- * Get the most recent tablet data.
- * \return Most recent tablet data.
- */
- GHOST_TabletData getLastTabletData();
+ void processWin32TabletActivateEvent(WORD state);
+ void processWin32TabletInitEvent();
+ void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
+ void bringTabletContextToFront();
GHOST_TSuccess beginFullScreen() const
{
@@ -512,9 +469,6 @@ class GHOST_WindowWin32 : public GHOST_Window {
GHOST_TUns16 getDPIHint() override;
- /** Whether the mouse is either over or captured by the window. */
- bool m_mousePresent;
-
/** Whether a tablet stylus is being tracked. */
bool m_tabletInRange;
@@ -598,51 +552,29 @@ class GHOST_WindowWin32 : public GHOST_Window {
static const wchar_t *s_windowClassName;
static const int s_maxTitleLength;
+ /** Tablet data for GHOST */
+ GHOST_TabletData m_tabletData;
+
/* Wintab API */
struct {
/** WinTab dll handle */
- HMODULE handle = NULL;
+ HMODULE handle;
/** API functions */
- GHOST_WIN32_WTInfo info = NULL;
- GHOST_WIN32_WTGet get = NULL;
- GHOST_WIN32_WTSet set = NULL;
- GHOST_WIN32_WTOpen open = NULL;
- GHOST_WIN32_WTClose close = NULL;
- GHOST_WIN32_WTPacketsGet packetsGet = NULL;
- GHOST_WIN32_WTQueueSizeGet queueSizeGet = NULL;
- GHOST_WIN32_WTQueueSizeSet queueSizeSet = NULL;
- GHOST_WIN32_WTEnable enable = NULL;
- GHOST_WIN32_WTOverlap overlap = NULL;
-
- /** Stores the Tablet context if detected Tablet features using WinTab.dll. */
- HCTX context = NULL;
- /** Number of connected Wintab digitizers. */
- UINT numDevices = 0;
- /** Pressed button map. */
- GHOST_TUns8 buttons = 0;
- LONG maxPressure = 0;
- LONG maxAzimuth = 0, maxAltitude = 0;
- /** Reusable buffer to read in Wintab Packets. */
- std::vector<PACKET> pkts;
+ GHOST_WIN32_WTInfo info;
+ GHOST_WIN32_WTOpen open;
+ GHOST_WIN32_WTClose close;
+ GHOST_WIN32_WTPacket packet;
+ GHOST_WIN32_WTEnable enable;
+ GHOST_WIN32_WTOverlap overlap;
+
+ /** Stores the Tablet context if detected Tablet features using WinTab.dll */
+ HCTX tablet;
+ LONG maxPressure;
+ LONG maxAzimuth, maxAltitude;
+ UINT numDevices;
} m_wintab;
- /** Most recent tablet data. */
- GHOST_TabletData lastTabletData = GHOST_TABLET_DATA_NONE;
-
- /**
- * Wintab setup.
- */
- void initializeWintab();
-
- /**
- * Convert Wintab system mapped (mouse) buttons into Ghost button mask.
- * \param cursor: The Wintab cursor associated to the button.
- * \param physicalButton: The physical button ID to inspect.
- * \return The system mapped button.
- */
- GHOST_TButtonMask wintabMouseToGhost(UINT cursor, WORD physicalButton);
-
GHOST_TWindowState m_normal_state;
/** user32 dll handle*/