[gimp/bug-357818: 7/10] Bug 357818 - TWAIN plug-in - Enabled TWAIN 64 Bit support on Windows.



commit dc39fe7d799d43bacf2fc8c85b9c5a20f5bbb3a5
Author: Jens M. Plonka <jens plonka gmx de>
Date:   Fri Jun 3 02:14:14 2016 +0200

    Bug 357818 - TWAIN plug-in - Enabled TWAIN 64 Bit support on Windows.
    
    Adapted to 2.8 by Dieter Verfaillie <dieterv optionexplicit be>
    Applying a slightly changed patch to accommodate for the code changes since the original patch had been 
made.

 plug-ins/twain/tw_func.c     |  193 ++++++++++--------------------------------
 plug-ins/twain/tw_func.h     |  118 ++++++++++++++++++++------
 plug-ins/twain/tw_local.h    |   42 +++++-----
 plug-ins/twain/tw_platform.h |   42 +++++++--
 plug-ins/twain/tw_util.c     |    5 +
 plug-ins/twain/tw_util.h     |    7 ++
 plug-ins/twain/tw_win.c      |   66 +++++++++------
 plug-ins/twain/tw_win.h      |    4 +-
 plug-ins/twain/twain.c       |   86 +++++++------------
 9 files changed, 278 insertions(+), 285 deletions(-)
---
diff --git a/plug-ins/twain/tw_func.c b/plug-ins/twain/tw_func.c
index 52035ee..94eb686 100644
--- a/plug-ins/twain/tw_func.c
+++ b/plug-ins/twain/tw_func.c
@@ -8,6 +8,10 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
+ * Added for Win x64 support
+ * Jens M. Plonka <jens plonka gmx de>
+ * 11/25/2011
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
@@ -57,6 +61,7 @@
  *  (03/31/99)  v0.5   Added support for multi-byte samples and paletted
  *                     images.
  *  (07/23/04)  v0.6   Added Mac OS X support.
+ *  (11/25/11)  v0.7   Added Win x64 support.
  */
 
 #include "config.h"
@@ -104,32 +109,6 @@ static char *twainErrors[] =
 };
 
 /*
- * FloatToFix32
- *
- * Convert a floating point value into a FIX32.
- */
-TW_FIX32 FloatToFIX32(float floater)
-{
-  TW_FIX32 Fix32_value;
-  TW_INT32 value = (TW_INT32) (floater * 65536.0 + 0.5);
-  Fix32_value.Whole = value >> 16;
-  Fix32_value.Frac = value & 0x0000ffffL;
-  return (Fix32_value);
-}
-
-/*
- * Fix32ToFloat
- *
- * Convert a FIX32 value into a floating point value.
- */
-float FIX32ToFloat(TW_FIX32 fix32)
-{
-  float floater;
-  floater = (float) fix32.Whole + (float) fix32.Frac / 65536.0;
-  return floater;
-}
-
-/*
  * twainError
  *
  * Return the TWAIN error message associated
@@ -166,9 +145,7 @@ 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);
+  twSession->twRC = DSM_GET_STATUS(twSession, twStatus);
 
   /* Return the mapped error code */
   return twainError (twStatus.ConditionCode);
@@ -230,9 +207,7 @@ openDSM (pTW_SESSION twSession)
   }
 
   /* Open the data source manager */
-  twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
-      DG_CONTROL, DAT_PARENT, MSG_OPENDSM,
-      (TW_MEMREF) &(twSession->hwnd));
+  twSession->twRC = DSM_OPEN(twSession);
 
   /* Check the return code */
   switch (twSession->twRC)
@@ -267,9 +242,7 @@ selectDS (pTW_SESSION twSession)
   }
 
   /* 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));
+  twSession->twRC = DSM_SELECT_USER(twSession);
 
   /* Check the return to determine what the user decided
    * to do.
@@ -295,8 +268,6 @@ selectDS (pTW_SESSION twSession)
 int
 openDS (pTW_SESSION twSession)
 {
-  TW_IDENTITY *dsIdentity;
-
   /* The datasource manager must be open */
   if (DSM_IS_CLOSED(twSession))
   {
@@ -312,14 +283,11 @@ openDS (pTW_SESSION twSession)
   }
 
   /* Open the TWAIN datasource */
-  dsIdentity = DS_IDENTITY(twSession);
-  twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
-                           DG_CONTROL, DAT_IDENTITY, MSG_OPENDS,
-                           (TW_MEMREF) dsIdentity);
+  twSession->twRC = DSM_OPEN_DS(twSession);
 
   /* Check the return to determine what the user decided
    * to do.
-        */
+   */
   switch (twSession->twRC)
   {
     case TWRC_SUCCESS:
@@ -366,9 +334,7 @@ setBufferedXfer (pTW_SESSION twSession)
   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);
+  twSession->twRC = DSM_XFER_SET(twSession, bufXfer);
   if (twSession->twRC == TWRC_FAILURE)
   {
     log_message ("Could not set capability: %s\n", currentTwainError(twSession));
@@ -409,18 +375,19 @@ requestImageAcquire (pTW_SESSION twSession, gboolean showUI)
     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);
+    twSession->twRC = DSM_ENABLE_DS(twSession, ui);
 
-    if (twSession->twRC == TWRC_SUCCESS)
+    switch (twSession->twRC)
     {
-      /* We are now at a new twain state */
-      twSession->twainState = 5;
+      case TWRC_SUCCESS:
+        /* We are now at a new twain state */
+        twSession->twainState = 5;
+        return TRUE;
 
-      return TRUE;
+         case TWRC_FAILURE:
+       log_message ("Error enabeling data source: %s\n", currentTwainError(twSession));
+          break;
     }
-    log_message ("Error enabeling data source: %s\n", currentTwainError(twSession));
   }
   return FALSE;
 }
@@ -440,22 +407,20 @@ disableDS(pTW_SESSION twSession)
     return;
   }
 
-    /* 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);
+  /* Make the call to the source manager */
+  twSession->twRC = DSM_DISABLE_DS(twSession, ui);
 
-    switch (twSession->twRC)
-    {
-      case TWRC_SUCCESS:
-        /* We are now at a new twain state */
-        twSession->twainState = 4;
-               break;
+  switch (twSession->twRC)
+  {
+    case TWRC_SUCCESS:
+      /* We are now at a new twain state */
+      twSession->twainState = 4;
+    break;
 
-      case TWRC_FAILURE:
-        log_message  ("Can't disable data source: %s\n", currentTwainError(twSession));
-               break;
-    }
+    case TWRC_FAILURE:
+      log_message  ("Can't disable data source: %s\n", currentTwainError(twSession));
+      break;
+  }
 }
 
 /*
@@ -475,9 +440,7 @@ closeDS (pTW_SESSION twSession)
   }
 
   /* Open the TWAIN datasource */
-  twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
-                           DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS,
-                           (TW_MEMREF) DS_IDENTITY(twSession));
+  twSession->twRC = DSM_CLOSE_DS(twSession);
 
   /* Check the return to determine what the user decided
    * to do.
@@ -509,9 +472,7 @@ closeDSM (pTW_SESSION twSession)
   }
   else
   {
-    twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
-                               DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM,
-                               (TW_MEMREF)&(twSession->hwnd));
+    twSession->twRC = DSM_CLOSE(twSession);
 
     switch (twSession->twRC)
     {
@@ -539,10 +500,7 @@ beginImageTransfer (pTW_SESSION twSession, pTW_IMAGEINFO imageInfo)
   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);
+  twSession->twRC = DSM_GET_IMAGE(twSession, imageInfo);
 
   /* Check the return code */
   switch (twSession->twRC)
@@ -585,9 +543,7 @@ transferImage (pTW_SESSION twSession, pTW_IMAGEINFO imageInfo)
   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);
+  twSession->twRC = DSM_XFER_START(twSession, setupMemXfer);
 
   /* Allocate the buffer for the transfer */
   buffer = g_new (char, setupMemXfer.Preferred);
@@ -608,18 +564,13 @@ transferImage (pTW_SESSION twSession, pTW_IMAGEINFO imageInfo)
     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);
+    twSession->twRC = DSM_XFER_GET(twSession, imageMemXfer);
 
     if ((twSession->twRC == TWRC_SUCCESS) ||
         (twSession->twRC == TWRC_XFERDONE))
     {
-      /* Call the callback function */
-      if (!(*twSession->transferFunctions->txfrDataCb) (
-                                                       imageInfo,
-                                                       &imageMemXfer,
-                                                       twSession->clientData))
+      /* Call dataTransferCallback */
+      if (!CB_XFER_DATA(twSession, imageInfo, imageMemXfer))
       {
         /* Callback function requested to cancel */
         twSession->twRC = TWRC_CANCEL;
@@ -643,9 +594,7 @@ 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);
+  twSession->twRC = DSM_XFER_STOP(twSession, pendingXfers);
 
   if (!pendingXfers.Count)
   {
@@ -665,9 +614,7 @@ 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);
+  twSession->twRC = DSM_XFER_RESET(twSession, pendingXfers);
 }
 
 /*
@@ -699,13 +646,8 @@ endImageTransfer (pTW_SESSION twSession, int *pendingCount)
   }
 
   /* Call the end transfer callback */
-  if (twSession->transferFunctions->txfrEndCb)
-  {
-    continueTransfers =
-      (*twSession->transferFunctions->txfrEndCb) (exitCode,
-                                                *pendingCount,
-                                                twSession->clientData);
-  }
+  CB_XFER_END(twSession, continueTransfers, exitCode, pendingCount);
+
   return (*pendingCount && continueTransfers);
 }
 
@@ -724,7 +666,7 @@ transferImages (pTW_SESSION twSession)
   /* Check the image transfer callback function
    * before even attempting to do the transfer
    */
-  if (!twSession->transferFunctions || !twSession->transferFunctions->txfrDataCb)
+  if (!twSession || !twSession->transferFunctions || !twSession->transferFunctions->txfrDataCb)
   {
     log_message ("Attempting image transfer without callback function.\n");
     return;
@@ -736,7 +678,7 @@ transferImages (pTW_SESSION twSession)
    */
   if (twSession->transferFunctions->preTxfrCb)
   {
-    (*twSession->transferFunctions->preTxfrCb)(twSession->clientData);
+    CB_XFER_PRE(twSession);
   }
 
   /* Loop through the available images */
@@ -760,11 +702,7 @@ transferImages (pTW_SESSION twSession)
    * Inform our application that we are done
    * transferring images.
    */
-  if (twSession->transferFunctions->postTxfrCb)
-  {
-    (*twSession->transferFunctions->postTxfrCb) (pendingCount,
-                                               twSession->clientData);
-  }
+  CB_XFER_POST(twSession, pendingCount);
 }
 
 void
@@ -829,42 +767,3 @@ newSession (pTW_IDENTITY appIdentity)
 
   return session;
 }
-
-/*
- * registerWindowHandle
- *
- * Register the window handle to be used for this
- * session.
- */
-void
-registerWindowHandle(pTW_SESSION session, TW_HANDLE hwnd)
-{
-  session->hwnd = hwnd;
-}
-
-/*
- * registerTransferCallback
- *
- * Register the callback to use when transferring
- * image data.
- */
-void
-registerTransferCallbacks(pTW_SESSION session,
-                         pTXFR_CB_FUNCS txfrFuncs,
-                         void *clientData)
-{
-  session->transferFunctions = txfrFuncs;
-  session->clientData = clientData;
-}
-
-/*
- * setClientData
- *
- * Set the client data associated with the specified
- * TWAIN session.
- */
-void
-setClientData(pTW_SESSION session, void *clientData)
-{
-  session->clientData = clientData;
-}
diff --git a/plug-ins/twain/tw_func.h b/plug-ins/twain/tw_func.h
index f575530..1fbc2ee 100644
--- a/plug-ins/twain/tw_func.h
+++ b/plug-ins/twain/tw_func.h
@@ -8,6 +8,10 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
+ * Added for Win x64 support
+ * Jens M. Plonka <jens plonka gmx de>
+ * 11/25/2011
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
@@ -57,6 +61,7 @@
  *  (03/31/99)  v0.5   Added support for multi-byte samples and paletted
  *                     images.
  *  (07/23/04)  v0.6   Added Mac OS X support.
+ *  (11/25/11)  v0.7   Added Win x64 support.
  */
 
 #ifndef _TW_FUNC_H
@@ -183,25 +188,100 @@ typedef struct _TWAIN_SESSION {
 
 } TW_SESSION, *pTW_SESSION;
 
+#define CB_XFER_PRE(s) if (s->transferFunctions->preTxfrCb) \
+    (*s->transferFunctions->preTxfrCb) (s->clientData);
+
+#define CB_XFER_BEGIN(s, i)   if (s->transferFunctions->txfrBeginCb) \
+    if (!(*s->transferFunctions->txfrBeginCb) (imageInfo, s->clientData)) \
+      return FALSE; \
+  return TRUE;
+
+#define CB_XFER_DATA(s, i, m) (*s->transferFunctions->txfrDataCb) \
+    (i, &m, s->clientData)
+
+#define CB_XFER_END(s, c, e, p)   if (s->transferFunctions->txfrEndCb) \
+    c = (*s->transferFunctions->txfrEndCb) (e, *p, s->clientData)
+
+#define CB_XFER_POST(s, p) if (s->transferFunctions->postTxfrCb) \
+    (*s->transferFunctions->postTxfrCb) (p, s->clientData)
+
 /* Session structure access
  * macros
  */
-/* #define pAPP_IDENTITY(tw_session) (&(tw_session->appIdentity)) */
-#define APP_IDENTITY(tw_session) (tw_session->appIdentity)
-/* #define pDS_IDENTITY(tw_session) (&(tw_session->dsIdentity)) */
-#define DS_IDENTITY(tw_session) (tw_session->dsIdentity)
+#define APP_IDENTITY(s)   ((s == NULL) ? NULL : s->appIdentity)
+#define DS_IDENTITY(s)    ((s == NULL) ? NULL : s->dsIdentity)
 
 /* State macros... Each expects
  * a Twain Session pointer
  */
-#define TWAIN_LOADED(tw_session) (tw_session->twainState >= 2)
-#define TWAIN_UNLOADED(tw_session) (tw_session->twainState < 2)
-#define DSM_IS_OPEN(tw_session) (tw_session->twainState >= 3)
-#define DSM_IS_CLOSED(tw_session) (tw_session->twainState < 3)
-#define DS_IS_OPEN(tw_session) (tw_session->twainState >= 4)
-#define DS_IS_CLOSED(tw_session) (tw_session->twainState < 4)
-#define DS_IS_ENABLED(tw_session) (tw_session->twainState >= 5)
-#define DS_IS_DISABLED(tw_session) (tw_session->twainState < 5)
+#define TWAIN_LOADED(s)   ((s == NULL) ? FALSE : s->twainState >= 2)
+#define TWAIN_UNLOADED(s) ((s == NULL) ? TRUE  : s->twainState <  2)
+#define DSM_IS_OPEN(s)    ((s == NULL) ? FALSE : s->twainState >= 3)
+#define DSM_IS_CLOSED(s)  ((s == NULL) ? TRUE  : s->twainState <  3)
+#define DS_IS_OPEN(s)     ((s == NULL) ? FALSE : s->twainState >= 4)
+#define DS_IS_CLOSED(s)   ((s == NULL) ? TRUE  : s->twainState <  4)
+#define DS_IS_ENABLED(s)  ((s == NULL) ? FALSE : s->twainState >= 5)
+#define DS_IS_DISABLED(s) ((s == NULL) ? TRUE  : s->twainState <  5)
+
+#define DSM_GET_STATUS(ses, sta)  callDSM(ses->appIdentity, ses->dsIdentity, \
+          DG_CONTROL, DAT_STATUS, MSG_GET, (TW_MEMREF) &sta)
+
+#define DSM_OPEN(ses) callDSM(ses->appIdentity, NULL,\
+          DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF) &(ses->hwnd))
+
+#define DSM_CLOSE(ses) callDSM(ses->appIdentity, NULL,\
+          DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, (TW_MEMREF)&(ses->hwnd))
+
+#define DSM_SET_CALLBACK(ses, cb) callDSM(ses->appIdentity, NULL,\
+          DG_CONTROL, DAT_CALLBACK, MSG_REGISTER_CALLBACK, (TW_MEMREF) &cb)
+
+#define DSM_PROCESS_EVENT(ses, ev) callDSM(ses->appIdentity, ses->dsIdentity,\
+          DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, (TW_MEMREF) &ev)
+
+#define DSM_GET_PALETTE(ses, d) callDSM(ses->appIdentity, ses->dsIdentity,\
+            DG_IMAGE, DAT_PALETTE8, MSG_GET, (TW_MEMREF) d->paletteData)
+
+#define DSM_SELECT_USER(ses) callDSM(ses->appIdentity, NULL,\
+          DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, (TW_MEMREF) ses->dsIdentity)
+
+#define DSM_SELECT_DEFAULT(ses) callDSM(ses->appIdentity, NULL,\
+          DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, (TW_MEMREF) ses->dsIdentity)
+
+#define DSM_OPEN_DS(ses) callDSM(ses->appIdentity, NULL,\
+          DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, (TW_MEMREF) ses->dsIdentity)
+
+#define DSM_CLOSE_DS(ses) callDSM(ses->appIdentity, NULL,\
+          DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, (TW_MEMREF) ses->dsIdentity)
+
+#define DSM_ENABLE_DS(ses, ui) callDSM(ses->appIdentity, ses->dsIdentity,\
+          DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, (TW_MEMREF) &ui)
+
+#define DSM_DISABLE_DS(ses, ui) callDSM(ses->appIdentity, ses->dsIdentity,\
+          DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, (TW_MEMREF) &ui)
+
+#define DSM_GET_IMAGE(ses, i) callDSM(ses->appIdentity, ses->dsIdentity,\
+          DG_IMAGE, DAT_IMAGEINFO, MSG_GET, (TW_MEMREF) i)
+
+#define DSM_XFER_SET(ses, x) callDSM(ses->appIdentity, ses->dsIdentity,\
+          DG_CONTROL, DAT_CAPABILITY, MSG_SET, (TW_MEMREF) &x)
+
+#define DSM_XFER_START(ses, x) callDSM(ses->appIdentity, ses->dsIdentity,\
+          DG_CONTROL, DAT_SETUPMEMXFER, MSG_GET, (TW_MEMREF) &x)
+
+#define DSM_XFER_GET(ses, x) callDSM(ses->appIdentity, ses->dsIdentity,\
+          DG_IMAGE, DAT_IMAGEMEMXFER, MSG_GET, (TW_MEMREF) &x)
+
+#define DSM_XFER_STOP(ses, x) callDSM(ses->appIdentity, ses->dsIdentity,\
+          DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, (TW_MEMREF) &x)
+
+#define DSM_XFER_RESET(ses, x) callDSM(ses->appIdentity, ses->dsIdentity,\
+          DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET, (TW_MEMREF) &x)
+
+#define DSM_GET_FIRST_DS(ses, ds) callDSM (ses->appIdentity, NULL, \
+          DG_CONTROL, DAT_IDENTITY, MSG_GETFIRST, (TW_MEMREF) ds);
+
+#define DSM_GET_NEXT_DS(ses, ds) callDSM (ses->appIdentity, NULL, \
+          DG_CONTROL, DAT_IDENTITY, MSG_GETNEXT, (TW_MEMREF) ds);
 
 /* Function declarations */
 char *          twainError (int errorCode);
@@ -217,21 +297,7 @@ void            disableDS (pTW_SESSION twSession);
 void            closeDS (pTW_SESSION twSession);
 void            closeDSM (pTW_SESSION twSession);
 void            cancelPendingTransfers (pTW_SESSION twSession);
-
-TW_FIX32 FloatToFIX32(float);
-float           FIX32ToFloat(TW_FIX32);
-
 void            processTwainMessage (TW_UINT16 message, pTW_SESSION twSession);
-
 pTW_SESSION     newSession (pTW_IDENTITY twSession);
-void            registerWindowHandle(pTW_SESSION, TW_HANDLE);
-void            registerTransferCallbacks(pTW_SESSION, pTXFR_CB_FUNCS, void *);
-void            setClientData(pTW_SESSION session, void *clientData);
-
-#ifdef G_OS_WIN32
-void LogLastWinError(void);
-BOOL InitApplication(HINSTANCE hInstance);
-BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, pTW_SESSION twSession);
-#endif
 
 #endif /* _TW_FUNC_H */
diff --git a/plug-ins/twain/tw_local.h b/plug-ins/twain/tw_local.h
index 8e1667b..a4b47d0 100644
--- a/plug-ins/twain/tw_local.h
+++ b/plug-ins/twain/tw_local.h
@@ -8,6 +8,10 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
+ * Added for Win x64 support
+ * Jens M. Plonka <jens plonka gmx de>
+ * 11/25/2011
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
@@ -22,6 +26,17 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/*
+ * Revision history
+ *  (02/07/99)  v0.1   First working version (internal)
+ *  (02/09/99)  v0.2   First release to anyone other than myself
+ *  (02/15/99)  v0.3   Added image dump and read support for debugging
+ *  (03/31/99)  v0.5   Added support for multi-byte samples and paletted
+ *                     images.
+ *  (07/23/04)  v0.6   Added Mac OS X support.
+ *  (11/25/11)  v0.7   Added Win x64 support.
+ */
+
 #ifndef _TW_LOCAL_H
 #define _TW_LOCAL_H
 
@@ -43,12 +58,12 @@
 
 /* Functions which the platform-independent code will call */
 TW_UINT16 callDSM (
-    pTW_IDENTITY,
-    pTW_IDENTITY,
-    TW_UINT32,
-    TW_UINT16,
-    TW_UINT16,
-    TW_MEMREF);
+  pTW_IDENTITY pOrigin,
+  pTW_IDENTITY pDest,
+  TW_UINT32    DG,
+  TW_UINT16    DAT,
+  TW_UINT16    MSG,
+  TW_MEMREF    pData);
 
 int       twainIsAvailable(void);
 void      twainQuitApplication (void);
@@ -71,21 +86,6 @@ void      postTransferCallback (int, void *);
 
 extern void set_gimp_PLUG_IN_INFO_PTR(GimpPlugInInfo *);
 
-/* Data structure holding data between runs */
-/* Currently unused... Eventually may be used
- * to track dialog data.
- */
-typedef struct {
-  gchar  sourceName[34];
-  gfloat xResolution;
-  gfloat yResolution;
-  gint   xOffset;
-  gint   yOffset;
-  gint   width;
-  gint   height;
-  gint   imageType;
-} TwainValues;
-
 /* Data used to carry data between each
  * of the callback function calls.
  */
diff --git a/plug-ins/twain/tw_platform.h b/plug-ins/twain/tw_platform.h
index 7322602..e6403a8 100644
--- a/plug-ins/twain/tw_platform.h
+++ b/plug-ins/twain/tw_platform.h
@@ -4,6 +4,10 @@
  * Craig Setera <setera home com>
  * 03/31/1999
  *
+ * Added for Win x64 support
+ * Jens M. Plonka <jens plonka gmx de>
+ * 11/25/2011
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
@@ -18,33 +22,53 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/*
+ * Revision history
+ *  (02/07/99)  v0.1   First working version (internal)
+ *  (02/09/99)  v0.2   First release to anyone other than myself
+ *  (02/15/99)  v0.3   Added image dump and read support for debugging
+ *  (03/31/99)  v0.5   Added support for multi-byte samples and paletted
+ *                     images.
+ *  (07/23/04)  v0.6   Added Mac OS X support.
+ *  (11/25/11)  v0.7   Added Win x64 support.
+ */
+
 #ifndef _TW_PLATFORM_H
-#define _TW_PLATFORM_H
+  #define _TW_PLATFORM_H
 
     /* Coding style violation: Don't include headers in headers */
     #include <windows.h>
     /* Coding style violation: Don't include headers in headers */
-    #define _MSWIN_ /* Definition for TWAIN.H */  
     #include "twain.h"
 
-/* The DLL to be loaded for TWAIN support */
-#define TWAIN_DLL_NAME "TWAIN_32.DLL"
+    /* The DLL to be loaded for TWAIN support */
+    #ifdef TWH_64BIT
+      #define TWAIN_DLL_NAME "TWAINDSM.DLL"
+    #else
+      #define TWAIN_DLL_NAME "TWAIN_32.DLL"
+    #endif /* TWH_64BIT */
 
-/* Windows uses separate entry point */
-#define TWAIN_ALTERNATE_MAIN
+  /* Windows uses separate entry point */
+  #define TWAIN_ALTERNATE_MAIN
 
   /*
    * Plug-in Definitions
    */
+  #define STRINGIFY(x) #x
+  #define TOSTRING(x) STRINGIFY(x)
+
   #define PRODUCT_FAMILY      "GNU"
   #define PRODUCT_NAME        "GIMP"
   #define PLUG_IN_NAME        "TWAIN"
   #define PLUG_IN_DESCRIPTION N_("Capture an image from a TWAIN datasource")
   #define PLUG_IN_HELP        "This plug-in will capture an image from a TWAIN datasource"
-  #define PLUG_IN_AUTHOR      "Craig Setera (setera home com)"
+  #define PLUG_IN_AUTHOR      "Jens Plonka (jens plonka gmx de)"
   #define PLUG_IN_COPYRIGHT   "Craig Setera"
   #define PLUG_IN_MAJOR       0
-  #define PLUG_IN_MINOR       6
-  #define PLUG_IN_VERSION     "v0.6 (07/22/2004)"
+  #define PLUG_IN_MINOR       7
+  #define PLUG_IN_DATE        "11/25/2011"
+  #define PLUG_IN_VERSION     "v" TOSTRING(PLUG_IN_MAJOR) "." TOSTRING(PLUG_IN_MINOR) " (" PLUG_IN_DATE ")"
+  #define PLUG_IN_HINT        PRODUCT_NAME " " PLUG_IN_NAME " v" TOSTRING(PLUG_IN_MAJOR) "." 
TOSTRING(PLUG_IN_MINOR)
+
   #define MID_SELECT          "twain-acquire"
 #endif
diff --git a/plug-ins/twain/tw_util.c b/plug-ins/twain/tw_util.c
index 9b3177f..8972fce 100644
--- a/plug-ins/twain/tw_util.c
+++ b/plug-ins/twain/tw_util.c
@@ -8,6 +8,10 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
+ * Added for Win x64 support
+ * Jens M. Plonka <jens plonka gmx de>
+ * 11/25/2011
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
@@ -57,6 +61,7 @@
  *  (03/31/99)  v0.5   Added support for multi-byte samples and paletted
  *                     images.
  *  (07/23/04)  v0.6   Added Mac OS X support.
+ *  (11/25/11)  v0.7   Added Win x64 support.
  */
 
 #include "config.h"
diff --git a/plug-ins/twain/tw_util.h b/plug-ins/twain/tw_util.h
index 7891452..ca409c7 100644
--- a/plug-ins/twain/tw_util.h
+++ b/plug-ins/twain/tw_util.h
@@ -8,6 +8,10 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
+ * Added for Win x64 support
+ * Jens M. Plonka <jens plonka gmx de>
+ * 11/25/2011
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
@@ -57,10 +61,13 @@
  *  (03/31/99)  v0.5   Added support for multi-byte samples and paletted
  *                     images.
  *  (07/23/04)  v0.6   Added Mac OS X support.
+ *  (11/25/11)  v0.7   Added Win x64 support.
  */
 #ifndef __TW_UTIL_H
 #define __TW_UTIL_H
 
+#define FIX32_TO_FLOAT(f) ((float) f.Whole + (float) f.Frac / 65536.0f)
+
 void log_message (char *format, ...);
 
 #endif /* __TW_UTIL_H */
diff --git a/plug-ins/twain/tw_win.c b/plug-ins/twain/tw_win.c
index 9dabe07..df35845 100644
--- a/plug-ins/twain/tw_win.c
+++ b/plug-ins/twain/tw_win.c
@@ -8,6 +8,10 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
+ * Added for Win x64 support
+ * Jens M. Plonka <jens plonka gmx de>
+ * 11/25/2011
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
@@ -23,6 +27,17 @@
  */
 
 /*
+ * Revision history
+ *  (02/07/99)  v0.1   First working version (internal)
+ *  (02/09/99)  v0.2   First release to anyone other than myself
+ *  (02/15/99)  v0.3   Added image dump and read support for debugging
+ *  (03/31/99)  v0.5   Added support for multi-byte samples and paletted
+ *                     images.
+ *  (07/23/04)  v0.6   Added Mac OS X support.
+ *  (11/25/11)  v0.7   Added Win x64 support.
+ */
+
+/*
  * Windows platform-specific code
  */
 
@@ -73,23 +88,23 @@ int
 twainIsAvailable (void)
 {
   /* Already loaded? */
-  if (dsmEntryPoint)
-  {
-    return TRUE;
-  }
-
-  /* Attempt to load the library */
-  hDLL = LoadLibrary (TWAIN_DLL_NAME);
-  if (hDLL == NULL)
-  {
-    return FALSE;
-  }
-
-  /* Look up the entry point for use */
-  dsmEntryPoint = (DSMENTRYPROC) GetProcAddress (hDLL, "DSM_Entry");
   if (dsmEntryPoint == NULL)
   {
-    return FALSE;
+    /* Attempt to load the library */
+    hDLL = LoadLibrary (TWAIN_DLL_NAME);
+    if (hDLL == NULL)
+    {
+      log_message ("Can't load library \"%s\"!\n", TWAIN_DLL_NAME);
+      return FALSE;
+    }
+
+    /* Look up the entry point for use */
+    dsmEntryPoint = (DSMENTRYPROC) GetProcAddress (hDLL, "DSM_Entry");
+    if (dsmEntryPoint == NULL)
+    {
+      log_message ("Lirary has no DSM Entry point.\n");
+      return FALSE;
+    }
   }
 
   return TRUE;
@@ -141,14 +156,17 @@ unloadTwainLibrary (pTW_SESSION twSession)
     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;
+  if (twSession != 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
+     */
+    twSession->dsIdentity->Id = 0;
 
        /* We are now back at state 0 */
-  twSession->twainState = 0;
+    twSession->twainState = 0;
+  }
 }
 
 /*
@@ -174,9 +192,7 @@ TwainProcessMessage (LPMSG lpMsg, pTW_SESSION twSession)
      * 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);
+    twSession->twRC = DSM_PROCESS_EVENT(twSession, twEvent);
 
     /* Check the return code */
     if (twSession->twRC == TWRC_NOTDSEVENT)
@@ -366,7 +382,7 @@ InitInstance (HINSTANCE hInstance, int nCmdShow, pTW_SESSION twSession)
   /* Register our window handle with the TWAIN
    * support.
    */
-  registerWindowHandle (twSession, hwnd);
+  twSession->hwnd = hwnd;
 
   /* Schedule the image transfer by posting a message */
   PostMessage (hwnd, WM_TRANSFER_IMAGE, 0, 0);
diff --git a/plug-ins/twain/tw_win.h b/plug-ins/twain/tw_win.h
index 998eb6d..b722658 100644
--- a/plug-ins/twain/tw_win.h
+++ b/plug-ins/twain/tw_win.h
@@ -8,7 +8,7 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
- * Added for Win x64 support, changed data source selection.
+ * Added for Win x64 support
  * Jens M. Plonka <jens plonka gmx de>
  * 11/25/2011
  *
@@ -34,7 +34,7 @@
  *  (03/31/99)  v0.5   Added support for multi-byte samples and paletted
  *                     images.
  *  (07/23/04)  v0.6   Added Mac OS X support.
- *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
+ *  (11/25/11)  v0.7   Added Win x64 support.
  */
 
 /*
diff --git a/plug-ins/twain/twain.c b/plug-ins/twain/twain.c
index e9c871e..be63838 100644
--- a/plug-ins/twain/twain.c
+++ b/plug-ins/twain/twain.c
@@ -8,6 +8,10 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
+ * Added for Win x64 support
+ * Jens M. Plonka <jens plonka gmx de>
+ * 11/25/2011
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
@@ -57,6 +61,7 @@
  *  (03/31/99)  v0.5   Added support for multi-byte samples and paletted
  *                     images.
  *  (07/23/04)  v0.6   Added Mac OS X support.
+ *  (11/25/11)  v0.7   Added Win x64 support.
  */
 #include "config.h"
 
@@ -103,16 +108,6 @@ const GimpPlugInInfo PLUG_IN_INFO =
   run,     /* run_proc */
 };
 
-/* Default Twain values */
-static TwainValues twainvals =
-{
-  "",
-  100.0, 100.0,
-  0, 0,
-  0, 0,
-  TWPT_RGB
-};
-
 /* The standard callback functions */
 TXFR_CB_FUNCS standardCbFuncs =
 {
@@ -124,9 +119,15 @@ TXFR_CB_FUNCS standardCbFuncs =
 };
 
 #ifndef TWAIN_ALTERNATE_MAIN
-MAIN()
-#endif
+MAIN ()
+#endif /* TWAIN_ALTERNATE_MAIN */
 
+/*
+ * scan_image
+ *
+ * Callback function for OS dependant implementation inside the
+ * event loop.
+ */
 int
 scanImage (void)
 {
@@ -140,7 +141,7 @@ scanImage (void)
  * the TWAIN runtime.
  */
 static pTW_IDENTITY
-getAppIdentity(void)
+getAppIdentity (void)
 {
   pTW_IDENTITY appIdentity = g_new (TW_IDENTITY, 1);
 
@@ -153,7 +154,8 @@ getAppIdentity(void)
   strcpy(appIdentity->Version.Info, PLUG_IN_VERSION);
   appIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
   appIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
-  appIdentity->SupportedGroups = DG_IMAGE;
+  /* Tell the data source manger that we only accept image data sources */
+  appIdentity->SupportedGroups = DF_APP2 | DG_CONTROL | DG_IMAGE;
   strcpy (appIdentity->Manufacturer, PLUG_IN_COPYRIGHT);
   strcpy (appIdentity->ProductFamily, PRODUCT_FAMILY);
   strcpy (appIdentity->ProductName, PRODUCT_NAME);
@@ -181,7 +183,9 @@ initializeTwain (void)
   twSession = newSession (appIdentity);
 
   /* Register our image transfer callback functions */
-  registerTransferCallbacks(twSession, &standardCbFuncs, NULL);
+  twSession->transferFunctions = &standardCbFuncs;
+  twSession->clientData = NULL;
+
   return twSession;
 }
 
@@ -260,29 +264,14 @@ run (const gchar      *name,
   /* How are we running today? */
   switch (run_mode)
   {
-  case GIMP_RUN_INTERACTIVE:
-    /* Retrieve values from the last run...
-     * Currently ignored
-     */
-    gimp_get_data(PLUG_IN_NAME, &twainvals);
-    break;
-
-  case GIMP_RUN_NONINTERACTIVE:
-    /* Currently, we don't do non-interactive calls.
-     * Bail if someone tries to call us non-interactively
-     */
-    values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
-    return;
-
-  case GIMP_RUN_WITH_LAST_VALS:
-    /* Retrieve values from the last run...
-     * Currently ignored
-     */
-    gimp_get_data(PLUG_IN_NAME, &twainvals);
-    break;
-
-  default:
-    break;
+    case GIMP_RUN_NONINTERACTIVE:
+      /* Non-interactive calls are not supported!
+       * Bail if someone tries to call this way.
+       */
+      values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
+      return;
+       default:
+         break; 
   } /* switch */
 
   /* Have we succeeded so far? */
@@ -295,19 +284,8 @@ run (const gchar      *name,
    * image.
    */
   if (values[1].data.d_int32 > 0) {
-    /* An image was captured from the TWAIN
-     * datasource.  Do final Interactive
-     * steps.
-     */
-    if (run_mode == GIMP_RUN_INTERACTIVE) {
-      /* Store variable states for next run */
-      gimp_set_data(PLUG_IN_NAME, &twainvals, sizeof (TwainValues));
-    }
-
     /* Set return values */
     *nreturn_vals = 3;
-  } else {
-    values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
   }
 }
 
@@ -360,9 +338,7 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo, void *clientData)
     case TWPT_PALETTE:
       /* Get the palette data */
       theClientData->paletteData = g_new (TW_PALETTE8, 1);
-      twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
-                             DG_IMAGE, DAT_PALETTE8, MSG_GET,
-                             (TW_MEMREF) theClientData->paletteData);
+      twSession->twRC = DSM_GET_PALETTE(twSession, theClientData);
       if (twSession->twRC != TWRC_SUCCESS)
       {
         return FALSE;
@@ -401,8 +377,8 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo, void *clientData)
 
   /* Set the actual resolution */
   gimp_image_set_resolution (theClientData->image_id,
-                             FIX32ToFloat(imageInfo->XResolution),
-                             FIX32ToFloat(imageInfo->YResolution));
+      FIX32_TO_FLOAT(imageInfo->XResolution),
+      FIX32_TO_FLOAT(imageInfo->YResolution));
   gimp_image_set_unit (theClientData->image_id, GIMP_UNIT_INCH);
 
   /* Create a layer */
@@ -435,7 +411,7 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo, void *clientData)
     g_free (clientData);
   }
 
-  setClientData(twSession, (void *) theClientData);
+  twSession->clientData = (void *) theClientData;
 
   /* Make sure to return TRUE to continue the image
    * transfer


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]