winex11.drv/wintab32[1/5]: store categories field-by-field (resend)

Mikolaj Zalewski mikolajz at google.com
Wed Sep 12 12:13:16 CDT 2007


As I wrote this will alllow to simplify the logic on the winex11.drv
side. Winex11.drv will only have to dump one field - it's wintab32.dll
that will care about the rest. To do that it will need winex11.drv to
inform it about how many indexes in a category there are and which
fields are string.
-------------- next part --------------
From f5fa571ee5e1a6b6cf3ffc56447d21e1dbbe3fd5 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Miko=C5=82aj_Zalewski?= <mikolaj at zalewski.pl>
Date: Wed, 5 Sep 2007 15:57:40 -0700
Subject: [PATCH] winex11.drv/wintab32: store categories field-by-field

---
 dlls/winex11.drv/winex11.drv.spec |    2 +-
 dlls/winex11.drv/wintab.c         |   77 +++++++++++++++++++++++++------------
 dlls/wintab32/context.c           |   68 +++++++++++++++++++++++----------
 dlls/wintab32/wintab32.c          |    2 +-
 dlls/wintab32/wintab_internal.h   |    2 +-
 5 files changed, 103 insertions(+), 48 deletions(-)

diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 6a6c173..b4fcb9b 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -119,7 +119,7 @@
 @ cdecl AttachEventQueueToTablet(long) X11DRV_AttachEventQueueToTablet
 @ cdecl GetCurrentPacket(ptr) X11DRV_GetCurrentPacket
 @ cdecl LoadTabletInfo(long) X11DRV_LoadTabletInfo
-@ cdecl WTInfoA(long long ptr) X11DRV_WTInfoA
+@ cdecl WTInfoA(long long ptr ptr) X11DRV_WTInfoA
 
 # X11 locks
 @ cdecl -norelay wine_tsx11_lock()
diff --git a/dlls/winex11.drv/wintab.c b/dlls/winex11.drv/wintab.c
index 8846342..8a9ac4a 100644
--- a/dlls/winex11.drv/wintab.c
+++ b/dlls/winex11.drv/wintab.c
@@ -753,8 +753,7 @@ int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
     return 1;
 }
 
-
-static inline int CopyTabletData(LPVOID target, LPVOID src, INT size)
+static inline int CopyTabletData(LPVOID target, LPCVOID src, INT size)
 {
     /*
      * It is valid to call CopyTabletData with NULL.
@@ -765,19 +764,37 @@ static inline int CopyTabletData(LPVOID target, LPVOID src, INT size)
     return(size);
 }
 
+static inline int CopyTabletString(LPVOID target, LPCSTR src, INT cchChars, DWORD *cchOnlyCountString)
+{
+    if (cchChars == -1)
+        cchChars = strlen(src)+1;
+    if (cchOnlyCountString != NULL)
+    {
+        *cchOnlyCountString = cchChars;
+        return 0;
+    }
+    return CopyTabletData(target, src, cchChars * sizeof(CHAR));
+}
+
 /***********************************************************************
  *		X11DRV_WTInfoA (X11DRV.@)
+ *
+ * NOTES
+ * If cchOnlyCountString is not NULL and the data is a string then no
+ * data is stored in the output buffer but only the string length is
+ * returned in *cchOnlyCountString (and is >= 1 as contains at least a NUL
+ * character). It have no effect on non-string data.
+ *
+ * Apart from the cchOnlyCountString parameter this function differs from the
+ * WTInfo[AW] as for nIndex == 0 it returns the number of items in the
+ * category. It's wintab32.dll that concatenates the data
+ *
+ * It is valid to call WTInfoA with lpOutput == NULL, as per standard.
+ * lpOutput == NULL signifies the user only wishes to find the size of
+ * the data.
  */
-UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
+UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput, DWORD *cchOnlyCountString)
 {
-    /*
-     * It is valid to call WTInfoA with lpOutput == NULL, as per standard.
-     * lpOutput == NULL signifies the user only wishes
-     * to find the size of the data.
-     * NOTE:
-     * From now on use CopyTabletData to fill lpOutput. memcpy will break
-     * the code.
-     */
     int rc = 0;
     LPWTI_CURSORS_INFO  tgtcursor;
     TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
@@ -797,9 +814,12 @@ UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
             switch (nIndex)
             {
                 WORD version;
+                case 0:
+                    *(DWORD *)lpOutput = IFC_MAX;
+                    rc = sizeof(DWORD);
+                    break;
                 case IFC_WINTABID:
-                    strcpy(lpOutput,"Wine Wintab 1.1");
-                    rc = 16;
+                    rc = CopyTabletString(lpOutput, "Wine Wintab 1.1", -1, cchOnlyCountString);
                     break;
                 case IFC_SPECVERSION:
                     version = (0x01) | (0x01 << 8);
@@ -820,12 +840,11 @@ UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
             switch (nIndex)
             {
                 case 0:
-                    rc = CopyTabletData(lpOutput, &gSysContext,
-                            sizeof(LOGCONTEXTA));
+                    *(DWORD *)lpOutput = CTX_MAX;
+                    rc = sizeof(DWORD);
                     break;
                 case CTX_NAME:
-                    rc = CopyTabletData(lpOutput, &gSysContext.lcName,
-                         strlen(gSysContext.lcName)+1);
+                    rc = CopyTabletString(lpOutput, gSysContext.lcName, -1, cchOnlyCountString);
                     break;
                 case CTX_OPTIONS:
                     rc = CopyTabletData(lpOutput, &gSysContext.lcOptions,
@@ -851,6 +870,10 @@ UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
                     rc = CopyTabletData(lpOutput, &gSysContext.lcPktRate,
                                         sizeof(UINT));
                     break;
+                case CTX_PKTDATA:
+                    rc = CopyTabletData(lpOutput, &gSysContext.lcPktData,
+                                        sizeof(WTPKT));
+                    break;
                 case CTX_PKTMODE:
                     rc = CopyTabletData(lpOutput, &gSysContext.lcPktMode,
                                         sizeof(WTPKT));
@@ -973,9 +996,12 @@ UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
             tgtcursor = &gSysCursor[wCategory - WTI_CURSORS];
             switch (nIndex)
             {
+                case 0:
+                    *(DWORD *)lpOutput = CSR_MAX;
+                    rc = sizeof(DWORD);
+                    break;
                 case CSR_NAME:
-                    rc = CopyTabletData(lpOutput, &tgtcursor->NAME,
-                                        strlen(tgtcursor->NAME)+1);
+                    rc = CopyTabletString(lpOutput, tgtcursor->NAME, -1, cchOnlyCountString);
                     break;
                 case CSR_ACTIVE:
                     rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE,
@@ -995,8 +1021,7 @@ UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
                     break;
                 case CSR_BTNNAMES:
                     FIXME("Button Names not returned correctly\n");
-                    rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES,
-                                        strlen(tgtcursor->BTNNAMES)+1);
+                    rc = CopyTabletString(lpOutput, tgtcursor->BTNNAMES, -1, cchOnlyCountString);
                     break;
                 case CSR_BUTTONMAP:
                     rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP,
@@ -1065,9 +1090,12 @@ UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
         case WTI_DEVICES:
             switch (nIndex)
             {
+                case 0:
+                    *(DWORD *)lpOutput = DVC_MAX;
+                    rc = sizeof(DWORD);
+                    break;
                 case DVC_NAME:
-                    rc = CopyTabletData(lpOutput,gSysDevice.NAME,
-                                        strlen(gSysDevice.NAME)+1);
+                    rc = CopyTabletString(lpOutput,gSysDevice.NAME, -1, cchOnlyCountString);
                     break;
                 case DVC_HARDWARE:
                     rc = CopyTabletData(lpOutput,&gSysDevice.HARDWARE,
@@ -1150,8 +1178,7 @@ UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
                     */
                     break;
                 case DVC_PNPID:
-                    rc = CopyTabletData(lpOutput,gSysDevice.PNPID,
-                                        strlen(gSysDevice.PNPID)+1);
+                    rc = CopyTabletString(lpOutput,gSysDevice.PNPID, -1, cchOnlyCountString);
                     break;
                 default:
                     FIXME("WTI_DEVICES unhandled index %i\n",nIndex);
diff --git a/dlls/wintab32/context.c b/dlls/wintab32/context.c
index 5b538ad..1410849 100644
--- a/dlls/wintab32/context.c
+++ b/dlls/wintab32/context.c
@@ -345,19 +345,15 @@ static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
     memset(lpPkt,0,rc);
 }
 
-
-/***********************************************************************
- *		WTInfoA (WINTAB32.20)
- */
-UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
+/* Is this a category for which a LOGCONTEXT should be returned? */
+static BOOL is_logcontext_category(UINT wCategory)
 {
-    UINT result;
-    if (gLoaded == FALSE)
-         LoadTablet();
+    return wCategory == WTI_DEFSYSCTX || wCategory == WTI_DEFCONTEXT || wCategory == WTI_DDCTXS;
+}
 
-    /*
-     *  Handle system extents here, as we can use user32.dll code to set them.
-     */
+static UINT get_wtinfo_field(UINT wCategory, UINT nIndex, LPVOID lpOutput)
+{
+    /*  Handle system extents here, as we can use user32.dll code to set them */
     if(wCategory == WTI_DEFSYSCTX)
     {
         switch(nIndex)
@@ -374,18 +370,50 @@ UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
         }
     }
 
-    result =  pWTInfoA( wCategory, nIndex, lpOutput );
+    return pWTInfoA(wCategory, nIndex, lpOutput, NULL);
+}
 
-    /*
-     *  Handle system extents here, as we can use user32.dll code to set them.
-     */
-    if(wCategory == WTI_DEFSYSCTX && nIndex == 0)
+/***********************************************************************
+ *		WTInfoA (WINTAB32.20)
+ */
+UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
+{
+    if (gLoaded == FALSE)
+         LoadTablet();
+
+    if (wCategory == 0) /* TODO */
+        return get_wtinfo_field(0, 0, NULL);
+
+    if (nIndex == 0)
     {
-        LPLOGCONTEXTA lpCtx = (LPLOGCONTEXTA)lpOutput;
-        lpCtx->lcSysExtX = GetSystemMetrics(SM_CXSCREEN);
-        lpCtx->lcSysExtY = GetSystemMetrics(SM_CYSCREEN);
+        DWORD numIndex;
+        int size = 0;
+        int i;
+
+        if (get_wtinfo_field(wCategory, 0, &numIndex) != sizeof(DWORD))
+            return 0;  /* an unknown category */
+
+        if (!is_logcontext_category(wCategory))
+            FIXME("Dumping whole category %d not well tested\n", wCategory);
+
+        for (i = 1; i <= numIndex; i++)
+        {
+            char *buf = lpOutput ? (char *)lpOutput + size : 0;
+            int field_size = get_wtinfo_field(wCategory, i, buf);
+
+            /* it seems that only the LOGCONTEXT categories the string is
+             * padded so that the result fits in the C structure
+             */
+            if (is_logcontext_category(wCategory) && i == CTX_NAME)
+                size += LCNAMELEN;
+            else
+                size += field_size;
+        }
+
+        return size;
     }
-    return result;
+    else
+        return get_wtinfo_field(wCategory, nIndex, lpOutput);
 }
 
 /***********************************************************************
diff --git a/dlls/wintab32/wintab32.c b/dlls/wintab32/wintab32.c
index c34a681..ba9db9c 100644
--- a/dlls/wintab32/wintab32.c
+++ b/dlls/wintab32/wintab32.c
@@ -39,7 +39,7 @@ 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;
+UINT (*pWTInfoA)(UINT wCategory, UINT nIndex, LPVOID lpOutput, DWORD *cchOnlyCountString) = NULL;
 
 static LRESULT WINAPI TABLET_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                                           LPARAM lParam);
diff --git a/dlls/wintab32/wintab_internal.h b/dlls/wintab32/wintab_internal.h
index 711a48f..b1c6297 100644
--- a/dlls/wintab32/wintab_internal.h
+++ b/dlls/wintab32/wintab_internal.h
@@ -155,7 +155,7 @@ LPOPENCONTEXT FindOpenContext(HWND hwnd);
 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 UINT (*pWTInfoA)(UINT wCategory, UINT nIndex, LPVOID lpOutput, DWORD *cchOnlyCountString);
 
 extern HWND hwndDefault;
 extern CRITICAL_SECTION csTablet;
-- 
1.4.4.2


More information about the wine-patches mailing list