Enable Tablet support with both Tilt and Pressure.

This commit is contained in:
Aric Stewart 2004-01-09 00:03:00 +00:00 committed by Alexandre Julliard
parent 4e4460eaef
commit 2eebf3c78e
13 changed files with 2191 additions and 48 deletions

76
configure vendored
View File

@ -7410,9 +7410,11 @@ _ACEOF
for ac_header in X11/XKBlib.h \
X11/Xutil.h \
X11/extensions/shape.h \
X11/extensions/XInput.h \
X11/extensions/XShm.h \
X11/extensions/Xrandr.h \
X11/extensions/Xrender.h \
@ -14333,6 +14335,80 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
fi
echo "$as_me:$LINENO: checking for -lXi soname" >&5
echo $ECHO_N "checking for -lXi soname... $ECHO_C" >&6
if test "${ac_cv_lib_soname_Xi+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_get_soname_save_LIBS=$LIBS
LIBS="-lXi $X_LIBS -lXext -lX11 $X_EXTRA_LIBS $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char XOpenDevice ();
int
main ()
{
XOpenDevice ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_soname_Xi=`$ac_cv_path_LDD conftest$ac_exeext | grep libXi\\.so | sed 's/^.*\(libXi\.so[^ ]*\).*$/\1/'`
if test "x$ac_cv_lib_soname_Xi" = "x"
then
ac_cv_lib_soname_Xi="libXi.so"
fi
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_soname_Xi="libXi.so"
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_get_soname_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_soname_Xi" >&5
echo "${ECHO_T}$ac_cv_lib_soname_Xi" >&6
if test "x$ac_cv_lib_soname_Xi" != xNONE
then
cat >>confdefs.h <<_ACEOF
#define SONAME_LIBXI "$ac_cv_lib_soname_Xi"
_ACEOF
fi
echo "$as_me:$LINENO: checking for -lXrender soname" >&5
echo $ECHO_N "checking for -lXrender soname... $ECHO_C" >&6
if test "${ac_cv_lib_soname_Xrender+set}" = set; then

View File

@ -181,6 +181,7 @@ then
AC_CHECK_HEADERS([X11/XKBlib.h \
X11/Xutil.h \
X11/extensions/shape.h \
X11/extensions/XInput.h \
X11/extensions/XShm.h \
X11/extensions/Xrandr.h \
X11/extensions/Xrender.h \
@ -989,6 +990,7 @@ if test "$LIBEXT" = "so"
then
WINE_GET_SONAME(X11,XCreateWindow,[$X_LIBS $X_EXTRA_LIBS])
WINE_GET_SONAME(Xext,XextCreateExtension,[$X_LIBS -lX11 $X_EXTRA_LIBS])
WINE_GET_SONAME(Xi,XOpenDevice,[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
WINE_GET_SONAME(Xrender,XRenderQueryExtension,[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
WINE_GET_SONAME(freetype,FT_Init_FreeType,[$X_LIBS])
WINE_GET_SONAME(GL,glXQueryExtension,[$X_LIBS $X_EXTRA_LIBS])

View File

@ -3,14 +3,15 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = wintab32.dll
IMPORTS = kernel32
IMPORTS = user32 kernel32
ALTNAMES = wintab.dll
SPEC_SRCS16 = $(ALTNAMES:.dll=.spec)
C_SRCS = \
context.c \
manager.c
manager.c \
wintab32.c
C_SRCS16 = \
wintab16.c

View File

@ -2,6 +2,7 @@
* Tablet Context
*
* Copyright 2002 Patrik Stridvall
* Copyright 2003 CodeWeavers, Aric Stewart
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -19,29 +20,333 @@
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winbase.h"
#include "winuser.h"
#include "wintab.h"
#include "wintab_internal.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
/*
* Documentation found at
* http://www.csl.sony.co.jp/projects/ar/restricted/wintabl.html
*/
static BOOL gLoaded;
static LPOPENCONTEXT gOpenContexts;
static HCTX gTopContext = (HCTX)0xc00;
static char* DUMPBITS(int x, char* buf)
{
strcpy(buf,"{");
if (x&PK_CONTEXT) strcat(buf,"PK_CONTEXT ");
if (x&PK_STATUS) strcat(buf, "PK_STATUS ");
if (x&PK_TIME) strcat(buf, "PK_TIME ");
if (x&PK_CHANGED) strcat(buf, "PK_CHANGED ");
if (x&PK_SERIAL_NUMBER) strcat(buf, "PK_SERIAL_NUMBER ");
if (x&PK_CURSOR) strcat(buf, "PK_CURSOR ");
if (x&PK_BUTTONS) strcat(buf, "PK_BUTTONS ");
if (x&PK_X) strcat(buf, "PK_X ");
if (x&PK_Y) strcat(buf, "PK_Y ");
if (x&PK_Z) strcat(buf, "PK_Z ");
if (x&PK_NORMAL_PRESSURE) strcat(buf, "PK_NORMAL_PRESSURE ");
if (x&PK_TANGENT_PRESSURE) strcat(buf, "PK_TANGENT_PRESSURE ");
if (x&PK_ORIENTATION) strcat(buf, "PK_ORIENTATION ");
if (x&PK_ROTATION) strcat(buf, "PK_ROTATION ");
strcat(buf, "}");
return buf;
}
static inline void DUMPPACKET(WTPACKET packet)
{
TRACE("pkContext: 0x%x pkStatus: 0x%x pkTime : 0x%x pkChanged: 0x%x pkSerialNumber: 0x%x pkCursor : %i pkButtons: %x pkX: %li pkY: %li pkZ: %li pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n"
,(UINT)packet.pkContext,
(UINT)packet.pkStatus,
(UINT)packet.pkTime,
(UINT)packet.pkChanged,
packet.pkSerialNumber,
packet.pkCursor,
(UINT)packet.pkButtons,
packet.pkX,
packet.pkY,
packet.pkZ,
packet.pkNormalPressure,
packet.pkTangentPressure,
packet.pkOrientation.orAzimuth,
packet.pkOrientation.orAltitude, packet.pkOrientation.orTwist,
packet.pkRotation.roPitch,
packet.pkRotation.roRoll, packet.pkRotation.roYaw);
}
static inline void DUMPCONTEXT(LOGCONTEXTA lc)
{
CHAR mmsg[4000];
CHAR bits[100];
CHAR bits1[100];
CHAR bits2[100];
sprintf(mmsg,"%s, %x, %x, %x, %x, %x, %x, %x%s, %x%s, %x%s, %x, %x, %i, %i, %i, %li ,%li, %li, %li, %li, %li,%li, %li, %li, %li, %li, %li, %i, %i, %i, %i, %i %li %li\n",
debugstr_a(lc.lcName), lc.lcOptions, lc.lcStatus, lc.lcLocks, lc.lcMsgBase,
lc.lcDevice, lc.lcPktRate, (UINT)lc.lcPktData, DUMPBITS(lc.lcPktData,bits),
(UINT)lc.lcPktMode, DUMPBITS(lc.lcPktMode,bits1), (UINT)lc.lcMoveMask,
DUMPBITS(lc.lcMoveMask,bits2), (INT)lc.lcBtnDnMask, (INT)lc.lcBtnUpMask,
(INT)lc.lcInOrgX, (INT)lc.lcInOrgY, (INT)lc.lcInOrgZ, lc.lcInExtX, lc.lcInExtY,
lc.lcInExtZ, lc.lcOutOrgX, lc.lcOutOrgY, lc.lcOutOrgZ, lc.lcOutExtX,
lc.lcOutExtY, lc.lcOutExtZ, lc.lcSensX, lc.lcSensY, lc.lcSensZ, lc.lcSysMode,
lc.lcSysOrgX, lc.lcSysOrgY, lc.lcSysExtX, lc.lcSysExtY, lc.lcSysSensX,
lc.lcSysSensY);
TRACE("context: %s",mmsg);
}
/* Find an open context given the handle */
static LPOPENCONTEXT TABLET_FindOpenContext(HCTX hCtx)
{
LPOPENCONTEXT ptr = gOpenContexts;
while (ptr)
{
if (ptr->handle == hCtx) return ptr;
ptr = ptr->next;
}
return NULL;
}
static void LoadTablet()
{
TRACE("Initilizing the tablet to hwnd %p\n",hwndDefault);
gLoaded= TRUE;
pLoadTabletInfo(hwndDefault);
}
int TABLET_PostTabletMessage(LPOPENCONTEXT newcontext, UINT msg, WPARAM wParam,
LPARAM lParam, BOOL send_always)
{
if ((send_always) || (newcontext->context.lcOptions & CXO_MESSAGES))
{
TRACE("Posting message %x to %x\n",msg, (UINT)newcontext->hwndOwner);
return PostMessageA(newcontext->hwndOwner, msg, wParam, lParam);
}
return 0;
}
static inline DWORD ScaleForContext(DWORD In, DWORD InOrg, DWORD InExt, DWORD
OutOrg, DWORD OutExt)
{
if (((InExt > 0 )&&(OutExt > 0)) || ((InExt<0) && (OutExt < 0)))
return ((In - InOrg) * abs(OutExt) / abs(InExt)) + OutOrg;
else
return ((abs(InExt) - (In - InOrg))*abs(OutExt) / abs(InExt)) + OutOrg;
}
LPOPENCONTEXT FindOpenContext(HWND hwnd)
{
LPOPENCONTEXT ptr;
EnterCriticalSection(&csTablet);
ptr = gOpenContexts;
while (ptr)
{
TRACE("Trying Context %p (%p %p)\n",ptr->handle,hwnd,ptr->hwndOwner);
if (ptr->hwndOwner == hwnd) break;
}
LeaveCriticalSection(&csTablet);
return ptr;
}
LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
{
LPOPENCONTEXT ptr=NULL;
EnterCriticalSection(&csTablet);
ptr = gOpenContexts;
while (ptr)
{
TRACE("Trying Queue %p (%p %p)\n", ptr->handle, hwnd, ptr->hwndOwner);
if (ptr->hwndOwner == hwnd)
{
int tgt;
if (!ptr->enabled)
{
ptr = ptr->next;
continue;
}
tgt = ptr->PacketsQueued;
packet->pkContext = ptr->handle;
/* translate packet data to the context */
/* Scale as per documentation */
packet->pkY = ScaleForContext(packet->pkY, ptr->context.lcInOrgY,
ptr->context.lcInExtY, ptr->context.lcOutOrgY,
ptr->context.lcOutExtY);
packet->pkX = ScaleForContext(packet->pkX, ptr->context.lcInOrgX,
ptr->context.lcInExtX, ptr->context.lcOutOrgX,
ptr->context.lcOutExtX);
/* flip the Y axis */
if (ptr->context.lcOutExtY > 0)
packet->pkY = ptr->context.lcOutExtY - packet->pkY;
DUMPPACKET(*packet);
if (tgt + 1 == ptr->QueueSize)
{
TRACE("Queue Overflow %p\n",ptr->handle);
packet->pkStatus = TPS_QUEUE_ERR;
}
else
{
TRACE("Placed in queue %p index %i\n",ptr->handle,tgt);
memcpy(&ptr->PacketQueue[tgt], packet, sizeof
(WTPACKET));
ptr->PacketsQueued++;
if (ptr->ActiveCursor != packet->pkCursor)
{
ptr->ActiveCursor = packet->pkCursor;
if (ptr->context.lcOptions & CXO_CSRMESSAGES)
TABLET_PostTabletMessage(ptr, WT_CSRCHANGE,
(WPARAM)packet->pkSerialNumber, (LPARAM)ptr->handle,
FALSE);
}
}
break;
}
ptr = ptr->next;
}
LeaveCriticalSection(&csTablet);
TRACE("Done (%p)\n",ptr);
return ptr;
}
int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
{
memcpy(target,src,size);
return(size);
}
static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
LPWTPACKET *pkt)
{
int loop;
int index = -1;
for (loop = 0; loop < context->PacketsQueued; loop++)
if (context->PacketQueue[loop].pkSerialNumber == wSerial)
{
index = loop;
*pkt = &context->PacketQueue[loop];
break;
}
TRACE("%i .. %i\n",context->PacketsQueued,index);
return index;
}
static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
LPWTPACKET wtp)
{
LPBYTE ptr;
CHAR bits[100];
ptr = lpPkt;
TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData,bits));
if (context->context.lcPktData & PK_CONTEXT)
ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
if (context->context.lcPktData & PK_STATUS)
ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
if (context->context.lcPktData & PK_TIME)
ptr+=CopyTabletData(ptr,&wtp->pkTime,sizeof(LONG));
if (context->context.lcPktData & PK_CHANGED)
ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(WTPKT));
if (context->context.lcPktData & PK_SERIAL_NUMBER)
ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(UINT));
if (context->context.lcPktData & PK_CURSOR)
ptr+=CopyTabletData(ptr,&wtp->pkCursor,sizeof(UINT));
if (context->context.lcPktData & PK_BUTTONS)
ptr+=CopyTabletData(ptr,&wtp->pkButtons,sizeof(DWORD));
if (context->context.lcPktData & PK_X)
ptr+=CopyTabletData(ptr,&wtp->pkX,sizeof(DWORD));
if (context->context.lcPktData & PK_Y)
ptr+=CopyTabletData(ptr,&wtp->pkY,sizeof(DWORD));
if (context->context.lcPktData & PK_Z)
ptr+=CopyTabletData(ptr,&wtp->pkZ,sizeof(DWORD));
if (context->context.lcPktData & PK_NORMAL_PRESSURE)
ptr+=CopyTabletData(ptr,&wtp->pkNormalPressure,sizeof(UINT));
if (context->context.lcPktData & PK_TANGENT_PRESSURE)
ptr+=CopyTabletData(ptr,&wtp->pkTangentPressure,sizeof(UINT));
if (context->context.lcPktData & PK_ORIENTATION)
ptr+=CopyTabletData(ptr,&wtp->pkOrientation,sizeof(ORIENTATION));
if (context->context.lcPktData & PK_ROTATION)
ptr+=CopyTabletData(ptr,&wtp->pkRotation,sizeof(ROTATION));
/*TRACE("Copied %i bytes\n",(INT)ptr - (INT)lpPkt); */
return ptr;
}
static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
{
int rc = 0;
if (context->context.lcPktData & PK_CONTEXT)
rc +=sizeof(HCTX);
if (context->context.lcPktData & PK_STATUS)
rc +=sizeof(UINT);
if (context->context.lcPktData & PK_TIME)
rc += sizeof(LONG);
if (context->context.lcPktData & PK_CHANGED)
rc += sizeof(WTPKT);
if (context->context.lcPktData & PK_SERIAL_NUMBER)
rc += sizeof(UINT);
if (context->context.lcPktData & PK_CURSOR)
rc += sizeof(UINT);
if (context->context.lcPktData & PK_BUTTONS)
rc += sizeof(DWORD);
if (context->context.lcPktData & PK_X)
rc += sizeof(DWORD);
if (context->context.lcPktData & PK_Y)
rc += sizeof(DWORD);
if (context->context.lcPktData & PK_Z)
rc += sizeof(DWORD);
if (context->context.lcPktData & PK_NORMAL_PRESSURE)
rc += sizeof(UINT);
if (context->context.lcPktData & PK_TANGENT_PRESSURE)
rc += sizeof(UINT);
if (context->context.lcPktData & PK_ORIENTATION)
rc += sizeof(ORIENTATION);
if (context->context.lcPktData & PK_ROTATION)
rc += sizeof(ROTATION);
rc *= n;
memset(lpPkt,0,rc);
}
/***********************************************************************
* WTInfoA (WINTAB32.20)
*/
UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
{
FIXME("(%u, %u, %p): stub\n", wCategory, nIndex, lpOutput);
if (gLoaded == FALSE)
LoadTablet();
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
return pWTInfoA( wCategory, nIndex, lpOutput );
}
/***********************************************************************
@ -61,11 +366,38 @@ UINT WINAPI WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput)
*/
HCTX WINAPI WTOpenA(HWND hWnd, LPLOGCONTEXTA lpLogCtx, BOOL fEnable)
{
FIXME("(%p, %p, %u): stub\n", hWnd, lpLogCtx, fEnable);
LPOPENCONTEXT newcontext;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p, %p, %u)\n", hWnd, lpLogCtx, fEnable);
DUMPCONTEXT(*lpLogCtx);
return NULL;
newcontext = HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT));
memcpy(&(newcontext->context),lpLogCtx,sizeof(LOGCONTEXTA));
newcontext->hwndOwner = hWnd;
newcontext->enabled = fEnable;
newcontext->ActiveCursor = -1;
newcontext->QueueSize = 10;
newcontext->PacketsQueued = 0;
newcontext->PacketQueue=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET)*10);
EnterCriticalSection(&csTablet);
newcontext->handle = gTopContext++;
newcontext->next = gOpenContexts;
gOpenContexts = newcontext;
LeaveCriticalSection(&csTablet);
pAttachEventQueueToTablet(hWnd);
TABLET_PostTabletMessage(newcontext, WT_CTXOPEN, (WPARAM)newcontext->handle,
newcontext->context.lcStatus, TRUE);
newcontext->context.lcStatus = CXS_ONTOP;
TABLET_PostTabletMessage(newcontext, WT_CTXOVERLAP,
(WPARAM)newcontext->handle,
newcontext->context.lcStatus, TRUE);
return newcontext->handle;
}
/***********************************************************************
@ -85,9 +417,37 @@ HCTX WINAPI WTOpenW(HWND hWnd, LPLOGCONTEXTW lpLogCtx, BOOL fEnable)
*/
BOOL WINAPI WTClose(HCTX hCtx)
{
FIXME("(%p): stub\n", hCtx);
LPOPENCONTEXT context,ptr;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p)\n", hCtx);
EnterCriticalSection(&csTablet);
ptr = context = gOpenContexts;
while (context && (context->handle != hCtx))
{
ptr = context;
context = context->next;
}
if (!context)
{
LeaveCriticalSection(&csTablet);
return TRUE;
}
if (context == gOpenContexts)
gOpenContexts = context->next;
else
ptr->next = context->next;
LeaveCriticalSection(&csTablet);
TABLET_PostTabletMessage(context, WT_CTXCLOSE, (WPARAM)context->handle,
context->context.lcStatus,TRUE);
HeapFree(GetProcessHeap(),0,context->PacketQueue);
HeapFree(GetProcessHeap(),0,context);
return TRUE;
}
@ -97,11 +457,39 @@ BOOL WINAPI WTClose(HCTX hCtx)
*/
int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
{
FIXME("(%p, %d, %p): stub\n", hCtx, cMaxPkts, lpPkts);
int limit;
LPOPENCONTEXT context;
LPVOID ptr = lpPkts;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
return 0;
if (!hCtx || !lpPkts) return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
if (context->PacketsQueued == 0)
{
LeaveCriticalSection(&csTablet);
return 0;
}
for(limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
if (limit < context->PacketsQueued)
{
memcpy(context->PacketQueue, &context->PacketQueue[limit],
(context->QueueSize - (limit))*sizeof(WTPACKET));
}
context->PacketsQueued -= limit;
LeaveCriticalSection(&csTablet);
TRACE("Copied %i packets\n",limit);
return limit;
}
/***********************************************************************
@ -109,11 +497,36 @@ int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
*/
BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
{
FIXME("(%p, %d, %p): stub\n", hCtx, wSerial, lpPkt);
int rc = 0;
LPOPENCONTEXT context;
LPWTPACKET wtp;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
return FALSE;
if (!hCtx) return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
rc = TABLET_FindPacket(context ,wSerial, &wtp);
if (rc >= 0)
{
if (lpPkt)
TABLET_CopyPacketData(context ,lpPkt, wtp);
if ((rc+1) < context->QueueSize)
{
memcpy(context->PacketQueue, &context->PacketQueue[rc+1],
(context->QueueSize - (rc+1))*sizeof(WTPACKET));
}
context->PacketsQueued -= (rc+1);
}
LeaveCriticalSection(&csTablet);
TRACE("Returning %i\n",rc+1);
return rc+1;
}
/***********************************************************************
@ -121,11 +534,18 @@ BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
*/
BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable)
{
FIXME("(%p, %u): stub\n", hCtx, fEnable);
LPOPENCONTEXT context;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p, %u)\n", hCtx, fEnable);
return FALSE;
if (!hCtx) return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
context->enabled = fEnable;
LeaveCriticalSection(&csTablet);
return TRUE;
}
/***********************************************************************
@ -135,9 +555,7 @@ BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
{
FIXME("(%p, %u): stub\n", hCtx, fToTop);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
return TRUE;
}
/***********************************************************************
@ -157,11 +575,18 @@ BOOL WINAPI WTConfig(HCTX hCtx, HWND hWnd)
*/
BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
{
FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
LPOPENCONTEXT context;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p, %p)\n", hCtx, lpLogCtx);
return FALSE;
if (!hCtx) return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
memcpy(lpLogCtx,&context->context,sizeof(LOGCONTEXTA));
LeaveCriticalSection(&csTablet);
return TRUE;
}
/***********************************************************************
@ -253,11 +678,30 @@ HCTX WINAPI WTRestore(HWND hWnd, LPVOID lpSaveInfo, BOOL fEnable)
*/
int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
{
FIXME("(%p, %d, %p): stub\n", hCtx, cMaxPkts, lpPkts);
int limit;
LPOPENCONTEXT context;
LPVOID ptr = lpPkts;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
return 0;
if (!hCtx || !lpPkts) return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
if (context->PacketsQueued == 0)
{
LeaveCriticalSection(&csTablet);
return 0;
}
for (limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
LeaveCriticalSection(&csTablet);
TRACE("Copied %i packets\n",limit);
return limit;
}
/***********************************************************************
@ -266,12 +710,56 @@ int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
{
FIXME("(%p, %u, %u, %d, %p, %p): stub\n",
LPOPENCONTEXT context;
LPVOID ptr = lpPkts;
UINT bgn = 0;
UINT end = 0;
UINT num = 0;
TRACE("(%p, %u, %u, %d, %p, %p)\n",
hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
if (!hCtx) return 0;
return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
if (context->PacketsQueued == 0)
{
LeaveCriticalSection(&csTablet);
return 0;
}
while (bgn < context->PacketsQueued &&
context->PacketQueue[bgn].pkSerialNumber != wBegin)
bgn++;
end = bgn;
while (end < context->PacketsQueued &&
context->PacketQueue[end].pkSerialNumber != wEnd)
end++;
if (bgn == end == context->PacketsQueued)
{
LeaveCriticalSection(&csTablet);
return 0;
}
for (num = bgn; num <= end; num++)
ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[end]);
/* remove read packets */
if ((end+1) < context->PacketsQueued)
memcpy( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
(context->PacketsQueued - ((end-bgn)+1)) * sizeof (WTPACKET));
context->PacketsQueued -= ((end-bgn)+1);
*lpNPkts = ((end-bgn)+1);
LeaveCriticalSection(&csTablet);
TRACE("Copied %i packets\n",*lpNPkts);
return (end - bgn)+1;
}
/***********************************************************************
@ -280,12 +768,51 @@ int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
{
FIXME("(%p, %u, %u, %d, %p, %p): stub\n",
LPOPENCONTEXT context;
LPVOID ptr = lpPkts;
UINT bgn = 0;
UINT end = 0;
UINT num = 0;
TRACE("(%p, %u, %u, %d, %p, %p)\n",
hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
if (!hCtx) return 0;
return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
if (context->PacketsQueued == 0)
{
LeaveCriticalSection(&csTablet);
return 0;
}
while (bgn < context->PacketsQueued &&
context->PacketQueue[bgn].pkSerialNumber != wBegin)
bgn++;
end = bgn;
while (end < context->PacketsQueued &&
context->PacketQueue[end].pkSerialNumber != wEnd)
end++;
if (bgn == context->PacketsQueued || end == context->PacketsQueued)
{
TRACE("%i %i %i \n", bgn, end, context->PacketsQueued);
LeaveCriticalSection(&csTablet);
return 0;
}
for (num = bgn; num <= end; num++)
ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[end]);
*lpNPkts = ((end-bgn)+1);
LeaveCriticalSection(&csTablet);
TRACE("Copied %i packets\n",*lpNPkts);
return (end - bgn)+1;
}
/***********************************************************************
@ -293,9 +820,28 @@ int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
*/
BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
{
FIXME("(%p, %p, %p): stub\n", hCtx, lpOld, lpNew);
LPOPENCONTEXT context;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p, %p, %p)\n", hCtx, lpOld, lpNew);
if (!hCtx) return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
if (context->PacketsQueued)
{
*lpOld = context->PacketQueue[0].pkSerialNumber;
*lpNew = context->PacketQueue[context->PacketsQueued-1].pkSerialNumber;
}
else
{
TRACE("No packets\n");
LeaveCriticalSection(&csTablet);
return FALSE;
}
LeaveCriticalSection(&csTablet);
return TRUE;
}
@ -305,11 +851,15 @@ BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
*/
int WINAPI WTQueueSizeGet(HCTX hCtx)
{
FIXME("(%p): stub\n", hCtx);
LPOPENCONTEXT context;
TRACE("(%p)\n", hCtx);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
if (!hCtx) return 0;
return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
LeaveCriticalSection(&csTablet);
return context->QueueSize;
}
/***********************************************************************
@ -317,9 +867,21 @@ int WINAPI WTQueueSizeGet(HCTX hCtx)
*/
BOOL WINAPI WTQueueSizeSet(HCTX hCtx, int nPkts)
{
FIXME("(%p, %d): stub\n", hCtx, nPkts);
LPOPENCONTEXT context;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p, %d)\n", hCtx, nPkts);
return 0;
if (!hCtx) return 0;
EnterCriticalSection(&csTablet);
context = TABLET_FindOpenContext(hCtx);
context->PacketQueue = HeapReAlloc(GetProcessHeap(), 0,
context->PacketQueue, sizeof(WTPACKET)*nPkts);
context->QueueSize = nPkts;
LeaveCriticalSection(&csTablet);
return nPkts;
}

148
dlls/wintab32/wintab32.c Normal file
View File

@ -0,0 +1,148 @@
/*
* WinTab32 library
*
* Copyright 2003 CodeWeavers, Aric Stewart
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "wintab.h"
#include "wintab_internal.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
HWND hwndDefault = NULL;
static const WCHAR
WC_TABLETCLASSNAME[] = {'W','i','n','e','T','a','b','l','e','t','C','l','a','s','s',0};
CRITICAL_SECTION csTablet;
int (*pLoadTabletInfo)(HWND hwnddefault) = NULL;
int (*pGetCurrentPacket)(LPWTPACKET packet) = NULL;
int (*pAttachEventQueueToTablet)(HWND hOwner) = NULL;
UINT (*pWTInfoA)(UINT wCategory, UINT nIndex, LPVOID lpOutput) = NULL;
static LRESULT WINAPI TABLET_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
static VOID TABLET_Register()
{
WNDCLASSW wndClass;
ZeroMemory(&wndClass, sizeof(WNDCLASSW));
wndClass.style = CS_GLOBALCLASS;
wndClass.lpfnWndProc = TABLET_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hCursor = (HCURSOR)NULL;
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
wndClass.lpszClassName = WC_TABLETCLASSNAME;
RegisterClassW(&wndClass);
}
static VOID TABLET_Unregister()
{
UnregisterClassW(WC_TABLETCLASSNAME, (HINSTANCE)NULL);
}
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
{
static const WCHAR name[] = {'T','a','b','l','e','t',0};
HMODULE hx11drv;
TRACE("%p, %lx, %p\n",hInstDLL,fdwReason,lpReserved);
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
TRACE("Initialization\n");
InitializeCriticalSection(&csTablet);
hx11drv = GetModuleHandleA("x11drv.dll");
if (hx11drv)
{
pLoadTabletInfo = (void *)GetProcAddress(hx11drv, "LoadTabletInfo");
pAttachEventQueueToTablet = (void *)GetProcAddress(hx11drv, "AttachEventQueueToTablet");
pGetCurrentPacket = (void *)GetProcAddress(hx11drv, "GetCurrentPacket");
pWTInfoA = (void *)GetProcAddress(hx11drv, "WTInfoA");
TABLET_Register();
hwndDefault = CreateWindowW(WC_TABLETCLASSNAME, name,
WS_POPUPWINDOW,0,0,0,0,0,0,hInstDLL,0);
}
else
return FALSE;
break;
case DLL_PROCESS_DETACH:
TRACE("Detaching\n");
if (hwndDefault)
{
DestroyWindow(hwndDefault);
hwndDefault = 0;
}
TABLET_Unregister();
DeleteCriticalSection(&csTablet);
break;
}
return TRUE;
}
/*
* The window proc for the default TABLET window
*/
static LRESULT WINAPI TABLET_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
TRACE("Incomming Message 0x%x (0x%08x, 0x%08x)\n", uMsg, (UINT)wParam,
(UINT)lParam);
switch(uMsg)
{
case WM_NCCREATE:
return TRUE;
case WT_PACKET:
{
WTPACKET packet;
LPOPENCONTEXT handler;
pGetCurrentPacket(&packet);
handler = AddPacketToContextQueue(&packet,(HWND)lParam);
if (handler)
TABLET_PostTabletMessage(handler, WT_PACKET,
(WPARAM)packet.pkSerialNumber,
(LPARAM)handler->handle, FALSE);
break;
}
case WT_PROXIMITY:
{
LPOPENCONTEXT handler;
LPARAM prox;
handler = FindOpenContext((HWND)lParam);
if (handler)
{
prox = MAKELPARAM( wParam, 1 );
TABLET_PostTabletMessage(handler, WT_PROXIMITY,
(WPARAM)handler->handle, (LPARAM)prox,
TRUE);
}
break;
}
}
return 0;
}

View File

@ -0,0 +1,163 @@
/*
* Tablet header
*
* Copyright 2003 CodeWeavers (Aric Stewart)
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __WINE_WINTAB_INTERNAL_H
#define __WINE_WINTAB_INTERNAL_H
typedef struct tagWTI_INTERFACE_INFO {
CHAR WINTABID[1024];
/* a copy of the null-terminated tablet hardware identification string
* in the user buffer. This string should include make, model, and
* revision information in user-readable format.
*/
WORD SPECVERSION;
/* the specification version number. The high-order byte contains the
* major version number; the low-order byte contains the minor version
* number.
*/
WORD IMPLVERSION;
/* the implementation version number. The high-order byte contains the
* major version number; the low-order byte contains the minor version
* number.
*/
UINT NDEVICES;
/* the number of devices supported. */
UINT NCURSORS;
/* the total number of cursor types supported. */
UINT NCONTEXTS;
/* the number of contexts supported. */
UINT CTXOPTIONS;
/* flags indicating which context options are supported */
UINT CTXSAVESIZE;
/* the size of the save information returned from WTSave.*/
UINT NEXTENSIONS;
/* the number of extension data items supported.*/
UINT NMANAGERS;
/* the number of manager handles supported.*/
}WTI_INTERFACE_INFO, *LPWTI_INTERFACE_INFO;
typedef struct tagWTI_STATUS_INFO{
UINT CONTEXTS;
/* the number of contexts currently open.*/
UINT SYSCTXS;
/* the number of system contexts currently open.*/
UINT PKTRATE;
/* the maximum packet report rate currently being received by any
* context, in Hertz.
*/
WTPKT PKTDATA;
/* a mask indicating which packet data items are requested by at
* least one context.
*/
UINT MANAGERS;
/* the number of manager handles currently open.*/
BOOL SYSTEM;
/* a non-zero value if system pointing is available to the whole
* screen; zero otherwise.
*/
DWORD BUTTONUSE;
/* a button mask indicating the logical buttons whose events are
* requested by at least one context.
*/
DWORD SYSBTNUSE;
/* a button mask indicating which logical buttons are assigned a system
* button function by the current cursor's system button map.
*/
} WTI_STATUS_INFO, *LPWTI_STATUS_INFO;
typedef struct tagWTI_EXTENSIONS_INFO
{
CHAR NAME[256];
/* a unique, null-terminated string describing the extension.*/
UINT TAG;
/* a unique identifier for the extension. */
WTPKT MASK;
/* a mask that can be bitwise OR'ed with WTPKT-type variables to select
* the extension.
*/
UINT SIZE[2];
/* an array of two UINTs specifying the extension's size within a packet
* (in bytes). The first is for absolute mode; the second is for
* relative mode.
*/
AXIS *AXES;
/* an array of axis descriptions, as needed for the extension. */
BYTE *DEFAULT;
/* the current global default data, as needed for the extension. This
* data is modified via the WTMgrExt function.
*/
BYTE *DEFCONTEXT;
BYTE *DEFSYSCTX;
/* the current default context-specific data, as needed for the
* extension. The indices identify the digitizing- and system-context
* defaults, respectively.
*/
BYTE *CURSORS;
/* Is the first of one or more consecutive indices, one per cursor type.
* Each returns the current default cursor-specific data, as need for
* the extension. This data is modified via the WTMgrCsrExt function.
*/
} WTI_EXTENSIONS_INFO, *LPWTI_EXTENSIONS_INFO;
typedef struct tagWTPACKET {
HCTX pkContext;
UINT pkStatus;
LONG pkTime;
WTPKT pkChanged;
UINT pkSerialNumber;
UINT pkCursor;
DWORD pkButtons;
DWORD pkX;
DWORD pkY;
DWORD pkZ;
UINT pkNormalPressure;
UINT pkTangentPressure;
ORIENTATION pkOrientation;
ROTATION pkRotation; /* 1.1 */
} WTPACKET, *LPWTPACKET;
typedef struct tagOPENCONTEXT
{
HCTX handle;
LOGCONTEXTA context;
HWND hwndOwner;
BOOL enabled;
INT ActiveCursor;
INT QueueSize;
INT PacketsQueued;
LPWTPACKET PacketQueue;
struct tagOPENCONTEXT *next;
} OPENCONTEXT, *LPOPENCONTEXT;
int TABLET_PostTabletMessage(LPOPENCONTEXT newcontext, UINT msg, WPARAM wParam,
LPARAM lParam, BOOL send_always);
LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd);
LPOPENCONTEXT FindOpenContext(HWND hwnd);
/* X11drv functions */
extern int (*pLoadTabletInfo)(HWND hwnddefault);
extern int (*pGetCurrentPacket)(LPWTPACKET packet);
extern int (*pAttachEventQueueToTablet)(HWND hOwner);
extern UINT (*pWTInfoA)(UINT wCategory, UINT nIndex, LPVOID lpOutput);
extern HWND hwndDefault;
extern CRITICAL_SECTION csTablet;
#endif /* __WINE_WINTAB_INTERNAL_H */

View File

@ -34,6 +34,7 @@ C_SRCS = \
text.c \
window.c \
winpos.c \
wintab.c \
x11ddraw.c \
x11drv_main.c \
xdnd.c \

View File

@ -274,9 +274,18 @@ static void EVENT_ProcessEvent( XEvent *event )
if (!hWnd && event->type != PropertyNotify && event->type != MappingNotify)
WARN( "Got event %s for unknown Window %08lx\n",
event_names[event->type], event->xany.window );
else if (event->type <= MappingNotify)
TRACE("Got event %s for hwnd/window %p/%lx, GetFocus()=%p\n",
event_names[event->type], hWnd, event->xany.window, GetFocus() );
else
TRACE("Got event %s for hwnd %p\n",
event_names[event->type], hWnd );
TRACE("Got extension event for hwnd/window %p/%lx, GetFocus()=%p\n",
hWnd, event->xany.window, GetFocus() );
if (X11DRV_ProcessTabletEvent(hWnd, event))
{
TRACE("Return: filtered by tablet\n");
return;
}
switch(event->type)
{

1161
dlls/x11drv/wintab.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -475,6 +475,8 @@ extern INPUT_TYPE X11DRV_EVENT_SetInputMethod(INPUT_TYPE type);
void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base) ;
#endif
extern int X11DRV_ProcessTabletEvent(HWND hwnd, XEvent *event);
/* x11drv private window data */
struct x11drv_win_data
{

View File

@ -111,6 +111,12 @@
@ cdecl ShowWindow(long long) X11DRV_ShowWindow
@ cdecl SysCommandSizeMove(long long) X11DRV_SysCommandSizeMove
# WinTab32
@ cdecl AttachEventQueueToTablet(long) X11DRV_AttachEventQueueToTablet
@ cdecl GetCurrentPacket(ptr) X11DRV_GetCurrentPacket
@ cdecl LoadTabletInfo(long) X11DRV_LoadTabletInfo
@ cdecl WTInfoA(long long ptr) X11DRV_WTInfoA
# X11 locks
@ cdecl -norelay wine_tsx11_lock()
@ cdecl -norelay wine_tsx11_unlock()

View File

@ -1194,6 +1194,11 @@
header file. */
#undef HAVE_X11_EXTENSIONS_XF86VMODE_H
/*
Define to 1 if you have the <X11/extensions/XInput.h>
header file. */
#undef HAVE_X11_EXTENSIONS_XINPUT_H
/*
Define to 1 if you have the <X11/extensions/Xrandr.h>
header file. */
@ -1378,6 +1383,11 @@
*/
#undef SONAME_LIBXEXT
/*
Define to the soname of the libXi library.
*/
#undef SONAME_LIBXI
/*
Define to the soname of the libXrender library.
*/

View File

@ -328,7 +328,9 @@ typedef struct tagAXIS {
#define CSR_MINPKTDATA 17 /* 1.1 */
#define CSR_MINBUTTONS 18 /* 1.1 */
#define CSR_CAPABILITIES 19 /* 1.1 */
#define CSR_MAX 19
/* from http://www.wacomeng.com/devsupport/ibmpc/wacomwindevfaq.html */
#define CSR_TYPE 20
#define CSR_MAX 20
#endif