From 20df53490301fda3e1549bcf5ddcaf69d287d4e7 Mon Sep 17 00:00:00 2001 From: cxl Date: Sat, 13 Mar 2021 14:06:35 +0000 Subject: [PATCH] CtrlCore: Window Ink support git-svn-id: svn://ultimatepp.org/upp/trunk@15844 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlCore/CtrlCore.h | 2 + uppsrc/CtrlCore/CtrlMouse.cpp | 1 + uppsrc/CtrlCore/Win32Proc.cpp | 137 ++++++++++++++++++------- uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp | 42 ++++++++ 4 files changed, 147 insertions(+), 35 deletions(-) diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 7f0eee6d0..e25cccd5f 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -679,6 +679,7 @@ private: static bool pen_barrel; static bool pen_inverted; static bool pen_eraser; + static bool pen_history; static double pen_pressure; static double pen_rotation; static Pointf pen_tilt; @@ -1298,6 +1299,7 @@ public: static int64 GetEventId() { return eventid; } static bool IsPointerPen() { return pen; } + static bool IsPenHistoryEvent() { return pen_history; } static bool IsPenBarrelPressed() { return pen_barrel; } static bool IsPenInverted() { return pen_inverted; } static bool IsPenEraserPressed() { return pen_eraser; } diff --git a/uppsrc/CtrlCore/CtrlMouse.cpp b/uppsrc/CtrlCore/CtrlMouse.cpp index 0a22b181e..4bddf5fee 100644 --- a/uppsrc/CtrlCore/CtrlMouse.cpp +++ b/uppsrc/CtrlCore/CtrlMouse.cpp @@ -22,6 +22,7 @@ bool Ctrl::pen; bool Ctrl::pen_barrel; bool Ctrl::pen_inverted; bool Ctrl::pen_eraser; +bool Ctrl::pen_history; double Ctrl::pen_pressure = Null; double Ctrl::pen_rotation = Null; Pointf Ctrl::pen_tilt = Null; diff --git a/uppsrc/CtrlCore/Win32Proc.cpp b/uppsrc/CtrlCore/Win32Proc.cpp index 01d0adf51..f0acf1a39 100644 --- a/uppsrc/CtrlCore/Win32Proc.cpp +++ b/uppsrc/CtrlCore/Win32Proc.cpp @@ -63,11 +63,111 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // LLOG("Ctrl::WindowProc(" << message << ") in " << ::Name(this) << ", focus " << (void *)::GetFocus()); Ptr _this = this; HWND hwnd = GetHWND(); + + auto DoMouseMove = [&](POINT p) { + if(ignoreclick) + EndIgnore(); + else { + if(_this) DoMouse(MOUSEMOVE, Point(p)); + DoCursorShape(); + } + }; + switch(message) { + case WM_POINTERDOWN: + case WM_POINTERUPDATE: + case WM_POINTERUP: { + POINT p = Point((LONG)lParam); + ScreenToClient(hwnd, &p); + + pen = false; + pen_pressure = pen_rotation = Null; + pen_tilt = Null; + pen_eraser = false; + pen_barrel = false; + pen_inverted = false; + pen_history = false; + + static BOOL (WINAPI *EnableMouseInPointer)(BOOL fEnable); + static BOOL (WINAPI *GetPointerType)(UINT32 pointerId, POINTER_INPUT_TYPE *pointerType); + static BOOL (WINAPI *GetPointerInfo)(UINT32 pointerId, POINTER_INFO *pointerInfo); + static BOOL (WINAPI *GetPointerPenInfo)(UINT32 pointerId, POINTER_PEN_INFO *penInfo); + static BOOL (WINAPI *GetPointerPenInfoHistory)(UINT32 pointerId, UINT32 *entriesCount, POINTER_PEN_INFO *penInfo); + + ONCELOCK { + DllFn(GetPointerType, "User32.dll", "GetPointerType"); + DllFn(GetPointerInfo, "User32.dll", "GetPointerInfo"); + DllFn(GetPointerPenInfo, "User32.dll", "GetPointerPenInfo"); + DllFn(GetPointerPenInfoHistory, "User32.dll", "GetPointerPenInfoHistory"); + }; + + if(!(GetPointerType && GetPointerInfo && GetPointerPenInfo && GetPointerPenInfoHistory)) + break; + + POINTER_INPUT_TYPE pointerType; + + auto ProcessPenInfo = [&] (POINTER_PEN_INFO& ppi) { + pen = true; + if(ppi.penFlags & PEN_FLAG_BARREL) + pen_barrel = true; + if(ppi.penFlags & PEN_FLAG_INVERTED) + pen_inverted = true; + if(ppi.penFlags & PEN_FLAG_ERASER) + pen_eraser = true; + if(ppi.penMask & PEN_MASK_PRESSURE) + pen_pressure = ppi.pressure / 1024.0; + if(ppi.penMask & PEN_MASK_ROTATION) + pen_rotation = ppi.rotation * M_2PI / 360; + if(ppi.penMask & PEN_MASK_TILT_X) + pen_tilt.x = ppi.tiltX * M_2PI / 360; + if(ppi.penMask & PEN_MASK_TILT_Y) + pen_tilt.y = ppi.tiltY * M_2PI / 360; + }; + + UINT32 pointerId = GET_POINTERID_WPARAM(wParam); + if(GetPointerType(pointerId, &pointerType) && pointerType == PT_PEN) { + UINT32 hc = 256; + Buffer ppit(hc); + if(message == WM_POINTERUPDATE && GetPointerPenInfoHistory(pointerId, &hc, ppit)) { + for(int i = hc - 1; i >= 0; i--) { + ProcessPenInfo(ppit[i]); + POINT hp = ppit[i].pointerInfo.ptPixelLocation; + ScreenToClient(hwnd, &hp); + DoMouseMove(hp); + pen_history = true; // first one is the current event + } + pen_history = false; + return 0L; + } + POINTER_PEN_INFO ppi; + if(GetPointerPenInfo(pointerId, &ppi)) + ProcessPenInfo(ppi); + switch(message) { + case WM_POINTERDOWN: + ClickActivateWnd(); + if(ignoreclick) return 0L; + DoMouse(LEFTDOWN, Point(p), 0); + if(_this) PostInput(); + break; + case WM_POINTERUP: + if(ignoreclick) EndIgnore(); + else DoMouse(LEFTUP, Point(p), 0); + if(_this) PostInput(); + break; + case WM_POINTERUPDATE: + DoMouseMove(p); + break; + } + return 0L; + } + } + break; + case WM_POINTERLEAVE: + pen = false; + break; case WM_PALETTECHANGED: if((HWND)wParam == hwnd) break; -#ifndef PLATFORM_WINCE case WM_QUERYNEWPALETTE: if(!SystemDraw::AutoPalette()) break; { @@ -81,7 +181,6 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if(i) InvalidateRect(hwnd, NULL, TRUE); return i; } -#endif case WM_PAINT: ASSERT_(!painting || IsPanicMode(), "WM_PAINT invoked for " + Name() + " while in Paint routine"); ASSERT(hwnd); @@ -93,37 +192,28 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { fullrefresh = false; if(IsVisible()) { SystemDraw draw(dc); - #ifndef PLATFORM_WINCE HPALETTE hOldPal; if(draw.PaletteMode() && SystemDraw::AutoPalette()) { hOldPal = SelectPalette(dc, GetQlibPalette(), TRUE); int n = RealizePalette(dc); LLOG("In paint realized " << n << " colors"); } - #endif painting = true; UpdateArea(draw, Rect(ps.rcPaint)); painting = false; - #ifndef PLATFORM_WINCE if(draw.PaletteMode() && SystemDraw::AutoPalette()) SelectPalette(dc, hOldPal, TRUE); - #endif } EndPaint(hwnd, &ps); UpdateDHCtrls(); // so that they are displayed withing the same WM_PAINT - looks better } return 0L; -#ifndef PLATFORM_WINCE case WM_NCHITTEST: CheckMouseCtrl(); if(ignoremouse) return HTTRANSPARENT; break; -#endif case WM_LBUTTONDOWN: -#ifdef PLARFORM_WINCE - wince_mouseleft = true; -#endif ClickActivateWnd(); if(ignoreclick) return 0L; DoMouse(LEFTDOWN, Point((dword)lParam), 0); @@ -134,14 +224,6 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { EndIgnore(); else DoMouse(LEFTUP, Point((dword)lParam), 0); -#ifdef PLATFORM_WINCE - wince_mouseleft = false; -#endif -#ifdef PLATFORM_WINCE - wince_mousepos = Point(-99999, -99999); - if(!ignoreclick) - if(_this) DoMouse(MOUSEMOVE, Point(-99999, -99999)); -#endif if(_this) PostInput(); return 0L; case WM_LBUTTONDBLCLK: @@ -188,23 +270,15 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { DoMouse(MIDDLEDOUBLE, Point((dword)lParam)); if(_this) PostInput(); return 0L; -#ifndef PLATFORM_WINCE case WM_NCLBUTTONDOWN: case WM_NCRBUTTONDOWN: case WM_NCMBUTTONDOWN: ClickActivateWnd(); IgnoreMouseUp(); break; -#endif case WM_MOUSEMOVE: LLOG("WM_MOUSEMOVE: ignoreclick = " << ignoreclick); - if(ignoreclick) { - EndIgnore(); - return 0L; - } - if(_this) - DoMouse(MOUSEMOVE, Point((dword)lParam)); - DoCursorShape(); + DoMouseMove(Point((dword)lParam)); return 0L; case 0x20a: // WM_MOUSEWHEEL: if(ignoreclick) { @@ -265,9 +339,6 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { keycode = KEYtoK((dword)wParam) | K_KEYUP; else if(message == WM_CHAR && wParam != 127 && wParam > 32 || wParam == 32 && KEYtoK(VK_SPACE) == K_SPACE) { -#ifdef PLATFORM_WINCE - keycode = wParam; -#else if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX Unicode patch keycode = (dword)wParam; else { @@ -280,7 +351,6 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { else keycode = (dword)wParam; } -#endif } bool b = false; if(keycode) { @@ -482,14 +552,11 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { */ } if(hwnd) { -#ifdef PLATFORM_WINCE return DefWindowProc(hwnd, message, wParam, lParam); -#else if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX unicode patch return DefWindowProcW(hwnd, message, wParam, lParam); else return DefWindowProc(hwnd, message, wParam, lParam); -#endif } return 0L; } diff --git a/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp b/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp index 8ea9a143b..2ff04c51d 100644 --- a/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp +++ b/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp @@ -2753,6 +2753,48 @@ This is helpful in certain caching situations `- e.g. if you want to lazy fetch some data, but only once per input event.&] [s3;%- &] [s4;%- &] +[s5;:Upp`:`:Ctrl`:`:IsPointerPen`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPointerP +en]()&] +[s2; Current mouse event is in fact not a mouse event, but was caused +by interaction of graphical pen with tablet.&] +[s3;%- &] +[s4;%- &] +[s5;:Upp`:`:Ctrl`:`:IsPenHistoryEvent`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPen +HistoryEvent]()&] +[s2; The current event is from coalesced pen history (that could +happen if your software is unable to process all events in time).&] +[s3;%- &] +[s4;%- &] +[s5;:Upp`:`:Ctrl`:`:IsPenBarrelPressed`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPe +nBarrelPressed]()&] +[s2; Barell is pressed.&] +[s3;%- &] +[s4;%- &] +[s5;:Upp`:`:Ctrl`:`:IsPenInverted`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPenInve +rted]()&] +[s2; Pen is inverted.&] +[s3;%- &] +[s4;%- &] +[s5;:Upp`:`:Ctrl`:`:IsPenEraserPressed`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPe +nEraserPressed]()&] +[s2; Pen is in eraser mode&] +[s3;%- &] +[s4;%- &] +[s5;:Upp`:`:Ctrl`:`:GetPenPressure`(`):%- [@(0.0.255) static] [@(0.0.255) double]_[* GetPen +Pressure]()&] +[s2; Returns pen pressure as number 0...1.&] +[s3;%- &] +[s4;%- &] +[s5;:Upp`:`:Ctrl`:`:GetPenRotation`(`):%- [@(0.0.255) static] [@(0.0.255) double]_[* GetPen +Rotation]()&] +[s2; Returns pen rotation in radians.&] +[s3;%- &] +[s4;%- &] +[s5;:Upp`:`:Ctrl`:`:GetPenTilt`(`):%- [@(0.0.255) static] [_^Upp`:`:Pointf^ Pointf]_[* GetP +enTilt]()&] +[s2; Returns pen tilt in radians.&] +[s3;%- &] +[s4;%- &] [s5;:Upp`:`:Ctrl`:`:begin`(`)const:%- [_^Upp`:`:Ctrl`:`:CtrlConstIterator^ CtrlConstIte rator]_[* begin]()_[@(0.0.255) const]&] [s5;:Upp`:`:Ctrl`:`:begin`(`):%- [_^Upp`:`:Ctrl`:`:CtrlIterator^ CtrlIterator]_[* begin](