Wintab: Update on debugging & demo patch.

Robert North 7ownq0k402 at sneakemail.com
Thu Jun 26 09:54:17 CDT 2003


Ok, Firstly, I'm including a patch that demonstrates fixes
to the crashing in Painter, and the recursion in Photoshop.

The patch assumes that you have already applied Aric's patch from April 
23rd.

I'd like feedback on wether the patch is OK, as it was generated
on from my local subversion repository, not CVS.
Please bear in mind that the code is designed as quick demonstration 
fixes, not for quality code. Having said that comments are welcome.

********

Secondly, I've done some more investigation into why Photoshop was not 
seeing tablet pressure.
It turns out that this is due to Photoshop requesting tablet events from
the desktop window.
In the x11drv/event.c file, X11 events are interrogated, and the X11
window converted to a win32 window. This is done using the X11 feature
of contexts: Application specific info mapping from an X11 window to
user defined value.
It appears that the X11 window has no X11 context, and therefore the
XInput event handler is passed a hWnd of NULL.
This causes the FindOpenContext not match any context.
(Hence the recursion)
Without a context, no event is posted (Hence the lack of pressure info)

Here's a typical debug trace showing the problem:

trace:event:EVENT_ProcessEvent called.
trace:event:EVENT_ProcessEvent Got extention event for hwnd/window 
(nil)/37, GetFocus()=0x40042
trace:event:X11DRV_ProcessTabletEvent Recieved tablet motion event ((nil))
trace:wintab32:X11DRV_ProcessTabletEvent Recieved tablet motion event 
((nil))
trace:wintab32:WTPacketsPeek (0xc00, 64, 0x43c828c4)
trace:wintab32:WTPacketsGet (0xc00, 64, 0x1098388)
trace:wintab32:TABLET_WindowProc Incomming Message 0x7ff0  (0x00000000, 
0x00000000)
trace:wintab32:AddPacketToContextQueue Trying Queue c00  (0 10020)
trace:wintab32:AddPacketToContextQueue Done ((nil))

********

Thirdly, I've found out why Painter wasn't scaling correctly.
There appear to be 2 issues.
	a. Tablet coordinates should be relative to the window
		the wintab context is attached to.
		Currently they are absoloute.
	b. The default system context as returned by WTInfo
		contains zero in the lcSysExtX,lcSysExtY fields
		These fields should contain the
		

I know how to fix the above problems, and will do so.
P.S. Aric, I can now see the race condtion problem you were talking
about in Painter.

Cheers
	-Rob.
-------------- next part --------------
Index: dlls/wintab32/context.c
===================================================================
--- dlls/wintab32/context.c (.../file:///usr/local/svnroot/wine/trunk)	(revision 73)
+++ dlls/wintab32/context.c	(revision 73)
@@ -3,6 +3,7 @@
  *
  * Copyright 2002 Patrik Stridvall
  * Copyright 2003 Codeweavers, Aric Stewart
+ * Copyright 2003 Robert North
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -168,11 +169,16 @@
     ptr = gOpenContexts;
     while (ptr)
     {
-        TRACE("Trying Context %lx  (%x %x)\n",(LONG)ptr->handle,(INT)hwnd,
+        TRACE("Trying Context %lx hwnd(%x %x)\n",(LONG)ptr->handle,(INT)hwnd,
                 (INT)ptr->hwndOwner);
 
-        if (ptr->hwndOwner == hwnd) 
+        if (ptr->hwndOwner == hwnd)
            return ptr;
+        /*     Rob 19-6-2003 Added recursion down pointer chein.
+            to avoid infinite loop.
+            Use TABLET_FindOpenContext as template.
+        */
+        ptr = ptr->next;
     }
     return NULL;
 }
@@ -251,7 +257,13 @@
 
 int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
 {
-    memcpy(target,src,size);
+/*
+    Rob 19-6-2003
+    Return size only, if target is NULL:
+    Was causing horrible crashes in MetaCreation's Painter 5.
+*/
+    if(target != NULL)
+        memcpy(target,src,size);
     return(size);
 }
 
@@ -318,39 +330,42 @@
 
 static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
 {
-    int rc = 0; 
+    if(lpPkt != NULL)
+    {
+        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);
+        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);
+        rc *= n;
+        memset(lpPkt,0,rc);
+    }
 }
 
 
@@ -856,7 +871,14 @@
  */
 int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
 {
-    int limit;
+    /*
+        Rob 19-6-2003
+        WTPacketsGet fails with lpPkts set to NULL.
+        TO DO: Handle null condition.
+        Null condition flushes queue (Of Max packets????)
+    */
+    int limit = 0;
+    int maxPktsToGet;
     LPOPENCONTEXT context;
     LPVOID ptr = lpPkts;
 
@@ -872,15 +894,20 @@
         return 0;
     }
 
-    for(limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
+    maxPktsToGet = min(cMaxPkts,context->PacketsQueued);
+    if(lpPkts != NULL)
+    {
+        for(limit = 0; limit < maxPktsToGet; limit++)
         ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
- 
-    if (limit < context->PacketsQueued)
+    }
+
+    if (maxPktsToGet < context->PacketsQueued)
     {
-        memcpy(context->PacketQueue, &context->PacketQueue[limit],
-            (context->QueueSize - (limit))*sizeof(WTPACKET));
+        /* TO DO: Wrong function mem areas overlap. should use memmove*/
+        memmove(context->PacketQueue, &context->PacketQueue[maxPktsToGet],
+            (context->QueueSize - (maxPktsToGet))*sizeof(WTPACKET));
     }
-    context->PacketsQueued -= limit;
+    context->PacketsQueued -= maxPktsToGet;
     LeaveCriticalSection(&csTablet);
 
     TRACE("Copied %i packets\n",limit);
@@ -911,7 +938,7 @@
 
         if ((rc+1) < context->QueueSize)
         {
-            memcpy(context->PacketQueue, &context->PacketQueue[rc+1],
+            memmove(context->PacketQueue, &context->PacketQueue[rc+1],
                 (context->QueueSize - (rc+1))*sizeof(WTPACKET));
         }
         context->PacketsQueued -= (rc+1);
@@ -1080,7 +1107,7 @@
 
     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;
@@ -1099,7 +1126,7 @@
     UINT num = 0;
 
     TRACE("(%p, %u, %u, %d, %p, %p)\n",
-	  hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
+      hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
 
     context = TABLET_FindOpenContext(hCtx);
 
@@ -1130,7 +1157,7 @@
 
     /* remove read packets */
     if ((end+1) < context->PacketsQueued)
-        memcpy( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
+        memmove( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
                 (context->PacketsQueued - ((end-bgn)+1)) * sizeof (WTPACKET));
 
     context->PacketsQueued -= ((end-bgn)+1);


More information about the wine-devel mailing list