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>
|
||||
|
||||
* 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)
|
||||
|
||||
|
||||
############################################################
|
||||
# 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
|
||||
##########################################################
|
||||
|
@ -3,6 +3,11 @@
|
||||
EXTRA_DIST = \
|
||||
makefile.msc
|
||||
|
||||
|
||||
if BUILD_HELPBROWSER
|
||||
helpbrowser = helpbrowser
|
||||
endif
|
||||
|
||||
if BUILD_PRINT
|
||||
print = print
|
||||
endif
|
||||
@ -11,20 +16,19 @@ if BUILD_PYTHON
|
||||
pygimp = pygimp
|
||||
endif
|
||||
|
||||
if BUILD_HELPBROWSER
|
||||
helpbrowser = helpbrowser
|
||||
if HAVE_MAC_TWAIN
|
||||
twain = twain
|
||||
endif
|
||||
|
||||
if OS_WIN32
|
||||
twain = twain
|
||||
winsnap = winsnap
|
||||
endif
|
||||
|
||||
if BUILD_XJT
|
||||
xjt = xjt
|
||||
endif
|
||||
|
||||
if OS_WIN32
|
||||
win32dirs = \
|
||||
twain \
|
||||
winsnap
|
||||
endif
|
||||
|
||||
|
||||
SUBDIRS = \
|
||||
libgimpoldpreview \
|
||||
@ -53,7 +57,8 @@ SUBDIRS = \
|
||||
rcm \
|
||||
sgi \
|
||||
sel2path \
|
||||
$(twain) \
|
||||
winicon \
|
||||
$(win32dirs) \
|
||||
$(winsnap) \
|
||||
$(xjt) \
|
||||
common
|
||||
|
@ -6,25 +6,50 @@ libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la
|
||||
libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
|
||||
libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
|
||||
|
||||
twain_LDFLAGS = -mwindows
|
||||
|
||||
libexecdir = $(gimpplugindir)/plug-ins
|
||||
|
||||
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 = \
|
||||
tw_func.c \
|
||||
tw_func.h \
|
||||
tw_util.c \
|
||||
tw_util.h \
|
||||
twain.c \
|
||||
twain.h
|
||||
twain.h \
|
||||
tw_local.h \
|
||||
tw_platform.h \
|
||||
$(twainplatform)
|
||||
|
||||
EXTRA_DIST = \
|
||||
README \
|
||||
gimp-twain.png \
|
||||
tw_dump.c \
|
||||
tw_dump.h \
|
||||
tw_sess.c
|
||||
tw_sess.c \
|
||||
tw_win.c \
|
||||
tw_mac.c
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
@ -38,4 +63,4 @@ LDADD = \
|
||||
$(GLIB_LIBS) \
|
||||
$(RT_LIBS) \
|
||||
$(INTLLIBS) \
|
||||
-luser32
|
||||
$(twain_LIBS)
|
||||
|
@ -3,6 +3,10 @@ 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
|
||||
@ -34,18 +38,16 @@ images:
|
||||
- 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.
|
||||
Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||
also on 10.2).
|
||||
|
||||
Known problems:
|
||||
|
||||
- Multiple image transfers will hang the plug-in. The current
|
||||
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:
|
||||
There are two different versions of the program included, a standard
|
||||
version and a version built for debugging. The debugging version is
|
||||
|
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 |
@ -1,9 +1,13 @@
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
@ -25,7 +29,7 @@
|
||||
* 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
|
||||
@ -36,27 +40,25 @@
|
||||
* - 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.
|
||||
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||
* also on 10.2).
|
||||
*
|
||||
* Known problems:
|
||||
* - Multiple image transfers will hang the plug-in. The current
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||
* images.
|
||||
* (07/23/04) v0.6 Added Mac OS X support.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "libgimp/gimp.h"
|
||||
@ -194,7 +196,7 @@ dumpPostTransferCallback(int pendingCount, void *clientData)
|
||||
gimp_message(buffer);
|
||||
|
||||
/* Post a message to close up the application */
|
||||
PostQuitMessage(0);
|
||||
twainQuitApplication ();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -262,5 +264,5 @@ void readDumpedImage(pTW_SESSION twSession)
|
||||
twSession->clientData);
|
||||
|
||||
/* Post a message to close up the application */
|
||||
PostQuitMessage(0);
|
||||
twainQuitApplication ();
|
||||
}
|
||||
|
@ -57,12 +57,9 @@
|
||||
* images.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "twain.h"
|
||||
#include "tw_platform.h"
|
||||
#include "tw_func.h"
|
||||
|
||||
#define DUMP_FILE "C:\\TWAINCAP.BIN"
|
||||
|
||||
void dumpPreTransferCallback(void *clientData);
|
||||
int dumpBeginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData);
|
||||
int dumpDataTransferCallback(pTW_IMAGEINFO imageInfo,
|
||||
|
@ -1,9 +1,13 @@
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
@ -25,7 +29,7 @@
|
||||
* 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
|
||||
@ -36,36 +40,33 @@
|
||||
* - 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.
|
||||
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||
* also on 10.2).
|
||||
*
|
||||
* Known problems:
|
||||
* - Multiple image transfers will hang the plug-in. The current
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||
* images.
|
||||
* (07/23/04) v0.6 Added Mac OS X support.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h> /* Needed when compiling with gcc */
|
||||
|
||||
#include <windows.h>
|
||||
#include "twain.h"
|
||||
#include "tw_func.h"
|
||||
#include "tw_util.h"
|
||||
|
||||
/* The DLL to be loaded for TWAIN support */
|
||||
#define TWAIN_DLL_NAME "TWAIN_32.DLL"
|
||||
#include "tw_local.h"
|
||||
|
||||
/*
|
||||
* Twain error code to string mappings
|
||||
@ -97,12 +98,6 @@ static char *twainErrors[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Storage for the DLL handle */
|
||||
static HINSTANCE hDLL = NULL;
|
||||
|
||||
/* Storage for the entry point into the DSM */
|
||||
static DSMENTRYPROC dsmEntryPoint = NULL;
|
||||
|
||||
/*
|
||||
* FloatToFix32
|
||||
*
|
||||
@ -129,23 +124,6 @@ float FIX32ToFloat(TW_FIX32 fix32)
|
||||
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
|
||||
*
|
||||
@ -185,31 +163,6 @@ currentTwainError(pTW_SESSION twSession)
|
||||
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
|
||||
@ -225,6 +178,7 @@ getImage(pTW_SESSION twSession)
|
||||
/* Do some sanity checking first and bail
|
||||
* if necessary.
|
||||
*/
|
||||
|
||||
if (!twainIsAvailable()) {
|
||||
LogMessage("TWAIN is not available for image capture\n");
|
||||
return FALSE;
|
||||
@ -245,7 +199,7 @@ getImage(pTW_SESSION twSession)
|
||||
LogMessage("Unable to open datasource\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
requestImageAcquire(twSession, TRUE);
|
||||
|
||||
return TRUE;
|
||||
@ -421,11 +375,12 @@ setBufferedXfer(pTW_SESSION twSession)
|
||||
/* Create the capability information */
|
||||
bufXfer.Cap = ICAP_XFERMECH;
|
||||
bufXfer.ConType = TWON_ONEVALUE;
|
||||
bufXfer.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE));
|
||||
pvalOneValue = (pTW_ONEVALUE) GlobalLock(bufXfer.hContainer);
|
||||
bufXfer.hContainer = twainAllocHandle(sizeof(TW_ONEVALUE));
|
||||
|
||||
pvalOneValue = (pTW_ONEVALUE) twainLockHandle(bufXfer.hContainer);
|
||||
pvalOneValue->ItemType = TWTY_UINT16;
|
||||
pvalOneValue->Item = TWSX_MEMORY;
|
||||
GlobalUnlock(bufXfer.hContainer);
|
||||
twainUnlockHandle(bufXfer.hContainer);
|
||||
|
||||
/* Make the call to the source manager */
|
||||
twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
|
||||
@ -433,7 +388,7 @@ setBufferedXfer(pTW_SESSION twSession)
|
||||
(TW_MEMREF) &bufXfer);
|
||||
|
||||
/* Free the container */
|
||||
GlobalFree(bufXfer.hContainer);
|
||||
twainFreeHandle(bufXfer.hContainer);
|
||||
|
||||
/* Let the caller know what happened */
|
||||
return (twSession->twRC==TWRC_SUCCESS);
|
||||
@ -447,7 +402,7 @@ setBufferedXfer(pTW_SESSION twSession)
|
||||
* an image to actually be transferred.
|
||||
*/
|
||||
int
|
||||
requestImageAcquire(pTW_SESSION twSession, BOOL showUI)
|
||||
requestImageAcquire(pTW_SESSION twSession, gboolean showUI)
|
||||
{
|
||||
/* Make sure in the correct state */
|
||||
if (DS_IS_CLOSED(twSession)) {
|
||||
@ -455,6 +410,8 @@ requestImageAcquire(pTW_SESSION twSession, BOOL showUI)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
twainSetupCallback(twSession);
|
||||
|
||||
/* Set the transfer mode */
|
||||
if (setBufferedXfer(twSession)) {
|
||||
TW_USERINTERFACE ui;
|
||||
@ -462,6 +419,7 @@ requestImageAcquire(pTW_SESSION twSession, BOOL showUI)
|
||||
/* Set the UI information */
|
||||
ui.ShowUI = TRUE;
|
||||
ui.ModalUI = TRUE;
|
||||
/* In Windows, the callbacks are sent to the window message handler */
|
||||
ui.hParent = twSession->hwnd;
|
||||
|
||||
/* Make the call to the source manager */
|
||||
@ -579,8 +537,8 @@ closeDSM(pTW_SESSION twSession)
|
||||
} else {
|
||||
twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
|
||||
DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM,
|
||||
&(twSession->hwnd));
|
||||
|
||||
(TW_MEMREF)&(twSession->hwnd));
|
||||
|
||||
if (twSession->twRC != TWRC_SUCCESS) {
|
||||
LogMessage("CloseDSM failure -- %s\n", currentTwainError(twSession));
|
||||
}
|
||||
@ -596,32 +554,6 @@ closeDSM(pTW_SESSION twSession)
|
||||
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
|
||||
@ -765,7 +697,7 @@ cancelPendingTransfers(pTW_SESSION twSession)
|
||||
static int
|
||||
endImageTransfer(pTW_SESSION twSession, int *pendingCount)
|
||||
{
|
||||
BOOL continueTransfers;
|
||||
gboolean continueTransfers;
|
||||
int exitCode = twSession->twRC;
|
||||
|
||||
/* Have now exited the transfer for some reason... Figure out
|
||||
@ -844,87 +776,32 @@ transferImages(pTW_SESSION twSession)
|
||||
twSession->clientData);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
void
|
||||
processTwainMessage(TW_UINT16 message, 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 */
|
||||
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);
|
||||
}
|
||||
switch (message) {
|
||||
case MSG_XFERREADY:
|
||||
LogMessage("Source says that data is ready\n");
|
||||
transferImages(twSession);
|
||||
break;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
@ -965,7 +842,7 @@ newSession(pTW_IDENTITY appIdentity) {
|
||||
* session.
|
||||
*/
|
||||
void
|
||||
registerWindowHandle(pTW_SESSION session, HWND hwnd)
|
||||
registerWindowHandle(pTW_SESSION session, TW_HANDLE hwnd)
|
||||
{
|
||||
session->hwnd = hwnd;
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
@ -25,7 +29,7 @@
|
||||
* 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
|
||||
@ -36,30 +40,30 @@
|
||||
* - 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.
|
||||
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||
* also on 10.2).
|
||||
*
|
||||
* Known problems:
|
||||
* - Multiple image transfers will hang the plug-in. The current
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||
* images.
|
||||
* (07/23/04) v0.6 Added Mac OS X support.
|
||||
*/
|
||||
|
||||
#ifndef _TW_FUNC_H
|
||||
#define _TW_FUNC_H
|
||||
#include "twain.h"
|
||||
|
||||
#include "tw_platform.h"
|
||||
|
||||
/*
|
||||
* Pre-image transfer function type
|
||||
@ -147,8 +151,8 @@ typedef struct _TXFR_CB_FUNCS {
|
||||
* session.
|
||||
*/
|
||||
typedef struct _TWAIN_SESSION {
|
||||
/* The window handle related to the TWAIN application */
|
||||
HWND hwnd;
|
||||
/* The window handle related to the TWAIN application on Win32 */
|
||||
TW_HANDLE hwnd;
|
||||
|
||||
/* The current TWAIN return code */
|
||||
TW_UINT16 twRC;
|
||||
@ -204,31 +208,27 @@ typedef struct _TWAIN_SESSION {
|
||||
#define DS_IS_DISABLED(tw_session) (tw_session->twainState < 5)
|
||||
|
||||
/* Function declarations */
|
||||
TW_UINT16 callDSM(pTW_IDENTITY, pTW_IDENTITY,
|
||||
TW_UINT32, TW_UINT16,
|
||||
TW_UINT16, TW_MEMREF);
|
||||
char *twainError(int);
|
||||
char *currentTwainError(pTW_SESSION);
|
||||
int twainIsAvailable(void);
|
||||
int getImage(pTW_SESSION);
|
||||
int loadTwainLibrary(pTW_SESSION);
|
||||
int openDSM(pTW_SESSION);
|
||||
int selectDS(pTW_SESSION);
|
||||
int selectDefaultDS(pTW_SESSION);
|
||||
int openDS(pTW_SESSION);
|
||||
int requestImageAcquire(pTW_SESSION, BOOL);
|
||||
int requestImageAcquire(pTW_SESSION, gboolean);
|
||||
int disableDS(pTW_SESSION);
|
||||
int closeDS(pTW_SESSION);
|
||||
int closeDSM(pTW_SESSION);
|
||||
int unloadTwainLibrary(pTW_SESSION);
|
||||
int twainMessageLoop(pTW_SESSION);
|
||||
void cancelPendingTransfers(pTW_SESSION);
|
||||
|
||||
TW_FIX32 FloatToFix32(float);
|
||||
float FIX32ToFloat(TW_FIX32);
|
||||
|
||||
void processTwainMessage(TW_UINT16 message, pTW_SESSION twSession);
|
||||
|
||||
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 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;
|
||||
}
|
@ -1,9 +1,13 @@
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
@ -25,7 +29,7 @@
|
||||
* 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
|
||||
@ -36,34 +40,37 @@
|
||||
* - 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.
|
||||
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||
* also on 10.2).
|
||||
*
|
||||
* Known problems:
|
||||
* - Multiple image transfers will hang the plug-in. The current
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||
* images.
|
||||
* (07/23/04) v0.6 Added Mac OS X support.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h> /* Needed when compiling with gcc */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "tw_util.h"
|
||||
#ifdef _DEBUG
|
||||
#include "tw_func.h"
|
||||
@ -71,6 +78,7 @@ FILE *logFile = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
/*
|
||||
* LogMessage
|
||||
*/
|
||||
@ -83,7 +91,7 @@ LogMessage(char *format, ...)
|
||||
|
||||
/* Open the log file as necessary */
|
||||
if (!logFile)
|
||||
logFile = fopen("c:\\twain.log", "w");
|
||||
logFile = fopen(DEBUG_LOGFILE, "w");
|
||||
|
||||
time_of_day = time(NULL);
|
||||
ctime_string = ctime(&time_of_day);
|
||||
@ -96,36 +104,6 @@ LogMessage(char *format, ...)
|
||||
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
|
||||
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 */
|
||||
|
@ -1,9 +1,13 @@
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
@ -25,7 +29,7 @@
|
||||
* 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
|
||||
@ -36,32 +40,31 @@
|
||||
* - 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.
|
||||
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||
* also on 10.2).
|
||||
*
|
||||
* Known problems:
|
||||
* - Multiple image transfers will hang the plug-in. The current
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||
* images.
|
||||
* (07/23/04) v0.6 Added Mac OS X support.
|
||||
*/
|
||||
#ifndef __TW_UTIL_H
|
||||
#define __TW_UTIL_H
|
||||
#include "twain.h"
|
||||
|
||||
#include "tw_platform.h"
|
||||
|
||||
void LogMessage(char *, ...);
|
||||
void LogLastWinError(void) ;
|
||||
|
||||
#ifdef _DEBUG
|
||||
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>
|
||||
* 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
|
||||
@ -36,16 +40,14 @@
|
||||
* - 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.
|
||||
* Should compile and run on both Win32 and Mac OS X 10.3 (possibly
|
||||
* also on 10.2).
|
||||
*
|
||||
* Known problems:
|
||||
* - Multiple image transfers will hang the plug-in. The current
|
||||
* 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
|
||||
* (03/31/99) v0.5 Added support for multi-byte samples and paletted
|
||||
* images.
|
||||
* (07/23/04) v0.6 Added Mac OS X support.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
@ -63,7 +66,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "tw_platform.h"
|
||||
#include "tw_local.h"
|
||||
|
||||
#include "libgimp/gimp.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_AUTHOR "Craig Setera (setera@home.com)"
|
||||
#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
|
||||
#define PLUG_IN_D_NAME "twain-acquire-dump"
|
||||
@ -93,10 +98,7 @@
|
||||
/*
|
||||
* Application definitions
|
||||
*/
|
||||
#define APP_NAME "TWAIN"
|
||||
#define MAX_IMAGES 1
|
||||
#define SHOW_WINDOW 0
|
||||
#define WM_TRANSFER_IMAGE (WM_USER + 100)
|
||||
|
||||
/*
|
||||
* Definition of the run states
|
||||
@ -108,10 +110,10 @@
|
||||
/* Global variables */
|
||||
pTW_SESSION twSession = NULL;
|
||||
|
||||
static HWND hwnd = NULL;
|
||||
static HINSTANCE hInst = NULL;
|
||||
static char *destBuf = NULL;
|
||||
#ifdef _DEBUG
|
||||
static int twain_run_mode = RUN_STANDARD;
|
||||
#endif
|
||||
|
||||
/* Forward declarations */
|
||||
void preTransferCallback(void *);
|
||||
@ -120,8 +122,6 @@ int dataTransferCallback(pTW_IMAGEINFO, pTW_IMAGEMEMXFER, void *);
|
||||
int endTransferCallback(int, int, void *);
|
||||
void postTransferCallback(int, void *);
|
||||
|
||||
static void init (void);
|
||||
static void quit (void);
|
||||
static void query (void);
|
||||
static void run (const gchar *name,
|
||||
gint nparams,
|
||||
@ -140,8 +140,6 @@ GimpPlugInInfo PLUG_IN_INFO =
|
||||
|
||||
extern void set_gimp_PLUG_IN_INFO_PTR(GimpPlugInInfo *);
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
/* Data structure holding data between runs */
|
||||
/* Currently unused... Eventually may be used
|
||||
* to track dialog data.
|
||||
@ -188,85 +186,34 @@ TXFR_CB_FUNCS dumperCbFuncs = {
|
||||
dumpEndTransferCallback,
|
||||
dumpPostTransferCallback };
|
||||
|
||||
static void
|
||||
void
|
||||
setRunMode(char *argv[])
|
||||
{
|
||||
char *exeName = strrchr(argv[0], '\\') + 1;
|
||||
|
||||
LogMessage("Executable name: %s\n", exeName);
|
||||
|
||||
if (!_stricmp(exeName, "DTWAIN.EXE"))
|
||||
if (!_stricmp(exeName, DUMP_NAME))
|
||||
twain_run_mode = RUN_DUMP;
|
||||
|
||||
if (!_stricmp(exeName, "RTWAIN.EXE"))
|
||||
if (!_stricmp(exeName, RUNDUMP_NAME))
|
||||
twain_run_mode = RUN_READDUMP;
|
||||
}
|
||||
#endif /* _DEBUG */
|
||||
|
||||
/******************************************************************
|
||||
* Win32 entry point and setup...
|
||||
******************************************************************/
|
||||
#ifndef TWAIN_ALTERNATE_MAIN
|
||||
MAIN()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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[])
|
||||
int
|
||||
scanImage (void)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
/* When in debug version, we allow different run modes...
|
||||
* make sure that it is correctly set.
|
||||
*/
|
||||
setRunMode(__argv);
|
||||
if (twain_run_mode == RUN_READDUMP)
|
||||
return readDumpedImage (twSession);
|
||||
else
|
||||
#endif /* _DEBUG */
|
||||
|
||||
/*
|
||||
* Now, call gimp_main... This is what the MAIN() macro
|
||||
* would usually do.
|
||||
*/
|
||||
return gimp_main(&PLUG_IN_INFO, __argc, __argv);
|
||||
return getImage (twSession);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -286,13 +233,13 @@ getAppIdentity(void)
|
||||
appIdentity->Version.MinorNum = 1;
|
||||
appIdentity->Version.Language = TWLG_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->ProtocolMinor = TWON_PROTOCOLMINOR;
|
||||
appIdentity->SupportedGroups = DG_IMAGE;
|
||||
strcpy(appIdentity->Manufacturer, "Craig Setera");
|
||||
strcpy(appIdentity->ProductFamily, "GIMP");
|
||||
strcpy(appIdentity->ProductName, "GIMP for Win32");
|
||||
strcpy(appIdentity->ProductName, "GIMP");
|
||||
|
||||
return appIdentity;
|
||||
}
|
||||
@ -305,7 +252,7 @@ getAppIdentity(void)
|
||||
* something built by me on top of the standard TWAIN
|
||||
* datasource manager calls.
|
||||
*/
|
||||
void
|
||||
pTW_SESSION
|
||||
initializeTwain(void)
|
||||
{
|
||||
pTW_IDENTITY appIdentity;
|
||||
@ -323,139 +270,7 @@ initializeTwain(void)
|
||||
else
|
||||
#endif /* _DEBUG */
|
||||
registerTransferCallbacks(twSession, &standardCbFuncs, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
return twSession;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
@ -625,7 +440,7 @@ run (const gchar *name,
|
||||
|
||||
/* Have we succeeded so far? */
|
||||
if (values[0].data.d_status == GIMP_PDB_SUCCESS)
|
||||
twainWinMain();
|
||||
twainMain ();
|
||||
|
||||
/* Check to make sure we got at least one valid
|
||||
* image.
|
||||
@ -686,7 +501,6 @@ preTransferCallback(void *clientData)
|
||||
int
|
||||
beginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData)
|
||||
{
|
||||
int done = 0;
|
||||
int imageType, layerType;
|
||||
|
||||
pClientDataStruct theClientData = g_new (ClientDataStruct, 1);
|
||||
@ -748,7 +562,13 @@ beginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData)
|
||||
/* Create the GIMP image */
|
||||
theClientData->image_id = gimp_image_new(imageInfo->ImageWidth,
|
||||
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 */
|
||||
theClientData->layer_id = gimp_layer_new(theClientData->image_id,
|
||||
_("Background"),
|
||||
@ -905,11 +725,9 @@ twoBytesPerSampleTransferCallback(pTW_IMAGEINFO imageInfo,
|
||||
{
|
||||
static float ratio = 0.00390625;
|
||||
int row, col, sample;
|
||||
char *srcBuf, *destByte;
|
||||
char *destByte;
|
||||
int rows = imageMemXfer->Rows;
|
||||
int cols = imageMemXfer->Columns;
|
||||
int bitsPerSample = imageInfo->BitsPerPixel / imageInfo->SamplesPerPixel;
|
||||
int bytesPerSample = bitsPerSample / 8;
|
||||
|
||||
TW_UINT16 *samplePtr;
|
||||
|
||||
@ -1163,5 +981,5 @@ postTransferCallback(int pendingCount, void *clientData)
|
||||
closeDSM(twSession);
|
||||
|
||||
/* Post a message to close up the application */
|
||||
PostQuitMessage(0);
|
||||
twainQuitApplication ();
|
||||
}
|
||||
|
Reference in New Issue
Block a user