diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 20ea7706..2739ba2d 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -3106,7 +3106,8 @@ fi # Patchset ddraw-Write_Vtable # | # | This patchset fixes the following Wine bugs: -# | * [#39534] Make ddraw1 and ddraw_surface1 vtable as writable +# | * [#39534] Make ddraw1 and ddraw_surface1 vtable as writable. +# | * [#46949] Make ddraw[2-7] and palette vtable as writable. # | # | Modified files: # | * dlls/ddraw/ddraw.c, dlls/ddraw/palette.c, dlls/ddraw/surface.c @@ -7174,7 +7175,7 @@ fi # | * [#18517] Improve eraser from working. # | # | Modified files: -# | * dlls/winex11.drv/wintab.c, dlls/wintab32/context.c +# | * dlls/winex11.drv/wintab.c, dlls/wintab32/context.c, dlls/wintab32/tests/Makefile.in, dlls/wintab32/tests/context.c # | if test "$enable_wintab32_improvements" -eq 1; then patch_apply wintab32-improvements/0001-winex11-Implement-PK_CHANGE-for-wintab.patch @@ -7182,14 +7183,16 @@ if test "$enable_wintab32_improvements" -eq 1; then patch_apply wintab32-improvements/0003-winex11-Handle-negative-orAltitude-values.patch patch_apply wintab32-improvements/0004-winex11.drv-Support-multiplex-categories-WTI_DSCTXS-.patch patch_apply wintab32-improvements/0005-winex11-Support-WTI_STATUS-in-WTInfo.patch - patch_apply wintab32-improvements/0006-winex11-Use-active-owner-when-sending-messages.patch + patch_apply wintab32-improvements/0006-wintab32-Scale-NormalPressure-before-sending-to-to-c.patch + patch_apply wintab32-improvements/0007-wintab32-tests-Initial-interactive-test.patch ( printf '%s\n' '+ { "Eriks Dobelis", "winex11: Implement PK_CHANGE for wintab.", 1 },'; printf '%s\n' '+ { "Alistair Leslie-Hughes", "wintab32: Set lcSysExtX/Y for the first index of WTI_DDCTXS.", 1 },'; printf '%s\n' '+ { "Alistair Leslie-Hughes", "winex11: Handle negative orAltitude values.", 1 },'; printf '%s\n' '+ { "Alistair Leslie-Hughes", "winex11.drv: Support multiplex categories WTI_DSCTXS and WTI_DDCTXS.", 1 },'; printf '%s\n' '+ { "Alistair Leslie-Hughes", "winex11: Support WTI_STATUS in WTInfo.", 1 },'; - printf '%s\n' '+ { "Robert Walker", "winex11: Use active owner when sending messages.", 1 },'; + printf '%s\n' '+ { "Alistair Leslie-Hughes", "wintab32: Scale NormalPressure before sending to the client.", 1 },'; + printf '%s\n' '+ { "Alistair Leslie-Hughes", "wintab32/tests: Initial interactive test.", 1 },'; ) >> "$patchlist" fi diff --git a/patches/wintab32-improvements/0006-winex11-Use-active-owner-when-sending-messages.patch b/patches/wintab32-improvements/0006-winex11-Use-active-owner-when-sending-messages.patch deleted file mode 100644 index 9c1591cb..00000000 --- a/patches/wintab32-improvements/0006-winex11-Use-active-owner-when-sending-messages.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 9099a135c1200d398e4a22e0c87bf7b494b82416 Mon Sep 17 00:00:00 2001 -From: Robert Walker -Date: Tue, 11 Dec 2018 09:22:18 +1100 -Subject: [PATCH] winex11: Use active owner when sending messages - ---- - dlls/winex11.drv/wintab.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - -diff --git a/dlls/winex11.drv/wintab.c b/dlls/winex11.drv/wintab.c -index 3517bd53cef..440c8f5d249 100644 ---- a/dlls/winex11.drv/wintab.c -+++ b/dlls/winex11.drv/wintab.c -@@ -265,6 +265,7 @@ static int proximity_in_type; - static int proximity_out_type; - - static HWND hwndTabletDefault; -+static HWND gActiveOwner; - static WTPACKET gMsgPacket; - static DWORD gSerial; - static DWORD lastX = 0xffff; -@@ -928,7 +929,7 @@ static BOOL motion_event( HWND hwnd, XEvent *event ) - gMsgPacket.pkNormalPressure = motion->axis_data[2]; - gMsgPacket.pkButtons = get_button_state(curnum); - gMsgPacket.pkChanged = get_changed_state(&gMsgPacket); -- SendMessageW(hwndTabletDefault,WT_PACKET,gMsgPacket.pkSerialNumber,(LPARAM)hwnd); -+ SendMessageW(hwndTabletDefault,WT_PACKET,gMsgPacket.pkSerialNumber,(LPARAM)gActiveOwner); - return TRUE; - } - -@@ -965,7 +966,7 @@ static BOOL button_event( HWND hwnd, XEvent *event ) - gMsgPacket.pkNormalPressure = button->axis_data[2]; - gMsgPacket.pkButtons = get_button_state(curnum); - gMsgPacket.pkChanged = get_changed_state(&gMsgPacket); -- SendMessageW(hwndTabletDefault,WT_PACKET,gMsgPacket.pkSerialNumber,(LPARAM)hwnd); -+ SendMessageW(hwndTabletDefault,WT_PACKET,gMsgPacket.pkSerialNumber,(LPARAM)gActiveOwner); - return TRUE; - } - -@@ -1021,7 +1022,7 @@ static BOOL proximity_event( HWND hwnd, XEvent *event ) - */ - proximity_info = MAKELPARAM((event->type == proximity_in_type), - (event->type == proximity_in_type) || (event->type == proximity_out_type)); -- SendMessageW(hwndTabletDefault, WT_PROXIMITY, (WPARAM)hwnd, proximity_info); -+ SendMessageW(hwndTabletDefault, WT_PROXIMITY, (WPARAM)gActiveOwner, proximity_info); - return TRUE; - } - -@@ -1038,12 +1039,12 @@ int CDECL X11DRV_AttachEventQueueToTablet(HWND hOwner) - XDeviceInfo *target = NULL; - XDevice *the_device; - XEventClass event_list[7]; -- Window win = X11DRV_get_whole_window( hOwner ); -- -- if (!win || !xinput_handle) return 0; -+ Window win = X11DRV_get_whole_window(GetDesktopWindow()); - - TRACE("Creating context for window %p (%lx) %i cursors\n", hOwner, win, gNumCursors); - -+ gActiveOwner = hOwner; -+ - devices = pXListInputDevices(data->display, &num_devices); - - X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL); --- -2.19.2 - diff --git a/patches/wintab32-improvements/0006-wintab32-Scale-NormalPressure-before-sending-to-to-c.patch b/patches/wintab32-improvements/0006-wintab32-Scale-NormalPressure-before-sending-to-to-c.patch new file mode 100644 index 00000000..490d1f03 --- /dev/null +++ b/patches/wintab32-improvements/0006-wintab32-Scale-NormalPressure-before-sending-to-to-c.patch @@ -0,0 +1,32 @@ +From dd5371720cce8910281a79d860d1fcb45acc1767 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Wed, 3 Apr 2019 16:43:30 +1100 +Subject: [PATCH] wintab32: Scale NormalPressure before sending to the client. + +We need to workout how to get valid Min/Max Pressure values that are the +same value as windows. + +--- + dlls/winex11.drv/wintab.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/dlls/winex11.drv/wintab.c b/dlls/winex11.drv/wintab.c +index 3517bd53cef..380562e9597 100644 +--- a/dlls/winex11.drv/wintab.c ++++ b/dlls/winex11.drv/wintab.c +@@ -925,7 +925,11 @@ static BOOL motion_event( HWND hwnd, XEvent *event ) + FIXME("Negative orAltitude detected\n"); + return FALSE; + } +- gMsgPacket.pkNormalPressure = motion->axis_data[2]; ++ /* Scale the value sent from XInput 0-65536 ++ * Windows 0-1043 ++ */ ++ gMsgPacket.pkNormalPressure = ((motion->axis_data[2] - gSysDevice.NPRESSURE.axMin) / ++ ((float)gSysDevice.NPRESSURE.axMax - gSysDevice.NPRESSURE.axMin)) * 1043; + gMsgPacket.pkButtons = get_button_state(curnum); + gMsgPacket.pkChanged = get_changed_state(&gMsgPacket); + SendMessageW(hwndTabletDefault,WT_PACKET,gMsgPacket.pkSerialNumber,(LPARAM)hwnd); +-- +2.20.1 + diff --git a/patches/wintab32-improvements/0007-wintab32-tests-Initial-interactive-test.patch b/patches/wintab32-improvements/0007-wintab32-tests-Initial-interactive-test.patch new file mode 100644 index 00000000..b9f35fee --- /dev/null +++ b/patches/wintab32-improvements/0007-wintab32-tests-Initial-interactive-test.patch @@ -0,0 +1,297 @@ +From 47421c170433df8172083dc2d0187bd9426ba3ee Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Tue, 2 Apr 2019 12:25:57 +1100 +Subject: [PATCH] wintab32/tests: Initial interactive test + +This is a work in progress test when using a stylus. +- Should display all information from the packet. +- Cleanup of variable naming. + +--- + dlls/wintab32/tests/Makefile.in | 2 +- + dlls/wintab32/tests/context.c | 195 ++++++++++++++++++++++++++++++-- + 2 files changed, 184 insertions(+), 13 deletions(-) + +diff --git a/dlls/wintab32/tests/Makefile.in b/dlls/wintab32/tests/Makefile.in +index 635e03fd5d6..ad63c27b5d1 100644 +--- a/dlls/wintab32/tests/Makefile.in ++++ b/dlls/wintab32/tests/Makefile.in +@@ -1,5 +1,5 @@ + TESTDLL = wintab32.dll +-IMPORTS = user32 ++IMPORTS = user32 gdi32 + + C_SRCS = \ + context.c +diff --git a/dlls/wintab32/tests/context.c b/dlls/wintab32/tests/context.c +index 5f059127657..b77e6c546a9 100644 +--- a/dlls/wintab32/tests/context.c ++++ b/dlls/wintab32/tests/context.c +@@ -21,6 +21,11 @@ + #include + #include + #include ++#include ++ ++#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE) ++#define PACKETMODE PK_BUTTONS ++#include "pktdef.h" + + #include "wine/test.h" + +@@ -29,11 +34,19 @@ static const CHAR wintabTestWindowClassName[] = "WintabTestWnd"; + static const CHAR contextName[] = "TestContext"; + static const UINT X = 0; + static const UINT Y = 0; +-static const UINT WIDTH = 200; +-static const UINT HEIGHT = 200; ++static const UINT WIDTH = 640; ++static const UINT HEIGHT = 480; ++ ++static LOGCONTEXTA glogContext; ++static HCTX hCtx = NULL; + +-static HCTX (WINAPI *pWTOpenA)(HWND, LPLOGCONTEXTA, BOOL); + static BOOL (WINAPI *pWTClose)(HCTX); ++static BOOL (WINAPI *pWTEnable)(HCTX, BOOL); ++static UINT (WINAPI *pWTInfoA)(UINT, UINT, void*); ++static HCTX (WINAPI *pWTOpenA)(HWND, LPLOGCONTEXTA, BOOL); ++static BOOL (WINAPI *pWTOverlap)(HCTX, BOOL); ++static BOOL (WINAPI *pWTPacket)(HCTX, UINT, void*); ++ + + static HMODULE load_functions(void) + { +@@ -49,8 +62,12 @@ static HMODULE load_functions(void) + return NULL; + } + +- if (GET_PROC(WTOpenA) && +- GET_PROC(WTClose) ) ++ if (GET_PROC(WTClose) && ++ GET_PROC(WTEnable) && ++ GET_PROC(WTInfoA) && ++ GET_PROC(WTOpenA) && ++ GET_PROC(WTOverlap) && ++ GET_PROC(WTPacket) ) + { + return hWintab; + } +@@ -70,7 +87,7 @@ static LRESULT CALLBACK wintabTestWndProc(HWND hwnd, UINT msg, WPARAM wParam, + return DefWindowProcA(hwnd, msg, wParam, lParam); + } + +-static void wintab_create_window(HWND* pHwnd) ++static void wintab_create_window(HWND* pHwnd, WNDPROC wndproc) + { + WNDCLASSA testWindowClass; + +@@ -80,18 +97,18 @@ static void wintab_create_window(HWND* pHwnd) + + ZeroMemory(&testWindowClass, sizeof(testWindowClass)); + +- testWindowClass.lpfnWndProc = wintabTestWndProc; ++ testWindowClass.lpfnWndProc = wndproc; + testWindowClass.hInstance = NULL; + testWindowClass.hIcon = NULL; + testWindowClass.hCursor = NULL; +- testWindowClass.hbrBackground = NULL; ++ testWindowClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);; + testWindowClass.lpszMenuName = NULL; + testWindowClass.lpszClassName = wintabTestWindowClassName; + + assert(RegisterClassA(&testWindowClass)); + + *pHwnd = CreateWindowA(wintabTestWindowClassName, NULL, +- WS_OVERLAPPED, X, Y, WIDTH, HEIGHT, NULL, NULL, ++ WS_OVERLAPPEDWINDOW, X, Y, WIDTH, HEIGHT, NULL, NULL, + NULL, NULL); + + assert(*pHwnd != NULL); +@@ -106,13 +123,12 @@ static void wintab_destroy_window(HWND hwnd) + /* test how a logcontext is validated by wtopen */ + static void test_WTOpenContextValidation(void) + { +- HWND defaultWindow = NULL; +- HCTX hCtx = NULL; ++ HWND defaultWindow = NULL; + LOGCONTEXTA testLogCtx; + LOGCONTEXTA refLogCtx; + int memdiff; + +- wintab_create_window(&defaultWindow); ++ wintab_create_window(&defaultWindow, wintabTestWndProc); + + ZeroMemory(&testLogCtx, sizeof(testLogCtx)); + strcpy(testLogCtx.lcName, contextName); +@@ -135,6 +151,158 @@ static void test_WTOpenContextValidation(void) + wintab_destroy_window(defaultWindow); + } + ++static HCTX initial_tablet(HWND hwnd) ++{ ++ HCTX hctx = NULL; ++ UINT wWTInfoRetVal = 0; ++ AXIS TabletX = {0}; ++ AXIS TabletY = {0}; ++ AXIS value = {0}; ++ ++ glogContext.lcOptions |= CXO_SYSTEM; ++ ++ /* Open default system context so that we can get tablet data in screen coordinates (not tablet coordinates). */ ++ wWTInfoRetVal = pWTInfoA(WTI_DEFSYSCTX, 0, &glogContext); ++ ok(wWTInfoRetVal == sizeof( LOGCONTEXTA ), "incorrect size\n" ); ++ ok(glogContext.lcOptions & CXO_SYSTEM, "Wrong options 0x%08x\n", glogContext.lcOptions); ++ ++ /*wsprintf(glogContext.lcName, "PrsTest Digitizing %x", hInst);*/ ++ ++ glogContext.lcOptions |= CXO_MESSAGES; /* We want WT_PACKET messages. */ ++ glogContext.lcPktData = PACKETDATA; ++ glogContext.lcPktMode = PACKETMODE; ++ glogContext.lcMoveMask = PACKETDATA; ++ glogContext.lcBtnUpMask = glogContext.lcBtnDnMask; ++ ++ wWTInfoRetVal = pWTInfoA( WTI_DEVICES, DVC_X, &TabletX ); ++ ok(wWTInfoRetVal == sizeof( AXIS ), "Wrong DVC_X size %d\n", wWTInfoRetVal); ++ ++ wWTInfoRetVal = pWTInfoA( WTI_DEVICES, DVC_Y, &TabletY ); ++ ok(wWTInfoRetVal == sizeof( AXIS ), "Wrong DVC_Y size %d\n", wWTInfoRetVal); ++ ++ wWTInfoRetVal = pWTInfoA( WTI_DEVICES, DVC_NPRESSURE, &value ); ++ ok(wWTInfoRetVal == sizeof( AXIS ), "Wrong DVC_NPRESSURE, size %d\n", wWTInfoRetVal); ++ ok(0, "DVC_NPRESSURE = %d, %d, %d\n", value.axMin, value.axMax, value.axUnits); ++ ++ glogContext.lcInOrgX = 0; ++ glogContext.lcInOrgY = 0; ++ glogContext.lcInExtX = TabletX.axMax; ++ glogContext.lcInExtY = TabletY.axMax; ++ ++ /* Guarantee the output coordinate space to be in screen coordinates. */ ++ glogContext.lcOutOrgX = GetSystemMetrics( SM_XVIRTUALSCREEN ); ++ glogContext.lcOutOrgY = GetSystemMetrics( SM_YVIRTUALSCREEN ); ++ glogContext.lcOutExtX = GetSystemMetrics( SM_CXVIRTUALSCREEN ); ++ ++ /* In Wintab, the tablet origin is lower left. Move origin to upper left ++ so that it coincides with screen origin. */ ++ glogContext.lcOutExtY = -GetSystemMetrics( SM_CYVIRTUALSCREEN ); ++ ++ hctx = pWTOpenA( hwnd, &glogContext, FALSE ); ++ ++ return hctx; ++} ++ ++static LRESULT CALLBACK wintabInteractiveWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ++{ ++ static POINT ptOld, ptNew; ++ static UINT prsOld, prsNew; ++ PACKET pkt; ++ static RECT rcClient; ++ PAINTSTRUCT psPaint; ++ HDC hdc; ++ ++ switch (msg) ++ { ++ case WM_CREATE: ++ hCtx = initial_tablet(hwnd); ++ break; ++ case WM_DESTROY: ++ if (hCtx) ++ pWTClose(hCtx); ++ PostQuitMessage(0); ++ break; ++ case WM_PAINT: ++ if ( (hdc = BeginPaint(hwnd, &psPaint)) ) ++ { ++ RECT clientRect; ++ char buffer[1024]; ++ ++ GetClientRect(hwnd, &clientRect); ++ if(!hCtx) ++ { ++ DrawTextA(hdc, "No Tablet", -1, &clientRect, 0); ++ } ++ else ++ { ++ POINT scrPoint = {ptNew.x, ptNew.y}; ++ ++ ScreenToClient(hwnd, &scrPoint); ++ ++ sprintf( buffer, "%d,%d, pressure %d", ptNew.x, ptNew.y, prsNew ); ++ DrawTextA(hdc, buffer, -1, &clientRect, 0); ++ ++ PatBlt(hdc, rcClient.left, scrPoint.y, rcClient.right, 1, DSTINVERT); ++ PatBlt(hdc, scrPoint.x, rcClient.top, 1, rcClient.bottom, DSTINVERT); ++ Ellipse(hdc, scrPoint.x - prsNew, scrPoint.y - prsNew, scrPoint.x + prsNew, scrPoint.y + prsNew); ++ EndPaint(hwnd, &psPaint); ++ } ++ } ++ break; ++ case WT_PACKET: ++ { ++ if (pWTPacket((HCTX)lParam, wParam, &pkt)) ++ { ++ ptOld = ptNew; ++ prsOld = prsNew; ++ ++ ptNew.x = pkt.pkX; ++ ptNew.y = pkt.pkY; ++ ++ prsNew = pkt.pkNormalPressure; ++ ++ if (ptNew.x != ptOld.x || ptNew.y != ptOld.y || prsNew != prsOld) ++ InvalidateRect(hwnd, NULL, TRUE); ++ } ++ break; ++ } ++ case WM_ACTIVATE: ++ if (LOWORD(wParam)) ++ { ++ InvalidateRect(hwnd, NULL, TRUE); ++ } ++ ++ /* if switching in the middle, disable the region */ ++ if (hCtx) ++ { ++ pWTEnable(hCtx, LOWORD(wParam)); ++ if (hCtx && LOWORD(wParam)) ++ { ++ pWTOverlap(hCtx, TRUE); ++ } ++ } ++ break; ++ } ++ return DefWindowProcA(hwnd, msg, wParam, lParam); ++} ++ ++static void test_interactive(void) ++{ ++ HWND defaultWindow = NULL; ++ MSG msg; ++ ++ wintab_create_window(&defaultWindow, wintabInteractiveWndProc); ++ ShowWindow(defaultWindow, SW_SHOW); ++ ++ while (GetMessageA(&msg, NULL, 0, 0)) ++ { ++ TranslateMessage(&msg); ++ DispatchMessageA(&msg); ++ } ++ ++ wintab_destroy_window(defaultWindow); ++} ++ + START_TEST(context) + { + HMODULE hWintab = load_functions(); +@@ -147,5 +315,8 @@ START_TEST(context) + + test_WTOpenContextValidation(); + ++ if(winetest_interactive) ++ test_interactive(); ++ + FreeLibrary(hWintab); + } +-- +2.20.1 +