/* * closeDS * * Close the datasource associated with the * specified session. */ int closeDS(pTW_SESSION twSession) { /* Can't close a closed data source */ if (DS_IS_CLOSED(twSession)) { LogMessage("closeDS: Data source already closed\n"); return TRUE; } /* Open the TWAIN datasource */ twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, (TW_MEMREF) DS_IDENTITY(twSession)); /* Check the return to determine what the user decided * to do. */ switch (twSession->twRC) { case TWRC_SUCCESS: /* We are now in TWAIN state 3 */ twSession->twainState = 3; LogMessage("Data source %s closed\n", DS_IDENTITY(twSession)->ProductName); return TRUE; break; default: LogMessage("Error \"%s\" closing data source\n", currentTwainError(twSession)); break; } return FALSE; }
/* * transferImage * * The Source indicated it is ready to transfer data. It is * waiting for the application to inquire about the image details, * initiate the actual transfer, and, hence, transition the session * from State 6 to 7. Return the reason for exiting the transfer. */ static void transferImage(pTW_SESSION twSession, pTW_IMAGEINFO imageInfo) { TW_SETUPMEMXFER setupMemXfer; TW_IMAGEMEMXFER imageMemXfer; char *buffer; /* Clear our structures */ memset(&setupMemXfer, 0, sizeof(TW_SETUPMEMXFER)); memset(&imageMemXfer, 0, sizeof(TW_IMAGEMEMXFER)); /* Find out how the source would like to transfer... */ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_CONTROL, DAT_SETUPMEMXFER, MSG_GET, (TW_MEMREF) &setupMemXfer); /* Allocate the buffer for the transfer */ buffer = g_new (char, setupMemXfer.Preferred); imageMemXfer.Memory.Flags = TWMF_APPOWNS | TWMF_POINTER; imageMemXfer.Memory.Length = setupMemXfer.Preferred; imageMemXfer.Memory.TheMem = (TW_MEMREF) buffer; /* Get the data */ do { /* Setup for the memory transfer */ imageMemXfer.Compression = TWON_DONTCARE16; imageMemXfer.BytesPerRow = TWON_DONTCARE32; imageMemXfer.Columns = TWON_DONTCARE32; imageMemXfer.Rows = TWON_DONTCARE32; imageMemXfer.XOffset = TWON_DONTCARE32; imageMemXfer.YOffset = TWON_DONTCARE32; imageMemXfer.BytesWritten = TWON_DONTCARE32; /* Get the next block of memory */ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_IMAGE, DAT_IMAGEMEMXFER, MSG_GET, (TW_MEMREF) &imageMemXfer); if ((twSession->twRC == TWRC_SUCCESS) || (twSession->twRC == TWRC_XFERDONE)) { /* Call the callback function */ if (!(*twSession->transferFunctions->txfrDataCb) ( imageInfo, &imageMemXfer, twSession->clientData)) { /* Callback function requested to cancel */ twSession->twRC = TWRC_CANCEL; break; } } } while (twSession->twRC == TWRC_SUCCESS); /* Free the memory buffer */ g_free (imageMemXfer.Memory.TheMem); }
/* * openDS * * Open a data source using the TWAIN user interface. */ int openDS(pTW_SESSION twSession) { TW_IDENTITY *dsIdentity; /* The datasource manager must be open */ if (DSM_IS_CLOSED(twSession)) { LogMessage("openDS: Cannot open data source... manager closed\n"); return FALSE; } /* Is the data source already open? */ if (DS_IS_OPEN(twSession)) { LogMessage("openDS: Data source already open\n"); return TRUE; } /* Open the TWAIN datasource */ dsIdentity = DS_IDENTITY(twSession); twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, (TW_MEMREF) dsIdentity); /* Check the return to determine what the user decided * to do. */ switch (twSession->twRC) { case TWRC_SUCCESS: /* We are now in TWAIN state 4 */ twSession->twainState = 4; LogMessage("Data source %s opened\n", DS_IDENTITY(twSession)->ProductName); LogMessage("\tVersion.MajorNum = %d\n", dsIdentity->Version.MajorNum); LogMessage("\tVersion.MinorNum = %d\n", dsIdentity->Version.MinorNum); LogMessage("\tVersion.Info = %s\n", dsIdentity->Version.Info); LogMessage("\tProtocolMajor = %d\n", dsIdentity->ProtocolMajor); LogMessage("\tProtocolMinor = %d\n", dsIdentity->ProtocolMinor); LogMessage("\tManufacturer = %s\n", dsIdentity->Manufacturer); LogMessage("\tProductFamily = %s\n", dsIdentity->ProductFamily); return TRUE; break; default: LogMessage("Error \"%s\" opening data source\n", currentTwainError(twSession)); break; } return FALSE; }
/* * beginImageTransfer * * Begin an image transfer. */ static int beginImageTransfer(pTW_SESSION twSession, pTW_IMAGEINFO imageInfo) { /* Clear our structures */ memset(imageInfo, 0, sizeof(TW_IMAGEINFO)); /* Query the image information */ twSession->twRC = callDSM( APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_IMAGE, DAT_IMAGEINFO, MSG_GET, (TW_MEMREF) imageInfo); /* Check the return code */ if (twSession->twRC != TWRC_SUCCESS) { LogMessage("Get Image Info failure - %s\n", currentTwainError(twSession)); return FALSE; } /* Call the begin transfer callback if registered */ if (twSession->transferFunctions->txfrBeginCb) if (!(*twSession->transferFunctions->txfrBeginCb)(imageInfo, twSession->clientData)) return FALSE; /* We should continue */ return TRUE; }
/* * disableDS * * Disable the datasource associated with twSession. */ int disableDS(pTW_SESSION twSession) { TW_USERINTERFACE ui; /* Verify the datasource is enabled */ if (DS_IS_DISABLED(twSession)) { LogMessage("disableDS: Data source not enabled\n"); return TRUE; } /* Set the UI information */ ui.ShowUI = TRUE; ui.ModalUI = TRUE; ui.hParent = twSession->hwnd; /* Make the call to the source manager */ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, (TW_MEMREF) &ui); if (twSession->twRC == TWRC_SUCCESS) { /* We are now at a new twain state */ twSession->twainState = 4; return TRUE; } else { LogMessage("Error during data source disable\n"); return FALSE; } }
/* * setBufferedXfer */ static int setBufferedXfer(pTW_SESSION twSession) { TW_CAPABILITY bufXfer; pTW_ONEVALUE pvalOneValue; /* Make sure the data source is open first */ if (DS_IS_CLOSED(twSession)) return FALSE; /* Create the capability information */ bufXfer.Cap = ICAP_XFERMECH; bufXfer.ConType = TWON_ONEVALUE; bufXfer.hContainer = twainAllocHandle(sizeof(TW_ONEVALUE)); pvalOneValue = (pTW_ONEVALUE) twainLockHandle(bufXfer.hContainer); pvalOneValue->ItemType = TWTY_UINT16; pvalOneValue->Item = TWSX_MEMORY; twainUnlockHandle(bufXfer.hContainer); /* Make the call to the source manager */ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_CONTROL, DAT_CAPABILITY, MSG_SET, (TW_MEMREF) &bufXfer); /* Free the container */ twainFreeHandle(bufXfer.hContainer); /* Let the caller know what happened */ return (twSession->twRC==TWRC_SUCCESS); }
/* * TwainProcessMessage * * Returns TRUE if the application should process message as usual. * Returns FALSE if the application should skip processing of this message */ int TwainProcessMessage(LPMSG lpMsg, pTW_SESSION twSession) { TW_EVENT twEvent; twSession->twRC = TWRC_NOTDSEVENT; /* Only ask Source Manager to process event if there is a Source connected. */ if (DSM_IS_OPEN(twSession) && DS_IS_OPEN(twSession)) { /* * A Source provides a modeless dialog box as its user interface. * The following call relays Windows messages down to the Source's * UI that were intended for its dialog box. It also retrieves TWAIN * messages sent from the Source to our Application. */ twEvent.pEvent = (TW_MEMREF) lpMsg; twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, (TW_MEMREF) &twEvent); /* Check the return code */ if (twSession->twRC == TWRC_NOTDSEVENT) { return FALSE; } /* Process the message as necessary */ processTwainMessage(twEvent.TWMessage, twSession); } /* tell the caller what happened */ return (twSession->twRC == TWRC_DSEVENT); }
/* * cancelPendingTransfers * * Cancel all pending image transfers. */ void cancelPendingTransfers(pTW_SESSION twSession) { TW_PENDINGXFERS pendingXfers; twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET, (TW_MEMREF) &pendingXfers); }
/* * currentTwainError * * Return the current TWAIN error message. */ char * currentTwainError(pTW_SESSION twSession) { TW_STATUS twStatus; /* Get the current status code from the DSM */ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_CONTROL, DAT_STATUS, MSG_GET, (TW_MEMREF) &twStatus); /* Return the mapped error code */ return twainError(twStatus.ConditionCode); }
/* * endPendingTransfer * * Cancel the currently pending transfer. * Return the count of pending transfers. */ static int endPendingTransfer(pTW_SESSION twSession) { TW_PENDINGXFERS pendingXfers; twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, (TW_MEMREF) &pendingXfers); if (!pendingXfers.Count) twSession->twainState = 5; return pendingXfers.Count; }
/* * selectDS * * Select a datasource using the TWAIN user * interface. */ int selectDS(pTW_SESSION twSession) { /* The datasource manager must be open */ if (DSM_IS_CLOSED(twSession)) { LogMessage("Can't select data source with closed source manager\n"); return FALSE; } /* Ask TWAIN to present the source select dialog */ twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, (TW_MEMREF) DS_IDENTITY(twSession)); /* Check the return to determine what the user decided * to do. */ switch (twSession->twRC) { case TWRC_SUCCESS: LogMessage("Data source %s selected\n", DS_IDENTITY(twSession)->ProductName); return TRUE; break; case TWRC_CANCEL: LogMessage("User cancelled TWAIN source selection\n"); break; case TWRC_FAILURE: default: LogMessage("Error \"%s\" during TWAIN source selection\n", currentTwainError(twSession)); break; } return FALSE; }
/* * selectDefaultDS * * Select the default datasource. */ int selectDefaultDS(pTW_SESSION twSession) { /* The datasource manager must be open */ if (DSM_IS_CLOSED(twSession)) { LogMessage("Can't select data source with closed source manager\n"); return FALSE; } /* Ask TWAIN to present the source select dialog */ twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, (TW_MEMREF) DS_IDENTITY(twSession)); /* Check the return code */ return (twSession->twRC == TWRC_SUCCESS); }
/* * requestImageAcquire * * Request that the acquire user interface * be displayed. This may or may not cause * an image to actually be transferred. */ int requestImageAcquire(pTW_SESSION twSession, gboolean showUI) { /* Make sure in the correct state */ if (DS_IS_CLOSED(twSession)) { LogMessage("Can't acquire image with closed datasource\n"); return FALSE; } twainSetupCallback(twSession); /* Set the transfer mode */ if (setBufferedXfer(twSession)) { TW_USERINTERFACE ui; /* Set the UI information */ ui.ShowUI = TRUE; ui.ModalUI = TRUE; /* In Windows, the callbacks are sent to the window message handler */ ui.hParent = twSession->hwnd; /* Make the call to the source manager */ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, (TW_MEMREF) &ui); if (twSession->twRC == TWRC_SUCCESS) { /* We are now at a new twain state */ twSession->twainState = 5; return TRUE; } else { LogMessage("Error during data source enable\n"); return FALSE; } } else { LogMessage("Unable to set buffered transfer mode: %s\n", currentTwainError(twSession)); return FALSE; } }
/* * unloadTwainLibrary * * Unload the TWAIN dynamic link library */ int unloadTwainLibrary(pTW_SESSION twSession) { /* Explicitly free the SM library */ if (hDLL) { FreeLibrary(hDLL); hDLL=NULL; } /* the data source id will no longer be valid after * twain is killed. If the id is left around the * data source can not be found or opened */ DS_IDENTITY(twSession)->Id = 0; /* We are now back at state 1 */ twSession->twainState = 1; LogMessage("Source Manager successfully closed\n"); return TRUE; }