sane.ds: Send events to applications through the DSM.

Signed-off-by: Vincent Povirk <vincent@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Vincent Povirk 2017-11-14 15:14:11 -06:00 committed by Alexandre Julliard
parent 21ade8538d
commit 870c4f3e99
5 changed files with 81 additions and 22 deletions

View File

@ -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); TRACE("DG_CONTROL/DAT_EVENT/MSG_PROCESSEVENT msg 0x%x, wParam 0x%lx\n", pMsg->message, pMsg->wParam);
activeDS.twCC = TWCC_SUCCESS; activeDS.twCC = TWCC_SUCCESS;
if (pMsg->message == activeDS.windowMessage && activeDS.windowMessage) pEvent->TWMessage = MSG_NULL; /* no message to the application */
{
twRC = TWRC_DSEVENT;
pEvent->TWMessage = pMsg->wParam;
}
else
pEvent->TWMessage = MSG_NULL; /* no message to the application */
if (activeDS.currentState < 5 || activeDS.currentState > 7) if (activeDS.currentState < 5 || activeDS.currentState > 7)
{ {
@ -232,8 +226,7 @@ TW_UINT16 SANE_PendingXfersEndXfer (pTW_IDENTITY pOrigin,
pPendingXfers->Count = 0; pPendingXfers->Count = 0;
activeDS.currentState = 5; activeDS.currentState = 5;
/* Notify the application that it can close the data source */ /* Notify the application that it can close the data source */
if (activeDS.windowMessage) SANE_Notify(MSG_CLOSEDSREQ);
PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_CLOSEDSREQ, 0);
} }
else else
activeDS.sane_started = TRUE; activeDS.sane_started = TRUE;
@ -403,8 +396,6 @@ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin,
else else
{ {
activeDS.hwndOwner = pUserInterface->hParent; activeDS.hwndOwner = pUserInterface->hParent;
if (! activeDS.windowMessage)
activeDS.windowMessage = RegisterWindowMessageA("SANE.DS ACTIVITY MESSAGE");
if (pUserInterface->ShowUI) if (pUserInterface->ShowUI)
{ {
BOOL rc; BOOL rc;
@ -413,8 +404,7 @@ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin,
pUserInterface->ModalUI = TRUE; pUserInterface->ModalUI = TRUE;
if (!rc) if (!rc)
{ {
if (activeDS.windowMessage) SANE_Notify(MSG_CLOSEDSREQ);
PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_CLOSEDSREQ, 0);
} }
#ifdef SONAME_LIBSANE #ifdef SONAME_LIBSANE
else else
@ -428,8 +418,7 @@ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin,
{ {
/* no UI will be displayed, so source is ready to transfer data */ /* no UI will be displayed, so source is ready to transfer data */
activeDS.currentState = 6; /* Transitions to state 6 directly */ activeDS.currentState = 6; /* Transitions to state 6 directly */
if (activeDS.windowMessage) SANE_Notify(MSG_XFERREADY);
PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_XFERREADY, 0);
} }
twRC = TWRC_SUCCESS; twRC = TWRC_SUCCESS;

View File

@ -62,10 +62,10 @@ extern HINSTANCE SANE_instance DECLSPEC_HIDDEN;
struct tagActiveDS struct tagActiveDS
{ {
struct tagActiveDS *next; /* next active DS */ struct tagActiveDS *next; /* next active DS */
TW_IDENTITY identity; /* identity */ TW_IDENTITY identity; /* identity of the DS */
TW_UINT16 currentState; /* current state */ TW_UINT16 currentState; /* current state */
UINT windowMessage; /* message to use to send status */
TW_UINT16 twCC; /* condition code */ TW_UINT16 twCC; /* condition code */
TW_IDENTITY appIdentity; /* identity of the app */
HWND hwndOwner; /* window handle of the app */ HWND hwndOwner; /* window handle of the app */
HWND progressWnd; /* window handle of the scanning window */ HWND progressWnd; /* window handle of the scanning window */
#ifdef SONAME_LIBSANE #ifdef SONAME_LIBSANE
@ -89,6 +89,7 @@ struct tagActiveDS
/* Helper functions */ /* Helper functions */
extern TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action) DECLSPEC_HIDDEN; extern TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action) DECLSPEC_HIDDEN;
extern TW_UINT16 SANE_SaneSetDefaults (void) DECLSPEC_HIDDEN; extern TW_UINT16 SANE_SaneSetDefaults (void) DECLSPEC_HIDDEN;
extern void SANE_Notify (TW_UINT16 message) DECLSPEC_HIDDEN;
/* Implementation of operation triplets /* Implementation of operation triplets
* From Application to Source (Control Information) */ * From Application to Source (Control Information) */

View File

@ -30,6 +30,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(twain); WINE_DEFAULT_DEBUG_CHANNEL(twain);
DSMENTRYPROC SANE_dsmentry;
#ifdef SONAME_LIBSANE #ifdef SONAME_LIBSANE
HINSTANCE SANE_instance; HINSTANCE SANE_instance;
@ -113,6 +115,8 @@ static TW_UINT16 SANE_OpenDS( pTW_IDENTITY, pTW_IDENTITY);
#endif /* SONAME_LIBSANE */ #endif /* SONAME_LIBSANE */
static TW_UINT16 SANE_SetEntryPoint (pTW_IDENTITY pOrigin, TW_MEMREF pData);
static TW_UINT16 SANE_SourceControlHandler ( static TW_UINT16 SANE_SourceControlHandler (
pTW_IDENTITY pOrigin, pTW_IDENTITY pOrigin,
TW_UINT16 DAT, TW_UINT16 DAT,
@ -181,6 +185,17 @@ static TW_UINT16 SANE_SourceControlHandler (
} }
break; 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: case DAT_EVENT:
if (MSG == MSG_PROCESSEVENT) if (MSG == MSG_PROCESSEVENT)
twRC = SANE_ProcessEvent (pOrigin, pData); twRC = SANE_ProcessEvent (pOrigin, pData);
@ -380,6 +395,21 @@ DS_Entry ( pTW_IDENTITY pOrigin,
return twRC; 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 #ifdef SONAME_LIBSANE
/* Sane returns device names that are longer than the 32 bytes allowed /* Sane returns device names that are longer than the 32 bytes allowed
by TWAIN. However, it colon separates them, and the last bit is 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; return TWRC_FAILURE;
self->ProtocolMajor = TWON_PROTOCOLMAJOR; self->ProtocolMajor = TWON_PROTOCOLMAJOR;
self->ProtocolMinor = TWON_PROTOCOLMINOR; 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); 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->Manufacturer, sane_devlist[cursanedev]->vendor, sizeof(self->Manufacturer) - 1);
lstrcpynA (self->ProductFamily, sane_devlist[cursanedev]->model, sizeof(self->ProductFamily) - 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; SANE_Status status;
int i; 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(); detect_sane_devices();
if (!sane_devlist[0]) { if (!sane_devlist[0]) {
ERR("No scanners? We should not get to OpenDS?\n"); 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(); activeDS.twCC = SANE_SaneSetDefaults();
if (activeDS.twCC == TWCC_SUCCESS) { if (activeDS.twCC == TWCC_SUCCESS) {
activeDS.currentState = 4; activeDS.currentState = 4;
activeDS.identity.Id = self->Id;
activeDS.appIdentity = *pOrigin;
return TWRC_SUCCESS; return TWRC_SUCCESS;
} }
else else

View File

@ -1034,13 +1034,11 @@ static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM
if (psn->lParam) if (psn->lParam)
{ {
activeDS.currentState = 6; activeDS.currentState = 6;
if (activeDS.windowMessage) SANE_Notify(MSG_XFERREADY);
PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_XFERREADY, 0);
} }
break; break;
case PSN_QUERYCANCEL: case PSN_QUERYCANCEL:
if (activeDS.windowMessage) SANE_Notify(MSG_CLOSEDSREQ);
PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_CLOSEDSREQ, 0);
break; break;
case PSN_SETACTIVE: case PSN_SETACTIVE:
InitializeDialog(hwndDlg); InitializeDialog(hwndDlg);

View File

@ -1843,6 +1843,30 @@ typedef TW_UINT16 (*DSENTRYPROC)(pTW_IDENTITY,
} }
#endif /* cplusplus */ #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 */ /* The Twain structures must be packed on 2 byte alignment */
#include "poppack.h" #include "poppack.h"