Changeset View
Standalone View
intern/ghost/intern/GHOST_WindowWin32.cpp
| Context not available. | |||||
| #include <string.h> | #include <string.h> | ||||
| #include <assert.h> | #include <assert.h> | ||||
| #ifndef GET_POINTERID_WPARAM | |||||
| #define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam)) | |||||
| #endif // GET_POINTERID_WPARAM | |||||
| const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass"; | const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass"; | ||||
| const int GHOST_WindowWin32::s_maxTitleLength = 128; | const int GHOST_WindowWin32::s_maxTitleLength = 128; | ||||
| Context not available. | |||||
| RegisterRawInputDevices(&device, 1, sizeof(device)); | RegisterRawInputDevices(&device, 1, sizeof(device)); | ||||
| } | } | ||||
| m_user32 = ::LoadLibrary("user32.dll"); | |||||
| m_wintab = ::LoadLibrary("Wintab32.dll"); | m_wintab = ::LoadLibrary("Wintab32.dll"); | ||||
| if (m_wintab) { | if (m_wintab) { | ||||
| GHOST_WIN32_WTInfo fpWTInfo = (GHOST_WIN32_WTInfo) ::GetProcAddress(m_wintab, "WTInfoA"); | GHOST_WIN32_WTInfo fpWTInfo = (GHOST_WIN32_WTInfo) ::GetProcAddress(m_wintab, "WTInfoA"); | ||||
| Context not available. | |||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| void GHOST_WindowWin32::processWin32PointerEvent(WPARAM wParam) | |||||
| { | |||||
| UINT32 pointerId = GET_POINTERID_WPARAM(wParam); | |||||
| if (!this->m_user32) { | |||||
| return; | |||||
| } | |||||
| GHOST_WIN32_GetPointerInfo fpGetPointerInfo = (GHOST_WIN32_GetPointerInfo) ::GetProcAddress(m_user32, "GetPointerInfo"); | |||||
LazyDodo: please do this only once and cache the result. | |||||
| if (!fpGetPointerInfo) { | |||||
| return; // OS version does not support pointer API | |||||
| } | |||||
| POINTER_INFO pointerInfo; | |||||
| if (!fpGetPointerInfo(pointerId, &pointerInfo)) { | |||||
| return; // Invalid pointer info | |||||
| } | |||||
| if (!m_tabletData) { | |||||
| m_tabletData = new GHOST_TabletData(); | |||||
brechtUnsubmitted Not Done Inline ActionsThis memory leaks in GHOST_WindowWin32::~GHOST_WindowWin32 if no wintab is present. The code there needs to be updated. brecht: This memory leaks in `GHOST_WindowWin32::~GHOST_WindowWin32` if no wintab is present. The code… | |||||
| m_tabletData->Active = GHOST_kTabletModeNone; | |||||
| } | |||||
| m_tabletData->Active = GHOST_kTabletModeNone; | |||||
| m_tabletData->Pressure = 1.0f; | |||||
| if (pointerInfo.pointerType & PT_POINTER) { | |||||
| GHOST_WIN32_GetPointerPenInfo fpGetPointerPenInfo = (GHOST_WIN32_GetPointerPenInfo) ::GetProcAddress(m_user32, "GetPointerPenInfo"); | |||||
| if (!fpGetPointerPenInfo) { | |||||
| return; // OS version does not support pointer API | |||||
| } | |||||
| POINTER_PEN_INFO pointerPenInfo; | |||||
| if (!fpGetPointerPenInfo(pointerId, &pointerPenInfo)) { | |||||
| return; | |||||
| } | |||||
| if (pointerPenInfo.penFlags & PEN_FLAG_ERASER) { | |||||
| m_tabletData->Active = GHOST_kTabletModeEraser; | |||||
| } | |||||
| if (pointerPenInfo.penMask & PEN_MASK_PRESSURE && pointerPenInfo.pressure > 0) { | |||||
brechtUnsubmitted Not Done Inline ActionsIs the pointerPenInfo.pressure > 0 test correct? Are there case where the mask is set but no valid pressure is provided? It seems like it could cause full pressure when there is none. brecht: Is the `pointerPenInfo.pressure > 0` test correct? Are there case where the mask is set but no… | |||||
chris_82AuthorUnsubmitted Done Inline ActionsWith the Microsoft Surface Pen if you hover the pen within 1cm of the screen you'll start getting WM_POINTERUPDATE events with the PEN_MASK_PRESSURE mask set and zero pressure. When the pen is touching the screen the pressure field will have a value between 1 and 1024. After taking a look at the WinTab code I made it so that if the pen is not physically touching the screen GHOST_kTabletModeNone is set. With this implementation if the user switches from the pen to the mouse it will switch from GHOST_kTabletModeStylus to GHOST_kTabletModeNone and they'll be able to draw at full pressure with the mouse. That said I have realised that the test for PEN_FLAG_ERASER should happen after this, otherwise if their is a user with a pressure sensitive eraser it may start drawing a line instead. chris_82: With the Microsoft Surface Pen if you hover the pen within 1cm of the screen you'll start… | |||||
brechtUnsubmitted Done Inline ActionsMakes sense then. You could leave a comment explaining this in the code. brecht: Makes sense then. You could leave a comment explaining this in the code. | |||||
| m_tabletData->Active = GHOST_kTabletModeStylus; | |||||
| m_tabletData->Pressure = pointerPenInfo.pressure / 1024.0f; | |||||
| } | |||||
| } | |||||
| } | |||||
| void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state) | void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state) | ||||
| { | { | ||||
| if (!m_tablet) { | if (!m_tablet) { | ||||
Not Done Inline Actionsthe within -> to within brecht: the within -> to within | |||||
| Context not available. | |||||
| GHOST_TUns16 GHOST_WindowWin32::getDPIHint() | GHOST_TUns16 GHOST_WindowWin32::getDPIHint() | ||||
| { | { | ||||
| if (!m_user32) { | |||||
| m_user32 = ::LoadLibrary("user32.dll"); | |||||
| } | |||||
| if (m_user32) { | if (m_user32) { | ||||
| GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow) ::GetProcAddress(m_user32, "GetDpiForWindow"); | GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow) ::GetProcAddress(m_user32, "GetDpiForWindow"); | ||||
| Context not available. | |||||
please do this only once and cache the result.