[PATCH] sane.ds: Send events to applications through the DSM.

Vincent Povirk vincent at codeweavers.com
Mon Nov 13 16:33:37 CST 2017


Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
---
 dlls/sane.ds/ds_ctrl.c   | 19 ++++---------------
 dlls/sane.ds/sane_i.h    |  5 +++--
 dlls/sane.ds/sane_main.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 dlls/sane.ds/ui.c        |  6 ++----
 include/twain.h          | 24 ++++++++++++++++++++++++
 5 files changed, 80 insertions(+), 22 deletions(-)

diff --git a/dlls/sane.ds/ds_ctrl.c b/dlls/sane.ds/ds_ctrl.c
index 713f311c565..b7d283725c8 100644
--- a/dlls/sane.ds/ds_ctrl.c
+++ b/dlls/sane.ds/ds_ctrl.c
@@ -184,13 +184,7 @@ TW_UINT16 SANE_ProcessEvent (pTW_IDENTITY pOrigin,
     TRACE("DG_CONTROL/DAT_EVENT/MSG_PROCESSEVENT  msg 0x%x, wParam 0x%lx\n", pMsg->message, pMsg->wParam);
 
     activeDS.twCC = TWCC_SUCCESS;
-    if (pMsg->message == activeDS.windowMessage && activeDS.windowMessage)
-    {
-        twRC = TWRC_DSEVENT;
-        pEvent->TWMessage = pMsg->wParam;
-    }
-    else
-        pEvent->TWMessage = MSG_NULL;  /* no message to the application */
+    pEvent->TWMessage = MSG_NULL;  /* no message to the application */
 
     if (activeDS.currentState < 5 || activeDS.currentState > 7)
     {
@@ -232,8 +226,7 @@ TW_UINT16 SANE_PendingXfersEndXfer (pTW_IDENTITY pOrigin,
                 pPendingXfers->Count = 0;
                 activeDS.currentState = 5;
                 /* Notify the application that it can close the data source */
-                if (activeDS.windowMessage)
-                    PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_CLOSEDSREQ, 0);
+                SANE_Notify(MSG_CLOSEDSREQ);
             }
             else
                 activeDS.sane_started = TRUE;
@@ -403,8 +396,6 @@ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin,
     else
     {
         activeDS.hwndOwner = pUserInterface->hParent;
-        if (! activeDS.windowMessage)
-            activeDS.windowMessage = RegisterWindowMessageA("SANE.DS ACTIVITY MESSAGE");
         if (pUserInterface->ShowUI)
         {
             BOOL rc;
@@ -413,8 +404,7 @@ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin,
             pUserInterface->ModalUI = TRUE;
             if (!rc)
             {
-                if (activeDS.windowMessage)
-                    PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_CLOSEDSREQ, 0);
+                SANE_Notify(MSG_CLOSEDSREQ);
             }
 #ifdef SONAME_LIBSANE
             else
@@ -428,8 +418,7 @@ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin,
         {
             /* no UI will be displayed, so source is ready to transfer data */
             activeDS.currentState = 6; /* Transitions to state 6 directly */
-            if (activeDS.windowMessage)
-                PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_XFERREADY, 0);
+            SANE_Notify(MSG_XFERREADY);
         }
 
         twRC = TWRC_SUCCESS;
diff --git a/dlls/sane.ds/sane_i.h b/dlls/sane.ds/sane_i.h
index ae58159d596..941e8b9e1b9 100644
--- a/dlls/sane.ds/sane_i.h
+++ b/dlls/sane.ds/sane_i.h
@@ -62,10 +62,10 @@ extern HINSTANCE SANE_instance DECLSPEC_HIDDEN;
 struct tagActiveDS
 {
     struct tagActiveDS	*next;			/* next active DS */
-    TW_IDENTITY		identity;		/* identity */
+    TW_IDENTITY		identity;		/* identity of the DS */
     TW_UINT16		currentState;		/* current state */
-    UINT                windowMessage;          /* message to use to send status */
     TW_UINT16		twCC;			/* condition code */
+    TW_IDENTITY         appIdentity;            /* identity of the app */
     HWND		hwndOwner;		/* window handle of the app */
     HWND		progressWnd;		/* window handle of the scanning window */
 #ifdef SONAME_LIBSANE
@@ -89,6 +89,7 @@ struct tagActiveDS
 /* Helper functions */
 extern TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action) DECLSPEC_HIDDEN;
 extern TW_UINT16 SANE_SaneSetDefaults (void) DECLSPEC_HIDDEN;
+extern void SANE_Notify (TW_UINT16 message) DECLSPEC_HIDDEN;
 
 /* Implementation of operation triplets
  * From Application to Source (Control Information) */
diff --git a/dlls/sane.ds/sane_main.c b/dlls/sane.ds/sane_main.c
index 5c0f56f6c38..80a0baf9217 100644
--- a/dlls/sane.ds/sane_main.c
+++ b/dlls/sane.ds/sane_main.c
@@ -32,6 +32,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(twain);
 
 #ifdef SONAME_LIBSANE
 
+DSMENTRYPROC SANE_dsmentry;
+
 HINSTANCE SANE_instance;
 
 static void *libsane_handle;
@@ -109,6 +111,7 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 }
 
 static TW_UINT16 SANE_GetIdentity( pTW_IDENTITY, pTW_IDENTITY);
+static TW_UINT16 SANE_SetEntryPoint (pTW_IDENTITY pOrigin, TW_MEMREF pData);
 static TW_UINT16 SANE_OpenDS( pTW_IDENTITY, pTW_IDENTITY);
 
 #endif /* SONAME_LIBSANE */
@@ -181,6 +184,17 @@ static TW_UINT16 SANE_SourceControlHandler (
             }
             break;
 
+        case DAT_ENTRYPOINT:
+            if (MSG == MSG_SET)
+                twRC = SANE_SetEntryPoint (pOrigin, pData);
+            else
+            {
+                twRC = TWRC_FAILURE;
+                activeDS.twCC = TWCC_CAPBADOPERATION;
+                FIXME("unrecognized operation triplet\n");
+            }
+            break;
+
         case DAT_EVENT:
             if (MSG == MSG_PROCESSEVENT)
                 twRC = SANE_ProcessEvent (pOrigin, pData);
@@ -432,7 +446,7 @@ SANE_GetIdentity( pTW_IDENTITY pOrigin, pTW_IDENTITY self) {
 	return TWRC_FAILURE;
     self->ProtocolMajor = TWON_PROTOCOLMAJOR;
     self->ProtocolMinor = TWON_PROTOCOLMINOR;
-    self->SupportedGroups = DG_CONTROL | DG_IMAGE;
+    self->SupportedGroups = DG_CONTROL | DG_IMAGE | DF_DS2;
     copy_sane_short_name(sane_devlist[cursanedev]->name, self->ProductName, sizeof(self->ProductName) - 1);
     lstrcpynA (self->Manufacturer, sane_devlist[cursanedev]->vendor, sizeof(self->Manufacturer) - 1);
     lstrcpynA (self->ProductFamily, sane_devlist[cursanedev]->model, sizeof(self->ProductFamily) - 1);
@@ -447,10 +461,40 @@ SANE_GetIdentity( pTW_IDENTITY pOrigin, pTW_IDENTITY self) {
     return TWRC_SUCCESS;
 }
 
+void SANE_Notify (TW_UINT16 message)
+{
+    SANE_dsmentry (&activeDS.identity, &activeDS.appIdentity, DG_CONTROL, DAT_NULL, message, NULL);
+}
+
+/* DG_CONTROL/DAT_ENTRYPOINT/MSG_SET */
+TW_UINT16 SANE_SetEntryPoint (pTW_IDENTITY pOrigin, TW_MEMREF pData)
+{
+    TW_ENTRYPOINT *entry = (TW_ENTRYPOINT*)pData;
+
+    SANE_dsmentry = entry->DSM_Entry;
+
+    return TWRC_SUCCESS;
+}
+
 static TW_UINT16 SANE_OpenDS( pTW_IDENTITY pOrigin, pTW_IDENTITY self) {
     SANE_Status status;
     int i;
 
+    if (SANE_dsmentry == NULL)
+    {
+        static const WCHAR twain32W[] = {'t','w','a','i','n','_','3','2',0};
+        HMODULE moddsm = GetModuleHandleW(twain32W);
+
+        if (moddsm)
+            SANE_dsmentry = (void*)GetProcAddress(moddsm, "DSM_Entry");
+
+        if (!SANE_dsmentry)
+        {
+            ERR("can't find DSM entry point\n");
+            return TWRC_FAILURE;
+        }
+    }
+
     detect_sane_devices();
     if (!sane_devlist[0]) {
 	ERR("No scanners? We should not get to OpenDS?\n");
@@ -481,6 +525,8 @@ static TW_UINT16 SANE_OpenDS( pTW_IDENTITY pOrigin, pTW_IDENTITY self) {
         activeDS.twCC = SANE_SaneSetDefaults();
         if (activeDS.twCC == TWCC_SUCCESS) {
 	    activeDS.currentState = 4;
+            activeDS.identity.Id = self->Id;
+            activeDS.appIdentity = *pOrigin;
 	    return TWRC_SUCCESS;
         }
         else
diff --git a/dlls/sane.ds/ui.c b/dlls/sane.ds/ui.c
index 9a9bcb0347e..fe1988a88ad 100644
--- a/dlls/sane.ds/ui.c
+++ b/dlls/sane.ds/ui.c
@@ -1034,13 +1034,11 @@ static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
                         if (psn->lParam)
                         {
                             activeDS.currentState = 6;
-                            if (activeDS.windowMessage)
-                                PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_XFERREADY, 0);
+                            SANE_Notify(MSG_XFERREADY);
                         }
                         break;
                     case PSN_QUERYCANCEL:
-                        if (activeDS.windowMessage)
-                            PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_CLOSEDSREQ, 0);
+                        SANE_Notify(MSG_CLOSEDSREQ);
                         break;
                     case PSN_SETACTIVE:
                         InitializeDialog(hwndDlg);
diff --git a/include/twain.h b/include/twain.h
index bdbda4761e4..28eaddf0840 100644
--- a/include/twain.h
+++ b/include/twain.h
@@ -1843,6 +1843,30 @@ typedef TW_UINT16 (*DSENTRYPROC)(pTW_IDENTITY,
 }
 #endif  /* cplusplus */
 
+/* Definitions from TWAIN 2.x used by our builtin data sources */
+#define DAT_ENTRYPOINT 0x0403
+#define DF_DS2 0x40000000
+
+#ifdef  __cplusplus
+extern "C" {
+#endif  /* __cplusplus */
+typedef TW_HANDLE (PASCAL *DSM_MEMALLOCATE)(TW_UINT32 _size);
+typedef void (PASCAL *DSM_MEMFREE)(TW_HANDLE _handle);
+typedef TW_MEMREF (PASCAL *DSM_MEMLOCK)(TW_HANDLE _handle);
+typedef void (PASCAL *DSM_MEMUNLOCK)(TW_HANDLE _handle);
+#ifdef  __cplusplus
+}
+#endif  /* cplusplus */
+
+typedef struct {
+    TW_UINT32 Size;
+    DSMENTRYPROC DSM_Entry;
+    DSM_MEMALLOCATE DSM_MemAllocate;
+    DSM_MEMFREE DSM_MemFree;
+    DSM_MEMLOCK DSM_MemLock;
+    DSM_MEMUNLOCK DSM_MemUnlock;
+} TW_ENTRYPOINT;
+
 /* The Twain structures must be packed on 2 byte alignment */
 #include "poppack.h"
 
-- 
2.11.0




More information about the wine-devel mailing list