[gimp] plug-ins: fix #3854 by porting twain to the new plugin framework.



commit d0b1c143b6e322f023ea5469c8130bfa529fc9f7
Author: Jacob Boerema <jgboerema gmail com>
Date:   Fri Sep 18 17:47:42 2020 -0400

    plug-ins: fix #3854 by porting twain to the new plugin framework.
    
    Removed the WinMain specific stuff for the plug-in and determine
    hInstance in twainMain which made porting a lot easier.
    
    The _DEBUG enabled functions I have mostly left alone and
    should be revised at a later time.

 plug-ins/twain/tw_platform.h |   3 -
 plug-ins/twain/tw_win.c      |  74 ++----------
 plug-ins/twain/twain.c       | 277 ++++++++++++++++++++++---------------------
 plug-ins/twain/twain.h       |   6 +-
 4 files changed, 153 insertions(+), 207 deletions(-)
---
diff --git a/plug-ins/twain/tw_platform.h b/plug-ins/twain/tw_platform.h
index de0263b82d..4f8609a3d1 100644
--- a/plug-ins/twain/tw_platform.h
+++ b/plug-ins/twain/tw_platform.h
@@ -31,7 +31,4 @@
 #define DUMP_NAME "DTWAIN.EXE"
 #define READDUMP_NAME "RTWAIN.EXE"
 
-/* Windows uses separate entry point */
-#define TWAIN_ALTERNATE_MAIN
-
 #endif
diff --git a/plug-ins/twain/tw_win.c b/plug-ins/twain/tw_win.c
index 615da6cd16..3c97af9583 100644
--- a/plug-ins/twain/tw_win.c
+++ b/plug-ins/twain/tw_win.c
@@ -40,7 +40,6 @@ LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 int twainMessageLoop(pTW_SESSION);
 int TwainProcessMessage(LPMSG lpMsg, pTW_SESSION twSession);
 
-extern GimpPlugInInfo PLUG_IN_INFO;
 extern pTW_SESSION initializeTwain ();
 #ifdef _DEBUG
 extern void setRunMode(char *argv[]);
@@ -253,78 +252,16 @@ LogLastWinError(void)
        LocalFree( lpMsgBuf );
 }
 
-void twainQuitApplication ()
+void twainQuitApplication (void)
 {
   PostQuitMessage (0);
 }
 
 
 /******************************************************************
- * Win32 entry point and setup...
+ * Win32 setup...
  ******************************************************************/
 
-/*
- * WinMain
- *
- * The standard gimp entry point won't quite cut it for
- * this plug-in.  This plug-in requires creation of a
- * standard Win32 window (hidden) in order to receive
- * and process window messages on behalf of the TWAIN
- * datasource.
- */
-int APIENTRY
-WinMain(HINSTANCE hInstance,
-       HINSTANCE hPrevInstance,
-       LPSTR     lpCmdLine,
-       int       nCmdShow)
-{
-
-  /*
-   * Normally, we would do all of the Windows-ish set up of
-   * the window classes and stuff here in WinMain.  But,
-   * the only time we really need the window and message
-   * queues is during the plug-in run.  So, all of that will
-   * be done during run().  This avoids all of the Windows
-   * setup stuff for the query().  Stash the instance handle now
-   * so it is available from the run() procedure.
-   */
-  hInst = hInstance;
-
-#ifdef _DEBUG
-  /* When in debug version, we allow different run modes...
-   * make sure that it is correctly set.
-   */
-  setRunMode(__argv);
-#endif /* _DEBUG */
-
-  /*
-   * Now, call gimp_main_legacy... This is what the MAIN() macro
-   * would usually do.
-   */
-  return gimp_main_legacy(&PLUG_IN_INFO, __argc, __argv);
-}
-
-/*
- * main
- *
- * allow to build as console app as well
- */
-int main (int argc, char *argv[])
-{
-#ifdef _DEBUG
-  /* When in debug version, we allow different run modes...
-   * make sure that it is correctly set.
-   */
-  setRunMode(__argv);
-#endif /* _DEBUG */
-
-  /*
-   * Now, call gimp_main_legacy... This is what the MAIN() macro
-   * would usually do.
-   */
-  return gimp_main_legacy(&PLUG_IN_INFO, __argc, __argv);
-}
-
 /*
  * InitApplication
  *
@@ -403,11 +340,16 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, pTW_SESSION twSession)
  * operate.
  */
 int
-twainMain()
+twainMain (void)
 {
   /* Initialize the twain information */
   pTW_SESSION twSession = initializeTwain();
 
+  /* Since we are not using our own WinMain anymore where we
+     could get hInst we get it here using GetModuleHandle. */
+  if (!hInst)
+    hInst = GetModuleHandle(NULL);
+
   /* Perform instance initialization */
   if (!InitApplication(hInst))
     return (FALSE);
diff --git a/plug-ins/twain/twain.c b/plug-ins/twain/twain.c
index 9e161a95e0..f42854928d 100644
--- a/plug-ins/twain/twain.c
+++ b/plug-ins/twain/twain.c
@@ -84,9 +84,9 @@
  */
 #define PLUG_IN_NAME        "twain-acquire"
 #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_HELP        N_("This plug-in will capture an image from a TWAIN datasource")
 #define PLUG_IN_AUTHOR      "Craig Setera (setera home com)"
-#define PLUG_IN_COPYRIGHT   "Craig Setera"
+#define PLUG_IN_COPYRIGHT   "Copyright 2004 by Craig Setera"
 #define PLUG_IN_VERSION     "v0.6 (07/22/2004)"
 
 #ifdef _DEBUG
@@ -126,23 +126,102 @@ int  endTransferCallback   (int               completionState,
 void postTransferCallback  (int               pendingCount,
                             void             *clientData);
 
-static void query (void);
-static void run   (const gchar      *name,
-                  gint              nparams,
-                  const GimpParam  *param,
-                  gint             *nreturn_vals,
-                  GimpParam       **return_vals);
 
+typedef struct _Twain      Twain;
+typedef struct _TwainClass TwainClass;
 
-const GimpPlugInInfo PLUG_IN_INFO =
+struct _Twain
 {
-  NULL,    /* init_proc */
-  NULL,    /* quit_proc */
-  query,   /* query_proc */
-  run,     /* run_proc */
+  GimpPlugIn      parent_instance;
 };
 
-extern void set_gimp_PLUG_IN_INFO_PTR (GimpPlugInInfo *);
+struct _TwainClass
+{
+  GimpPlugInClass parent_class;
+};
+
+
+#define TWAIN_TYPE  (twain_get_type ())
+#define TWAIN (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TWAIN_TYPE, Twain))
+
+GType                   twain_get_type         (void) G_GNUC_CONST;
+
+static GList          * twain_query_procedures (GimpPlugIn           *plug_in);
+static GimpProcedure  * twain_create_procedure (GimpPlugIn           *plug_in,
+                                                const gchar          *name);
+
+static GimpValueArray * twain_run              (GimpProcedure        *procedure,
+                                                GimpRunMode           run_mode,
+                                                GimpImage            *image,
+                                                GimpDrawable         *drawable,
+                                                const GimpValueArray *args,
+                                                gpointer              run_data);
+
+G_DEFINE_TYPE (Twain, twain, GIMP_TYPE_PLUG_IN)
+
+GIMP_MAIN (TWAIN_TYPE)
+
+static void
+twain_class_init (TwainClass *klass)
+{
+  GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
+
+  plug_in_class->query_procedures = twain_query_procedures;
+  plug_in_class->create_procedure = twain_create_procedure;
+}
+
+static void
+twain_init (Twain *twain)
+{
+}
+
+static GList *
+twain_query_procedures (GimpPlugIn *plug_in)
+{
+  return g_list_append (NULL, g_strdup (PLUG_IN_NAME));
+}
+
+static GimpProcedure *
+twain_create_procedure (GimpPlugIn  *plug_in,
+                        const gchar *name)
+{
+  GimpProcedure *procedure = NULL;
+
+  if (! strcmp (name, PLUG_IN_NAME))
+    {
+      procedure = gimp_image_procedure_new (plug_in, name,
+                                            GIMP_PDB_PROC_TYPE_PLUGIN,
+                                            twain_run, NULL, NULL);
+
+      gimp_procedure_set_image_types (procedure, "*");
+
+      gimp_procedure_set_menu_label (procedure, N_("_Scanner/Camera..."));
+      gimp_procedure_add_menu_path (procedure, "<Image>/File/Create/Acquire");
+
+      gimp_procedure_set_documentation (procedure,
+                                        PLUG_IN_DESCRIPTION,
+                                        PLUG_IN_HELP,
+                                        name);
+      gimp_procedure_set_attribution (procedure,
+                                      PLUG_IN_AUTHOR,
+                                      PLUG_IN_COPYRIGHT,
+                                      PLUG_IN_VERSION);
+
+      GIMP_PROC_VAL_INT (procedure, "image-count",
+                         "Number of acquired images",
+                         "Number of acquired images",
+                         0, G_MAXINT, 0,
+                         G_PARAM_READWRITE);
+
+      GIMP_PROC_VAL_OBJECT_ARRAY (procedure, "images",
+                                  "Array of acquired images",
+                                  "Array of acquired images",
+                                  GIMP_TYPE_IMAGE,
+                                  G_PARAM_READWRITE);
+     }
+
+  return procedure;
+}
 
 /* Data structure holding data between runs */
 /* Currently unused... Eventually may be used
@@ -205,21 +284,21 @@ setRunMode (char *argv[])
   if (!_stricmp (exeName, DUMP_NAME))
     twain_run_mode = RUN_DUMP;
 
-  if (!_stricmp (exeName, RUNDUMP_NAME))
+  if (!_stricmp (exeName, READDUMP_NAME))
     twain_run_mode = RUN_READDUMP;
 }
 #endif /* _DEBUG */
 
-#ifndef TWAIN_ALTERNATE_MAIN
-MAIN ()
-#endif
 
 int
 scanImage (void)
 {
 #ifdef _DEBUG
   if (twain_run_mode == RUN_READDUMP)
-    return readDumpedImage (twSession);
+    {
+      readDumpedImage (twSession);
+      return 0;
+    }
   else
 #endif /* _DEBUG */
     return getImage (twSession);
@@ -287,93 +366,9 @@ initializeTwain (void)
  * GIMP Plug-in entry points
  ******************************************************************/
 
-/*
- * Plug-in Parameter definitions
- */
-#define NUMBER_IN_ARGS 1
-#define IN_ARGS { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" 
}
-#define NUMBER_OUT_ARGS 2
-#define OUT_ARGS \
-       { GIMP_PDB_INT32, "image-count", "Number of acquired images" }, \
-       { GIMP_PDB_INT32ARRAY, "image-ids", "Array of acquired image identifiers" }
-
-
-/*
- * query
- *
- * The plug-in is being queried.  Install our procedure for
- * acquiring.
- */
-static void
-query (void)
-{
-  static const GimpParamDef args[] = { IN_ARGS };
-  static const GimpParamDef return_vals[] = { OUT_ARGS };
-
-#ifdef _DEBUG
-  if (twain_run_mode == RUN_DUMP)
-    {
-      /* the installation of the plugin */
-      gimp_install_procedure (PLUG_IN_D_NAME,
-                              PLUG_IN_DESCRIPTION,
-                              PLUG_IN_HELP,
-                              PLUG_IN_AUTHOR,
-                              PLUG_IN_COPYRIGHT,
-                              PLUG_IN_VERSION,
-                              "TWAIN (Dump)...",
-                              NULL,
-                              GIMP_PLUGIN,
-                              NUMBER_IN_ARGS,
-                              NUMBER_OUT_ARGS,
-                              args,
-                              return_vals);
-
-      gimp_plugin_menu_register (PLUG_IN_D_NAME, "<Image>/File/Create/Acquire");
-    }
-  else if (twain_run_mode == RUN_READDUMP)
-    {
-      /* the installation of the plugin */
-      gimp_install_procedure (PLUG_IN_R_NAME,
-                              PLUG_IN_DESCRIPTION,
-                              PLUG_IN_HELP,
-                              PLUG_IN_AUTHOR,
-                              PLUG_IN_COPYRIGHT,
-                              PLUG_IN_VERSION,
-                              "TWAIN (Read)...",
-                              NULL,
-                              GIMP_PLUGIN,
-                              NUMBER_IN_ARGS,
-                              NUMBER_OUT_ARGS,
-                              args,
-                              return_vals);
-
-      gimp_plugin_menu_register (PLUG_IN_R_NAME, "<Image>/File/Create/Acquire");
-    }
-  else
-#endif /* _DEBUG */
-    {
-      /* the installation of the plugin */
-      gimp_install_procedure (PLUG_IN_NAME,
-                              PLUG_IN_DESCRIPTION,
-                              PLUG_IN_HELP,
-                              PLUG_IN_AUTHOR,
-                              PLUG_IN_COPYRIGHT,
-                              PLUG_IN_VERSION,
-                              N_("_Scanner/Camera..."),
-                              NULL,
-                              GIMP_PLUGIN,
-                              NUMBER_IN_ARGS,
-                              NUMBER_OUT_ARGS,
-                              args,
-                              return_vals);
-
-      gimp_plugin_menu_register (PLUG_IN_NAME, "<Image>/File/Create/Acquire");
-    }
-}
-
-
 /* Return values storage */
-static GimpParam values[3];
+static GList *image_list  = NULL;
+static gint   image_count = 0;
 
 /*
  * run
@@ -381,23 +376,24 @@ static GimpParam values[3];
  * The plug-in is being requested to run.
  * Capture an image from a TWAIN datasource
  */
-static void
-run (const gchar      *name,
-     gint              nparams,
-     const GimpParam  *param,
-     gint             *nreturn_vals,
-     GimpParam       **return_vals)
+static GimpValueArray *
+twain_run (GimpProcedure        *procedure,
+           GimpRunMode           run_mode,
+           GimpImage            *image,
+           GimpDrawable         *drawable,
+           const GimpValueArray *args,
+           gpointer              run_data)
 {
-  GimpRunMode run_mode = param[0].data.d_int32;
-
   /* Initialize the return values
    * Always return at least the status to the caller.
    */
-  values[0].type          = GIMP_PDB_STATUS;
-  values[0].data.d_status = GIMP_PDB_SUCCESS;
+  GimpPDBStatusType   status      = GIMP_PDB_SUCCESS;
+  GimpValueArray     *return_vals = NULL;
+  GimpImage         **images;
+  GList              *list;
+  gint                num_images;
+  gint                i;
 
-  *nreturn_vals = 1;
-  *return_vals = values;
 
   INIT_I18N ();
   gegl_init (NULL, NULL);
@@ -408,16 +404,10 @@ run (const gchar      *name,
    */
   if (! twainIsAvailable ())
     {
-      values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
-      return;
+      return gimp_procedure_new_return_values (procedure, GIMP_PDB_EXECUTION_ERROR,
+                                               NULL);
     }
 
-  /* Set up the rest of the return parameters */
-  values[1].type         = GIMP_PDB_INT32;
-  values[1].data.d_int32 = 0;
-  values[2].type              = GIMP_PDB_INT32ARRAY;
-  values[2].data.d_int32array = g_new (gint32, MAX_IMAGES);
-
   /* How are we running today? */
   switch (run_mode)
     {
@@ -432,8 +422,8 @@ run (const gchar      *name,
       /* 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;
+      return gimp_procedure_new_return_values (procedure, GIMP_PDB_CALLING_ERROR,
+                                               NULL);
 
     case GIMP_RUN_WITH_LAST_VALS:
       /* Retrieve values from the last run...
@@ -447,13 +437,13 @@ run (const gchar      *name,
     }
 
   /* Have we succeeded so far? */
-  if (values[0].data.d_status == GIMP_PDB_SUCCESS)
+  if (status == GIMP_PDB_SUCCESS)
     twainMain ();
 
   /* Check to make sure we got at least one valid
    * image.
    */
-  if (values[1].data.d_int32 > 0)
+  if (image_count > 0)
     {
       /* An image was captured from the TWAIN
        * datasource.  Do final Interactive
@@ -465,12 +455,30 @@ run (const gchar      *name,
           gimp_set_data (PLUG_IN_NAME, &twainvals, sizeof (TwainValues));
         }
 
+      num_images = g_list_length (image_list);
+      images     = g_new (GimpImage *, num_images);
+
+      for (list = image_list, i = 0;
+           list;
+           list = g_list_next (list), i++)
+        {
+          images[i] = g_object_ref (list->data);
+        }
+
+      g_list_free (image_list);
+
       /* Set return values */
-      *nreturn_vals = 3;
+      return_vals = gimp_procedure_new_return_values (procedure, status,
+                                                      NULL);
+      GIMP_VALUES_SET_INT           (return_vals, 1, num_images);
+      GIMP_VALUES_TAKE_OBJECT_ARRAY (return_vals, 2, GIMP_TYPE_IMAGE, images, num_images);
+
+      return return_vals;
     }
   else
     {
-      values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
+      return gimp_procedure_new_return_values (procedure, GIMP_PDB_EXECUTION_ERROR,
+                                               NULL);
     }
 }
 
@@ -913,9 +921,8 @@ endTransferCallback (int   completionState,
   if (completionState == TWRC_XFERDONE)
     {
       /* We have a completed image transfer */
-      values[2].type = GIMP_PDB_INT32ARRAY;
-      values[2].data.d_int32array[values[1].data.d_int32++] =
-        gimp_image_get_id (theClientData->image);
+      image_list = g_list_append (image_list, theClientData->image);
+      image_count++;
 
       /* Display the image */
       LogMessage ("Displaying image %d\n",
@@ -930,7 +937,7 @@ endTransferCallback (int   completionState,
     }
 
   /* Shut down if we have received all of the possible images */
-  return (values[1].data.d_int32 < MAX_IMAGES);
+  return (image_count < MAX_IMAGES);
 }
 
 /*
diff --git a/plug-ins/twain/twain.h b/plug-ins/twain/twain.h
index af00295215..76ba2d69e3 100644
--- a/plug-ins/twain/twain.h
+++ b/plug-ins/twain/twain.h
@@ -46,8 +46,8 @@
                                  for 1.8 Specification JMH
 \* ======================================================================== */
 
-#ifndef TWAIN
-#define TWAIN
+#ifndef TWAIN_H
+#define TWAIN_H
 
 /*  SDH - 02/08/95 - TWUNK */
 /*  Force 32-bit twain to use same packing of twain structures as existing */
@@ -1816,4 +1816,4 @@ typedef TW_UINT16 (*DSENTRYPROC)(pTW_IDENTITY,
 #else   /* WIN32 */
 #endif  /* WIN32 */
 
-#endif  /* TWAIN */
+#endif  /* TWAIN_H */


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