Applied a patch from Brion Vibber that makes the TWAIN plug-in available
2004-07-28 Sven Neumann <sven@gimp.org> Applied a patch from Brion Vibber that makes the TWAIN plug-in available on Mac OS X (bug #147962): * configure.in * plug-ins/Makefile.am: check for Mac OS X twain support. * plug-ins/twain/Makefile.am * plug-ins/twain/tw_local.h * plug-ins/twain/tw_mac.c * plug-ins/twain/tw_platform.h * plug-ins/twain/tw_win.c: new files with platform specific code. * plug-ins/twain/README * plug-ins/twain/tw_dump.[ch] * plug-ins/twain/tw_func.[ch] * plug-ins/twain/tw_util.[ch] * plug-ins/twain/twain.c: changed accordingly. * plug-ins/twain/gimp-twain.png: twain application icon used by the Mac port. * plug-ins/twain/tw_sess.c: removed, doesn't seem to be used.
This commit is contained in:

committed by
Sven Neumann

parent
f989a897f1
commit
e082fd5572
25
ChangeLog
25
ChangeLog
@ -1,3 +1,28 @@
|
|||||||
|
2004-07-28 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
|
Applied a patch from Brion Vibber that makes the TWAIN plug-in
|
||||||
|
available on Mac OS X (bug #147962):
|
||||||
|
|
||||||
|
* configure.in
|
||||||
|
* plug-ins/Makefile.am: check for Mac OS X twain support.
|
||||||
|
|
||||||
|
* plug-ins/twain/Makefile.am
|
||||||
|
* plug-ins/twain/tw_local.h
|
||||||
|
* plug-ins/twain/tw_mac.c
|
||||||
|
* plug-ins/twain/tw_platform.h
|
||||||
|
* plug-ins/twain/tw_win.c: new files with platform specific code.
|
||||||
|
|
||||||
|
* plug-ins/twain/README
|
||||||
|
* plug-ins/twain/tw_dump.[ch]
|
||||||
|
* plug-ins/twain/tw_func.[ch]
|
||||||
|
* plug-ins/twain/tw_util.[ch]
|
||||||
|
* plug-ins/twain/twain.c: changed accordingly.
|
||||||
|
|
||||||
|
* plug-ins/twain/gimp-twain.png: twain application icon used by
|
||||||
|
the Mac port.
|
||||||
|
|
||||||
|
* plug-ins/twain/tw_sess.c: removed, doesn't seem to be used.
|
||||||
|
|
||||||
2004-07-28 Michael Natterer <mitch@gimp.org>
|
2004-07-28 Michael Natterer <mitch@gimp.org>
|
||||||
|
|
||||||
* tools/pdbgen/pdb/image.pdb (image_is_dirty): fix typo in
|
* tools/pdbgen/pdb/image.pdb (image_is_dirty): fix typo in
|
||||||
|
15
configure.in
15
configure.in
@ -1324,6 +1324,21 @@ AC_SUBST(WINPRINT)
|
|||||||
AC_SUBST(WMF)
|
AC_SUBST(WMF)
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# Check for Mac OS X TWAIN framework (can't build on Darwin)
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([checking for Mac OS X TWAIN support])
|
||||||
|
AC_TRY_CPP([
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
#include <TWAIN/TWAIN.h>
|
||||||
|
],
|
||||||
|
twain_ok=yes,
|
||||||
|
twain_ok=no)
|
||||||
|
AC_MSG_RESULT($twain_ok)
|
||||||
|
AM_CONDITIONAL(HAVE_MAC_TWAIN, test x$twain_ok = xyes)
|
||||||
|
|
||||||
|
|
||||||
##########################################################
|
##########################################################
|
||||||
# Determine where to install the desktop & mime info files
|
# Determine where to install the desktop & mime info files
|
||||||
##########################################################
|
##########################################################
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
makefile.msc
|
makefile.msc
|
||||||
|
|
||||||
|
|
||||||
|
if BUILD_HELPBROWSER
|
||||||
|
helpbrowser = helpbrowser
|
||||||
|
endif
|
||||||
|
|
||||||
if BUILD_PRINT
|
if BUILD_PRINT
|
||||||
print = print
|
print = print
|
||||||
endif
|
endif
|
||||||
@ -11,20 +16,19 @@ if BUILD_PYTHON
|
|||||||
pygimp = pygimp
|
pygimp = pygimp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_HELPBROWSER
|
if HAVE_MAC_TWAIN
|
||||||
helpbrowser = helpbrowser
|
twain = twain
|
||||||
|
endif
|
||||||
|
|
||||||
|
if OS_WIN32
|
||||||
|
twain = twain
|
||||||
|
winsnap = winsnap
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_XJT
|
if BUILD_XJT
|
||||||
xjt = xjt
|
xjt = xjt
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if OS_WIN32
|
|
||||||
win32dirs = \
|
|
||||||
twain \
|
|
||||||
winsnap
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
libgimpoldpreview \
|
libgimpoldpreview \
|
||||||
@ -53,7 +57,8 @@ SUBDIRS = \
|
|||||||
rcm \
|
rcm \
|
||||||
sgi \
|
sgi \
|
||||||
sel2path \
|
sel2path \
|
||||||
|
$(twain) \
|
||||||
winicon \
|
winicon \
|
||||||
$(win32dirs) \
|
$(winsnap) \
|
||||||
$(xjt) \
|
$(xjt) \
|
||||||
common
|
common
|
||||||
|
@ -6,25 +6,50 @@ libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la
|
|||||||
libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
|
libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
|
||||||
libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
|
libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
|
||||||
|
|
||||||
twain_LDFLAGS = -mwindows
|
|
||||||
|
|
||||||
libexecdir = $(gimpplugindir)/plug-ins
|
libexecdir = $(gimpplugindir)/plug-ins
|
||||||
|
|
||||||
libexec_PROGRAMS = twain
|
libexec_PROGRAMS = twain
|
||||||
|
|
||||||
|
|
||||||
|
if OS_WIN32
|
||||||
|
twain_LDFLAGS = -mwindows
|
||||||
|
winlink = -luser32
|
||||||
|
|
||||||
|
twainplatform = tw_win.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
if HAVE_MAC_TWAIN
|
||||||
|
maclink = -framework Carbon -framework TWAIN
|
||||||
|
|
||||||
|
twainplatform = tw_mac.c
|
||||||
|
|
||||||
|
twaindatadir = $(gimpdatadir)/twain
|
||||||
|
twaindata_DATA = gimp-twain.png
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
AM_LDFLAGS = $(winlink) $(maclink)
|
||||||
|
|
||||||
twain_SOURCES = \
|
twain_SOURCES = \
|
||||||
tw_func.c \
|
tw_func.c \
|
||||||
tw_func.h \
|
tw_func.h \
|
||||||
tw_util.c \
|
tw_util.c \
|
||||||
tw_util.h \
|
tw_util.h \
|
||||||
twain.c \
|
twain.c \
|
||||||
twain.h
|
twain.h \
|
||||||
|
tw_local.h \
|
||||||
|
tw_platform.h \
|
||||||
|
$(twainplatform)
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
README \
|
README \
|
||||||
|
gimp-twain.png \
|
||||||
tw_dump.c \
|
tw_dump.c \
|
||||||
tw_dump.h \
|
tw_dump.h \
|
||||||
tw_sess.c
|
tw_sess.c \
|
||||||
|
tw_win.c \
|
||||||
|
tw_mac.c
|
||||||
|
|
||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-I$(top_srcdir) \
|
-I$(top_srcdir) \
|
||||||
@ -38,4 +63,4 @@ LDADD = \
|
|||||||
$(GLIB_LIBS) \
|
$(GLIB_LIBS) \
|
||||||
$(RT_LIBS) \
|
$(RT_LIBS) \
|
||||||
$(INTLLIBS) \
|
$(INTLLIBS) \
|
||||||
-luser32
|
$(twain_LIBS)
|
||||||
|
@ -3,6 +3,10 @@ Copyright (C) 1999 Craig Setera
|
|||||||
Craig Setera <setera@home.com>
|
Craig Setera <setera@home.com>
|
||||||
03/31/1999
|
03/31/1999
|
||||||
|
|
||||||
|
Updated for Mac OS X support
|
||||||
|
Brion Vibber <brion@pobox.com>
|
||||||
|
07/22/2004
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -34,17 +38,15 @@ images:
|
|||||||
- Paletted images (both Gray and RGB)
|
- Paletted images (both Gray and RGB)
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
This plug-in will not compile on anything other than a Win32
|
Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||||
platform. Although the TWAIN documentation implies that there
|
also on 10.2).
|
||||||
is TWAIN support available on Macintosh, I neither have a
|
|
||||||
Macintosh nor the interest in porting this. If anyone else
|
|
||||||
has an interest, consult www.twain.org for more information on
|
|
||||||
interfacing to TWAIN.
|
|
||||||
|
|
||||||
Known problems:
|
Known problems:
|
||||||
|
|
||||||
- Multiple image transfers will hang the plug-in. The current
|
- Multiple image transfers will hang the plug-in. The current
|
||||||
configuration compiles with a maximum of single image transfers.
|
configuration compiles with a maximum of single image transfers.
|
||||||
|
- On Mac OS X, canceling doesn't always close things out fully.
|
||||||
|
- Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
|
||||||
|
|
||||||
Debugging:
|
Debugging:
|
||||||
There are two different versions of the program included, a standard
|
There are two different versions of the program included, a standard
|
||||||
|
BIN
plug-ins/twain/gimp-twain.png
Normal file
BIN
plug-ins/twain/gimp-twain.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -4,6 +4,10 @@
|
|||||||
* Craig Setera <setera@home.com>
|
* Craig Setera <setera@home.com>
|
||||||
* 03/31/1999
|
* 03/31/1999
|
||||||
*
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -36,16 +40,14 @@
|
|||||||
* - Paletted images (both Gray and RGB)
|
* - Paletted images (both Gray and RGB)
|
||||||
*
|
*
|
||||||
* Prerequisites:
|
* Prerequisites:
|
||||||
* This plug-in will not compile on anything other than a Win32
|
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||||
* platform. Although the TWAIN documentation implies that there
|
* also on 10.2).
|
||||||
* is TWAIN support available on Macintosh, I neither have a
|
|
||||||
* Macintosh nor the interest in porting this. If anyone else
|
|
||||||
* has an interest, consult www.twain.org for more information on
|
|
||||||
* interfacing to TWAIN.
|
|
||||||
*
|
*
|
||||||
* Known problems:
|
* Known problems:
|
||||||
* - Multiple image transfers will hang the plug-in. The current
|
* - Multiple image transfers will hang the plug-in. The current
|
||||||
* configuration compiles with a maximum of single image transfers.
|
* configuration compiles with a maximum of single image transfers.
|
||||||
|
* - On Mac OS X, canceling doesn't always close things out fully.
|
||||||
|
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -55,8 +57,8 @@
|
|||||||
* (02/15/99) v0.3 Added image dump and read support for debugging
|
* (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
|
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||||
* images.
|
* images.
|
||||||
|
* (07/23/04) v0.6 Added Mac OS X support.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "libgimp/gimp.h"
|
#include "libgimp/gimp.h"
|
||||||
@ -194,7 +196,7 @@ dumpPostTransferCallback(int pendingCount, void *clientData)
|
|||||||
gimp_message(buffer);
|
gimp_message(buffer);
|
||||||
|
|
||||||
/* Post a message to close up the application */
|
/* Post a message to close up the application */
|
||||||
PostQuitMessage(0);
|
twainQuitApplication ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -262,5 +264,5 @@ void readDumpedImage(pTW_SESSION twSession)
|
|||||||
twSession->clientData);
|
twSession->clientData);
|
||||||
|
|
||||||
/* Post a message to close up the application */
|
/* Post a message to close up the application */
|
||||||
PostQuitMessage(0);
|
twainQuitApplication ();
|
||||||
}
|
}
|
||||||
|
@ -57,12 +57,9 @@
|
|||||||
* images.
|
* images.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include "tw_platform.h"
|
||||||
#include "twain.h"
|
|
||||||
#include "tw_func.h"
|
#include "tw_func.h"
|
||||||
|
|
||||||
#define DUMP_FILE "C:\\TWAINCAP.BIN"
|
|
||||||
|
|
||||||
void dumpPreTransferCallback(void *clientData);
|
void dumpPreTransferCallback(void *clientData);
|
||||||
int dumpBeginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData);
|
int dumpBeginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData);
|
||||||
int dumpDataTransferCallback(pTW_IMAGEINFO imageInfo,
|
int dumpDataTransferCallback(pTW_IMAGEINFO imageInfo,
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
* Craig Setera <setera@home.com>
|
* Craig Setera <setera@home.com>
|
||||||
* 03/31/1999
|
* 03/31/1999
|
||||||
*
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -36,16 +40,14 @@
|
|||||||
* - Paletted images (both Gray and RGB)
|
* - Paletted images (both Gray and RGB)
|
||||||
*
|
*
|
||||||
* Prerequisites:
|
* Prerequisites:
|
||||||
* This plug-in will not compile on anything other than a Win32
|
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||||
* platform. Although the TWAIN documentation implies that there
|
* also on 10.2).
|
||||||
* is TWAIN support available on Macintosh, I neither have a
|
|
||||||
* Macintosh nor the interest in porting this. If anyone else
|
|
||||||
* has an interest, consult www.twain.org for more information on
|
|
||||||
* interfacing to TWAIN.
|
|
||||||
*
|
*
|
||||||
* Known problems:
|
* Known problems:
|
||||||
* - Multiple image transfers will hang the plug-in. The current
|
* - Multiple image transfers will hang the plug-in. The current
|
||||||
* configuration compiles with a maximum of single image transfers.
|
* configuration compiles with a maximum of single image transfers.
|
||||||
|
* - On Mac OS X, canceling doesn't always close things out fully.
|
||||||
|
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -55,17 +57,16 @@
|
|||||||
* (02/15/99) v0.3 Added image dump and read support for debugging
|
* (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
|
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||||
* images.
|
* images.
|
||||||
|
* (07/23/04) v0.6 Added Mac OS X support.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <glib.h> /* Needed when compiling with gcc */
|
#include <glib.h> /* Needed when compiling with gcc */
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include "twain.h"
|
|
||||||
#include "tw_func.h"
|
#include "tw_func.h"
|
||||||
#include "tw_util.h"
|
#include "tw_util.h"
|
||||||
|
#include "tw_local.h"
|
||||||
/* The DLL to be loaded for TWAIN support */
|
|
||||||
#define TWAIN_DLL_NAME "TWAIN_32.DLL"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Twain error code to string mappings
|
* Twain error code to string mappings
|
||||||
@ -97,12 +98,6 @@ static char *twainErrors[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Storage for the DLL handle */
|
|
||||||
static HINSTANCE hDLL = NULL;
|
|
||||||
|
|
||||||
/* Storage for the entry point into the DSM */
|
|
||||||
static DSMENTRYPROC dsmEntryPoint = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FloatToFix32
|
* FloatToFix32
|
||||||
*
|
*
|
||||||
@ -129,23 +124,6 @@ float FIX32ToFloat(TW_FIX32 fix32)
|
|||||||
return floater;
|
return floater;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* callDSM
|
|
||||||
*
|
|
||||||
* Call the specified function on the data source manager.
|
|
||||||
*/
|
|
||||||
TW_UINT16
|
|
||||||
callDSM(pTW_IDENTITY pOrigin,
|
|
||||||
pTW_IDENTITY pDest,
|
|
||||||
TW_UINT32 DG,
|
|
||||||
TW_UINT16 DAT,
|
|
||||||
TW_UINT16 MSG,
|
|
||||||
TW_MEMREF pData)
|
|
||||||
{
|
|
||||||
/* Call the function */
|
|
||||||
return (*dsmEntryPoint) (pOrigin, pDest, DG, DAT, MSG, pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* twainError
|
* twainError
|
||||||
*
|
*
|
||||||
@ -185,31 +163,6 @@ currentTwainError(pTW_SESSION twSession)
|
|||||||
return twainError(twStatus.ConditionCode);
|
return twainError(twStatus.ConditionCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* twainIsAvailable
|
|
||||||
*
|
|
||||||
* Return boolean indicating whether TWAIN is available
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getImage
|
* getImage
|
||||||
@ -225,6 +178,7 @@ getImage(pTW_SESSION twSession)
|
|||||||
/* Do some sanity checking first and bail
|
/* Do some sanity checking first and bail
|
||||||
* if necessary.
|
* if necessary.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!twainIsAvailable()) {
|
if (!twainIsAvailable()) {
|
||||||
LogMessage("TWAIN is not available for image capture\n");
|
LogMessage("TWAIN is not available for image capture\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -421,11 +375,12 @@ setBufferedXfer(pTW_SESSION twSession)
|
|||||||
/* Create the capability information */
|
/* Create the capability information */
|
||||||
bufXfer.Cap = ICAP_XFERMECH;
|
bufXfer.Cap = ICAP_XFERMECH;
|
||||||
bufXfer.ConType = TWON_ONEVALUE;
|
bufXfer.ConType = TWON_ONEVALUE;
|
||||||
bufXfer.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE));
|
bufXfer.hContainer = twainAllocHandle(sizeof(TW_ONEVALUE));
|
||||||
pvalOneValue = (pTW_ONEVALUE) GlobalLock(bufXfer.hContainer);
|
|
||||||
|
pvalOneValue = (pTW_ONEVALUE) twainLockHandle(bufXfer.hContainer);
|
||||||
pvalOneValue->ItemType = TWTY_UINT16;
|
pvalOneValue->ItemType = TWTY_UINT16;
|
||||||
pvalOneValue->Item = TWSX_MEMORY;
|
pvalOneValue->Item = TWSX_MEMORY;
|
||||||
GlobalUnlock(bufXfer.hContainer);
|
twainUnlockHandle(bufXfer.hContainer);
|
||||||
|
|
||||||
/* Make the call to the source manager */
|
/* Make the call to the source manager */
|
||||||
twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
|
twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
|
||||||
@ -433,7 +388,7 @@ setBufferedXfer(pTW_SESSION twSession)
|
|||||||
(TW_MEMREF) &bufXfer);
|
(TW_MEMREF) &bufXfer);
|
||||||
|
|
||||||
/* Free the container */
|
/* Free the container */
|
||||||
GlobalFree(bufXfer.hContainer);
|
twainFreeHandle(bufXfer.hContainer);
|
||||||
|
|
||||||
/* Let the caller know what happened */
|
/* Let the caller know what happened */
|
||||||
return (twSession->twRC==TWRC_SUCCESS);
|
return (twSession->twRC==TWRC_SUCCESS);
|
||||||
@ -447,7 +402,7 @@ setBufferedXfer(pTW_SESSION twSession)
|
|||||||
* an image to actually be transferred.
|
* an image to actually be transferred.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
requestImageAcquire(pTW_SESSION twSession, BOOL showUI)
|
requestImageAcquire(pTW_SESSION twSession, gboolean showUI)
|
||||||
{
|
{
|
||||||
/* Make sure in the correct state */
|
/* Make sure in the correct state */
|
||||||
if (DS_IS_CLOSED(twSession)) {
|
if (DS_IS_CLOSED(twSession)) {
|
||||||
@ -455,6 +410,8 @@ requestImageAcquire(pTW_SESSION twSession, BOOL showUI)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
twainSetupCallback(twSession);
|
||||||
|
|
||||||
/* Set the transfer mode */
|
/* Set the transfer mode */
|
||||||
if (setBufferedXfer(twSession)) {
|
if (setBufferedXfer(twSession)) {
|
||||||
TW_USERINTERFACE ui;
|
TW_USERINTERFACE ui;
|
||||||
@ -462,6 +419,7 @@ requestImageAcquire(pTW_SESSION twSession, BOOL showUI)
|
|||||||
/* Set the UI information */
|
/* Set the UI information */
|
||||||
ui.ShowUI = TRUE;
|
ui.ShowUI = TRUE;
|
||||||
ui.ModalUI = TRUE;
|
ui.ModalUI = TRUE;
|
||||||
|
/* In Windows, the callbacks are sent to the window message handler */
|
||||||
ui.hParent = twSession->hwnd;
|
ui.hParent = twSession->hwnd;
|
||||||
|
|
||||||
/* Make the call to the source manager */
|
/* Make the call to the source manager */
|
||||||
@ -579,7 +537,7 @@ closeDSM(pTW_SESSION twSession)
|
|||||||
} else {
|
} else {
|
||||||
twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
|
twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
|
||||||
DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM,
|
DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM,
|
||||||
&(twSession->hwnd));
|
(TW_MEMREF)&(twSession->hwnd));
|
||||||
|
|
||||||
if (twSession->twRC != TWRC_SUCCESS) {
|
if (twSession->twRC != TWRC_SUCCESS) {
|
||||||
LogMessage("CloseDSM failure -- %s\n", currentTwainError(twSession));
|
LogMessage("CloseDSM failure -- %s\n", currentTwainError(twSession));
|
||||||
@ -596,32 +554,6 @@ closeDSM(pTW_SESSION twSession)
|
|||||||
return (twSession->twRC==TWRC_SUCCESS);
|
return (twSession->twRC==TWRC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* beginImageTransfer
|
* beginImageTransfer
|
||||||
@ -765,7 +697,7 @@ cancelPendingTransfers(pTW_SESSION twSession)
|
|||||||
static int
|
static int
|
||||||
endImageTransfer(pTW_SESSION twSession, int *pendingCount)
|
endImageTransfer(pTW_SESSION twSession, int *pendingCount)
|
||||||
{
|
{
|
||||||
BOOL continueTransfers;
|
gboolean continueTransfers;
|
||||||
int exitCode = twSession->twRC;
|
int exitCode = twSession->twRC;
|
||||||
|
|
||||||
/* Have now exited the transfer for some reason... Figure out
|
/* Have now exited the transfer for some reason... Figure out
|
||||||
@ -844,87 +776,32 @@ transferImages(pTW_SESSION twSession)
|
|||||||
twSession->clientData);
|
twSession->clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void
|
||||||
* TwainProcessMessage
|
processTwainMessage(TW_UINT16 message, pTW_SESSION twSession)
|
||||||
*
|
|
||||||
* 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;
|
switch (message) {
|
||||||
|
case MSG_XFERREADY:
|
||||||
|
LogMessage("Source says that data is ready\n");
|
||||||
|
transferImages(twSession);
|
||||||
|
break;
|
||||||
|
|
||||||
twSession->twRC = TWRC_NOTDSEVENT;
|
case MSG_CLOSEDSREQ:
|
||||||
|
/* Disable the datasource, Close the Data source
|
||||||
|
* and close the data source manager
|
||||||
|
*/
|
||||||
|
LogMessage("CloseDSReq\n");
|
||||||
|
disableDS(twSession);
|
||||||
|
closeDS(twSession);
|
||||||
|
closeDSM(twSession);
|
||||||
|
break;
|
||||||
|
|
||||||
/* Only ask Source Manager to process event if there is a Source connected. */
|
/* No message from the Source to the App break;
|
||||||
if (DSM_IS_OPEN(twSession) && DS_IS_OPEN(twSession)) {
|
* possible new message
|
||||||
/*
|
*/
|
||||||
* A Source provides a modeless dialog box as its user interface.
|
case MSG_NULL:
|
||||||
* The following call relays Windows messages down to the Source's
|
default:
|
||||||
* UI that were intended for its dialog box. It also retrieves TWAIN
|
break;
|
||||||
* 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 */
|
|
||||||
switch (twEvent.TWMessage) {
|
|
||||||
case MSG_XFERREADY:
|
|
||||||
LogMessage("Source says that data is ready\n");
|
|
||||||
transferImages(twSession);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSG_CLOSEDSREQ:
|
|
||||||
/* Disable the datasource, Close the Data source
|
|
||||||
* and close the data source manager
|
|
||||||
*/
|
|
||||||
LogMessage("CloseDSReq\n");
|
|
||||||
disableDS(twSession);
|
|
||||||
closeDS(twSession);
|
|
||||||
closeDSM(twSession);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* No message from the Source to the App break;
|
|
||||||
* possible new message
|
|
||||||
*/
|
|
||||||
case MSG_NULL:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tell the caller what happened */
|
|
||||||
return (twSession->twRC == TWRC_DSEVENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* twainMessageLoop
|
|
||||||
*
|
|
||||||
* Process Win32 window messages and provide special handling
|
|
||||||
* of TWAIN specific messages. This loop will not exit until
|
|
||||||
* the application exits.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
twainMessageLoop(pTW_SESSION twSession)
|
|
||||||
{
|
|
||||||
MSG msg;
|
|
||||||
|
|
||||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
|
||||||
if (DS_IS_CLOSED(twSession) || !TwainProcessMessage(&msg, twSession)) {
|
|
||||||
TranslateMessage((LPMSG)&msg);
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return msg.wParam;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
@ -965,7 +842,7 @@ newSession(pTW_IDENTITY appIdentity) {
|
|||||||
* session.
|
* session.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
registerWindowHandle(pTW_SESSION session, HWND hwnd)
|
registerWindowHandle(pTW_SESSION session, TW_HANDLE hwnd)
|
||||||
{
|
{
|
||||||
session->hwnd = hwnd;
|
session->hwnd = hwnd;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
* Craig Setera <setera@home.com>
|
* Craig Setera <setera@home.com>
|
||||||
* 03/31/1999
|
* 03/31/1999
|
||||||
*
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -36,16 +40,14 @@
|
|||||||
* - Paletted images (both Gray and RGB)
|
* - Paletted images (both Gray and RGB)
|
||||||
*
|
*
|
||||||
* Prerequisites:
|
* Prerequisites:
|
||||||
* This plug-in will not compile on anything other than a Win32
|
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||||
* platform. Although the TWAIN documentation implies that there
|
* also on 10.2).
|
||||||
* is TWAIN support available on Macintosh, I neither have a
|
|
||||||
* Macintosh nor the interest in porting this. If anyone else
|
|
||||||
* has an interest, consult www.twain.org for more information on
|
|
||||||
* interfacing to TWAIN.
|
|
||||||
*
|
*
|
||||||
* Known problems:
|
* Known problems:
|
||||||
* - Multiple image transfers will hang the plug-in. The current
|
* - Multiple image transfers will hang the plug-in. The current
|
||||||
* configuration compiles with a maximum of single image transfers.
|
* configuration compiles with a maximum of single image transfers.
|
||||||
|
* - On Mac OS X, canceling doesn't always close things out fully.
|
||||||
|
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -55,11 +57,13 @@
|
|||||||
* (02/15/99) v0.3 Added image dump and read support for debugging
|
* (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
|
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||||
* images.
|
* images.
|
||||||
|
* (07/23/04) v0.6 Added Mac OS X support.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TW_FUNC_H
|
#ifndef _TW_FUNC_H
|
||||||
#define _TW_FUNC_H
|
#define _TW_FUNC_H
|
||||||
#include "twain.h"
|
|
||||||
|
#include "tw_platform.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pre-image transfer function type
|
* Pre-image transfer function type
|
||||||
@ -147,8 +151,8 @@ typedef struct _TXFR_CB_FUNCS {
|
|||||||
* session.
|
* session.
|
||||||
*/
|
*/
|
||||||
typedef struct _TWAIN_SESSION {
|
typedef struct _TWAIN_SESSION {
|
||||||
/* The window handle related to the TWAIN application */
|
/* The window handle related to the TWAIN application on Win32 */
|
||||||
HWND hwnd;
|
TW_HANDLE hwnd;
|
||||||
|
|
||||||
/* The current TWAIN return code */
|
/* The current TWAIN return code */
|
||||||
TW_UINT16 twRC;
|
TW_UINT16 twRC;
|
||||||
@ -204,31 +208,27 @@ typedef struct _TWAIN_SESSION {
|
|||||||
#define DS_IS_DISABLED(tw_session) (tw_session->twainState < 5)
|
#define DS_IS_DISABLED(tw_session) (tw_session->twainState < 5)
|
||||||
|
|
||||||
/* Function declarations */
|
/* Function declarations */
|
||||||
TW_UINT16 callDSM(pTW_IDENTITY, pTW_IDENTITY,
|
|
||||||
TW_UINT32, TW_UINT16,
|
|
||||||
TW_UINT16, TW_MEMREF);
|
|
||||||
char *twainError(int);
|
char *twainError(int);
|
||||||
char *currentTwainError(pTW_SESSION);
|
char *currentTwainError(pTW_SESSION);
|
||||||
int twainIsAvailable(void);
|
|
||||||
int getImage(pTW_SESSION);
|
int getImage(pTW_SESSION);
|
||||||
int loadTwainLibrary(pTW_SESSION);
|
int loadTwainLibrary(pTW_SESSION);
|
||||||
int openDSM(pTW_SESSION);
|
int openDSM(pTW_SESSION);
|
||||||
int selectDS(pTW_SESSION);
|
int selectDS(pTW_SESSION);
|
||||||
int selectDefaultDS(pTW_SESSION);
|
int selectDefaultDS(pTW_SESSION);
|
||||||
int openDS(pTW_SESSION);
|
int openDS(pTW_SESSION);
|
||||||
int requestImageAcquire(pTW_SESSION, BOOL);
|
int requestImageAcquire(pTW_SESSION, gboolean);
|
||||||
int disableDS(pTW_SESSION);
|
int disableDS(pTW_SESSION);
|
||||||
int closeDS(pTW_SESSION);
|
int closeDS(pTW_SESSION);
|
||||||
int closeDSM(pTW_SESSION);
|
int closeDSM(pTW_SESSION);
|
||||||
int unloadTwainLibrary(pTW_SESSION);
|
|
||||||
int twainMessageLoop(pTW_SESSION);
|
|
||||||
void cancelPendingTransfers(pTW_SESSION);
|
void cancelPendingTransfers(pTW_SESSION);
|
||||||
|
|
||||||
TW_FIX32 FloatToFix32(float);
|
TW_FIX32 FloatToFix32(float);
|
||||||
float FIX32ToFloat(TW_FIX32);
|
float FIX32ToFloat(TW_FIX32);
|
||||||
|
|
||||||
|
void processTwainMessage(TW_UINT16 message, pTW_SESSION twSession);
|
||||||
|
|
||||||
pTW_SESSION newSession(pTW_IDENTITY);
|
pTW_SESSION newSession(pTW_IDENTITY);
|
||||||
void registerWindowHandle(pTW_SESSION, HWND);
|
void registerWindowHandle(pTW_SESSION, TW_HANDLE);
|
||||||
void registerTransferCallbacks(pTW_SESSION, pTXFR_CB_FUNCS, void *);
|
void registerTransferCallbacks(pTW_SESSION, pTXFR_CB_FUNCS, void *);
|
||||||
void setClientData(pTW_SESSION session, void *clientData);
|
void setClientData(pTW_SESSION session, void *clientData);
|
||||||
|
|
||||||
|
49
plug-ins/twain/tw_local.h
Normal file
49
plug-ins/twain/tw_local.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* TWAIN Plug-in
|
||||||
|
* Copyright (C) 1999 Craig Setera
|
||||||
|
* Craig Setera <setera@home.com>
|
||||||
|
* 03/31/1999
|
||||||
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
|
* 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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TW_LOCAL_H
|
||||||
|
#define _TW_LOCAL_H
|
||||||
|
|
||||||
|
#include "tw_func.h"
|
||||||
|
|
||||||
|
/* Functions which the platform-independent code will call */
|
||||||
|
|
||||||
|
TW_UINT16 callDSM(pTW_IDENTITY, pTW_IDENTITY,
|
||||||
|
TW_UINT32, TW_UINT16,
|
||||||
|
TW_UINT16, TW_MEMREF);
|
||||||
|
|
||||||
|
int twainIsAvailable(void);
|
||||||
|
void twainQuitApplication ();
|
||||||
|
gboolean twainSetupCallback (pTW_SESSION twSession);
|
||||||
|
|
||||||
|
TW_HANDLE twainAllocHandle(size_t size);
|
||||||
|
TW_MEMREF twainLockHandle (TW_HANDLE handle);
|
||||||
|
void twainUnlockHandle (TW_HANDLE handle);
|
||||||
|
void twainFreeHandle (TW_HANDLE handle);
|
||||||
|
|
||||||
|
int twainMain ();
|
||||||
|
int scanImage ();
|
||||||
|
|
||||||
|
#endif
|
228
plug-ins/twain/tw_mac.c
Normal file
228
plug-ins/twain/tw_mac.c
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
* TWAIN Plug-in
|
||||||
|
* Copyright (C) 1999 Craig Setera
|
||||||
|
* Craig Setera <setera@home.com>
|
||||||
|
* 03/31/1999
|
||||||
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
|
* 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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Platform-specific code for Mac OS X
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <libgimp/gimp.h>
|
||||||
|
|
||||||
|
#include "tw_platform.h"
|
||||||
|
#include "tw_func.h"
|
||||||
|
#include "tw_util.h"
|
||||||
|
#include "tw_local.h"
|
||||||
|
|
||||||
|
TW_UINT16 twainCallback(pTW_IDENTITY pOrigin,
|
||||||
|
pTW_IDENTITY pDest,
|
||||||
|
TW_UINT32 DG,
|
||||||
|
TW_UINT16 DAT,
|
||||||
|
TW_UINT16 MSG,
|
||||||
|
TW_MEMREF pData);
|
||||||
|
extern pTW_SESSION initializeTwain ();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* callDSM
|
||||||
|
*
|
||||||
|
* Call the specified function on the data source manager.
|
||||||
|
*/
|
||||||
|
TW_UINT16
|
||||||
|
callDSM(pTW_IDENTITY pOrigin,
|
||||||
|
pTW_IDENTITY pDest,
|
||||||
|
TW_UINT32 DG,
|
||||||
|
TW_UINT16 DAT,
|
||||||
|
TW_UINT16 MSG,
|
||||||
|
TW_MEMREF pData)
|
||||||
|
{
|
||||||
|
/* Call the function */
|
||||||
|
return DSM_Entry (pOrigin, pDest, DG, DAT, MSG, pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* twainIsAvailable
|
||||||
|
*
|
||||||
|
* Return boolean indicating whether TWAIN is available
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
twainIsAvailable(void)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TW_HANDLE
|
||||||
|
twainAllocHandle(size_t size)
|
||||||
|
{
|
||||||
|
return NewHandle(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
TW_MEMREF
|
||||||
|
twainLockHandle (TW_HANDLE handle)
|
||||||
|
{
|
||||||
|
return *handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
twainUnlockHandle (TW_HANDLE handle)
|
||||||
|
{
|
||||||
|
/* NOP */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
twainFreeHandle (TW_HANDLE handle)
|
||||||
|
{
|
||||||
|
DisposeHandle (handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
twainSetupCallback (pTW_SESSION twSession)
|
||||||
|
{
|
||||||
|
TW_CALLBACK callback;
|
||||||
|
/* We need to set up our callback to receive messages */
|
||||||
|
callback.CallBackProc = (TW_MEMREF)twainCallback;
|
||||||
|
callback.RefCon = (TW_UINT32)twSession;
|
||||||
|
callback.Message = 0;
|
||||||
|
twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
|
||||||
|
DG_CONTROL, DAT_CALLBACK, MSG_REGISTER_CALLBACK,
|
||||||
|
(TW_MEMREF) &callback);
|
||||||
|
if (twSession->twRC != TWRC_SUCCESS) {
|
||||||
|
LogMessage("Couldn't set callback function (retval %d)", (int)(twSession->twRC));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unloadTwainLibrary
|
||||||
|
*
|
||||||
|
* Unload the TWAIN dynamic link library
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
unloadTwainLibrary(pTW_SESSION twSession)
|
||||||
|
{
|
||||||
|
/* We're statically linked; just clear the session */
|
||||||
|
DS_IDENTITY(twSession)->Id = 0;
|
||||||
|
|
||||||
|
/* We are now back at state 1 */
|
||||||
|
twSession->twainState = 1;
|
||||||
|
LogMessage("Source Manager successfully closed\n");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TW_UINT16 twainCallback(pTW_IDENTITY pOrigin,
|
||||||
|
pTW_IDENTITY pDest,
|
||||||
|
TW_UINT32 DG,
|
||||||
|
TW_UINT16 DAT,
|
||||||
|
TW_UINT16 MSG,
|
||||||
|
TW_MEMREF pData)
|
||||||
|
{
|
||||||
|
pTW_SESSION twSession = (pTW_SESSION)(((TW_CALLBACK *)pData)->RefCon);
|
||||||
|
LogMessage("twainCallback! DG 0x%x, DAT 0x%x, MSG 0x%x\n",
|
||||||
|
(int)DG, (int)DAT, (int)MSG);
|
||||||
|
processTwainMessage (MSG, twSession);
|
||||||
|
return TWRC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void twainQuitApplication ()
|
||||||
|
{
|
||||||
|
QuitApplicationEventLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* main bits */
|
||||||
|
|
||||||
|
// mojo from http://lists.wxwidgets.org/archive/wxPython-mac/msg00117.html
|
||||||
|
extern OSErr CPSSetProcessName (ProcessSerialNumber *psn, char *processname);
|
||||||
|
extern OSErr CPSEnableForegroundOperation( ProcessSerialNumber *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
|
||||||
|
|
||||||
|
static void
|
||||||
|
doGetImage (EventLoopTimerRef inTimer, void *inUserData)
|
||||||
|
{
|
||||||
|
if (! scanImage ())
|
||||||
|
QuitApplicationEventLoop ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void twainSetupMacUI()
|
||||||
|
{
|
||||||
|
ProcessSerialNumber psn;
|
||||||
|
GetCurrentProcess (&psn);
|
||||||
|
CPSSetProcessName (&psn, "GIMP TWAIN");
|
||||||
|
|
||||||
|
/* Need to do some magic here to get the UI to work */
|
||||||
|
CPSEnableForegroundOperation (&psn, 0x03, 0x3C, 0x2C, 0x1103);
|
||||||
|
SetFrontProcess (&psn);
|
||||||
|
|
||||||
|
/* We end up with the ugly console dock icon; let's override it */
|
||||||
|
gchar *iconfile = g_build_filename (gimp_data_directory (),
|
||||||
|
"twain",
|
||||||
|
"gimp-twain.png",
|
||||||
|
NULL);
|
||||||
|
CFURLRef url = CFURLCreateFromFileSystemRepresentation (kCFAllocatorDefault,
|
||||||
|
iconfile,
|
||||||
|
strlen (iconfile),
|
||||||
|
FALSE);
|
||||||
|
g_free (iconfile);
|
||||||
|
|
||||||
|
CGDataProviderRef png = CGDataProviderCreateWithURL (url);
|
||||||
|
CGImageRef icon = CGImageCreateWithPNGDataProvider (png, NULL, TRUE,
|
||||||
|
kCGRenderingIntentDefault);
|
||||||
|
|
||||||
|
/* Voodoo magic fix inspired by java_swt launcher */
|
||||||
|
/* Without this the icon setting doesn't work about half the time. */
|
||||||
|
CGrafPtr p = BeginQDContextForApplicationDockTile();
|
||||||
|
EndQDContextForApplicationDockTile(p);
|
||||||
|
|
||||||
|
SetApplicationDockTileImage (icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
twainMain()
|
||||||
|
{
|
||||||
|
EventLoopTimerRef timer;
|
||||||
|
OSStatus err;
|
||||||
|
|
||||||
|
twainSetupMacUI();
|
||||||
|
|
||||||
|
/* Ok, back to work! */
|
||||||
|
initializeTwain ();
|
||||||
|
|
||||||
|
/* Set this up to run once the event loop is started */
|
||||||
|
err = InstallEventLoopTimer (GetMainEventLoop (),
|
||||||
|
0, 0, /* Immediately, once only */
|
||||||
|
NewEventLoopTimerUPP (doGetImage),
|
||||||
|
NULL, &timer);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
g_warning ("InstallEventLoopTimer returned error %d", (int)err);
|
||||||
|
g_message ("Something went horribly awry.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RunApplicationEventLoop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
62
plug-ins/twain/tw_platform.h
Normal file
62
plug-ins/twain/tw_platform.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* TWAIN Plug-in
|
||||||
|
* Copyright (C) 1999 Craig Setera
|
||||||
|
* Craig Setera <setera@home.com>
|
||||||
|
* 03/31/1999
|
||||||
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
|
* 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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TW_PLATFORM_H
|
||||||
|
#define _TW_PLATFORM_H
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
/* Mac OS X */
|
||||||
|
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
#include <TWAIN/TWAIN.h>
|
||||||
|
|
||||||
|
#define DEBUG_LOGFILE "/tmp/twain.log"
|
||||||
|
#define DUMP_FILE "/tmp/twaincap.bin"
|
||||||
|
#define DUMP_NAME "dtwain"
|
||||||
|
#define READDUMP_NAME "rtwain"
|
||||||
|
|
||||||
|
#define _stricmp strcasecmp
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Win32 */
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "twain.h"
|
||||||
|
|
||||||
|
/* The DLL to be loaded for TWAIN support */
|
||||||
|
#define TWAIN_DLL_NAME "TWAIN_32.DLL"
|
||||||
|
#define DEBUG_LOGFILE "c:\\twain.log"
|
||||||
|
#define DUMP_FILE "C:\\TWAINCAP.BIN"
|
||||||
|
#define DUMP_NAME "DTWAIN.EXE"
|
||||||
|
#define READDUMP_NAME "RTWAIN.EXE"
|
||||||
|
|
||||||
|
/* Windows uses separate entry point */
|
||||||
|
#define TWAIN_ALTERNATE_MAIN
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* TWAIN Plug-in
|
|
||||||
* Copyright (C) 1999 Craig Setera
|
|
||||||
* Craig Setera <setera@home.com>
|
|
||||||
* 03/31/1999
|
|
||||||
*
|
|
||||||
* 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 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Based on (at least) the following plug-ins:
|
|
||||||
* Screenshot
|
|
||||||
* GIF
|
|
||||||
* Randomize
|
|
||||||
*
|
|
||||||
* Any suggestions, bug-reports or patches are welcome.
|
|
||||||
*
|
|
||||||
* This plug-in interfaces to the TWAIN support library in order
|
|
||||||
* to capture images from TWAIN devices directly into GIMP images.
|
|
||||||
* The plug-in is capable of acquiring the following type of
|
|
||||||
* images:
|
|
||||||
* - B/W (1 bit images translated to grayscale B/W)
|
|
||||||
* - Grayscale up to 16 bits per pixel
|
|
||||||
* - RGB up to 16 bits per sample (24, 30, 36, etc.)
|
|
||||||
* - Paletted images (both Gray and RGB)
|
|
||||||
*
|
|
||||||
* Prerequisites:
|
|
||||||
* This plug-in will not compile on anything other than a Win32
|
|
||||||
* platform. Although the TWAIN documentation implies that there
|
|
||||||
* is TWAIN support available on Macintosh, I neither have a
|
|
||||||
* Macintosh nor the interest in porting this. If anyone else
|
|
||||||
* has an interest, consult www.twain.org for more information on
|
|
||||||
* interfacing to TWAIN.
|
|
||||||
*
|
|
||||||
* Known problems:
|
|
||||||
* - Multiple image transfers will hang the plug-in. The current
|
|
||||||
* configuration compiles with a maximum of single image transfers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include "twain.h"
|
|
||||||
#include "tw_func.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* newSession
|
|
||||||
*
|
|
||||||
* Create a new TWAIN session.
|
|
||||||
*/
|
|
||||||
pTW_SESSION
|
|
||||||
newSession(pTW_IDENTITY appIdentity) {
|
|
||||||
/* Create the structure */
|
|
||||||
pTW_SESSION session = g_new (TW_SESSION, 1);
|
|
||||||
|
|
||||||
/* Set the structure fields */
|
|
||||||
session->hwnd = 0;
|
|
||||||
session->twRC = TWRC_SUCCESS;
|
|
||||||
session->appIdentity = appIdentity;
|
|
||||||
session->dsIdentity = g_new (TW_IDENTITY, 1);
|
|
||||||
session->dsIdentity->Id = 0;
|
|
||||||
session->dsIdentity->ProductName[0] = '\0';
|
|
||||||
session->transferFunctions = NULL;
|
|
||||||
|
|
||||||
if (twainIsAvailable())
|
|
||||||
session->twainState = 2;
|
|
||||||
else
|
|
||||||
session->twainState = 0;
|
|
||||||
|
|
||||||
return session;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* registerWindowHandle
|
|
||||||
*
|
|
||||||
* Register the window handle to be used for this
|
|
||||||
* session.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
registerWindowHandle(pTW_SESSION session, HWND 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;
|
|
||||||
}
|
|
@ -4,6 +4,10 @@
|
|||||||
* Craig Setera <setera@home.com>
|
* Craig Setera <setera@home.com>
|
||||||
* 03/31/1999
|
* 03/31/1999
|
||||||
*
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -36,16 +40,14 @@
|
|||||||
* - Paletted images (both Gray and RGB)
|
* - Paletted images (both Gray and RGB)
|
||||||
*
|
*
|
||||||
* Prerequisites:
|
* Prerequisites:
|
||||||
* This plug-in will not compile on anything other than a Win32
|
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||||
* platform. Although the TWAIN documentation implies that there
|
* also on 10.2).
|
||||||
* is TWAIN support available on Macintosh, I neither have a
|
|
||||||
* Macintosh nor the interest in porting this. If anyone else
|
|
||||||
* has an interest, consult www.twain.org for more information on
|
|
||||||
* interfacing to TWAIN.
|
|
||||||
*
|
*
|
||||||
* Known problems:
|
* Known problems:
|
||||||
* - Multiple image transfers will hang the plug-in. The current
|
* - Multiple image transfers will hang the plug-in. The current
|
||||||
* configuration compiles with a maximum of single image transfers.
|
* configuration compiles with a maximum of single image transfers.
|
||||||
|
* - On Mac OS X, canceling doesn't always close things out fully.
|
||||||
|
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -55,15 +57,20 @@
|
|||||||
* (02/15/99) v0.3 Added image dump and read support for debugging
|
* (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
|
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||||
* images.
|
* images.
|
||||||
|
* (07/23/04) v0.6 Added Mac OS X support.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <glib.h> /* Needed when compiling with gcc */
|
#include <glib.h> /* Needed when compiling with gcc */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "tw_util.h"
|
#include "tw_util.h"
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#include "tw_func.h"
|
#include "tw_func.h"
|
||||||
@ -71,6 +78,7 @@ FILE *logFile = NULL;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LogMessage
|
* LogMessage
|
||||||
*/
|
*/
|
||||||
@ -83,7 +91,7 @@ LogMessage(char *format, ...)
|
|||||||
|
|
||||||
/* Open the log file as necessary */
|
/* Open the log file as necessary */
|
||||||
if (!logFile)
|
if (!logFile)
|
||||||
logFile = fopen("c:\\twain.log", "w");
|
logFile = fopen(DEBUG_LOGFILE, "w");
|
||||||
|
|
||||||
time_of_day = time(NULL);
|
time_of_day = time(NULL);
|
||||||
ctime_string = ctime(&time_of_day);
|
ctime_string = ctime(&time_of_day);
|
||||||
@ -96,36 +104,6 @@ LogMessage(char *format, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* LogLastWinError
|
|
||||||
*
|
|
||||||
* Log the last Windows error as returned by
|
|
||||||
* GetLastError.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
LogLastWinError(void)
|
|
||||||
{
|
|
||||||
LPVOID lpMsgBuf;
|
|
||||||
|
|
||||||
FormatMessage(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL,
|
|
||||||
GetLastError(),
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
|
|
||||||
(LPTSTR) &lpMsgBuf,
|
|
||||||
0,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
LogMessage("%s\n", lpMsgBuf);
|
|
||||||
|
|
||||||
/* Free the buffer. */
|
|
||||||
LocalFree( lpMsgBuf );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
logBegin(pTW_IMAGEINFO imageInfo, void *clientData)
|
logBegin(pTW_IMAGEINFO imageInfo, void *clientData)
|
||||||
{
|
{
|
||||||
@ -190,15 +168,4 @@ LogMessage(char *format, ...)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* LogLastWinError
|
|
||||||
*
|
|
||||||
* Log the last Windows error as returned by
|
|
||||||
* GetLastError.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
LogLastWinError(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
* Craig Setera <setera@home.com>
|
* Craig Setera <setera@home.com>
|
||||||
* 03/31/1999
|
* 03/31/1999
|
||||||
*
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -36,16 +40,14 @@
|
|||||||
* - Paletted images (both Gray and RGB)
|
* - Paletted images (both Gray and RGB)
|
||||||
*
|
*
|
||||||
* Prerequisites:
|
* Prerequisites:
|
||||||
* This plug-in will not compile on anything other than a Win32
|
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||||
* platform. Although the TWAIN documentation implies that there
|
* also on 10.2).
|
||||||
* is TWAIN support available on Macintosh, I neither have a
|
|
||||||
* Macintosh nor the interest in porting this. If anyone else
|
|
||||||
* has an interest, consult www.twain.org for more information on
|
|
||||||
* interfacing to TWAIN.
|
|
||||||
*
|
*
|
||||||
* Known problems:
|
* Known problems:
|
||||||
* - Multiple image transfers will hang the plug-in. The current
|
* - Multiple image transfers will hang the plug-in. The current
|
||||||
* configuration compiles with a maximum of single image transfers.
|
* configuration compiles with a maximum of single image transfers.
|
||||||
|
* - On Mac OS X, canceling doesn't always close things out fully.
|
||||||
|
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -55,13 +57,14 @@
|
|||||||
* (02/15/99) v0.3 Added image dump and read support for debugging
|
* (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
|
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||||
* images.
|
* images.
|
||||||
|
* (07/23/04) v0.6 Added Mac OS X support.
|
||||||
*/
|
*/
|
||||||
#ifndef __TW_UTIL_H
|
#ifndef __TW_UTIL_H
|
||||||
#define __TW_UTIL_H
|
#define __TW_UTIL_H
|
||||||
#include "twain.h"
|
|
||||||
|
#include "tw_platform.h"
|
||||||
|
|
||||||
void LogMessage(char *, ...);
|
void LogMessage(char *, ...);
|
||||||
void LogLastWinError(void) ;
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
void logBegin(pTW_IMAGEINFO, void *);
|
void logBegin(pTW_IMAGEINFO, void *);
|
||||||
|
453
plug-ins/twain/tw_win.c
Normal file
453
plug-ins/twain/tw_win.c
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
/*
|
||||||
|
* TWAIN Plug-in
|
||||||
|
* Copyright (C) 1999 Craig Setera
|
||||||
|
* Craig Setera <setera@home.com>
|
||||||
|
* 03/31/1999
|
||||||
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
|
* 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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows platform-specific code
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <libgimp/gimp.h>
|
||||||
|
|
||||||
|
#include "tw_platform.h"
|
||||||
|
#include "tw_func.h"
|
||||||
|
#include "tw_util.h"
|
||||||
|
#include "tw_local.h"
|
||||||
|
|
||||||
|
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[]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define APP_NAME "TWAIN"
|
||||||
|
#define SHOW_WINDOW 0
|
||||||
|
#define WM_TRANSFER_IMAGE (WM_USER + 100)
|
||||||
|
|
||||||
|
/* main bits */
|
||||||
|
static HWND hwnd = NULL;
|
||||||
|
static HINSTANCE hInst = NULL;
|
||||||
|
|
||||||
|
/* Storage for the DLL handle */
|
||||||
|
static HINSTANCE hDLL = NULL;
|
||||||
|
|
||||||
|
/* Storage for the entry point into the DSM */
|
||||||
|
static DSMENTRYPROC dsmEntryPoint = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* callDSM
|
||||||
|
*
|
||||||
|
* Call the specified function on the data source manager.
|
||||||
|
*/
|
||||||
|
TW_UINT16
|
||||||
|
callDSM(pTW_IDENTITY pOrigin,
|
||||||
|
pTW_IDENTITY pDest,
|
||||||
|
TW_UINT32 DG,
|
||||||
|
TW_UINT16 DAT,
|
||||||
|
TW_UINT16 MSG,
|
||||||
|
TW_MEMREF pData)
|
||||||
|
{
|
||||||
|
/* Call the function */
|
||||||
|
return (*dsmEntryPoint) (pOrigin, pDest, DG, DAT, MSG, pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* twainIsAvailable
|
||||||
|
*
|
||||||
|
* Return boolean indicating whether TWAIN is available
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TW_HANDLE
|
||||||
|
twainAllocHandle (size_t size)
|
||||||
|
{
|
||||||
|
return GlobalAlloc(GHND, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
TW_MEMREF
|
||||||
|
twainLockHandle (TW_HANDLE handle)
|
||||||
|
{
|
||||||
|
return GlobalLock (handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
twainUnlockHandle (TW_HANDLE handle)
|
||||||
|
{
|
||||||
|
GlobalUnlock (handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
twainFreeHandle (TW_HANDLE handle)
|
||||||
|
{
|
||||||
|
GlobalFree (handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
twainSetupCallback (pTW_SESSION twSession)
|
||||||
|
{
|
||||||
|
/* Callbacks go through the window messaging system */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* twainMessageLoop
|
||||||
|
*
|
||||||
|
* Process Win32 window messages and provide special handling
|
||||||
|
* of TWAIN specific messages. This loop will not exit until
|
||||||
|
* the application exits.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
twainMessageLoop(pTW_SESSION twSession)
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||||
|
if (DS_IS_CLOSED(twSession) || !TwainProcessMessage(&msg, twSession)) {
|
||||||
|
TranslateMessage((LPMSG)&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg.wParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LogLastWinError
|
||||||
|
*
|
||||||
|
* Log the last Windows error as returned by
|
||||||
|
* GetLastError.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LogLastWinError(void)
|
||||||
|
{
|
||||||
|
LPVOID lpMsgBuf;
|
||||||
|
|
||||||
|
FormatMessage(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
GetLastError(),
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
|
||||||
|
(LPTSTR) &lpMsgBuf,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
LogMessage("%s\n", lpMsgBuf);
|
||||||
|
|
||||||
|
/* Free the buffer. */
|
||||||
|
LocalFree( lpMsgBuf );
|
||||||
|
}
|
||||||
|
|
||||||
|
void twainQuitApplication ()
|
||||||
|
{
|
||||||
|
PostQuitMessage (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* Win32 entry point and 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... This is what the MAIN() macro
|
||||||
|
* would usually do.
|
||||||
|
*/
|
||||||
|
return gimp_main(&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... This is what the MAIN() macro
|
||||||
|
* would usually do.
|
||||||
|
*/
|
||||||
|
return gimp_main(&PLUG_IN_INFO, __argc, __argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* InitApplication
|
||||||
|
*
|
||||||
|
* Initialize window data and register the window class
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
InitApplication(HINSTANCE hInstance)
|
||||||
|
{
|
||||||
|
WNDCLASS wc;
|
||||||
|
BOOL retValue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in window class structure with parameters to describe
|
||||||
|
* the main window.
|
||||||
|
*/
|
||||||
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
|
wc.lpfnWndProc = (WNDPROC) WndProc;
|
||||||
|
wc.cbClsExtra = 0;
|
||||||
|
wc.cbWndExtra = 0;
|
||||||
|
wc.hInstance = hInstance;
|
||||||
|
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
|
||||||
|
wc.lpszClassName = APP_NAME;
|
||||||
|
wc.lpszMenuName = NULL;
|
||||||
|
|
||||||
|
/* Register the window class and stash success/failure code. */
|
||||||
|
retValue = RegisterClass(&wc);
|
||||||
|
|
||||||
|
/* Log error */
|
||||||
|
if (!retValue)
|
||||||
|
LogLastWinError();
|
||||||
|
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* InitInstance
|
||||||
|
*
|
||||||
|
* Create the main window for the application. Used to
|
||||||
|
* interface with the TWAIN datasource.
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
InitInstance(HINSTANCE hInstance, int nCmdShow, pTW_SESSION twSession)
|
||||||
|
{
|
||||||
|
/* Create our window */
|
||||||
|
hwnd = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
|
||||||
|
NULL, NULL, hInstance, NULL);
|
||||||
|
|
||||||
|
if (!hwnd) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register our window handle with the TWAIN
|
||||||
|
* support.
|
||||||
|
*/
|
||||||
|
registerWindowHandle(twSession, hwnd);
|
||||||
|
|
||||||
|
/* Schedule the image transfer by posting a message */
|
||||||
|
PostMessage(hwnd, WM_TRANSFER_IMAGE, 0, 0);
|
||||||
|
|
||||||
|
ShowWindow(hwnd, nCmdShow);
|
||||||
|
UpdateWindow(hwnd);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* twainWinMain
|
||||||
|
*
|
||||||
|
* This is the function that represents the code that
|
||||||
|
* would normally reside in WinMain (see above). This
|
||||||
|
* function will get called during run() in order to set
|
||||||
|
* up the windowing environment necessary for TWAIN to
|
||||||
|
* operate.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
twainMain()
|
||||||
|
{
|
||||||
|
/* Initialize the twain information */
|
||||||
|
pTW_SESSION twSession = initializeTwain();
|
||||||
|
|
||||||
|
/* Perform instance initialization */
|
||||||
|
if (!InitApplication(hInst))
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
|
/* Perform application initialization */
|
||||||
|
if (!InitInstance(hInst, SHOW_WINDOW, twSession))
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the main message processing loop...
|
||||||
|
* This call will not return until the application
|
||||||
|
* exits.
|
||||||
|
*/
|
||||||
|
return twainMessageLoop(twSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WndProc
|
||||||
|
*
|
||||||
|
* Process window message for the main window.
|
||||||
|
*/
|
||||||
|
LRESULT CALLBACK
|
||||||
|
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (message) {
|
||||||
|
|
||||||
|
case WM_TRANSFER_IMAGE:
|
||||||
|
/* Get an image */
|
||||||
|
scanImage ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_DESTROY:
|
||||||
|
LogMessage("Exiting application\n");
|
||||||
|
PostQuitMessage(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (DefWindowProc(hWnd, message, wParam, lParam));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,10 @@
|
|||||||
* Craig Setera <setera@home.com>
|
* Craig Setera <setera@home.com>
|
||||||
* 03/31/1999
|
* 03/31/1999
|
||||||
*
|
*
|
||||||
|
* Updated for Mac OS X support
|
||||||
|
* Brion Vibber <brion@pobox.com>
|
||||||
|
* 07/22/2004
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -36,16 +40,14 @@
|
|||||||
* - Paletted images (both Gray and RGB)
|
* - Paletted images (both Gray and RGB)
|
||||||
*
|
*
|
||||||
* Prerequisites:
|
* Prerequisites:
|
||||||
* This plug-in will not compile on anything other than a Win32
|
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||||
* platform. Although the TWAIN documentation implies that there
|
* also on 10.2).
|
||||||
* is TWAIN support available on Macintosh, I neither have a
|
|
||||||
* Macintosh nor the interest in porting this. If anyone else
|
|
||||||
* has an interest, consult www.twain.org for more information on
|
|
||||||
* interfacing to TWAIN.
|
|
||||||
*
|
*
|
||||||
* Known problems:
|
* Known problems:
|
||||||
* - Multiple image transfers will hang the plug-in. The current
|
* - Multiple image transfers will hang the plug-in. The current
|
||||||
* configuration compiles with a maximum of single image transfers.
|
* configuration compiles with a maximum of single image transfers.
|
||||||
|
* - On Mac OS X, canceling doesn't always close things out fully.
|
||||||
|
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -55,6 +57,7 @@
|
|||||||
* (02/15/99) v0.3 Added image dump and read support for debugging
|
* (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
|
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||||
* images.
|
* images.
|
||||||
|
* (07/23/04) v0.6 Added Mac OS X support.
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@ -63,7 +66,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <windows.h>
|
|
||||||
|
#include "tw_platform.h"
|
||||||
|
#include "tw_local.h"
|
||||||
|
|
||||||
#include "libgimp/gimp.h"
|
#include "libgimp/gimp.h"
|
||||||
#include "libgimp/stdplugins-intl.h"
|
#include "libgimp/stdplugins-intl.h"
|
||||||
@ -83,7 +88,7 @@
|
|||||||
#define PLUG_IN_HELP "This plug-in will 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 "Craig Setera (setera@home.com)"
|
||||||
#define PLUG_IN_COPYRIGHT "Craig Setera"
|
#define PLUG_IN_COPYRIGHT "Craig Setera"
|
||||||
#define PLUG_IN_VERSION "v0.5 (03/31/1999)"
|
#define PLUG_IN_VERSION "v0.6 (07/22/2004)"
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define PLUG_IN_D_NAME "twain-acquire-dump"
|
#define PLUG_IN_D_NAME "twain-acquire-dump"
|
||||||
@ -93,10 +98,7 @@
|
|||||||
/*
|
/*
|
||||||
* Application definitions
|
* Application definitions
|
||||||
*/
|
*/
|
||||||
#define APP_NAME "TWAIN"
|
|
||||||
#define MAX_IMAGES 1
|
#define MAX_IMAGES 1
|
||||||
#define SHOW_WINDOW 0
|
|
||||||
#define WM_TRANSFER_IMAGE (WM_USER + 100)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of the run states
|
* Definition of the run states
|
||||||
@ -108,10 +110,10 @@
|
|||||||
/* Global variables */
|
/* Global variables */
|
||||||
pTW_SESSION twSession = NULL;
|
pTW_SESSION twSession = NULL;
|
||||||
|
|
||||||
static HWND hwnd = NULL;
|
|
||||||
static HINSTANCE hInst = NULL;
|
|
||||||
static char *destBuf = NULL;
|
static char *destBuf = NULL;
|
||||||
|
#ifdef _DEBUG
|
||||||
static int twain_run_mode = RUN_STANDARD;
|
static int twain_run_mode = RUN_STANDARD;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
void preTransferCallback(void *);
|
void preTransferCallback(void *);
|
||||||
@ -120,8 +122,6 @@ int dataTransferCallback(pTW_IMAGEINFO, pTW_IMAGEMEMXFER, void *);
|
|||||||
int endTransferCallback(int, int, void *);
|
int endTransferCallback(int, int, void *);
|
||||||
void postTransferCallback(int, void *);
|
void postTransferCallback(int, void *);
|
||||||
|
|
||||||
static void init (void);
|
|
||||||
static void quit (void);
|
|
||||||
static void query (void);
|
static void query (void);
|
||||||
static void run (const gchar *name,
|
static void run (const gchar *name,
|
||||||
gint nparams,
|
gint nparams,
|
||||||
@ -140,8 +140,6 @@ GimpPlugInInfo PLUG_IN_INFO =
|
|||||||
|
|
||||||
extern void set_gimp_PLUG_IN_INFO_PTR(GimpPlugInInfo *);
|
extern void set_gimp_PLUG_IN_INFO_PTR(GimpPlugInInfo *);
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
|
|
||||||
|
|
||||||
/* Data structure holding data between runs */
|
/* Data structure holding data between runs */
|
||||||
/* Currently unused... Eventually may be used
|
/* Currently unused... Eventually may be used
|
||||||
* to track dialog data.
|
* to track dialog data.
|
||||||
@ -188,85 +186,34 @@ TXFR_CB_FUNCS dumperCbFuncs = {
|
|||||||
dumpEndTransferCallback,
|
dumpEndTransferCallback,
|
||||||
dumpPostTransferCallback };
|
dumpPostTransferCallback };
|
||||||
|
|
||||||
static void
|
void
|
||||||
setRunMode(char *argv[])
|
setRunMode(char *argv[])
|
||||||
{
|
{
|
||||||
char *exeName = strrchr(argv[0], '\\') + 1;
|
char *exeName = strrchr(argv[0], '\\') + 1;
|
||||||
|
|
||||||
LogMessage("Executable name: %s\n", exeName);
|
LogMessage("Executable name: %s\n", exeName);
|
||||||
|
|
||||||
if (!_stricmp(exeName, "DTWAIN.EXE"))
|
if (!_stricmp(exeName, DUMP_NAME))
|
||||||
twain_run_mode = RUN_DUMP;
|
twain_run_mode = RUN_DUMP;
|
||||||
|
|
||||||
if (!_stricmp(exeName, "RTWAIN.EXE"))
|
if (!_stricmp(exeName, RUNDUMP_NAME))
|
||||||
twain_run_mode = RUN_READDUMP;
|
twain_run_mode = RUN_READDUMP;
|
||||||
}
|
}
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
/******************************************************************
|
#ifndef TWAIN_ALTERNATE_MAIN
|
||||||
* Win32 entry point and setup...
|
MAIN()
|
||||||
******************************************************************/
|
#endif
|
||||||
|
|
||||||
/*
|
int
|
||||||
* WinMain
|
scanImage (void)
|
||||||
*
|
|
||||||
* 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... This is what the MAIN() macro
|
|
||||||
* would usually do.
|
|
||||||
*/
|
|
||||||
return gimp_main(&PLUG_IN_INFO, __argc, __argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* main
|
|
||||||
*
|
|
||||||
* allow to build as console app as well
|
|
||||||
*/
|
|
||||||
int main (int argc, char *argv[])
|
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
/* When in debug version, we allow different run modes...
|
if (twain_run_mode == RUN_READDUMP)
|
||||||
* make sure that it is correctly set.
|
return readDumpedImage (twSession);
|
||||||
*/
|
else
|
||||||
setRunMode(__argv);
|
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
return getImage (twSession);
|
||||||
/*
|
|
||||||
* Now, call gimp_main... This is what the MAIN() macro
|
|
||||||
* would usually do.
|
|
||||||
*/
|
|
||||||
return gimp_main(&PLUG_IN_INFO, __argc, __argv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -286,13 +233,13 @@ getAppIdentity(void)
|
|||||||
appIdentity->Version.MinorNum = 1;
|
appIdentity->Version.MinorNum = 1;
|
||||||
appIdentity->Version.Language = TWLG_USA;
|
appIdentity->Version.Language = TWLG_USA;
|
||||||
appIdentity->Version.Country = TWCY_USA;
|
appIdentity->Version.Country = TWCY_USA;
|
||||||
strcpy(appIdentity->Version.Info, "GIMP TWAIN 0.5");
|
strcpy(appIdentity->Version.Info, "GIMP TWAIN 0.6");
|
||||||
appIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
|
appIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
|
||||||
appIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
|
appIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
|
||||||
appIdentity->SupportedGroups = DG_IMAGE;
|
appIdentity->SupportedGroups = DG_IMAGE;
|
||||||
strcpy(appIdentity->Manufacturer, "Craig Setera");
|
strcpy(appIdentity->Manufacturer, "Craig Setera");
|
||||||
strcpy(appIdentity->ProductFamily, "GIMP");
|
strcpy(appIdentity->ProductFamily, "GIMP");
|
||||||
strcpy(appIdentity->ProductName, "GIMP for Win32");
|
strcpy(appIdentity->ProductName, "GIMP");
|
||||||
|
|
||||||
return appIdentity;
|
return appIdentity;
|
||||||
}
|
}
|
||||||
@ -305,7 +252,7 @@ getAppIdentity(void)
|
|||||||
* something built by me on top of the standard TWAIN
|
* something built by me on top of the standard TWAIN
|
||||||
* datasource manager calls.
|
* datasource manager calls.
|
||||||
*/
|
*/
|
||||||
void
|
pTW_SESSION
|
||||||
initializeTwain(void)
|
initializeTwain(void)
|
||||||
{
|
{
|
||||||
pTW_IDENTITY appIdentity;
|
pTW_IDENTITY appIdentity;
|
||||||
@ -323,139 +270,7 @@ initializeTwain(void)
|
|||||||
else
|
else
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
registerTransferCallbacks(twSession, &standardCbFuncs, NULL);
|
registerTransferCallbacks(twSession, &standardCbFuncs, NULL);
|
||||||
}
|
return twSession;
|
||||||
|
|
||||||
/*
|
|
||||||
* InitApplication
|
|
||||||
*
|
|
||||||
* Initialize window data and register the window class
|
|
||||||
*/
|
|
||||||
BOOL
|
|
||||||
InitApplication(HINSTANCE hInstance)
|
|
||||||
{
|
|
||||||
WNDCLASS wc;
|
|
||||||
BOOL retValue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill in window class structure with parameters to describe
|
|
||||||
* the main window.
|
|
||||||
*/
|
|
||||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
||||||
wc.lpfnWndProc = (WNDPROC) WndProc;
|
|
||||||
wc.cbClsExtra = 0;
|
|
||||||
wc.cbWndExtra = 0;
|
|
||||||
wc.hInstance = hInstance;
|
|
||||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
||||||
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
|
|
||||||
wc.lpszClassName = APP_NAME;
|
|
||||||
wc.lpszMenuName = NULL;
|
|
||||||
|
|
||||||
/* Register the window class and stash success/failure code. */
|
|
||||||
retValue = RegisterClass(&wc);
|
|
||||||
|
|
||||||
/* Log error */
|
|
||||||
if (!retValue)
|
|
||||||
LogLastWinError();
|
|
||||||
|
|
||||||
return retValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* InitInstance
|
|
||||||
*
|
|
||||||
* Create the main window for the application. Used to
|
|
||||||
* interface with the TWAIN datasource.
|
|
||||||
*/
|
|
||||||
BOOL
|
|
||||||
InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|
||||||
{
|
|
||||||
/* Create our window */
|
|
||||||
hwnd = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPEDWINDOW,
|
|
||||||
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
|
|
||||||
NULL, NULL, hInstance, NULL);
|
|
||||||
|
|
||||||
if (!hwnd) {
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowWindow(hwnd, nCmdShow);
|
|
||||||
UpdateWindow(hwnd);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* twainWinMain
|
|
||||||
*
|
|
||||||
* This is the function that represents the code that
|
|
||||||
* would normally reside in WinMain (see above). This
|
|
||||||
* function will get called during run() in order to set
|
|
||||||
* up the windowing environment necessary for TWAIN to
|
|
||||||
* operate.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
twainWinMain(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* Initialize the twain information */
|
|
||||||
initializeTwain();
|
|
||||||
|
|
||||||
/* Perform instance initialization */
|
|
||||||
if (!InitApplication(hInst))
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
/* Perform application initialization */
|
|
||||||
if (!InitInstance(hInst, SHOW_WINDOW))
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Call the main message processing loop...
|
|
||||||
* This call will not return until the application
|
|
||||||
* exits.
|
|
||||||
*/
|
|
||||||
return twainMessageLoop(twSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* WndProc
|
|
||||||
*
|
|
||||||
* Process window message for the main window.
|
|
||||||
*/
|
|
||||||
LRESULT CALLBACK
|
|
||||||
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch (message) {
|
|
||||||
|
|
||||||
case WM_CREATE:
|
|
||||||
/* Register our window handle with the TWAIN
|
|
||||||
* support.
|
|
||||||
*/
|
|
||||||
registerWindowHandle(twSession, hWnd);
|
|
||||||
|
|
||||||
/* Schedule the image transfer by posting a message */
|
|
||||||
PostMessage(hWnd, WM_TRANSFER_IMAGE, 0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_TRANSFER_IMAGE:
|
|
||||||
/* Get an image */
|
|
||||||
#ifdef _DEBUG
|
|
||||||
if (twain_run_mode == RUN_READDUMP)
|
|
||||||
readDumpedImage(twSession);
|
|
||||||
else
|
|
||||||
#endif /* _DEBUG */
|
|
||||||
getImage(twSession);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_DESTROY:
|
|
||||||
LogMessage("Exiting application\n");
|
|
||||||
PostQuitMessage(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return (DefWindowProc(hWnd, message, wParam, lParam));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
@ -625,7 +440,7 @@ run (const gchar *name,
|
|||||||
|
|
||||||
/* Have we succeeded so far? */
|
/* Have we succeeded so far? */
|
||||||
if (values[0].data.d_status == GIMP_PDB_SUCCESS)
|
if (values[0].data.d_status == GIMP_PDB_SUCCESS)
|
||||||
twainWinMain();
|
twainMain ();
|
||||||
|
|
||||||
/* Check to make sure we got at least one valid
|
/* Check to make sure we got at least one valid
|
||||||
* image.
|
* image.
|
||||||
@ -686,7 +501,6 @@ preTransferCallback(void *clientData)
|
|||||||
int
|
int
|
||||||
beginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData)
|
beginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData)
|
||||||
{
|
{
|
||||||
int done = 0;
|
|
||||||
int imageType, layerType;
|
int imageType, layerType;
|
||||||
|
|
||||||
pClientDataStruct theClientData = g_new (ClientDataStruct, 1);
|
pClientDataStruct theClientData = g_new (ClientDataStruct, 1);
|
||||||
@ -749,6 +563,12 @@ beginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData)
|
|||||||
theClientData->image_id = gimp_image_new(imageInfo->ImageWidth,
|
theClientData->image_id = gimp_image_new(imageInfo->ImageWidth,
|
||||||
imageInfo->ImageLength, imageType);
|
imageInfo->ImageLength, imageType);
|
||||||
|
|
||||||
|
/* Set the actual resolution */
|
||||||
|
gimp_image_set_resolution (theClientData->image_id,
|
||||||
|
FIX32ToFloat(imageInfo->XResolution),
|
||||||
|
FIX32ToFloat(imageInfo->YResolution));
|
||||||
|
gimp_image_set_unit (theClientData->image_id, GIMP_UNIT_INCH);
|
||||||
|
|
||||||
/* Create a layer */
|
/* Create a layer */
|
||||||
theClientData->layer_id = gimp_layer_new(theClientData->image_id,
|
theClientData->layer_id = gimp_layer_new(theClientData->image_id,
|
||||||
_("Background"),
|
_("Background"),
|
||||||
@ -905,11 +725,9 @@ twoBytesPerSampleTransferCallback(pTW_IMAGEINFO imageInfo,
|
|||||||
{
|
{
|
||||||
static float ratio = 0.00390625;
|
static float ratio = 0.00390625;
|
||||||
int row, col, sample;
|
int row, col, sample;
|
||||||
char *srcBuf, *destByte;
|
char *destByte;
|
||||||
int rows = imageMemXfer->Rows;
|
int rows = imageMemXfer->Rows;
|
||||||
int cols = imageMemXfer->Columns;
|
int cols = imageMemXfer->Columns;
|
||||||
int bitsPerSample = imageInfo->BitsPerPixel / imageInfo->SamplesPerPixel;
|
|
||||||
int bytesPerSample = bitsPerSample / 8;
|
|
||||||
|
|
||||||
TW_UINT16 *samplePtr;
|
TW_UINT16 *samplePtr;
|
||||||
|
|
||||||
@ -1163,5 +981,5 @@ postTransferCallback(int pendingCount, void *clientData)
|
|||||||
closeDSM(twSession);
|
closeDSM(twSession);
|
||||||
|
|
||||||
/* Post a message to close up the application */
|
/* Post a message to close up the application */
|
||||||
PostQuitMessage(0);
|
twainQuitApplication ();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user