[gimp/bug-357818: 8/10] Bug 357818 - TWAIN plug-in - fixes bug 357818.



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

    Bug 357818 - TWAIN plug-in - fixes bug 357818.
    
    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/Makefile.am   |    3 +-
 plug-ins/twain/tw_func.c     |  113 ++++++++++++++++++++++++++++++++++++++++--
 plug-ins/twain/tw_func.h     |   18 ++++++-
 plug-ins/twain/tw_local.h    |   13 ++---
 plug-ins/twain/tw_platform.h |    5 +-
 plug-ins/twain/tw_util.c     |    4 +-
 plug-ins/twain/tw_util.h     |    4 +-
 plug-ins/twain/tw_win.c      |    8 ++-
 plug-ins/twain/tw_win.h      |    6 +-
 plug-ins/twain/twain.c       |  105 +++++++++++++++++++++++++++++++++------
 10 files changed, 237 insertions(+), 42 deletions(-)
---
diff --git a/plug-ins/twain/Makefile.am b/plug-ins/twain/Makefile.am
index 094769d..17e8faa 100644
--- a/plug-ins/twain/Makefile.am
+++ b/plug-ins/twain/Makefile.am
@@ -22,8 +22,9 @@ endif
 if HAVE_WINDRES
 include $(top_srcdir)/build/windows/gimprc-plug-ins.rule
 twain_RC = twain.rc.o
+twaindata_DATA = twain-menu.png
 endif
-
+twaindatadir = $(gimpdatadir)/twain
 
 twain_SOURCES = \
        tw_func.c       \
diff --git a/plug-ins/twain/tw_func.c b/plug-ins/twain/tw_func.c
index 94eb686..9942659 100644
--- a/plug-ins/twain/tw_func.c
+++ b/plug-ins/twain/tw_func.c
@@ -8,7 +8,7 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
- * Added for Win x64 support
+ * Added for Win x64 support, changed data source selection
  * Jens M. Plonka <jens plonka gmx de>
  * 11/25/2011
  *
@@ -61,7 +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.
+ *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
  */
 
 #include "config.h"
@@ -226,6 +226,39 @@ openDSM (pTW_SESSION twSession)
 }
 
 /*
+ * adjust_selected_data_source
+ *
+ * Selects the
+ */
+int
+adjust_selected_data_source (pTW_SESSION twSession)
+{
+  pTW_DATA_SOURCE dataSource;
+  pTW_IDENTITY dsIdentity;
+  gchar *dsName;
+
+  twSession->dsIdentity = NULL;
+  /* get all available data source as a linked list into twSession */
+  dataSource = get_available_ds (twSession);
+
+  while (dataSource != NULL)
+  {
+    dataSource = twSession->dataSources;
+    /* for each data source create an own menu item */
+    dsIdentity = dataSource->dsIdentity;
+    dsName = dsIdentity->ProductName;
+    if (strcmp (dsName, twSession->name) == 0)
+    {
+      twSession->dsIdentity = dataSource->dsIdentity;
+      twSession->twRC = TWRC_SUCCESS;
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/*
  * selectDS
  *
  * Select a datasource using the TWAIN user
@@ -241,8 +274,12 @@ selectDS (pTW_SESSION twSession)
     return FALSE;
   }
 
-  /* Ask TWAIN to present the source select dialog */
-  twSession->twRC = DSM_SELECT_USER(twSession);
+  if ((strcmp (MID_SELECT, twSession->name) == 0)
+      || (adjust_selected_data_source (twSession) == FALSE))
+  {
+    /* Ask TWAIN to present the source select dialog */
+    twSession->twRC = DSM_SELECT_USER(twSession);
+  }
 
   /* Check the return to determine what the user decided
    * to do.
@@ -767,3 +804,71 @@ newSession (pTW_IDENTITY appIdentity)
 
   return session;
 }
+
+/*
+ * get_available_ds
+ *
+ * Get the list of available data sources.
+ */
+pTW_DATA_SOURCE
+get_available_ds (pTW_SESSION twSession)
+{
+  pTW_DATA_SOURCE data_source = NULL;
+  pTW_IDENTITY dsIdentity;
+
+  if(DSM_IS_CLOSED(twSession))
+  {
+    log_message ("You need to open the DSM first.\n");
+    return NULL;
+  }
+
+  if (twSession != NULL)
+  {
+    dsIdentity = g_new (TW_IDENTITY, 1);
+    twSession->twRC = DSM_GET_FIRST_DS(twSession, dsIdentity);
+
+    switch (twSession->twRC)
+    {
+      case TWRC_SUCCESS:
+        data_source = g_new (TW_DATA_SOURCE, 1);
+        data_source->dsIdentity = dsIdentity;
+        data_source->dsNext = NULL;
+        twSession->dataSources = data_source;
+        break;
+
+    case TWRC_ENDOFLIST:
+        twSession->dataSources = NULL;
+        break;
+
+      case TWRC_FAILURE:
+        log_message ("Error getting first data source: %s\n", currentTwainError(twSession));
+        break;
+    }
+
+    /* get the rest of the data sources */
+    while (TWRC_SUCCESS == twSession->twRC)
+    {
+      dsIdentity = g_new (TW_IDENTITY, 1);
+      twSession->twRC = DSM_GET_NEXT_DS(twSession, dsIdentity);
+
+      switch (twSession->twRC)
+      {
+        case TWRC_SUCCESS:
+          data_source->dsNext = g_new (TW_DATA_SOURCE, 1);
+          data_source = data_source->dsNext;
+          data_source->dsIdentity = dsIdentity;
+          data_source->dsNext = NULL;
+          break;
+
+        case TWRC_ENDOFLIST:
+          break;
+
+        case TWRC_FAILURE:
+          log_message ("Error getting next data source: %s\n", currentTwainError(twSession));
+          break;
+      }
+    }
+  }
+
+  return twSession->dataSources;
+}
diff --git a/plug-ins/twain/tw_func.h b/plug-ins/twain/tw_func.h
index 1fbc2ee..54ad04f 100644
--- a/plug-ins/twain/tw_func.h
+++ b/plug-ins/twain/tw_func.h
@@ -8,7 +8,7 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
- * Added for Win x64 support
+ * Added for Win x64 support, changed data source selection.
  * Jens M. Plonka <jens plonka gmx de>
  * 11/25/2011
  *
@@ -61,7 +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.
+ *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
  */
 
 #ifndef _TW_FUNC_H
@@ -146,6 +146,11 @@ typedef struct _TXFR_CB_FUNCS {
   TW_POST_TXFR_CB postTxfrCb;
 } TXFR_CB_FUNCS, *pTXFR_CB_FUNCS;
 
+typedef struct _TW_DATA_SOURCE {
+  pTW_IDENTITY dsIdentity;
+  struct _TW_DATA_SOURCE *dsNext;
+} TW_DATA_SOURCE, *pTW_DATA_SOURCE;
+
 /*
  * Data representing a TWAIN
  * application to data source
@@ -186,6 +191,13 @@ typedef struct _TWAIN_SESSION {
    */
   int twainState;
 
+  const gchar *name;
+  /*
+   * The available data sources for this session.
+   * The list will be updated each time the plugin is invoked on query.
+   */
+  struct _TW_DATA_SOURCE *dataSources;
+
 } TW_SESSION, *pTW_SESSION;
 
 #define CB_XFER_PRE(s) if (s->transferFunctions->preTxfrCb) \
@@ -299,5 +311,7 @@ void            closeDSM (pTW_SESSION twSession);
 void            cancelPendingTransfers (pTW_SESSION twSession);
 void            processTwainMessage (TW_UINT16 message, pTW_SESSION twSession);
 pTW_SESSION     newSession (pTW_IDENTITY twSession);
+pTW_DATA_SOURCE get_available_ds (pTW_SESSION twSession);
+int             adjust_selected_data_source (pTW_SESSION twSession);
 
 #endif /* _TW_FUNC_H */
diff --git a/plug-ins/twain/tw_local.h b/plug-ins/twain/tw_local.h
index a4b47d0..85f3335 100644
--- a/plug-ins/twain/tw_local.h
+++ b/plug-ins/twain/tw_local.h
@@ -8,7 +8,7 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
- * Added for Win x64 support
+ * Added for Win x64 support, changed data source selection.
  * 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.
+ *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
  */
 
 #ifndef _TW_LOCAL_H
@@ -74,7 +74,7 @@ TW_MEMREF twainLockHandle (TW_HANDLE handle);
 void      twainUnlockHandle (TW_HANDLE handle);
 void      twainFreeHandle (TW_HANDLE handle);
 
-int       twainMain (void);
+int       twainMain (const gchar *name);
 int       scanImage (void);
 pTW_SESSION initializeTwain (void);
 
@@ -83,8 +83,8 @@ int       beginTransferCallback (pTW_IMAGEINFO, void *);
 int       dataTransferCallback (pTW_IMAGEINFO, pTW_IMAGEMEMXFER, void *);
 int       endTransferCallback (int, int, void *);
 void      postTransferCallback (int, void *);
-
-extern void set_gimp_PLUG_IN_INFO_PTR(GimpPlugInInfo *);
+void      register_menu (pTW_IDENTITY dsIdentity);
+void      register_scanner_menus (void);
 
 /* Data used to carry data between each
  * of the callback function calls.
@@ -99,5 +99,4 @@ typedef struct
   int totalPixels;
   int completedPixels;
 } ClientDataStruct, *pClientDataStruct;
-
-#endif
+#endif /* _TW_LOCAL_H */
diff --git a/plug-ins/twain/tw_platform.h b/plug-ins/twain/tw_platform.h
index e6403a8..99ae0e1 100644
--- a/plug-ins/twain/tw_platform.h
+++ b/plug-ins/twain/tw_platform.h
@@ -4,7 +4,7 @@
  * Craig Setera <setera home com>
  * 03/31/1999
  *
- * Added for Win x64 support
+ * Added for Win x64 support, changed data source selection
  * Jens M. Plonka <jens plonka gmx de>
  * 11/25/2011
  *
@@ -30,7 +30,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.
+ *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
  */
 
 #ifndef _TW_PLATFORM_H
@@ -71,4 +71,5 @@
   #define PLUG_IN_HINT        PRODUCT_NAME " " PLUG_IN_NAME " v" TOSTRING(PLUG_IN_MAJOR) "." 
TOSTRING(PLUG_IN_MINOR)
 
   #define MID_SELECT          "twain-acquire"
+  #define MP_SELECT           "<Image>/File/Create/Acquire"
 #endif
diff --git a/plug-ins/twain/tw_util.c b/plug-ins/twain/tw_util.c
index 8972fce..6c926d4 100644
--- a/plug-ins/twain/tw_util.c
+++ b/plug-ins/twain/tw_util.c
@@ -8,7 +8,7 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
- * Added for Win x64 support
+ * Added for Win x64 support, changed data source selection.
  * Jens M. Plonka <jens plonka gmx de>
  * 11/25/2011
  *
@@ -61,7 +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.
+ *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
  */
 
 #include "config.h"
diff --git a/plug-ins/twain/tw_util.h b/plug-ins/twain/tw_util.h
index ca409c7..0f57b8a 100644
--- a/plug-ins/twain/tw_util.h
+++ b/plug-ins/twain/tw_util.h
@@ -8,7 +8,7 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
- * Added for Win x64 support
+ * Added for Win x64 support, changed data source selection.
  * Jens M. Plonka <jens plonka gmx de>
  * 11/25/2011
  *
@@ -61,7 +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.
+ *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
  */
 #ifndef __TW_UTIL_H
 #define __TW_UTIL_H
diff --git a/plug-ins/twain/tw_win.c b/plug-ins/twain/tw_win.c
index df35845..bbd15c8 100644
--- a/plug-ins/twain/tw_win.c
+++ b/plug-ins/twain/tw_win.c
@@ -8,7 +8,7 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
- * Added for Win x64 support
+ * Added for Win x64 support, changed data source selection.
  * 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.
+ *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
  */
 
 /*
@@ -404,11 +404,13 @@ InitInstance (HINSTANCE hInstance, int nCmdShow, pTW_SESSION twSession)
  * operate.
  */
 int
-twainMain (void)
+twainMain (const gchar *name)
 {
   /* Initialize the twain information */
   pTW_SESSION twSession = initializeTwain();
 
+  twSession->name = name;
+
   /* Perform instance initialization */
   if (!InitApplication (hInst))
   {
diff --git a/plug-ins/twain/tw_win.h b/plug-ins/twain/tw_win.h
index b722658..d40312d 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
+ * Added for Win x64 support, changed data source selection.
  * 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.
+ *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
  */
 
 /*
@@ -63,7 +63,7 @@ void    LogLastWinError (void);
 void    twainQuitApplication (void);
 BOOL    InitApplication (HINSTANCE hInstance);
 BOOL    InitInstance (HINSTANCE hInstance, int nCmdShow, pTW_SESSION twSession);
-int     twainMain (void);
+int     twainMain (const gchar *name);
 extern  pTW_SESSION initializeTwain (void);
 
 #endif /* _TW_WIN_H */
diff --git a/plug-ins/twain/twain.c b/plug-ins/twain/twain.c
index be63838..bd98c4c 100644
--- a/plug-ins/twain/twain.c
+++ b/plug-ins/twain/twain.c
@@ -8,7 +8,7 @@
  * Brion Vibber <brion pobox com>
  * 07/22/2004
  *
- * Added for Win x64 support
+ * Added for Win x64 support, changed data source selection.
  * Jens M. Plonka <jens plonka gmx de>
  * 11/25/2011
  *
@@ -61,7 +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.
+ *  (11/25/11)  v0.7   Added Win x64 support, changed data source selection.
  */
 #include "config.h"
 
@@ -189,6 +189,79 @@ initializeTwain (void)
   return twSession;
 }
 
+/*
+ * register_menu
+ *
+ * Registers a menu item for the given scanner.
+ */
+void
+register_menu (const pTW_IDENTITY dsIdentity)
+{
+  guint8 *iconfile;
+  gchar  *name;
+
+  name = dsIdentity->ProductName;
+
+  gimp_install_procedure (
+      name,
+      PLUG_IN_DESCRIPTION,
+      PLUG_IN_HELP,
+      dsIdentity->Manufacturer,
+      PLUG_IN_COPYRIGHT,
+      PLUG_IN_VERSION,
+      name,
+      NULL,
+      GIMP_PLUGIN,
+      NUMBER_IN_ARGS,
+      NUMBER_OUT_ARGS,
+      args, return_vals);
+
+  gimp_plugin_menu_register (name, MP_SELECT);
+  iconfile = (guint8 *) g_build_filename (gimp_data_directory (),
+                                      "twain",
+                                      "twain-menu.png",
+                                      NULL);
+  gimp_plugin_icon_register (name, GIMP_ICON_TYPE_IMAGE_FILE, iconfile);
+  g_free (iconfile);
+}
+
+/*
+ * register_scanner_menus
+ *
+ * Initilizes communication with the Data Source Manager.
+ * Communication will be kept open till shutdown of GIMP
+ * because the id might change due to new installed data
+ * sources wile GIMP is open!
+ * The name of each scanner is the identifyer of the menu.
+ */
+void
+register_scanner_menus (void)
+{
+  pTW_DATA_SOURCE dataSource;
+  pTW_IDENTITY dsIdentity;
+
+  // Get the list of available TWAIN data sources
+  initializeTwain ();
+
+  if (openDSM (twSession))
+  {
+    /* get all available data source as a linked list into twSession */
+    dataSource = get_available_ds (twSession);
+
+    /* for each found data source create an own menu item */
+    while (dataSource != NULL)
+    {
+      dsIdentity = dataSource->dsIdentity;
+      register_menu (dsIdentity);
+
+      /* handle the next data source */
+      dataSource = dataSource->dsNext;
+    }
+
+    closeDSM (twSession);
+  }
+}
+
 /******************************************************************
  * GIMP Plug-in entry points
  ******************************************************************/
@@ -202,7 +275,7 @@ initializeTwain (void)
 static void
 query (void)
 {
-  /* the installation of the plugin */
+  /* Select scanner by dialog */
   gimp_install_procedure(MID_SELECT,
                          PLUG_IN_DESCRIPTION,
                          PLUG_IN_HELP,
@@ -217,7 +290,10 @@ query (void)
                          args,
                          return_vals);
 
-  gimp_plugin_menu_register (MID_SELECT, "<Image>/File/Create/Acquire");
+  gimp_plugin_menu_register (MID_SELECT, MP_SELECT);
+
+  /* Direct scanner selection by menu items */
+  register_scanner_menus ();
 }
 
 /*
@@ -277,7 +353,7 @@ run (const gchar      *name,
   /* Have we succeeded so far? */
   if (values[0].data.d_status == GIMP_PDB_SUCCESS)
   {
-    twainMain ();
+    twainMain (name);
   }
 
   /* Check to make sure we got at least one valid
@@ -316,6 +392,8 @@ int
 beginTransferCallback (pTW_IMAGEINFO imageInfo, void *clientData)
 {
   int imageType, layerType;
+  TW_INT32 width = imageInfo->ImageWidth;
+  TW_INT32 length = imageInfo->ImageLength;
 
   pClientDataStruct theClientData = g_new (ClientDataStruct, 1);
 
@@ -372,8 +450,7 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo, void *clientData)
   }
 
   /* Create the GIMP image */
-  theClientData->image_id = gimp_image_new(imageInfo->ImageWidth,
-                                          imageInfo->ImageLength, imageType);
+  theClientData->image_id = gimp_image_new (width, length, imageType);
 
   /* Set the actual resolution */
   gimp_image_set_resolution (theClientData->image_id,
@@ -383,17 +460,14 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo, void *clientData)
 
   /* Create a layer */
   theClientData->layer_id = gimp_layer_new(theClientData->image_id,
-                                          _("Background"),
-                                          imageInfo->ImageWidth,
-                                          imageInfo->ImageLength,
-                                          layerType, 100, GIMP_NORMAL_MODE);
+      _("Background"), width, length, layerType, 100, GIMP_NORMAL_MODE);
 
   /* Add the layer to the image */
-  gimp_image_insert_layer(theClientData->image_id,
-                          theClientData->layer_id, -1, 0);
+  gimp_image_insert_layer (theClientData->image_id,
+      theClientData->layer_id, -1, 0);
 
   /* Update the progress dialog */
-  theClientData->totalPixels = imageInfo->ImageWidth * imageInfo->ImageLength;
+  theClientData->totalPixels = width * length;
   theClientData->completedPixels = 0;
   gimp_progress_update ((double) 0);
 
@@ -402,8 +476,7 @@ beginTransferCallback (pTW_IMAGEINFO imageInfo, void *clientData)
 
   /* Initialize a pixel region for writing to the image */
   gimp_pixel_rgn_init (&(theClientData->pixel_rgn), theClientData->drawable,
-                     0, 0, imageInfo->ImageWidth, imageInfo->ImageLength,
-                     TRUE, FALSE);
+      0, 0, width, length, TRUE, FALSE);
 
   /* Store our client data for the data transfer callbacks */
   if (clientData)


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