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
path: root/intern
diff options
context:
space:
mode:
authorNicholas Rishel <nicholas_rishel>2020-12-25 03:25:07 +0300
committerNicholas Rishel <rishel.nick@gmail.com>2020-12-25 03:41:19 +0300
commit565ea3df6077a1af5995b9b4defec9b03f3c6c29 (patch)
tree8a4d5af1f3aca7442e3061aefead39f9c8b631b5 /intern
parentaf316d276144b905cf6cf5a1b1d7ae727d545e2f (diff)
Simplification of Wintab event handling.
Previously Wintab packets were added to a local queue to be processed during Win32 mouse events, in order to correlate Wintab to Win32 mouse buttons. Wintab packets before Win32 mouse down events were expired on a timer. This commit drives mouse events during Wintab events when a device is in range. When a Wintab button is found it is dispatched if an equivalent event can be popped from the Win32 event queue. If a Win32 mouse button event is not associated with a Wintab event, it falls through to WM_BUTTON handling. All Wintab packets are handled as they are received. Reviewed By: brecht Differential Revision: https://developer.blender.org/D9908
Diffstat (limited to 'intern')
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp292
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h16
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp345
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h99
4 files changed, 298 insertions, 454 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 7e800619dda..d1822fe46fd 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -569,13 +569,13 @@ GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons &buttons) const
*/
bool swapped = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE;
- bool down = HIBYTE(::GetKeyState(VK_LBUTTON)) != 0;
+ bool down = HIBYTE(::GetAsyncKeyState(VK_LBUTTON)) != 0;
buttons.set(swapped ? GHOST_kButtonMaskRight : GHOST_kButtonMaskLeft, down);
- down = HIBYTE(::GetKeyState(VK_MBUTTON)) != 0;
+ down = HIBYTE(::GetAsyncKeyState(VK_MBUTTON)) != 0;
buttons.set(GHOST_kButtonMaskMiddle, down);
- down = HIBYTE(::GetKeyState(VK_RBUTTON)) != 0;
+ down = HIBYTE(::GetAsyncKeyState(VK_RBUTTON)) != 0;
buttons.set(swapped ? GHOST_kButtonMaskLeft : GHOST_kButtonMaskRight, down);
return GHOST_kSuccess;
}
@@ -939,148 +939,106 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
{
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- if (type == GHOST_kEventButtonDown) {
- window->updateMouseCapture(MousePressed);
- }
- else if (type == GHOST_kEventButtonUp) {
- window->updateMouseCapture(MouseReleased);
- }
+ GHOST_TabletData td = window->m_tabletInRange ? window->getLastTabletData() :
+ GHOST_TABLET_DATA_NONE;
- /* Check for active Wintab mouse emulation in addition to a tablet in range because a proximity
- * leave event might have fired before the Windows mouse up event, thus there are still tablet
- * events to grab. The described behavior was observed in a Wacom Bamboo CTE-450. */
- if (window->useTabletAPI(GHOST_kTabletWintab) &&
- (window->m_tabletInRange || window->wintabSysButPressed()) &&
- processWintabEvent(type, window, mask, window->getMousePressed())) {
- /* Wintab processing only handles in-contact events. */
- return NULL;
- }
+ /* Ensure button click occurs at its intended position. */
+ DWORD msgPos = ::GetMessagePos();
+ GHOST_TInt32 x_screen = GET_X_LPARAM(msgPos), y_screen = GET_Y_LPARAM(msgPos);
+ system->pushEvent(new GHOST_EventCursor(
+ system->getMilliSeconds(), GHOST_kEventCursorMove, window, x_screen, y_screen, td));
- return new GHOST_EventButton(
- system->getMilliSeconds(), type, window, mask, GHOST_TABLET_DATA_NONE);
+ window->updateMouseCapture(type == GHOST_kEventButtonDown ? MousePressed : MouseReleased);
+ return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask, td);
}
-GHOST_TSuccess GHOST_SystemWin32::processWintabEvent(GHOST_TEventType type,
- GHOST_WindowWin32 *window,
- GHOST_TButtonMask mask,
- bool mousePressed)
+void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
{
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- /* Only process Wintab packets if we can correlate them to a Window's mouse button event. When a
- * button event associated to a mouse button by Wintab occurs outside of WM_*BUTTON events,
- * there's no way to tell if other simultaneously pressed non-mouse mapped buttons are associated
- * to a modifier key (shift, alt, ctrl) or a system event (scroll, etc.) and thus it is not
- * possible to determine if a mouse click event should occur. */
- if (!mousePressed && !window->wintabSysButPressed()) {
- return GHOST_kFailure;
- }
-
std::vector<GHOST_WintabInfoWin32> wintabInfo;
if (!window->getWintabInfo(wintabInfo)) {
- return GHOST_kFailure;
- }
-
- auto wtiIter = wintabInfo.begin();
-
- /* We only process events that correlate to a mouse button events, so there may exist Wintab
- * button down events that were instead mapped to e.g. scroll still in the queue. We need to
- * skip those and find the last button down mapped to mouse buttons. */
- if (!window->wintabSysButPressed()) {
- /* Assume there may be no button down event currently in the queue. */
- wtiIter = wintabInfo.end();
-
- for (auto it = wintabInfo.begin(); it != wintabInfo.end(); it++) {
- if (it->type == GHOST_kEventButtonDown) {
- wtiIter = it;
- }
- }
+ return;
}
- bool unhandledButton = type != GHOST_kEventCursorMove;
-
- for (; wtiIter != wintabInfo.end(); wtiIter++) {
- auto info = *wtiIter;
-
+ 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: {
- /* While changing windows with a tablet, Window's mouse button events normally occur before
- * tablet proximity events, so a button up event can't be differentiated as occurring from
- * a Wintab tablet or a normal mouse and a Ghost button event will always be generated.
- *
- * If we were called during a button down event create a ghost button down event, otherwise
- * don't duplicate the prior button down as it interrupts drawing immediately after
- * changing a window. */
system->pushEvent(new GHOST_EventCursor(
info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
- if (type == GHOST_kEventButtonDown && mask == info.button) {
+
+ 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));
- unhandledButton = false;
}
- window->updateWintabSysBut(MousePressed);
break;
}
- case GHOST_kEventCursorMove:
- system->pushEvent(new GHOST_EventCursor(
- info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
- break;
- case GHOST_kEventButtonUp:
- system->pushEvent(
- new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
- if (type == GHOST_kEventButtonUp && mask == info.button) {
- unhandledButton = false;
+ 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));
}
- window->updateWintabSysBut(MouseReleased);
break;
+ }
default:
break;
}
}
-
- /* No Wintab button found correlating to the system button event, handle it too.
- *
- * Wintab button up events may be handled during WM_MOUSEMOVE, before their corresponding
- * WM_*BUTTONUP event has fired, which results in two GHOST Button up events for a single Wintab
- * associated button event. Alternatively this Windows button up event may have been generated
- * from a non-stylus device such as a button on the tablet pad and needs to be handled for some
- * workflows.
- *
- * The ambiguity introduced by Windows and Wintab buttons being asynchronous and having no
- * definitive way to associate each, and that the Wintab API does not provide enough information
- * to differentiate whether the stylus down is or is not modified by another button to a
- * non-mouse mapping, means that we must pessimistically generate mouse up events when we are
- * unsure of an association to prevent the mouse locking into a down state. */
- if (unhandledButton) {
- if (!window->wintabSysButPressed()) {
- GHOST_TInt32 x, y;
- system->getCursorPosition(x, y);
- system->pushEvent(new GHOST_EventCursor(system->getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- x,
- y,
- GHOST_TABLET_DATA_NONE));
- }
- system->pushEvent(new GHOST_EventButton(
- system->getMilliSeconds(), type, window, mask, GHOST_TABLET_DATA_NONE));
- }
-
- return GHOST_kSuccess;
}
void GHOST_SystemWin32::processPointerEvent(
UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventHandled)
{
- std::vector<GHOST_PointerInfoWin32> pointerInfo;
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
-
/* Pointer events might fire when changing windows for a device which is set to use Wintab, even
* when when Wintab is left enabled but set to the bottom of Wintab overlap order. */
if (!window->useTabletAPI(GHOST_kTabletNative)) {
return;
}
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ std::vector<GHOST_PointerInfoWin32> pointerInfo;
+
if (window->getPointerInfo(pointerInfo, wParam, lParam) != GHOST_kSuccess) {
return;
}
@@ -1148,36 +1106,16 @@ void GHOST_SystemWin32::processPointerEvent(
GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window)
{
- GHOST_TInt32 x_screen, y_screen;
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
-
- GHOST_TabletData tabletData = GHOST_TABLET_DATA_NONE;
-
- if (window->m_tabletInRange || window->wintabSysButPressed()) {
- if (window->useTabletAPI(GHOST_kTabletWintab) &&
- processWintabEvent(
- GHOST_kEventCursorMove, window, GHOST_kButtonMaskNone, window->getMousePressed())) {
- return NULL;
- }
- else if (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 NULL;
- }
-
- /* If using Wintab but no button event is currently active, fall through to default handling.
- *
- * Populate tablet data so that cursor is recognized as an absolute position device. */
- tabletData.Active = GHOST_kTabletModeStylus;
- tabletData.Pressure = 0.0f;
- tabletData.Xtilt = 0.0f;
- tabletData.Ytilt = 0.0f;
+ if (window->m_tabletInRange) {
+ return NULL;
}
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ GHOST_TInt32 x_screen, y_screen;
+
system->getCursorPosition(x_screen, y_screen);
- if (window->getCursorGrabModeIsWarp() && !window->m_tabletInRange) {
+ if (window->getCursorGrabModeIsWarp()) {
GHOST_TInt32 x_new = x_screen;
GHOST_TInt32 y_new = y_screen;
GHOST_TInt32 x_accum, y_accum;
@@ -1205,12 +1143,16 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
window,
x_screen + x_accum,
y_screen + y_accum,
- tabletData);
+ GHOST_TABLET_DATA_NONE);
}
}
else {
- return new GHOST_EventCursor(
- system->getMilliSeconds(), GHOST_kEventCursorMove, window, x_screen, y_screen, tabletData);
+ return new GHOST_EventCursor(system->getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ window,
+ x_screen,
+ y_screen,
+ GHOST_TABLET_DATA_NONE);
}
return NULL;
}
@@ -1320,6 +1262,23 @@ 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)
{
@@ -1359,12 +1318,10 @@ void GHOST_SystemWin32::setTabletAPI(GHOST_TTabletAPI api)
GHOST_System::setTabletAPI(api);
GHOST_WindowManager *wm = getWindowManager();
- GHOST_WindowWin32 *activeWindow = (GHOST_WindowWin32 *)wm->getActiveWindow();
for (GHOST_IWindow *win : wm->getWindows()) {
- GHOST_WindowWin32 *windowsWindow = (GHOST_WindowWin32 *)win;
- windowsWindow->updateWintab(windowsWindow == activeWindow,
- !::IsIconic(windowsWindow->getHWND()));
+ GHOST_WindowWin32 *windowWin32 = (GHOST_WindowWin32 *)win;
+ windowWin32->setWintabEnabled(windowWin32->useTabletAPI(GHOST_kTabletWintab));
}
}
@@ -1609,15 +1566,23 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
////////////////////////////////////////////////////////////////////////
case WT_INFOCHANGE: {
window->processWintabInfoChangeEvent(lParam);
+ eventHandled = true;
break;
}
+ case WT_CSRCHANGE:
+ window->updateWintabCursorInfo();
+ eventHandled = true;
+ break;
case WT_PROXIMITY: {
- bool inRange = LOWORD(lParam);
- window->processWintabProximityEvent(inRange);
+ if (window->useTabletAPI(GHOST_kTabletWintab)) {
+ window->m_tabletInRange = LOWORD(lParam);
+ }
+ eventHandled = true;
break;
}
case WT_PACKET:
- window->updateWintabEventsSyncTime();
+ processWintabEvent(window);
+ eventHandled = true;
break;
////////////////////////////////////////////////////////////////////////
// Pointer events, processed
@@ -1667,6 +1632,15 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
}
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);
+ }
+
event = processCursorEvent(window);
break;
case WM_MOUSEWHEEL: {
@@ -1709,7 +1683,10 @@ 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);
+ break;
////////////////////////////////////////////////////////////////////////
// Mouse events, ignored
////////////////////////////////////////////////////////////////////////
@@ -1725,7 +1702,6 @@ 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
////////////////////////////////////////////////////////////////////////
@@ -1758,8 +1734,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
if (LOWORD(wParam) == WA_INACTIVE)
window->lostMouseCapture();
- window->updateWintab(LOWORD(wParam) != WA_INACTIVE, !::IsIconic(window->getHWND()));
-
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
@@ -1801,6 +1775,8 @@ 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
@@ -1808,21 +1784,13 @@ 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.
*/
- /* 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 {
- event = processWindowEvent(GHOST_kEventWindowSize, window);
- }
+ event = processWindowSizeEvent(window);
- /* Window might be minimized while inactive. When a window is inactive but not minimized,
- * Wintab is left enabled (to catch the case where a pen is used to activate a window).
- * When an inactive window is minimized, we need to disable Wintab. */
- if (msg == WM_SIZE && wParam == SIZE_MINIMIZED) {
- window->updateWintab(false, false);
+ if (wParam == SIZE_MINIMIZED) {
+ window->setWintabEnabled(false);
+ }
+ else if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED) {
+ window->setWintabEnabled(true);
}
break;
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 00b626511ab..ca227278fa7 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -322,16 +322,9 @@ class GHOST_SystemWin32 : public GHOST_System {
/**
* Creates tablet events from Wintab events.
- * \param type: The type of pointer event.
* \param window: The window receiving the event (the active window).
- * \param mask: The button mask of the calling event.
- * \param mousePressed: Whether the mouse is currently pressed.
- * \return True if the method handled the event.
*/
- static GHOST_TSuccess processWintabEvent(GHOST_TEventType type,
- GHOST_WindowWin32 *window,
- GHOST_TButtonMask mask,
- bool mousePressed);
+ static void processWintabEvent(GHOST_WindowWin32 *window);
/**
* Creates tablet events from pointer events.
@@ -377,6 +370,13 @@ 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 a4cbf66b22d..f5088c6505e 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -72,6 +72,7 @@ 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),
@@ -309,8 +310,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
(m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable")) &&
(m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap"))) {
initializeWintab();
- // Determine which tablet API to use and enable it.
- updateWintab(m_system->m_windowFocus, m_system->m_windowFocus);
+ setWintabEnabled(true);
}
CoCreateInstance(
@@ -326,13 +326,12 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
}
if (m_wintab.handle) {
- updateWintab(false, false);
+ setWintabEnabled(false);
if (m_wintab.close && m_wintab.context) {
m_wintab.close(m_wintab.context);
}
FreeLibrary(m_wintab.handle);
- memset(&m_wintab, 0, sizeof(m_wintab));
}
if (m_user32) {
@@ -771,32 +770,6 @@ void GHOST_WindowWin32::updateMouseCapture(GHOST_MouseCaptureEventWin32 event)
}
}
-bool GHOST_WindowWin32::getMousePressed() const
-{
- return m_nPressedButtons;
-}
-
-bool GHOST_WindowWin32::wintabSysButPressed() const
-{
- return m_wintab.numSysButtons;
-}
-
-void GHOST_WindowWin32::updateWintabSysBut(GHOST_MouseCaptureEventWin32 event)
-{
- switch (event) {
- case MousePressed:
- m_wintab.numSysButtons++;
- break;
- case MouseReleased:
- if (m_wintab.numSysButtons)
- m_wintab.numSysButtons--;
- break;
- case OperatorGrab:
- case OperatorUngrab:
- break;
- }
-}
-
HCURSOR GHOST_WindowWin32::getStandardCursor(GHOST_TStandardCursor shape) const
{
// Convert GHOST cursor to Windows OEM cursor
@@ -1000,28 +973,6 @@ GHOST_TSuccess GHOST_WindowWin32::hasCursorShape(GHOST_TStandardCursor cursorSha
return (getStandardCursor(cursorShape)) ? GHOST_kSuccess : GHOST_kFailure;
}
-void GHOST_WindowWin32::updateWintab(bool active, bool visible)
-{
- if (m_wintab.enable && m_wintab.overlap && m_wintab.context) {
- bool enable = useTabletAPI(GHOST_kTabletWintab) && visible;
- bool overlap = enable && active;
-
- /* Disabling context while the Window is not minimized can cause issues on receiving Wintab
- * input while changing a window for some drivers, so only disable if either Wintab had been
- * disabled or the window is minimized. */
- m_wintab.enable(m_wintab.context, enable);
- m_wintab.overlap(m_wintab.context, overlap);
-
- if (!overlap) {
- /* WT_PROXIMITY event doesn't occur unless tablet's cursor leaves the proximity while the
- * window is active. */
- m_tabletInRange = false;
- m_wintab.numSysButtons = 0;
- m_wintab.sysButtonsPressed = 0;
- }
- }
-}
-
void GHOST_WindowWin32::initializeWintab()
{
/* Return if wintab library handle doesn't exist or wintab is already initialized. */
@@ -1034,8 +985,6 @@ void GHOST_WindowWin32::initializeWintab()
if (m_wintab.open && m_wintab.info && m_wintab.queueSizeGet && m_wintab.queueSizeSet &&
m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) {
- /* The pressure and orientation (tilt) */
- AXIS Pressure, Orientation[3];
lc.lcPktData = PACKETDATA;
lc.lcPktMode = PACKETMODE;
lc.lcMoveMask = PACKETDATA;
@@ -1046,19 +995,7 @@ void GHOST_WindowWin32::initializeWintab()
m_wintab.info(WTI_INTERFACE, IFC_NDEVICES, &m_wintab.numDevices);
- BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
- m_wintab.maxPressure = pressureSupport ? Pressure.axMax : 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) {
- /* 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;
- }
+ 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);
@@ -1171,9 +1108,63 @@ GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
}
}
+ if (!outPointerInfo.empty()) {
+ lastTabletData = outPointerInfo.back().tabletData;
+ }
+
return GHOST_kSuccess;
}
+void GHOST_WindowWin32::setWintabEnabled(bool enable)
+{
+ 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);
+ }
+ }
+ }
+}
+
+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.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)) {
+ /* Set tablet as not in range, proximity event may not occur. */
+ m_tabletInRange = false;
+ /* 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};
@@ -1207,48 +1198,38 @@ bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const
}
}
-void GHOST_WindowWin32::processWintabProximityEvent(bool inRange)
+void GHOST_WindowWin32::updateWintabCursorInfo()
{
- if (!useTabletAPI(GHOST_kTabletWintab)) {
- return;
- }
-
- // Let's see if we can initialize tablet here
if (m_wintab.info && m_wintab.context) {
- AXIS Pressure, Orientation[3]; /* The maximum tablet size */
+ AXIS Pressure, Orientation[3];
BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
m_wintab.maxPressure = pressureSupport ? Pressure.axMax : 0;
BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
- /* does the tablet support azimuth ([0]) and altitude ([1]) */
+ /* 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 { /* no so dont do tilt stuff */
+ else {
m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
}
}
-
- m_tabletInRange = inRange;
}
void GHOST_WindowWin32::processWintabInfoChangeEvent(LPARAM lParam)
{
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
-
- // Update number of connected Wintab digitizers
+ /* 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);
- updateWintab((GHOST_WindowWin32 *)system->getWindowManager()->getActiveWindow() == this,
- !::IsIconic(m_hWnd));
+ if (useTabletAPI(GHOST_kTabletWintab)) {
+ setWintabEnabled(true);
+ }
}
}
-GHOST_TSuccess GHOST_WindowWin32::wintabMouseToGhost(UINT cursor,
- WORD physicalButton,
- GHOST_TButtonMask &ghostButton)
+GHOST_TButtonMask GHOST_WindowWin32::wintabMouseToGhost(UINT cursor, WORD physicalButton)
{
const WORD numButtons = 32;
BYTE logicalButtons[numButtons] = {0};
@@ -1258,198 +1239,120 @@ GHOST_TSuccess GHOST_WindowWin32::wintabMouseToGhost(UINT cursor,
m_wintab.info(WTI_CURSORS + cursor, CSR_SYSBTNMAP, &systemButtons);
if (physicalButton >= numButtons) {
- return GHOST_kFailure;
+ return GHOST_kButtonMaskNone;
}
BYTE lb = logicalButtons[physicalButton];
if (lb >= numButtons) {
- return GHOST_kFailure;
+ return GHOST_kButtonMaskNone;
}
switch (systemButtons[lb]) {
case SBN_LCLICK:
- ghostButton = GHOST_kButtonMaskLeft;
- return GHOST_kSuccess;
+ return GHOST_kButtonMaskLeft;
case SBN_RCLICK:
- ghostButton = GHOST_kButtonMaskRight;
- return GHOST_kSuccess;
+ return GHOST_kButtonMaskRight;
case SBN_MCLICK:
- ghostButton = GHOST_kButtonMaskMiddle;
- return GHOST_kSuccess;
+ return GHOST_kButtonMaskMiddle;
default:
- return GHOST_kFailure;
+ return GHOST_kButtonMaskNone;
}
}
GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
{
- if (!useTabletAPI(GHOST_kTabletWintab)) {
- return GHOST_kFailure;
- }
-
- if (!(m_wintab.packetsGet && m_wintab.context)) {
+ if (!(useTabletAPI(GHOST_kTabletWintab) && m_wintab.packetsGet && m_wintab.context)) {
return GHOST_kFailure;
}
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
- updateWintabEvents();
-
- auto &pendingEvents = m_wintab.pendingEvents;
- size_t pendingEventSize = pendingEvents.size();
- outWintabInfo.resize(pendingEventSize);
+ 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 < pendingEventSize; i++) {
- PACKET pkt = pendingEvents.front();
- pendingEvents.pop();
+ for (int i = 0; i < numPackets; i++) {
+ PACKET pkt = m_wintab.pkts[i];
+ GHOST_WintabInfoWin32 &out = outWintabInfo[i];
- GHOST_TabletData tabletData = GHOST_TABLET_DATA_NONE;
- switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */
+ out.tabletData = GHOST_TABLET_DATA_NONE;
+ /* % 3 for multiple devices ("DualTrack"). */
+ switch (pkt.pkCursor % 3) {
case 0:
- tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */
+ /* Puck - processed as mouse. */
+ out.tabletData.Active = GHOST_kTabletModeNone;
break;
case 1:
- tabletData.Active = GHOST_kTabletModeStylus; /* stylus */
+ out.tabletData.Active = GHOST_kTabletModeStylus;
break;
case 2:
- tabletData.Active = GHOST_kTabletModeEraser; /* eraser */
+ out.tabletData.Active = GHOST_kTabletModeEraser;
break;
}
+ out.x = pkt.pkX;
+ out.y = pkt.pkY;
+
if (m_wintab.maxPressure > 0) {
- tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
+ 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 */
+ 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.
+ * 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.
*
- * 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.
+ * 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 */
+ /* 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 */
+ /* Find length of the stylus' projected vector on the XY plane. */
vecLen = cos(altRad);
- /* from there calculate X and Y components based on azimuth */
- tabletData.Xtilt = sin(azmRad) * vecLen;
- tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
+ /* 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);
}
- outWintabInfo[i].x = pkt.pkX;
- outWintabInfo[i].y = pkt.pkY;
-
- /* Some Wintab libraries don't handle relative button input correctly, so we track button
- * presses manually. Examples include Wacom's Bamboo modifying button events in the queue when
- * peeked, or missing events when entering the window when the context is not on top. */
- DWORD buttonsChanged = m_wintab.sysButtonsPressed ^ pkt.pkButtons;
-
- /* 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 (buttonsChanged &&
- wintabMouseToGhost(pkt.pkCursor, physicalButton, outWintabInfo[i].button)) {
- if (buttonsChanged & pkt.pkButtons) {
- outWintabInfo[i].type = GHOST_kEventButtonDown;
- }
- else {
- outWintabInfo[i].type = GHOST_kEventButtonUp;
- }
- }
- else {
- outWintabInfo[i].type = GHOST_kEventCursorMove;
+ out.button = wintabMouseToGhost(pkt.pkCursor, LOWORD(pkt.pkButtons));
+ switch (HIWORD(pkt.pkButtons)) {
+ case TBN_NONE:
+ out.type = GHOST_kEventCursorMove;
+ break;
+ case TBN_DOWN:
+ out.type = GHOST_kEventButtonDown;
+ break;
+ case TBN_UP:
+ out.type = GHOST_kEventButtonUp;
+ break;
}
- m_wintab.sysButtonsPressed = pkt.pkButtons;
-
- outWintabInfo[i].time = system->millisSinceStart(pkt.pkTime);
- outWintabInfo[i].tabletData = tabletData;
+ out.time = system->tickCountToMillis(pkt.pkTime);
}
- return GHOST_kSuccess;
-}
-
-void GHOST_WindowWin32::updateWintabEvents()
-{
- readWintabEvents();
- // When a Wintab device is used to leave window focus, some of it's packets are periodically not
- // queued in time to be flushed. Reading packets needs to occur before expiring packets to clear
- // these from the queue.
- expireWintabEvents();
-}
-
-void GHOST_WindowWin32::updateWintabEventsSyncTime()
-{
- readWintabEvents();
-
- if (!m_wintab.pendingEvents.empty()) {
- auto lastEvent = m_wintab.pendingEvents.back();
- m_wintab.sysTimeOffset = ::GetTickCount() - lastEvent.pkTime;
- }
-
- expireWintabEvents();
-}
-
-void GHOST_WindowWin32::readWintabEvents()
-{
- if (!(m_wintab.packetsGet && m_wintab.context)) {
- return;
+ if (!outWintabInfo.empty()) {
+ lastTabletData = outWintabInfo.back().tabletData;
}
- auto &pendingEvents = m_wintab.pendingEvents;
-
- /* Get new packets. */
- const int numPackets = m_wintab.packetsGet(
- m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
-
- for (int i = 0; i < numPackets; i++) {
- pendingEvents.push(m_wintab.pkts[i]);
- }
+ return GHOST_kSuccess;
}
-/* Wintab (per documentation but may vary with implementation) does not update when its event
- * buffer is full. This is an issue because we need some synchronization point between Wintab
- * events and Win32 events, so we can't drain and process the queue immediately. We need to
- * associate Wintab mouse events to Win32 mouse events because Wintab buttons are modal (a button
- * associated to left click is not always a left click) and there's no way to reconstruct their
- * mode from the Wintab API alone. There is no guaranteed ordering between Wintab and Win32 mouse
- * events and no documented time stamp shared between the two, so we synchronize on mouse button
- * events. */
-void GHOST_WindowWin32::expireWintabEvents()
+GHOST_TabletData GHOST_WindowWin32::getLastTabletData()
{
- auto &pendingEvents = m_wintab.pendingEvents;
-
- DWORD currTime = ::GetTickCount() - m_wintab.sysTimeOffset;
- DWORD millisTimeout = 300;
- while (!pendingEvents.empty()) {
- DWORD pkTime = pendingEvents.front().pkTime;
-
- if (currTime > pkTime + millisTimeout) {
- pendingEvents.pop();
- }
- else {
- break;
- }
- }
+ return lastTabletData;
}
GHOST_TUns16 GHOST_WindowWin32::getDPIHint()
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 829bbdea051..1cff8b2036e 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -41,7 +41,7 @@
// 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 PACKETMODE PK_BUTTONS
#include <pktdef.h>
class GHOST_SystemWin32;
@@ -438,13 +438,6 @@ class GHOST_WindowWin32 : public GHOST_Window {
void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
/**
- * Handle setup and switch between Wintab and Pointer APIs.
- * \param active: Whether the window is or will be in an active state.
- * \param visible: Whether the window is currently (or will be) visible).
- */
- void updateWintab(bool active, bool visible);
-
- /**
* Query whether given tablet API should be used.
* \param api: Tablet API to test.
*/
@@ -462,15 +455,26 @@ 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);
+
+ /**
* Handle Wintab coordinate changes when DisplayChange events occur.
*/
void processWintabDisplayChangeEvent();
/**
- * Set tablet details when a cursor enters range.
- * \param inRange: Whether the Wintab device is in tracking range.
+ * Updates cached Wintab properties for current cursor.
*/
- void processWintabProximityEvent(bool inRange);
+ void updateWintabCursorInfo();
/**
* Handle Wintab info changes such as change in number of connected tablets.
@@ -486,14 +490,10 @@ class GHOST_WindowWin32 : public GHOST_Window {
GHOST_TSuccess getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo);
/**
- * Updates pending Wintab events and syncs Wintab time with OS time.
- */
- void updateWintabEventsSyncTime();
-
- /**
- * Updates pending Wintab events.
+ * Get the most recent tablet data.
+ * \return Most recent tablet data.
*/
- void updateWintabEvents();
+ GHOST_TabletData getLastTabletData();
GHOST_TSuccess beginFullScreen() const
{
@@ -507,24 +507,8 @@ class GHOST_WindowWin32 : public GHOST_Window {
GHOST_TUns16 getDPIHint() override;
- /**
- * Get whether there are currently any mouse buttons pressed.
- * \return True if there are any currently pressed mouse buttons.
- */
- bool getMousePressed() const;
-
- /**
- * Get if there are currently pressed Wintab buttons associated to a Windows mouse button press.
- * \return True if there are currently any pressed Wintab buttons associated to a Windows
- * mouse button press.
- */
- bool wintabSysButPressed() const;
-
- /**
- * Register a Wintab button has been associated to a Windows mouse button press.
- * \param event: Whether the button was pressed or released.
- */
- void updateWintabSysBut(GHOST_MouseCaptureEventWin32 event);
+ /** Whether the mouse is either over or captured by the window. */
+ bool m_mousePresent;
/** Whether a tablet stylus is being tracked. */
bool m_tabletInRange;
@@ -582,28 +566,28 @@ class GHOST_WindowWin32 : public GHOST_Window {
int hotY,
bool canInvertColor);
- /** Pointer to system */
+ /** Pointer to system. */
GHOST_SystemWin32 *m_system;
- /** Pointer to COM IDropTarget implementor */
+ /** Pointer to COM IDropTarget implementor. */
GHOST_DropTargetWin32 *m_dropTarget;
/** Window handle. */
HWND m_hWnd;
/** Device context handle. */
HDC m_hDC;
- /** Flag for if window has captured the mouse */
+ /** Flag for if window has captured the mouse. */
bool m_hasMouseCaptured;
- /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab()
- * Multiple grabs must be released with a single ungrab */
+ /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab().
+ * Multiple grabs must be released with a single ungrab. */
bool m_hasGrabMouse;
- /** Count of number of pressed buttons */
+ /** Count of number of pressed buttons. */
int m_nPressedButtons;
- /** HCURSOR structure of the custom cursor */
+ /** HCURSOR structure of the custom cursor. */
HCURSOR m_customCursor;
- /** request GL context aith alpha channel */
+ /** Request GL context aith alpha channel. */
bool m_wantAlphaBackground;
- /** ITaskbarList3 structure for progress bar*/
+ /** ITaskbarList3 structure for progress bar. */
ITaskbarList3 *m_Bar;
static const wchar_t *s_windowClassName;
@@ -626,42 +610,31 @@ class GHOST_WindowWin32 : public GHOST_Window {
GHOST_WIN32_WTEnable enable = NULL;
GHOST_WIN32_WTOverlap overlap = NULL;
- /** Stores the Tablet context if detected Tablet features using WinTab.dll */
+ /** Stores the Tablet context if detected Tablet features using WinTab.dll. */
HCTX context = NULL;
- /** Number of connected Wintab digitizers */
+ /** Number of connected Wintab digitizers. */
UINT numDevices = 0;
- /** Number of cursors currently in contact mapped to system buttons */
- GHOST_TUns8 numSysButtons = 0;
- /** Cursors currently in contact mapped to system buttons */
- DWORD sysButtonsPressed = 0;
- DWORD sysTimeOffset = 0;
LONG maxPressure = 0;
LONG maxAzimuth = 0, maxAltitude = 0;
/** Reusable buffer to read in Wintab Packets. */
std::vector<PACKET> pkts;
- /** Queue of packets to process. */
- std::queue<PACKET> pendingEvents;
} m_wintab;
+ /** Most recent tablet data. */
+ GHOST_TabletData lastTabletData = GHOST_TABLET_DATA_NONE;
+
/**
* Wintab setup.
*/
void initializeWintab();
- void readWintabEvents();
-
- void expireWintabEvents();
-
/**
* 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.
- * \param buttonMask: Return pointer for button found.
- * \return Whether an associated button was found.
+ * \return The system mapped button.
*/
- GHOST_TSuccess wintabMouseToGhost(UINT cursor,
- WORD physicalButton,
- GHOST_TButtonMask &buttonMask);
+ GHOST_TButtonMask wintabMouseToGhost(UINT cursor, WORD physicalButton);
GHOST_TWindowState m_normal_state;