Signed-off-by: Elaine Lefler elaineclefler@gmail.com ---
v2: Splitting into smaller patches as per feedback. --- dlls/winemac.drv/Makefile.in | 3 +- dlls/winemac.drv/cocoa_wintab.h | 34 +++++++ dlls/winemac.drv/winemac.drv.spec | 6 ++ dlls/winemac.drv/wintab.c | 154 ++++++++++++++++++++++++++++++ 4 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 dlls/winemac.drv/cocoa_wintab.h create mode 100644 dlls/winemac.drv/wintab.c
diff --git a/dlls/winemac.drv/Makefile.in b/dlls/winemac.drv/Makefile.in index da2e5eaf4c4..47b7c68feb3 100644 --- a/dlls/winemac.drv/Makefile.in +++ b/dlls/winemac.drv/Makefile.in @@ -21,7 +21,8 @@ C_SRCS = \ surface.c \ systray.c \ vulkan.c \ - window.c + window.c \ + wintab.c
OBJC_SRCS = \ cocoa_app.m \ diff --git a/dlls/winemac.drv/cocoa_wintab.h b/dlls/winemac.drv/cocoa_wintab.h new file mode 100644 index 00000000000..0fa20f6752c --- /dev/null +++ b/dlls/winemac.drv/cocoa_wintab.h @@ -0,0 +1,34 @@ +/* + * MACDRV Cocoa wintab declarations + * + * Copyright 2022 Elaine Lefler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_MACDRV_COCOA_WINTAB_H +#define __WINE_MACDRV_COCOA_WINTAB_H + +#include "windef.h" +#include "wintab.h" + +/* Extents that shouldn't cause math problems */ +#define TABLET_WIDTH 0x40000000 +#define TABLET_HEIGHT 0x40000000 + +/* Shared device context */ +extern LOGCONTEXTW macdrv_tablet_ctx DECLSPEC_HIDDEN; + +#endif /* !defined(__WINE_MACDRV_COCOA_WINTAB_H) */ diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec index b060d1cc2a6..13f5522242c 100644 --- a/dlls/winemac.drv/winemac.drv.spec +++ b/dlls/winemac.drv/winemac.drv.spec @@ -18,3 +18,9 @@ @ stdcall ImeToAsciiEx(long long ptr ptr long long) @ stdcall ImeUnregisterWord(wstr long wstr) @ stdcall NotifyIME(long long long long) + +# WinTab32 +@ cdecl AttachEventQueueToTablet(long) macdrv_AttachEventQueueToTablet +@ cdecl GetCurrentPacket(ptr) macdrv_GetCurrentPacket +@ cdecl LoadTabletInfo(long) macdrv_LoadTabletInfo +@ cdecl WTInfoW(long long ptr) macdrv_WTInfoW diff --git a/dlls/winemac.drv/wintab.c b/dlls/winemac.drv/wintab.c new file mode 100644 index 00000000000..fffae85f735 --- /dev/null +++ b/dlls/winemac.drv/wintab.c @@ -0,0 +1,154 @@ +/* + * MACDRV Wintab implementations + * + * Copyright 2022 Elaine Lefler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include "macdrv.h" +#include "macdrv_cocoa.h" + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "wine/unicode.h" +#include "wine/debug.h" + +#include "cocoa_wintab.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wintab32); + +LOGCONTEXTW macdrv_tablet_ctx; +static LOGCONTEXTW macdrv_system_ctx; + +void* macdrv_tablet_window; +static HWND macdrv_tablet_hwnd; + +static size_t registered_hwnd_count = 0; +static size_t registered_hwnd_cap = 0; +static HWND* registered_hwnd = NULL; + +static const BYTE BUTTON_COUNT = 16; + +BOOL CDECL macdrv_LoadTabletInfo(HWND tablet_hwnd) +{ + static const WCHAR tablet_name[] = {'M','a','c','d','r','v',' ','T','a','b','l','e','t',' ','C','o','n','t','e','x','t',0}; + static const WCHAR sys_name[] = {'M','a','c','d','r','v',' ','S','y','s','t','e','m',' ','C','o','n','t','e','x','t',0}; + struct macdrv_win_data* tablet_win_data; + + macdrv_tablet_hwnd = tablet_hwnd; + TRACE("%p\n", macdrv_tablet_hwnd); + + tablet_win_data = get_win_data(macdrv_tablet_hwnd); + macdrv_tablet_window = tablet_win_data->cocoa_window; + release_win_data(tablet_win_data); + + /* TODO?: It is possible to query the Wacom driver for real values, but it + * doesn't report all of these fields anyway and adds a lot of complexity. + * The quick'n'dirty solution is to make a fake tablet with the greatest + * possible capabilities. */ + macdrv_tablet_ctx.lcOptions = CXO_SYSTEM; + macdrv_tablet_ctx.lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN + | CXL_SENSITIVITY | CXL_SYSOUT; + macdrv_tablet_ctx.lcStatus = CXS_ONTOP; + macdrv_tablet_ctx.lcMsgBase = WT_DEFBASE; + macdrv_tablet_ctx.lcDevice = 0; + macdrv_tablet_ctx.lcPktRate = 0; /* not supported */ + macdrv_tablet_ctx.lcPktData = PK_CONTEXT | PK_STATUS | PK_TIME | PK_CHANGED + | PK_SERIAL_NUMBER | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | PK_Z + | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION; + macdrv_tablet_ctx.lcPktMode = 0; /* all absolute */ + macdrv_tablet_ctx.lcMoveMask = PK_BUTTONS | PK_X | PK_Y | PK_Z + | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION; + macdrv_tablet_ctx.lcBtnDnMask = (1 << BUTTON_COUNT) - 1; + macdrv_tablet_ctx.lcBtnUpMask = (1 << BUTTON_COUNT) - 1; + + macdrv_tablet_ctx.lcInOrgX = 0; + macdrv_tablet_ctx.lcInOrgY = 0; + /* NSEvent reports floating point coordinates. The actual precision is not + * known, so we convert them to really big values. */ + macdrv_tablet_ctx.lcInExtX = TABLET_WIDTH; + macdrv_tablet_ctx.lcInExtY = TABLET_HEIGHT; + /* These values are correct for Intuos tablets. Wacom's Mac driver doesn't + * reveal them. */ + macdrv_tablet_ctx.lcInOrgZ = -1023; + macdrv_tablet_ctx.lcInExtZ = 2047; + + macdrv_tablet_ctx.lcOutOrgZ = macdrv_tablet_ctx.lcInOrgZ; + macdrv_tablet_ctx.lcOutExtZ = macdrv_tablet_ctx.lcInExtZ; + macdrv_tablet_ctx.lcSensX = 65536; + macdrv_tablet_ctx.lcSensY = 65536; + macdrv_tablet_ctx.lcSensZ = 65536; + + macdrv_tablet_ctx.lcSysMode = 0; /* absolute */ + macdrv_tablet_ctx.lcSysOrgX = GetSystemMetrics(SM_XVIRTUALSCREEN); + macdrv_tablet_ctx.lcSysOrgY = GetSystemMetrics(SM_YVIRTUALSCREEN); + macdrv_tablet_ctx.lcSysExtX = GetSystemMetrics(SM_CXVIRTUALSCREEN); + macdrv_tablet_ctx.lcSysExtY = GetSystemMetrics(SM_CYVIRTUALSCREEN); + macdrv_tablet_ctx.lcSysSensX = 65536; + macdrv_tablet_ctx.lcSysSensY = 65536; + + /* "device" and "system" context are identical, except that "system" + * translates tablet coords to screen coords */ + macdrv_system_ctx = macdrv_tablet_ctx; + strcpyW(macdrv_tablet_ctx.lcName, tablet_name); + strcpyW(macdrv_system_ctx.lcName, sys_name); + + macdrv_tablet_ctx.lcOutOrgX = macdrv_tablet_ctx.lcInOrgX; + macdrv_tablet_ctx.lcOutOrgY = macdrv_tablet_ctx.lcInOrgY; + macdrv_tablet_ctx.lcOutExtX = macdrv_tablet_ctx.lcInExtX; + macdrv_tablet_ctx.lcOutExtY = macdrv_tablet_ctx.lcInExtY; + + macdrv_system_ctx.lcOutOrgX = macdrv_system_ctx.lcSysOrgX; + macdrv_system_ctx.lcOutOrgY = macdrv_system_ctx.lcSysOrgY; + macdrv_system_ctx.lcOutExtX = macdrv_system_ctx.lcSysExtX; + macdrv_system_ctx.lcOutExtY = macdrv_system_ctx.lcSysExtY; + + return TRUE; +} + +UINT CDECL macdrv_WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput) +{ + TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput); + FIXME("Unhandled Category %i\n", wCategory); + return 0; +} + +int CDECL macdrv_AttachEventQueueToTablet(HWND hOwner) +{ + /* Tablet events come from a global monitor rather than relying on + * individual views. Maintain a list of HWNDs interested in these events so + * we can deliver to them later. */ + if (registered_hwnd_count >= registered_hwnd_cap) + { + registered_hwnd_cap = registered_hwnd_cap * 2 + 1; + registered_hwnd = realloc(registered_hwnd, registered_hwnd_cap * sizeof(*registered_hwnd)); + } + + registered_hwnd[registered_hwnd_count++] = hOwner; + + if (registered_hwnd_count > 1) + FIXME("Multiple contexts are not correctly supported. All events are delivered to all contexts.\n"); + + return 0; +} + +int CDECL macdrv_GetCurrentPacket(LPPACKET packet) +{ + return 0; +}