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:
Sven Neumann
2004-07-28 15:54:50 +00:00
committed by Sven Neumann
parent f989a897f1
commit e082fd5572
18 changed files with 1052 additions and 652 deletions

View File

@ -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

View File

@ -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
##########################################################

View File

@ -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

View File

@ -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)

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -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 ();
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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
View 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
View 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;
}

View 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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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
View 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;
}

View File

@ -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 ();
}