From 870c4f3e99e373063978ba833fa201e78d7bd73e Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Tue, 14 Nov 2017 15:14:11 -0600 Subject: [PATCH] sane.ds: Send events to applications through the DSM. Signed-off-by: Vincent Povirk Signed-off-by: Alexandre Julliard --- dlls/sane.ds/ds_ctrl.c | 19 ++++--------------- dlls/sane.ds/sane_i.h | 5 +++-- dlls/sane.ds/sane_main.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++- dlls/sane.ds/ui.c | 6 ++---- include/twain.h | 24 ++++++++++++++++++++++++ 5 files changed, 81 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..7af0a2321ac 100644 --- a/dlls/sane.ds/sane_main.c +++ b/dlls/sane.ds/sane_main.c @@ -30,6 +30,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(twain); +DSMENTRYPROC SANE_dsmentry; + #ifdef SONAME_LIBSANE HINSTANCE SANE_instance; @@ -113,6 +115,8 @@ static TW_UINT16 SANE_OpenDS( pTW_IDENTITY, pTW_IDENTITY); #endif /* SONAME_LIBSANE */ +static TW_UINT16 SANE_SetEntryPoint (pTW_IDENTITY pOrigin, TW_MEMREF pData); + static TW_UINT16 SANE_SourceControlHandler ( pTW_IDENTITY pOrigin, TW_UINT16 DAT, @@ -181,6 +185,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); @@ -380,6 +395,21 @@ DS_Entry ( pTW_IDENTITY pOrigin, return twRC; } +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; +} + #ifdef SONAME_LIBSANE /* Sane returns device names that are longer than the 32 bytes allowed by TWAIN. However, it colon separates them, and the last bit is @@ -432,7 +462,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); @@ -451,6 +481,21 @@ 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 +526,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.4.GIT