[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