|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(disable : 4996)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define TTWAINLIB_MAIN
|
|
Toshihiro Shimizu |
890ddd |
#include <assert.h></assert.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <string.h></string.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <stdlib.h></stdlib.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <ctype.h></ctype.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <stdio.h></stdio.h>
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwain_state.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwain_statePD.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwain_error.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwain_win.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwain_winPD.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwain_util.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwain_utilP.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwain_conversion.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwainP.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "ttwain_global_def.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef __cplusplus
|
|
Toshihiro Shimizu |
890ddd |
extern "C" {
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
extern int exitTwainSession(void);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
static void TTWAIN_FreeVar(void);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define CASE \
|
|
Toshihiro Shimizu |
890ddd |
break; \
|
|
Toshihiro Shimizu |
890ddd |
case
|
|
Toshihiro Shimizu |
890ddd |
#define DEFAULT \
|
|
Toshihiro Shimizu |
890ddd |
break; \
|
|
Toshihiro Shimizu |
890ddd |
default
|
|
Toshihiro Shimizu |
890ddd |
#define RELEASE_STR "5.1"
|
|
Toshihiro Shimizu |
890ddd |
#define TITLEBAR_STR "Toonz5.1"
|
|
Toshihiro Shimizu |
890ddd |
#define TwProgramName "Toonz5.1"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define COMPANY "Digital Video"
|
|
Toshihiro Shimizu |
890ddd |
#define PRODUCT "TOONZ"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define MIN(A, B) (((A) < (B)) ? (A) : (B))
|
|
Toshihiro Shimizu |
890ddd |
#define CEIL(x) ((int)(x) < (x) ? (int)(x) + 1 : (int)(x))
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define PRINTF
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/* LOCAL PROTOTYPES */
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_DoOneTransfer(void);
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_WaitForXfer(void *hwnd);
|
|
Toshihiro Shimizu |
890ddd |
static void *TTWAIN_WaitForNativeXfer(void *hwnd);
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_WaitForMemoryXfer(void *hwnd);
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_NativeXferHandler(void);
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_MemoryXferHandler(void);
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_AbortAllPendingXfers(void);
|
|
Toshihiro Shimizu |
890ddd |
static void TTWAIN_ModalEventLoop(void);
|
|
Toshihiro Shimizu |
890ddd |
static void TTWAIN_BreakModalLoop(void);
|
|
Toshihiro Shimizu |
890ddd |
static void TTWAIN_EmptyMessageQueue(void);
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
void TTWAIN_SetState(TWAINSTATE status);
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/* int TTWAIN_LoadSourceManager(void) <- this is in ttwain_state.h */
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* int TTWAIN_SelectImageSource(void* hwnd) <-\
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_SelectImageSource(void* hwnd) <-|--\
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_OpenDefaultSource(void) <-|-- these are in ttwain.h
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_CloseAll (void *hwnd) <-/
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* these are local */
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_EnableSource(void *hwnd);
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_MessageHook(void *lpmsg);
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_EndXfer(void);
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_DisableSource(void);
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_CloseSource(void);
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_CloseSourceManager(void *hwnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* int TTWAIN_UnloadSourceManager(void) <- this is in ttwain_state.h */
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_MGR(TUINT32 dg, TUINT32 dat, TUINT32 msg, void *pd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define INVERT_BYTE(START, HOWMANY) \
|
|
Toshihiro Shimizu |
890ddd |
{ \
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *p = (START); \
|
|
Toshihiro Shimizu |
890ddd |
unsigned int ijk; \
|
|
Toshihiro Shimizu |
890ddd |
for (ijk = 0; ijk < (HOWMANY); ijk++, p++) { \
|
|
Toshihiro Shimizu |
890ddd |
*p = ~*p; \
|
|
Toshihiro Shimizu |
890ddd |
} \
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define BB(H, L) (H << 8 | L)
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/* TWAIN STATE */
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 1 TO 2*/
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_LoadSourceManager(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_InitVar();
|
|
Toshihiro Shimizu |
890ddd |
return TTWAIN_LoadSourceManagerPD();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 2 TO 3*/
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_OpenSourceManager(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.hwnd32SM = (TW_INT32)TTWAIN_GetValidHwnd(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() < TWAIN_SM_OPEN) {
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_LoadSourceManager() &&
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_MGR(DG_CONTROL, DAT_PARENT, MSG_OPENDSM, &TTwainData.hwnd32SM)) {
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_SM_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return (TTWAIN_GetState() >= TWAIN_SM_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 3*/
|
|
Toshihiro Shimizu |
890ddd |
static TW_IDENTITY newSourceId;
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_SelectImageSource(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int success = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
TWAINSTATE entryState = TTWAIN_GetState();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() >= TWAIN_SM_OPEN ||
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_OpenSourceManager(hwnd)) {
|
|
Toshihiro Shimizu |
890ddd |
//TW_IDENTITY newSourceId;
|
|
Toshihiro Shimizu |
890ddd |
memset(&newSourceId, 0, sizeof newSourceId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_MGR(DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &newSourceId);
|
|
Toshihiro Shimizu |
890ddd |
/* Post the Select Source dialog */
|
|
Toshihiro Shimizu |
890ddd |
success = TTWAIN_MGR(DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &newSourceId);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
char msg[2048];
|
|
Toshihiro Shimizu |
890ddd |
sprintf(msg, "Unable to open Source Manager (%s)", DSM_FILENAME);
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_ErrorBox(msg);
|
|
Toshihiro Shimizu |
890ddd |
return FALSE;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (entryState < TWAIN_SM_OPEN) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_CloseSourceManager(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
if (entryState < TWAIN_SM_LOADED) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_UnloadSourceManager();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return success;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 3 TO 4*/
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_OpenDefaultSource(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TW_IDENTITY tempId;
|
|
Toshihiro Shimizu |
890ddd |
int rc;
|
|
Toshihiro Shimizu |
890ddd |
static int first_time = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() < TWAIN_SOURCE_OPEN) {
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() < TWAIN_SM_OPEN && !TTWAIN_OpenSourceManager(NULL))
|
|
Toshihiro Shimizu |
890ddd |
return FALSE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
rc = TTWAIN_MGR(DG_CONTROL, DAT_IDENTITY, MSG_GETFIRST, &tempId);
|
|
Toshihiro Shimizu |
890ddd |
while (rc && tempId.Id != 0) {
|
|
Toshihiro Shimizu |
890ddd |
if (strcmp((char *)newSourceId.ProductName, (char *)tempId.ProductName) == 0) {
|
|
Toshihiro Shimizu |
890ddd |
newSourceId = tempId;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
rc = TTWAIN_MGR(DG_CONTROL, DAT_IDENTITY, MSG_GETNEXT, &tempId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_MGR(DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, &newSourceId)) {
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_SOURCE_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (first_time && (TTWAIN_GetState() == TWAIN_SOURCE_OPEN)) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_GetSupportedCaps();
|
|
Toshihiro Shimizu |
890ddd |
/*first_time = FALSE;*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return (TTWAIN_GetState() == TWAIN_SOURCE_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 4 TO 5*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_EnableSource(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() < TWAIN_SOURCE_OPEN &&
|
|
Toshihiro Shimizu |
890ddd |
!TTWAIN_OpenDefaultSource())
|
|
Toshihiro Shimizu |
890ddd |
return FALSE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.twainUI.ShowUI = TTWAIN_GetUIStatus();
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.twainUI.ModalUI = TTWAIN_GetModalStatus();
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.twainUI.hParent = (TW_HANDLE)TTWAIN_GetValidHwnd(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_DS(DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, &TTwainData.twainUI);
|
|
Toshihiro Shimizu |
890ddd |
return (TTWAIN_GetState() == TWAIN_SOURCE_ENABLED);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 5 TO 6 TO 7*/
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_MessageHook(void *lpmsg)
|
|
Toshihiro Shimizu |
890ddd |
/* returns TRUE if msg processed by TWAIN (source) */
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int bProcessed = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
//printf("%s\n", __PRETTY_FUNCTION__);
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() >= TWAIN_SOURCE_ENABLED) {
|
|
Toshihiro Shimizu |
890ddd |
/* source enabled */
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Toshihiro Shimizu |
890ddd |
TW_EVENT twEvent;
|
|
Toshihiro Shimizu |
890ddd |
twEvent.pEvent = (TW_MEMREF)lpmsg;
|
|
Toshihiro Shimizu |
890ddd |
twEvent.TWMessage = MSG_NULL;
|
|
Toshihiro Shimizu |
890ddd |
/* see if source wants to process (eat) the message */
|
|
Toshihiro Shimizu |
890ddd |
bProcessed = (TTWAIN_DS(DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, &twEvent) == TWRC_DSEVENT);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
TW_EVENT twEvent;
|
|
Toshihiro Shimizu |
890ddd |
twEvent.pEvent = (TW_MEMREF)0;
|
|
Toshihiro Shimizu |
890ddd |
twEvent.TWMessage = (TW_UINT32)lpmsg;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
switch (twEvent.TWMessage) {
|
|
Toshihiro Shimizu |
890ddd |
case MSG_XFERREADY:
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_TRANSFER_READY);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_TRANSFER_READY);
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_DoOneTransfer();
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case MSG_CLOSEDSREQ:
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_DisableSource();
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case MSG_NULL:
|
|
Toshihiro Shimizu |
890ddd |
/* no message returned from DS */
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
} /* switch */
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return bProcessed;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 7 TO 6 TO 5*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_EndXfer(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() == TWAIN_TRANSFERRING)
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
|
|
Toshihiro Shimizu |
890ddd |
&TTwainData.transferInfo.pendingXfers);
|
|
Toshihiro Shimizu |
890ddd |
return (TTWAIN_GetState() < TWAIN_TRANSFERRING);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/* STATE 5 TO 1 */
|
|
Toshihiro Shimizu |
890ddd |
/* 3 OP + 1 PD OP*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 5 TO 4*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_DisableSource(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_AbortAllPendingXfers();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((TTWAIN_GetState() >= TWAIN_SOURCE_ENABLED) &&
|
|
Toshihiro Shimizu |
890ddd |
(TTWAIN_DS(DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS,
|
|
Toshihiro Shimizu |
890ddd |
&TTwainData.twainUI) == TWRC_SUCCESS)) {
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_SOURCE_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
return FALSE;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_EmptyMessageQueue();
|
|
Toshihiro Shimizu |
890ddd |
return (TTWAIN_GetState() < TWAIN_SOURCE_ENABLED);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 4 TO 3*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_CloseSource(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.resultCode = TWRC_SUCCESS;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_DisableSource();
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() == TWAIN_SOURCE_OPEN &&
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_MGR(DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, &TTwainData.sourceId)) {
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_SM_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return (TTWAIN_GetState() <= TWAIN_SM_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 3 TO 2*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_CloseSourceManager(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_EmptyMessageQueue();
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.hwnd32SM = (TW_INT32)TTWAIN_GetValidHwnd(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.resultCode = TWRC_SUCCESS;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_CloseSource() &&
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_MGR(DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, &TTwainData.hwnd32SM)) {
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_SM_LOADED);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return (TTWAIN_GetState() <= TWAIN_SM_LOADED);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*STATE 2 TO 1*/
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_UnloadSourceManager(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_CloseSourceManager(NULL);
|
|
Toshihiro Shimizu |
890ddd |
return TTWAIN_UnloadSourceManagerPD();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_CloseAll(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_EndXfer();
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_DisableSource();
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_CloseSource();
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_CloseSourceManager(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_UnloadSourceManager();
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_FreeVar();
|
|
Toshihiro Shimizu |
890ddd |
return 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/* MISC. AUX FUNCTIONS */
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
TWAINSTATE TTWAIN_GetState(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return TTwainData.twainState;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
void TTWAIN_SetState(TWAINSTATE status)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.twainState = status;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_AbortAllPendingXfers(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_EndXfer();
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() == TWAIN_TRANSFER_READY) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET,
|
|
Toshihiro Shimizu |
890ddd |
&TTwainData.transferInfo.pendingXfers);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_EmptyMessageQueue();
|
|
Toshihiro Shimizu |
890ddd |
return (TTWAIN_GetState() < TWAIN_TRANSFER_READY);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/* DATA SOURCE */
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
TW_INT16 TTWAIN_DS(TUINT32 dg, TUINT32 dat, TUINT32 msg, void *pd)
|
|
Toshihiro Shimizu |
890ddd |
{ /* Call the current source with a triplet */
|
|
Toshihiro Shimizu |
890ddd |
int bOk = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
static TUINT32 nMemBuffer = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PRINTF("%s dg=0x%x dat=0x%x msg=0x%x pd=0x%x\n", __FUNCTION__, dg, dat, msg, pd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() >= TWAIN_SOURCE_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.resultCode = TWRC_FAILURE;
|
|
Toshihiro Shimizu |
890ddd |
if (dg == DG_IMAGE) {
|
|
Toshihiro Shimizu |
890ddd |
if (dat == DAT_IMAGEMEMXFER) {
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_GET && pd != NULL) {
|
|
Toshihiro Shimizu |
890ddd |
pTW_IMAGEMEMXFER pmxb = (pTW_IMAGEMEMXFER)pd;
|
|
Toshihiro Shimizu |
890ddd |
pmxb->Compression = TWON_DONTCARE16;
|
|
Toshihiro Shimizu |
890ddd |
pmxb->BytesPerRow = TWON_DONTCARE32;
|
|
Toshihiro Shimizu |
890ddd |
pmxb->Columns = TWON_DONTCARE32;
|
|
Toshihiro Shimizu |
890ddd |
pmxb->Rows = TWON_DONTCARE32;
|
|
Toshihiro Shimizu |
890ddd |
pmxb->XOffset = TWON_DONTCARE32;
|
|
Toshihiro Shimizu |
890ddd |
pmxb->YOffset = TWON_DONTCARE32;
|
|
Toshihiro Shimizu |
890ddd |
pmxb->BytesWritten = TWON_DONTCARE32;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.DSM_Entry) {
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.resultCode = (*TTwainData.DSM_Entry)(&TTwainData.appId,
|
|
Toshihiro Shimizu |
890ddd |
&TTwainData.sourceId,
|
|
Toshihiro Shimizu |
890ddd |
(TW_UINT32)dg,
|
|
Toshihiro Shimizu |
890ddd |
(TW_UINT16)dat,
|
|
Toshihiro Shimizu |
890ddd |
(TW_UINT16)msg,
|
|
Toshihiro Shimizu |
890ddd |
(TW_MEMREF)pd);
|
|
Toshihiro Shimizu |
890ddd |
bOk = (TTwainData.resultCode == TWRC_SUCCESS);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dg == DG_CONTROL) {
|
|
Toshihiro Shimizu |
890ddd |
switch (dat) {
|
|
Toshihiro Shimizu |
890ddd |
case DAT_EVENT:
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_PROCESSEVENT) {
|
|
Toshihiro Shimizu |
890ddd |
if (((pTW_EVENT)pd)->TWMessage == MSG_XFERREADY) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_TRANSFER_READY);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
bOk = (TTwainData.resultCode == TWRC_DSEVENT);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case DAT_CAPABILITY:
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case DAT_PENDINGXFERS:
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_ENDXFER && bOk) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(((pTW_PENDINGXFERS)pd)->Count ? TWAIN_TRANSFER_READY : TWAIN_SOURCE_ENABLED);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_RESET && bOk) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_SOURCE_ENABLED);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case DAT_USERINTERFACE:
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_ENABLEDS) {
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.resultCode == TWRC_FAILURE || TTwainData.resultCode == TWRC_CANCEL) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_RecordError();
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
/* TTwainData.resultCode could be either SUCCESS or CHECKSTATUS */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_SOURCE_ENABLED);
|
|
Toshihiro Shimizu |
890ddd |
bOk = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_DISABLEDS && bOk) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_SOURCE_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
exitTwainSession(); // exited from TwainUI using close button
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case DAT_SETUPMEMXFER:
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_GET && bOk) {
|
|
Toshihiro Shimizu |
890ddd |
nMemBuffer = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
} /* switch */
|
|
Toshihiro Shimizu |
890ddd |
} else if (dg == DG_IMAGE) {
|
|
Toshihiro Shimizu |
890ddd |
if (dat == DAT_IMAGENATIVEXFER || dat == DAT_IMAGEFILEXFER) {
|
|
Toshihiro Shimizu |
890ddd |
/* Native and File transfers work much the same way. */
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_GET) {
|
|
Toshihiro Shimizu |
890ddd |
bOk = (TTwainData.resultCode == TWRC_XFERDONE);
|
|
Toshihiro Shimizu |
890ddd |
switch (TTwainData.resultCode) {
|
|
Toshihiro Shimizu |
890ddd |
case TWRC_XFERDONE:
|
|
Toshihiro Shimizu |
890ddd |
case TWRC_CANCEL:
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_TRANSFERRING);
|
|
Toshihiro Shimizu |
890ddd |
/* Need to acknowledge end of transfer with */
|
|
Toshihiro Shimizu |
890ddd |
/* DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER */
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case TWRC_FAILURE:
|
|
Toshihiro Shimizu |
890ddd |
default:
|
|
Toshihiro Shimizu |
890ddd |
/* Transfer failed (e.g. insufficient memory, write-locked file) */
|
|
Toshihiro Shimizu |
890ddd |
/* check condition code for more info */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_TRANSFER_READY);
|
|
Toshihiro Shimizu |
890ddd |
/* The image is still pending */
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
} /* switch */
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else if (dat == DAT_IMAGEMEMXFER) {
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_GET) {
|
|
Toshihiro Shimizu |
890ddd |
bOk = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
switch (TTwainData.resultCode) {
|
|
Toshihiro Shimizu |
890ddd |
case TWRC_SUCCESS:
|
|
Toshihiro Shimizu |
890ddd |
case TWRC_XFERDONE:
|
|
Toshihiro Shimizu |
890ddd |
bOk = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
nMemBuffer++;
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_TRANSFERRING);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case TWRC_FAILURE:
|
|
Toshihiro Shimizu |
890ddd |
/* "If the failure occurred during the transfer of the first
|
|
Toshihiro Shimizu |
890ddd |
buffer, the session is in State 6. If the failure occurred
|
|
Toshihiro Shimizu |
890ddd |
on a subsequent buffer, the session is in State 7."
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(nMemBuffer == 0 ? TWAIN_TRANSFER_READY : TWAIN_TRANSFERRING);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case TWRC_CANCEL:
|
|
Toshihiro Shimizu |
890ddd |
/* Transfer cancelled, no state change. */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_BreakModalLoop();
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
} /* switch */
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
if (!bOk)
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_RecordError();
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
return TTwainData.resultCode;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/* DATA SOURCE MANAGER */
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_MGR(TUINT32 dg, TUINT32 dat, TUINT32 msg, void *pd)
|
|
Toshihiro Shimizu |
890ddd |
/* Call the Source Manager with a triplet */
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int bOk = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.resultCode = TWRC_FAILURE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.DSM_Entry) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.resultCode = (*TTwainData.DSM_Entry)(&TTwainData.appId,
|
|
Toshihiro Shimizu |
890ddd |
NULL,
|
|
Toshihiro Shimizu |
890ddd |
(TW_UINT32)dg,
|
|
Toshihiro Shimizu |
890ddd |
(TW_UINT16)dat,
|
|
Toshihiro Shimizu |
890ddd |
(TW_UINT16)msg,
|
|
Toshihiro Shimizu |
890ddd |
(TW_MEMREF)pd);
|
|
Toshihiro Shimizu |
890ddd |
bOk = (TTwainData.resultCode == TWRC_SUCCESS);
|
|
Toshihiro Shimizu |
890ddd |
if (dg == DG_CONTROL) {
|
|
Toshihiro Shimizu |
890ddd |
if (dat == DAT_IDENTITY) {
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_OPENDS) {
|
|
Toshihiro Shimizu |
890ddd |
if (bOk) {
|
|
Toshihiro Shimizu |
890ddd |
/* Source opened - record identity for future triplets */
|
|
Toshihiro Shimizu |
890ddd |
memcpy(&TTwainData.sourceId, pd, sizeof(TW_IDENTITY));
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_SOURCE_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
} else { /*RecordError(ED_DSM_FAILURE);*/
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_RecordError();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_CLOSEDS && bOk) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_SM_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (dat == DAT_PARENT) {
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_OPENDSM && bOk) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_SM_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (msg == MSG_CLOSEDSM && bOk) {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_SetState(TWAIN_SM_LOADED);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return bOk;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
/* ERRORS */
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
TUINT32 TTWAIN_GetConditionCode(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TW_STATUS twStatus;
|
|
Toshihiro Shimizu |
890ddd |
TW_INT16 rcLast = TTwainData.resultCode;
|
|
Toshihiro Shimizu |
890ddd |
TW_INT16 rc = TWRC_FAILURE;
|
|
Toshihiro Shimizu |
890ddd |
twStatus.ConditionCode = TWCC_BUMMER;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() >= 4) {
|
|
Toshihiro Shimizu |
890ddd |
/* get source status if open */
|
|
Toshihiro Shimizu |
890ddd |
rc = TTWAIN_DS(DG_CONTROL, DAT_STATUS, MSG_GET, (TW_MEMREF)&twStatus);
|
|
Toshihiro Shimizu |
890ddd |
} else if (TTWAIN_GetState() == 3) {
|
|
Toshihiro Shimizu |
890ddd |
/* otherwise get source manager status */
|
|
Toshihiro Shimizu |
890ddd |
rc = TTWAIN_MGR(DG_CONTROL, DAT_STATUS, MSG_GET, (TW_MEMREF)&twStatus);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.resultCode = rcLast;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (rc != TWRC_SUCCESS)
|
|
Toshihiro Shimizu |
890ddd |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
return twStatus.ConditionCode;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
TUINT32 TTWAIN_GetResultCode(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return TTwainData.resultCode;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_DSM_HasEntryPoint(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return !!(TTwainData.DSM_Entry);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_DoOneTransfer(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int rc = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
switch (TTwainData.transferInfo.transferMech) {
|
|
Toshihiro Shimizu |
890ddd |
case TTWAIN_TRANSFERMODE_NATIVE:
|
|
Toshihiro Shimizu |
890ddd |
rc = TTWAIN_NativeXferHandler();
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case TTWAIN_TRANSFERMODE_FILE:
|
|
Toshihiro Shimizu |
890ddd |
assert(!"NOT IMPL!");
|
|
Toshihiro Shimizu |
890ddd |
/*TTWAIN_FileXferHandler(); */
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case TTWAIN_TRANSFERMODE_MEMORY:
|
|
Toshihiro Shimizu |
890ddd |
rc = TTWAIN_MemoryXferHandler();
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
} /* switch */
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.lastTransferWasOk = rc;
|
|
Toshihiro Shimizu |
890ddd |
/* If inside ModalEventLoop, break out */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_BreakModalLoop();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* Acknowledge transfer */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_EndXfer();
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_TRANSFER_READY ||
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_GetState() == TWAIN_SOURCE_ENABLED);
|
|
Toshihiro Shimizu |
890ddd |
return rc;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
void TTWAIN_RegisterApp(int majorNum, int minorNum, /* app. revision*/
|
|
Toshihiro Shimizu |
890ddd |
int nLanguage, /* (human) language (use TWLG_xxx from TWAIN.H) */
|
|
Toshihiro Shimizu |
890ddd |
int nCountry, /* country (use TWCY_xxx from TWAIN.H) */
|
|
Toshihiro Shimizu |
890ddd |
char *version, /* version info string */
|
|
Toshihiro Shimizu |
890ddd |
char *manufacter, /* name of manufacter */
|
|
Toshihiro Shimizu |
890ddd |
char *family, /* product family */
|
|
Toshihiro Shimizu |
890ddd |
char *product) /* specific product */
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
memset(&TTwainData.appId, 0, sizeof(TTwainData.appId));
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.Id = 0; /* init to 0, but Source Manager will assign THE real value*/
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.Version.MajorNum = majorNum;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.Version.MinorNum = minorNum;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.Version.Language = nLanguage;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.Version.Country = nCountry;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.ProtocolMajor = TWON_PROTOCOLMAJOR;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.ProtocolMinor = TWON_PROTOCOLMINOR;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.SupportedGroups = DG_IMAGE | DG_CONTROL;
|
|
Toshihiro Shimizu |
890ddd |
strcpy((char *)TTwainData.appId.Version.Info, version);
|
|
Toshihiro Shimizu |
890ddd |
strcpy((char *)TTwainData.appId.Manufacturer, manufacter);
|
|
Toshihiro Shimizu |
890ddd |
strcpy((char *)TTwainData.appId.ProductFamily, family);
|
|
Toshihiro Shimizu |
890ddd |
strcpy((char *)TTwainData.appId.ProductName, product);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
void *TTWAIN_AcquireNative(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
void *hnative = NULL;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.lastTransferWasOk = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.transferMech != TTWAIN_TRANSFERMODE_NATIVE)
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
hwnd = TTWAIN_GetValidHwnd(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() < TWAIN_SOURCE_OPEN) {
|
|
Toshihiro Shimizu |
890ddd |
if (!TTWAIN_OpenSourceManager(hwnd)) /* Bring up to state 4 */
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
char msg[2048];
|
|
Toshihiro Shimizu |
890ddd |
sprintf(msg, "Unable to open Source Manager (%s)", DSM_FILENAME);
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_ErrorBox(msg);
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (!TTWAIN_OpenDefaultSource())
|
|
Toshihiro Shimizu |
890ddd |
/*TTWAIN_ReportLastError("Unable to open default Data Source.");*/
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_RecordError();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_SOURCE_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() >= TWAIN_SOURCE_OPEN)
|
|
Toshihiro Shimizu |
890ddd |
hnative = TTWAIN_WaitForNativeXfer(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!TTwainData.transferInfo.multiTransfer) {
|
|
Toshihiro Shimizu |
890ddd |
/* shut everything down in the right sequence */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_AbortAllPendingXfers(); /* TRANSFER_READY or TRANSFERRING -> SOURCE_ENABLED */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_UnloadSourceManager();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.lastTransferWasOk = !!(hnative);
|
|
Toshihiro Shimizu |
890ddd |
return hnative;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef void(MyFun)(HWND);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*it's an hack function to force bring to top the twain UI module window */
|
|
Toshihiro Shimizu |
890ddd |
static BOOL CALLBACK myHackEnumFunction(HWND hwnd, LPARAM lParam)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
MyFun *f = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define TITLESIZE (1024)
|
|
Toshihiro Shimizu |
890ddd |
char title[TITLESIZE + 1];
|
|
Toshihiro Shimizu |
890ddd |
int len;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
GetWindowText(hwnd, (char *)&title, TITLESIZE);
|
|
Toshihiro Shimizu |
890ddd |
if (title[0] == 0x00)
|
|
Toshihiro Shimizu |
890ddd |
return 1; /*continue the search....*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
len = strlen(TTwainData.sourceId.ProductName);
|
|
Toshihiro Shimizu |
890ddd |
if (!len)
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
len--;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (len &&
|
|
Toshihiro Shimizu |
890ddd |
(isdigit(TTwainData.sourceId.ProductName[len]) /*skip digit at the end*/
|
|
Toshihiro Shimizu |
890ddd |
|| TTwainData.sourceId.ProductName[len] == '.')) /*skip . */
|
|
Toshihiro Shimizu |
890ddd |
len--;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (len && !strncmp(title, TTwainData.sourceId.ProductName, len)) {
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
char dbg_str[1024];
|
|
Toshihiro Shimizu |
890ddd |
sprintf(dbg_str,"set focus on 0x%8x %s\n",hwnd, title);
|
|
Toshihiro Shimizu |
890ddd |
OutputDebugString(dbg_str);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
f = (MyFun *)lParam;
|
|
Toshihiro Shimizu |
890ddd |
f(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return FALSE; /*it means stop the search...*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return 1; /*continue the search....*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
static BOOL CALLBACK myHackEnumFunction2(HWND hwnd, LPARAM lParam)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
MyFun *f = 0;
|
|
Toshihiro Shimizu |
890ddd |
char *ptr;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define TITLESIZE (1024)
|
|
Toshihiro Shimizu |
890ddd |
char title[TITLESIZE + 1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
GetWindowText(hwnd, (char *)&title, TITLESIZE);
|
|
Toshihiro Shimizu |
890ddd |
if (title[0] == 0x00)
|
|
Toshihiro Shimizu |
890ddd |
return 1; /*continue the search....*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ptr = strstr(title, TTwainData.sourceId.Manufacturer);
|
|
Toshihiro Shimizu |
890ddd |
if (!ptr)
|
|
Toshihiro Shimizu |
890ddd |
return 1; /*continue the search....*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
f = (MyFun *)lParam;
|
|
Toshihiro Shimizu |
890ddd |
f(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return FALSE; /*it means stop the search...*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void bringToTop(HWND hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
BringWindowToTop(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void putToBottom(HWND hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
const int unused = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
BOOL rc = SetWindowPos(
|
|
Toshihiro Shimizu |
890ddd |
hwnd, // handle to window
|
|
Toshihiro Shimizu |
890ddd |
HWND_BOTTOM, // placement-order handle
|
|
Toshihiro Shimizu |
890ddd |
unused, // horizontal position
|
|
Toshihiro Shimizu |
890ddd |
unused, // vertical position
|
|
Toshihiro Shimizu |
890ddd |
unused, // width
|
|
Toshihiro Shimizu |
890ddd |
unused, // height
|
|
Toshihiro Shimizu |
890ddd |
SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE // window-positioning options
|
|
Toshihiro Shimizu |
890ddd |
);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
static void myHackFunction(int v)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
BOOL rc;
|
|
Toshihiro Shimizu |
890ddd |
if (v == 1)
|
|
Toshihiro Shimizu |
890ddd |
rc = EnumWindows((WNDENUMPROC)myHackEnumFunction, (LPARAM)&bringToTop);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
rc = EnumWindows((WNDENUMPROC)myHackEnumFunction, (LPARAM)&putToBottom);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (rc) /* it means that myHackEnumFunction fails to find the proper window to bring up or put down*/
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (v == 1)
|
|
Toshihiro Shimizu |
890ddd |
rc = EnumWindows((WNDENUMPROC)myHackEnumFunction2, (LPARAM)&bringToTop);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
rc = EnumWindows((WNDENUMPROC)myHackEnumFunction2, (LPARAM)&putToBottom);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
static void myHackFunction(int v)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
/*it's empty...*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_AcquireMemory(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int rc = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.lastTransferWasOk = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.transferMech != TTWAIN_TRANSFERMODE_MEMORY)
|
|
Toshihiro Shimizu |
890ddd |
return FALSE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
myHackFunction(1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
hwnd = TTWAIN_GetValidHwnd(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() < TWAIN_SOURCE_OPEN) {
|
|
Toshihiro Shimizu |
890ddd |
if (!TTWAIN_OpenSourceManager(hwnd)) /* Bring up to state 4 */
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_ErrorBox("Unable to open Source Manager (" DSM_FILENAME ")");
|
|
Toshihiro Shimizu |
890ddd |
return FALSE;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (!TTWAIN_OpenDefaultSource())
|
|
Toshihiro Shimizu |
890ddd |
/*TTWAIN_ReportLastError("Unable to open default Data Source.");*/
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_RecordError();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_SOURCE_OPEN);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() >= TWAIN_SOURCE_OPEN)
|
|
Toshihiro Shimizu |
890ddd |
rc = TTWAIN_WaitForMemoryXfer(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!TTwainData.transferInfo.multiTransfer) {
|
|
Toshihiro Shimizu |
890ddd |
/* shut everything down in the right sequence */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_AbortAllPendingXfers(); /* TRANSFER_READY or TRANSFERRING -> SOURCE_ENABLED */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_UnloadSourceManager();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
myHackFunction(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return TTwainData.transferInfo.lastTransferWasOk;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
void TTWAIN_StopAcquire(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.oneAtLeast = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static void *TTWAIN_WaitForNativeXfer(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.hDib = NULL;
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() >= TWAIN_SOURCE_OPEN)
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_WaitForXfer(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_ErrorBox("TWAIN_WaitForNativeXfer called in state < 4.");
|
|
Toshihiro Shimizu |
890ddd |
return TTwainData.transferInfo.hDib;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_WaitForMemoryXfer(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int rc = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() >= TWAIN_SOURCE_OPEN)
|
|
Toshihiro Shimizu |
890ddd |
rc = TTWAIN_WaitForXfer(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_ErrorBox("TWAIN_WaitForNativeXfer called in state < 4.");
|
|
Toshihiro Shimizu |
890ddd |
return rc;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_WaitForXfer(void *hwnd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int bWasEnabled;
|
|
Toshihiro Shimizu |
890ddd |
int rc = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
/* Make up a valid window if we weren't given one */
|
|
Toshihiro Shimizu |
890ddd |
hwnd = TTWAIN_GetValidHwnd(hwnd);
|
|
Toshihiro Shimizu |
890ddd |
/* Disable the parent window during the modal acquire */
|
|
Toshihiro Shimizu |
890ddd |
bWasEnabled = (TTWAIN_EnableWindow(hwnd, FALSE) == 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.oneAtLeast = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_DS( DG_CONTROL,DAT_PENDINGXFERS, MSG_ENDXFER,
|
|
Toshihiro Shimizu |
890ddd |
(TW_MEMREF)&TTwainData.transferInfo.pendingXfers);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
do {
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_GetState() == TWAIN_TRANSFER_READY)
|
|
Toshihiro Shimizu |
890ddd |
rc = TTWAIN_DoOneTransfer();
|
|
Toshihiro Shimizu |
890ddd |
else if (TTWAIN_GetState() >= TWAIN_SOURCE_ENABLED ||
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_EnableSource(hwnd)) {
|
|
Toshihiro Shimizu |
890ddd |
/* source is enabled, wait for transfer or source closed */
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.resultCode != TWRC_CANCEL)
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_ModalEventLoop();
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_BreakModalLoop();
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
/*TTWAIN_ReportLastError("Failed to enable Data Source.");*/
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_RecordError();
|
|
Toshihiro Shimizu |
890ddd |
} while (TTwainData.transferInfo.pendingXfers.Count &&
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.oneAtLeast /*&& rc*/);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* Re-enable the parent window if it was enabled */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_EnableWindow(hwnd, bWasEnabled);
|
|
Toshihiro Shimizu |
890ddd |
return rc;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
void TTWAIN_FreeMemory(void *hMem)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
free(hMem);
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
if (hMem)
|
|
Toshihiro Shimizu |
890ddd |
GLOBAL_FREE(hMem);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static void TTWAIN_ModalEventLoop(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_ModalEventLoopPD();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static void TTWAIN_BreakModalLoop(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.breakModalLoop = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static void TTWAIN_EmptyMessageQueue(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_EmptyMessageQueuePD();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_NativeXferHandler(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 hNative;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(TTWAIN_GetState() == TWAIN_TRANSFER_READY);
|
|
Toshihiro Shimizu |
890ddd |
if (TTWAIN_DS(DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &hNative) == TWRC_XFERDONE)
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.hDib = (void *)hNative;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.hDib = NULL;
|
|
Toshihiro Shimizu |
890ddd |
return (!!TTwainData.transferInfo.hDib);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static int TTWAIN_MemoryXferHandler(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TW_IMAGEMEMXFER *imageMemXfer = 0;
|
|
Toshihiro Shimizu |
890ddd |
TW_HANDLE imageMemXferH = 0;
|
|
Toshihiro Shimizu |
890ddd |
TW_HANDLE transferBufferH = 0;
|
|
Toshihiro Shimizu |
890ddd |
TW_SETUPMEMXFER setup;
|
|
Toshihiro Shimizu |
890ddd |
TW_IMAGEINFO info;
|
|
Toshihiro Shimizu |
890ddd |
TW_IMAGELAYOUT imageLayout;
|
|
Toshihiro Shimizu |
890ddd |
TUINT32 nTransferDone;
|
|
Toshihiro Shimizu |
890ddd |
TW_INT16 rc1, rc2, rc3, rc4, twRC2;
|
|
Toshihiro Shimizu |
890ddd |
int ret = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
int stopScanning = 0;
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *transferBuffer = 0;
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *sourceBuffer = 0;
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *targetBuffer = 0;
|
|
Toshihiro Shimizu |
890ddd |
unsigned int rows;
|
|
Toshihiro Shimizu |
890ddd |
double pixSize;
|
|
Toshihiro Shimizu |
890ddd |
int extraX = 0;
|
|
Toshihiro Shimizu |
890ddd |
int extraY = 0;
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 rowsToCopy = 0;
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 rowsRemaining = 0;
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 bytesToCopy = 0;
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 bytesToWrap = 0;
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 memorySize = 0;
|
|
Toshihiro Shimizu |
890ddd |
int imgInfoOk; /* on Mac often (always) is impossible to get the imageinfo
|
|
Toshihiro Shimizu |
890ddd |
about the transfer... so no I can't prealloc memory
|
|
Toshihiro Shimizu |
890ddd |
and do other checks about size etc...
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*printf("%s\n", __PRETTY_FUNCTION__);*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
memset(&info, 0, sizeof(TW_IMAGEINFO));
|
|
Toshihiro Shimizu |
890ddd |
rc1 = TTWAIN_DS(DG_IMAGE, DAT_IMAGEINFO, MSG_GET, (TW_MEMREF)&info);
|
|
Toshihiro Shimizu |
890ddd |
imgInfoOk = (rc1 == TWRC_SUCCESS);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*printf("get image info returns %d\n", imgInfoOk);*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
rc4 = TTWAIN_DS(DG_IMAGE, DAT_IMAGELAYOUT, MSG_GET, &imageLayout);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* determine the transfer buffer size */
|
|
Toshihiro Shimizu |
890ddd |
rc2 = TTWAIN_DS(DG_CONTROL, DAT_SETUPMEMXFER, MSG_GET, (TW_MEMREF)&setup);
|
|
Toshihiro Shimizu |
890ddd |
transferBufferH = GLOBAL_ALLOC(GMEM_FIXED, setup.Preferred);
|
|
Toshihiro Shimizu |
890ddd |
if (!transferBufferH)
|
|
Toshihiro Shimizu |
890ddd |
return FALSE;
|
|
Toshihiro Shimizu |
890ddd |
transferBuffer = (UCHAR *)GLOBAL_LOCK(transferBufferH);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (imgInfoOk) {
|
|
Toshihiro Shimizu |
890ddd |
pixSize = info.BitsPerPixel / 8.0;
|
|
Toshihiro Shimizu |
890ddd |
memorySize = info.ImageLength * CEIL(info.ImageWidth * pixSize);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
/* we need to allocate incrementally the memory needs to store the image*/
|
|
Toshihiro Shimizu |
890ddd |
memorySize = setup.Preferred; /* start using the setupmemxfer.preferred size*/
|
|
Toshihiro Shimizu |
890ddd |
pixSize = 3;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.usageMode == TTWAIN_MODE_UNLEASHED) {
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo = GLOBAL_ALLOC(GMEM_FIXED, memorySize);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.memoryBuffer = (UCHAR *)malloc(memorySize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!TTwainData.transferInfo.memoryBuffer) {
|
|
Toshihiro Shimizu |
890ddd |
/*tmsg_error("unable to allocate memory!");*/
|
|
Toshihiro Shimizu |
890ddd |
return FALSE;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (imgInfoOk) {
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.memorySize = memorySize;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLx = info.ImageWidth;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLy = info.ImageLength;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.memorySize = setup.Preferred;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLx = 0;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLy = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
extraX = info.ImageWidth - TTwainData.transferInfo.preferredLx;
|
|
Toshihiro Shimizu |
890ddd |
extraY = info.ImageLength - TTwainData.transferInfo.preferredLy;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
rowsRemaining = MIN(TTwainData.transferInfo.preferredLy, info.ImageLength);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
targetBuffer = TTwainData.transferInfo.memoryBuffer;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*clean-up the buffer
|
|
Toshihiro Shimizu |
890ddd |
memset(targetBuffer, 0xff, TTwainData.transferInfo.memorySize);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
imageMemXferH = GLOBAL_ALLOC(GMEM_FIXED, sizeof(TW_IMAGEMEMXFER));
|
|
Toshihiro Shimizu |
890ddd |
if (!imageMemXferH)
|
|
Toshihiro Shimizu |
890ddd |
return FALSE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
imageMemXfer = (TW_IMAGEMEMXFER *)GLOBAL_LOCK(imageMemXferH);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
imageMemXfer->Memory.TheMem = (char *)transferBuffer;
|
|
Toshihiro Shimizu |
890ddd |
imageMemXfer->Memory.Length = setup.Preferred;
|
|
Toshihiro Shimizu |
890ddd |
imageMemXfer->Memory.Flags = TWMF_APPOWNS | TWMF_POINTER;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.pendingXfers.Count = 0;
|
|
Toshihiro Shimizu |
890ddd |
/* transfer the data -- loop until done or canceled */
|
|
Toshihiro Shimizu |
890ddd |
nTransferDone = 0;
|
|
Toshihiro Shimizu |
890ddd |
do {
|
|
Toshihiro Shimizu |
890ddd |
rc3 = TTWAIN_DS(DG_IMAGE, DAT_IMAGEMEMXFER, MSG_GET, (TW_MEMREF)imageMemXfer);
|
|
Toshihiro Shimizu |
890ddd |
nTransferDone++;
|
|
Toshihiro Shimizu |
890ddd |
switch (rc3) {
|
|
Toshihiro Shimizu |
890ddd |
CASE TWRC_SUCCESS : PRINTF("IMAGEMEMXFER, GET, returns SUCCESS\n");
|
|
Toshihiro Shimizu |
890ddd |
if (imgInfoOk) {
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 colsToCopy;
|
|
Toshihiro Shimizu |
890ddd |
rowsToCopy = MIN(imageMemXfer->Rows, rowsRemaining);
|
|
Toshihiro Shimizu |
890ddd |
colsToCopy = MIN(imageMemXfer->Columns, (unsigned long)TTwainData.transferInfo.preferredLx);
|
|
Toshihiro Shimizu |
890ddd |
bytesToCopy = CEIL(colsToCopy * pixSize);
|
|
Toshihiro Shimizu |
890ddd |
bytesToWrap = CEIL(TTwainData.transferInfo.preferredLx * pixSize);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 newMemorySize;
|
|
Toshihiro Shimizu |
890ddd |
rowsToCopy = imageMemXfer->Rows;
|
|
Toshihiro Shimizu |
890ddd |
bytesToCopy = imageMemXfer->BytesPerRow;
|
|
Toshihiro Shimizu |
890ddd |
bytesToWrap = bytesToCopy;
|
|
Toshihiro Shimizu |
890ddd |
newMemorySize = (TTwainData.transferInfo.preferredLy + imageMemXfer->Rows) * imageMemXfer->BytesPerRow;
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.memorySize < newMemorySize) {
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.memoryBuffer = (UCHAR *)realloc(TTwainData.transferInfo.memoryBuffer, newMemorySize);
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.memorySize = newMemorySize;
|
|
Toshihiro Shimizu |
890ddd |
targetBuffer = TTwainData.transferInfo.memoryBuffer + (TTwainData.transferInfo.preferredLy * imageMemXfer->BytesPerRow);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLy += rowsToCopy;
|
|
Toshihiro Shimizu |
890ddd |
if ((int)imageMemXfer->Columns > TTwainData.transferInfo.preferredLx)
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLx = imageMemXfer->Columns;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
sourceBuffer = (UCHAR *)imageMemXfer->Memory.TheMem;
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.nextImageNeedsToBeInverted)
|
|
Toshihiro Shimizu |
890ddd |
INVERT_BYTE(sourceBuffer, bytesToCopy)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (rows = 0; rows < rowsToCopy; rows++) {
|
|
Toshihiro Shimizu |
890ddd |
memcpy(targetBuffer, sourceBuffer, bytesToCopy);
|
|
Toshihiro Shimizu |
890ddd |
targetBuffer += bytesToWrap;
|
|
Toshihiro Shimizu |
890ddd |
sourceBuffer += imageMemXfer->BytesPerRow;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
rowsRemaining -= rowsToCopy;
|
|
Toshihiro Shimizu |
890ddd |
CASE TWRC_XFERDONE : PRINTF("IMAGEMEMXFER, GET, returns XFERDONE\n");
|
|
Toshihiro Shimizu |
890ddd |
/*copy the last transfer data*/
|
|
Toshihiro Shimizu |
890ddd |
if (imgInfoOk) {
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 colsToCopy;
|
|
Toshihiro Shimizu |
890ddd |
rowsToCopy = MIN(imageMemXfer->Rows, rowsRemaining);
|
|
Toshihiro Shimizu |
890ddd |
colsToCopy = MIN(imageMemXfer->Columns, (unsigned long)TTwainData.transferInfo.preferredLx);
|
|
Toshihiro Shimizu |
890ddd |
bytesToCopy = CEIL(colsToCopy * pixSize);
|
|
Toshihiro Shimizu |
890ddd |
bytesToWrap = CEIL(TTwainData.transferInfo.preferredLx * pixSize);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT32 newMemorySize;
|
|
Toshihiro Shimizu |
890ddd |
rowsToCopy = imageMemXfer->Rows;
|
|
Toshihiro Shimizu |
890ddd |
bytesToCopy = imageMemXfer->BytesPerRow;
|
|
Toshihiro Shimizu |
890ddd |
bytesToWrap = bytesToCopy;
|
|
Toshihiro Shimizu |
890ddd |
newMemorySize = (TTwainData.transferInfo.preferredLy + imageMemXfer->Rows) * imageMemXfer->BytesPerRow;
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.memorySize < newMemorySize) {
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.memoryBuffer = (UCHAR *)realloc(TTwainData.transferInfo.memoryBuffer, newMemorySize);
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.memorySize = newMemorySize;
|
|
Toshihiro Shimizu |
890ddd |
targetBuffer = TTwainData.transferInfo.memoryBuffer + (TTwainData.transferInfo.preferredLy * imageMemXfer->BytesPerRow);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLy += rowsToCopy;
|
|
Toshihiro Shimizu |
890ddd |
if ((int)imageMemXfer->Columns > TTwainData.transferInfo.preferredLx)
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLx = imageMemXfer->Columns;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
sourceBuffer = (UCHAR *)imageMemXfer->Memory.TheMem;
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.nextImageNeedsToBeInverted)
|
|
Toshihiro Shimizu |
890ddd |
INVERT_BYTE(sourceBuffer, bytesToCopy)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (rows = 0; rows < rowsToCopy; rows++) {
|
|
Toshihiro Shimizu |
890ddd |
memcpy(targetBuffer, sourceBuffer, bytesToCopy);
|
|
Toshihiro Shimizu |
890ddd |
targetBuffer += bytesToWrap;
|
|
Toshihiro Shimizu |
890ddd |
sourceBuffer += imageMemXfer->BytesPerRow;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
rowsRemaining -= rowsToCopy;
|
|
Toshihiro Shimizu |
890ddd |
PRINTF("get pending xfers\n");
|
|
Toshihiro Shimizu |
890ddd |
twRC2 = TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
|
|
Toshihiro Shimizu |
890ddd |
(TW_MEMREF)&TTwainData.transferInfo.pendingXfers);
|
|
Toshihiro Shimizu |
890ddd |
if (twRC2 != TWRC_SUCCESS) {
|
|
Toshihiro Shimizu |
890ddd |
printf("pending xfers != success");
|
|
Toshihiro Shimizu |
890ddd |
ret = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
PRINTF(" pending count = %d\n", TTwainData.transferInfo.pendingXfers.Count);
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.pendingXfers.Count == 0) {
|
|
Toshihiro Shimizu |
890ddd |
ret = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.pendingXfers.Count == 0xffff) {
|
|
Toshihiro Shimizu |
890ddd |
ret = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.pendingXfers.Count == 0xfffe) {
|
|
Toshihiro Shimizu |
890ddd |
ret = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
ret = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
CASE TWRC_CANCEL : TTWAIN_RecordError();
|
|
Toshihiro Shimizu |
890ddd |
twRC2 = TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
|
|
Toshihiro Shimizu |
890ddd |
(TW_MEMREF)&TTwainData.transferInfo.pendingXfers);
|
|
Toshihiro Shimizu |
890ddd |
if (twRC2 != TWRC_SUCCESS) {
|
|
Toshihiro Shimizu |
890ddd |
ret = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.pendingXfers.Count == 0) {
|
|
Toshihiro Shimizu |
890ddd |
ret = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
CASE TWRC_FAILURE : PRINTF("IMAGEMEMXFER, GET, returns FAILURE\n");
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_RecordError();
|
|
Toshihiro Shimizu |
890ddd |
twRC2 = TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
|
|
Toshihiro Shimizu |
890ddd |
(TW_MEMREF)&TTwainData.transferInfo.pendingXfers);
|
|
Toshihiro Shimizu |
890ddd |
if (twRC2 != TWRC_SUCCESS) {
|
|
Toshihiro Shimizu |
890ddd |
ret = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.pendingXfers.Count == 0) {
|
|
Toshihiro Shimizu |
890ddd |
ret = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
DEFAULT:
|
|
Toshihiro Shimizu |
890ddd |
PRINTF("IMAGEMEMXFER, GET, returns ?!? Default handler called\n");
|
|
Toshihiro Shimizu |
890ddd |
/* Abort the image */
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_RecordError();
|
|
Toshihiro Shimizu |
890ddd |
twRC2 = TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
|
|
Toshihiro Shimizu |
890ddd |
(TW_MEMREF)&TTwainData.transferInfo.pendingXfers);
|
|
Toshihiro Shimizu |
890ddd |
if (twRC2 != TWRC_SUCCESS) {
|
|
Toshihiro Shimizu |
890ddd |
ret = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.transferInfo.pendingXfers.Count == 0) {
|
|
Toshihiro Shimizu |
890ddd |
ret = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
goto done;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} while (rc3 == TWRC_SUCCESS);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
done:
|
|
Toshihiro Shimizu |
890ddd |
if (ret == TRUE) {
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.callback.onDoneCb) {
|
|
Toshihiro Shimizu |
890ddd |
float xdpi, ydpi;
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_PIXTYPE pixType;
|
|
Toshihiro Shimizu |
890ddd |
xdpi = TTWAIN_Fix32ToFloat(info.XResolution);
|
|
Toshihiro Shimizu |
890ddd |
ydpi = TTWAIN_Fix32ToFloat(info.YResolution);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (imgInfoOk) {
|
|
Toshihiro Shimizu |
890ddd |
xdpi = TTWAIN_Fix32ToFloat(info.XResolution);
|
|
Toshihiro Shimizu |
890ddd |
ydpi = TTWAIN_Fix32ToFloat(info.YResolution);
|
|
Toshihiro Shimizu |
890ddd |
switch (BB(info.PixelType, info.BitsPerPixel)) {
|
|
Toshihiro Shimizu |
890ddd |
CASE BB(TWPT_BW, 1) : pixType = TTWAIN_BW;
|
|
Toshihiro Shimizu |
890ddd |
CASE BB(TWPT_GRAY, 8) : pixType = TTWAIN_GRAY8;
|
|
Toshihiro Shimizu |
890ddd |
CASE BB(TWPT_RGB, 24) : pixType = TTWAIN_RGB24;
|
|
Toshihiro Shimizu |
890ddd |
DEFAULT:
|
|
Toshihiro Shimizu |
890ddd |
pixType = TTWAIN_RGB24;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
float lx = TTWAIN_Fix32ToFloat(imageLayout.Frame.Right) - TTWAIN_Fix32ToFloat(imageLayout.Frame.Left);
|
|
Toshihiro Shimizu |
890ddd |
float ly = TTWAIN_Fix32ToFloat(imageLayout.Frame.Bottom) - TTWAIN_Fix32ToFloat(imageLayout.Frame.Top);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
xdpi = (float)TTwainData.transferInfo.preferredLx / lx;
|
|
Toshihiro Shimizu |
890ddd |
ydpi = (float)TTwainData.transferInfo.preferredLy / ly;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TW_UINT16 rc = TTWAIN_GetCurrentPixelType(&pixType);
|
|
Toshihiro Shimizu |
890ddd |
printf("get cur pix type %s\n", (rc==TWRC_SUCCESS)?"OK":"FAIL");
|
|
Toshihiro Shimizu |
890ddd |
if (rc == TWRC_SUCCESS)
|
|
Toshihiro Shimizu |
890ddd |
switch (pixType)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
CASE TWPT_BW : pixType = TTWAIN_BW;
|
|
Toshihiro Shimizu |
890ddd |
CASE TWPT_GRAY: pixType = TTWAIN_GRAY8;
|
|
Toshihiro Shimizu |
890ddd |
CASE TWPT_RGB : pixType = TTWAIN_RGB24;
|
|
Toshihiro Shimizu |
890ddd |
DEFAULT : pixType = TTWAIN_RGB24;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
pixType = TTWAIN_RGB24;
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
switch (imageMemXfer->BytesPerRow / TTwainData.transferInfo.preferredLx) {
|
|
Toshihiro Shimizu |
890ddd |
case 1:
|
|
Toshihiro Shimizu |
890ddd |
pixType = TTWAIN_GRAY8;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case 3:
|
|
Toshihiro Shimizu |
890ddd |
pixType = TTWAIN_RGB24;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
default: {
|
|
Toshihiro Shimizu |
890ddd |
double b = (imageMemXfer->BytesPerRow /
|
|
Toshihiro Shimizu |
890ddd |
(double)TTwainData.transferInfo.preferredLx);
|
|
Toshihiro Shimizu |
890ddd |
if ((b >= 0.125) && (b < 8))
|
|
Toshihiro Shimizu |
890ddd |
pixType = TTWAIN_BW;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
printf("unable to det pix type assume RGB24\n");
|
|
Toshihiro Shimizu |
890ddd |
pixType = TTWAIN_RGB24;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
stopScanning = !TTwainData.callback.onDoneCb(
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.memoryBuffer,
|
|
Toshihiro Shimizu |
890ddd |
pixType,
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLx,
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLy,
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.preferredLx,
|
|
Toshihiro Shimizu |
890ddd |
xdpi, ydpi,
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.callback.onDoneArg);
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
PRINTF("stopScanning = %d\n", stopScanning);
|
|
Toshihiro Shimizu |
890ddd |
exitTwainSession();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else /*ret == FALSE*/
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.callback.onErrorCb) {
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.callback.onErrorCb(TTwainData.callback.onErrorArg, 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (imageMemXferH) {
|
|
Toshihiro Shimizu |
890ddd |
GLOBAL_UNLOCK(imageMemXferH);
|
|
Toshihiro Shimizu |
890ddd |
GLOBAL_FREE(imageMemXferH);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (transferBufferH) {
|
|
Toshihiro Shimizu |
890ddd |
GLOBAL_UNLOCK(transferBuffer);
|
|
Toshihiro Shimizu |
890ddd |
GLOBAL_FREE(transferBufferH);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return ret && !stopScanning;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
int TTWAIN_InitVar(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
char *c;
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.initDone)
|
|
Toshihiro Shimizu |
890ddd |
return TRUE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.DSM_Entry = 0;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.hwnd32SM = 0;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.twainAvailable = AVAIABLE_DONTKNOW;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.breakModalLoop = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.UIStatus = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.twainState = TWAIN_PRESESSION;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.hDib = 0;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.transferInfo.multiTransfer = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.supportedCaps = 0;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.resultCode = 0;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.ErrRC = 0;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.ErrCC = 0;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.modalStatus = FALSE;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.Id = 0;
|
|
Toshihiro Shimizu |
890ddd |
TTWAIN_ConvertRevStrToRevNum(RELEASE_STR, &TTwainData.appId.Version.MajorNum,
|
|
Toshihiro Shimizu |
890ddd |
&TTwainData.appId.Version.MinorNum);
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.Version.Language = TWLG_USA;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.Version.Country = TWCY_USA;
|
|
Toshihiro Shimizu |
890ddd |
strcpy((char *)TTwainData.appId.Version.Info, TITLEBAR_STR);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.ProtocolMajor = TWON_PROTOCOLMAJOR;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.ProtocolMinor = TWON_PROTOCOLMINOR;
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.appId.SupportedGroups = DG_IMAGE | DG_CONTROL;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
c = (char *)TTwainData.appId.Manufacturer;
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
*c = strlen(COMPANY);
|
|
Toshihiro Shimizu |
890ddd |
c++;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
strcpy(c, COMPANY);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
c = (char *)TTwainData.appId.ProductFamily;
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
*c = strlen(PRODUCT);
|
|
Toshihiro Shimizu |
890ddd |
c++;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
strcpy(c, PRODUCT);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
c = (char *)TTwainData.appId.ProductName;
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
*c = strlen(TwProgramName);
|
|
Toshihiro Shimizu |
890ddd |
c++;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
strcpy(c, TwProgramName);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.initDone = TRUE;
|
|
Toshihiro Shimizu |
890ddd |
return TRUE;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
static void TTWAIN_FreeVar(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (TTwainData.supportedCaps) {
|
|
Toshihiro Shimizu |
890ddd |
/* MEMORY LEAK !
|
|
Toshihiro Shimizu |
890ddd |
GLOBAL_FREE(TTwainData.supportedCaps);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
TTwainData.supportedCaps = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*---------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef __cplusplus
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|