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