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> 2004-07-28 Michael Natterer <mitch@gimp.org>
* tools/pdbgen/pdb/image.pdb (image_is_dirty): fix typo in * tools/pdbgen/pdb/image.pdb (image_is_dirty): fix typo in

View File

@ -1324,6 +1324,21 @@ AC_SUBST(WINPRINT)
AC_SUBST(WMF) AC_SUBST(WMF)
############################################################
# Check for Mac OS X TWAIN framework (can't build on Darwin)
############################################################
AC_MSG_CHECKING([checking for Mac OS X TWAIN support])
AC_TRY_CPP([
#include <Carbon/Carbon.h>
#include <TWAIN/TWAIN.h>
],
twain_ok=yes,
twain_ok=no)
AC_MSG_RESULT($twain_ok)
AM_CONDITIONAL(HAVE_MAC_TWAIN, test x$twain_ok = xyes)
########################################################## ##########################################################
# Determine where to install the desktop & mime info files # Determine where to install the desktop & mime info files
########################################################## ##########################################################

View File

@ -3,6 +3,11 @@
EXTRA_DIST = \ EXTRA_DIST = \
makefile.msc makefile.msc
if BUILD_HELPBROWSER
helpbrowser = helpbrowser
endif
if BUILD_PRINT if BUILD_PRINT
print = print print = print
endif endif
@ -11,20 +16,19 @@ if BUILD_PYTHON
pygimp = pygimp pygimp = pygimp
endif endif
if BUILD_HELPBROWSER if HAVE_MAC_TWAIN
helpbrowser = helpbrowser twain = twain
endif
if OS_WIN32
twain = twain
winsnap = winsnap
endif endif
if BUILD_XJT if BUILD_XJT
xjt = xjt xjt = xjt
endif endif
if OS_WIN32
win32dirs = \
twain \
winsnap
endif
SUBDIRS = \ SUBDIRS = \
libgimpoldpreview \ libgimpoldpreview \
@ -53,7 +57,8 @@ SUBDIRS = \
rcm \ rcm \
sgi \ sgi \
sel2path \ sel2path \
$(twain) \
winicon \ winicon \
$(win32dirs) \ $(winsnap) \
$(xjt) \ $(xjt) \
common common

View File

@ -6,25 +6,50 @@ libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la
libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
twain_LDFLAGS = -mwindows
libexecdir = $(gimpplugindir)/plug-ins libexecdir = $(gimpplugindir)/plug-ins
libexec_PROGRAMS = twain libexec_PROGRAMS = twain
if OS_WIN32
twain_LDFLAGS = -mwindows
winlink = -luser32
twainplatform = tw_win.c
endif
if HAVE_MAC_TWAIN
maclink = -framework Carbon -framework TWAIN
twainplatform = tw_mac.c
twaindatadir = $(gimpdatadir)/twain
twaindata_DATA = gimp-twain.png
endif
AM_LDFLAGS = $(winlink) $(maclink)
twain_SOURCES = \ twain_SOURCES = \
tw_func.c \ tw_func.c \
tw_func.h \ tw_func.h \
tw_util.c \ tw_util.c \
tw_util.h \ tw_util.h \
twain.c \ twain.c \
twain.h twain.h \
tw_local.h \
tw_platform.h \
$(twainplatform)
EXTRA_DIST = \ EXTRA_DIST = \
README \ README \
gimp-twain.png \
tw_dump.c \ tw_dump.c \
tw_dump.h \ tw_dump.h \
tw_sess.c tw_sess.c \
tw_win.c \
tw_mac.c
INCLUDES = \ INCLUDES = \
-I$(top_srcdir) \ -I$(top_srcdir) \
@ -38,4 +63,4 @@ LDADD = \
$(GLIB_LIBS) \ $(GLIB_LIBS) \
$(RT_LIBS) \ $(RT_LIBS) \
$(INTLLIBS) \ $(INTLLIBS) \
-luser32 $(twain_LIBS)

View File

@ -3,6 +3,10 @@ Copyright (C) 1999 Craig Setera
Craig Setera <setera@home.com> Craig Setera <setera@home.com>
03/31/1999 03/31/1999
Updated for Mac OS X support
Brion Vibber <brion@pobox.com>
07/22/2004
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
@ -34,17 +38,15 @@ images:
- Paletted images (both Gray and RGB) - Paletted images (both Gray and RGB)
Prerequisites: Prerequisites:
This plug-in will not compile on anything other than a Win32 Should compile and run on both Win32 and Mac OS X 10.3 (possibly
platform. Although the TWAIN documentation implies that there also on 10.2).
is TWAIN support available on Macintosh, I neither have a
Macintosh nor the interest in porting this. If anyone else
has an interest, consult www.twain.org for more information on
interfacing to TWAIN.
Known problems: Known problems:
- Multiple image transfers will hang the plug-in. The current - Multiple image transfers will hang the plug-in. The current
configuration compiles with a maximum of single image transfers. configuration compiles with a maximum of single image transfers.
- On Mac OS X, canceling doesn't always close things out fully.
- Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
Debugging: Debugging:
There are two different versions of the program included, a standard There are two different versions of the program included, a standard

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -4,6 +4,10 @@
* Craig Setera <setera@home.com> * Craig Setera <setera@home.com>
* 03/31/1999 * 03/31/1999
* *
* Updated for Mac OS X support
* Brion Vibber <brion@pobox.com>
* 07/22/2004
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -36,16 +40,14 @@
* - Paletted images (both Gray and RGB) * - Paletted images (both Gray and RGB)
* *
* Prerequisites: * Prerequisites:
* This plug-in will not compile on anything other than a Win32 * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
* platform. Although the TWAIN documentation implies that there * also on 10.2).
* is TWAIN support available on Macintosh, I neither have a
* Macintosh nor the interest in porting this. If anyone else
* has an interest, consult www.twain.org for more information on
* interfacing to TWAIN.
* *
* Known problems: * Known problems:
* - Multiple image transfers will hang the plug-in. The current * - Multiple image transfers will hang the plug-in. The current
* configuration compiles with a maximum of single image transfers. * configuration compiles with a maximum of single image transfers.
* - On Mac OS X, canceling doesn't always close things out fully.
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
*/ */
/* /*
@ -55,8 +57,8 @@
* (02/15/99) v0.3 Added image dump and read support for debugging * (02/15/99) v0.3 Added image dump and read support for debugging
* (03/31/99) v0.5 Added support for multi-byte samples and paletted * (03/31/99) v0.5 Added support for multi-byte samples and paletted
* images. * images.
* (07/23/04) v0.6 Added Mac OS X support.
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "libgimp/gimp.h" #include "libgimp/gimp.h"
@ -194,7 +196,7 @@ dumpPostTransferCallback(int pendingCount, void *clientData)
gimp_message(buffer); gimp_message(buffer);
/* Post a message to close up the application */ /* Post a message to close up the application */
PostQuitMessage(0); twainQuitApplication ();
} }
/* /*
@ -262,5 +264,5 @@ void readDumpedImage(pTW_SESSION twSession)
twSession->clientData); twSession->clientData);
/* Post a message to close up the application */ /* Post a message to close up the application */
PostQuitMessage(0); twainQuitApplication ();
} }

View File

@ -57,12 +57,9 @@
* images. * images.
*/ */
#include <windows.h> #include "tw_platform.h"
#include "twain.h"
#include "tw_func.h" #include "tw_func.h"
#define DUMP_FILE "C:\\TWAINCAP.BIN"
void dumpPreTransferCallback(void *clientData); void dumpPreTransferCallback(void *clientData);
int dumpBeginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData); int dumpBeginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData);
int dumpDataTransferCallback(pTW_IMAGEINFO imageInfo, int dumpDataTransferCallback(pTW_IMAGEINFO imageInfo,

View File

@ -4,6 +4,10 @@
* Craig Setera <setera@home.com> * Craig Setera <setera@home.com>
* 03/31/1999 * 03/31/1999
* *
* Updated for Mac OS X support
* Brion Vibber <brion@pobox.com>
* 07/22/2004
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -36,16 +40,14 @@
* - Paletted images (both Gray and RGB) * - Paletted images (both Gray and RGB)
* *
* Prerequisites: * Prerequisites:
* This plug-in will not compile on anything other than a Win32 * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
* platform. Although the TWAIN documentation implies that there * also on 10.2).
* is TWAIN support available on Macintosh, I neither have a
* Macintosh nor the interest in porting this. If anyone else
* has an interest, consult www.twain.org for more information on
* interfacing to TWAIN.
* *
* Known problems: * Known problems:
* - Multiple image transfers will hang the plug-in. The current * - Multiple image transfers will hang the plug-in. The current
* configuration compiles with a maximum of single image transfers. * configuration compiles with a maximum of single image transfers.
* - On Mac OS X, canceling doesn't always close things out fully.
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
*/ */
/* /*
@ -55,17 +57,16 @@
* (02/15/99) v0.3 Added image dump and read support for debugging * (02/15/99) v0.3 Added image dump and read support for debugging
* (03/31/99) v0.5 Added support for multi-byte samples and paletted * (03/31/99) v0.5 Added support for multi-byte samples and paletted
* images. * images.
* (07/23/04) v0.6 Added Mac OS X support.
*/ */
#include "config.h"
#include <glib.h> /* Needed when compiling with gcc */ #include <glib.h> /* Needed when compiling with gcc */
#include <windows.h>
#include "twain.h"
#include "tw_func.h" #include "tw_func.h"
#include "tw_util.h" #include "tw_util.h"
#include "tw_local.h"
/* The DLL to be loaded for TWAIN support */
#define TWAIN_DLL_NAME "TWAIN_32.DLL"
/* /*
* Twain error code to string mappings * Twain error code to string mappings
@ -97,12 +98,6 @@ static char *twainErrors[] = {
NULL NULL
}; };
/* Storage for the DLL handle */
static HINSTANCE hDLL = NULL;
/* Storage for the entry point into the DSM */
static DSMENTRYPROC dsmEntryPoint = NULL;
/* /*
* FloatToFix32 * FloatToFix32
* *
@ -129,23 +124,6 @@ float FIX32ToFloat(TW_FIX32 fix32)
return floater; return floater;
} }
/*
* callDSM
*
* Call the specified function on the data source manager.
*/
TW_UINT16
callDSM(pTW_IDENTITY pOrigin,
pTW_IDENTITY pDest,
TW_UINT32 DG,
TW_UINT16 DAT,
TW_UINT16 MSG,
TW_MEMREF pData)
{
/* Call the function */
return (*dsmEntryPoint) (pOrigin, pDest, DG, DAT, MSG, pData);
}
/* /*
* twainError * twainError
* *
@ -185,31 +163,6 @@ currentTwainError(pTW_SESSION twSession)
return twainError(twStatus.ConditionCode); return twainError(twStatus.ConditionCode);
} }
/*
* twainIsAvailable
*
* Return boolean indicating whether TWAIN is available
*/
int
twainIsAvailable(void)
{
/* Already loaded? */
if (dsmEntryPoint) {
return TRUE;
}
/* Attempt to load the library */
hDLL = LoadLibrary(TWAIN_DLL_NAME);
if (hDLL == NULL)
return FALSE;
/* Look up the entry point for use */
dsmEntryPoint = (DSMENTRYPROC) GetProcAddress(hDLL, "DSM_Entry");
if (dsmEntryPoint == NULL)
return FALSE;
return TRUE;
}
/* /*
* getImage * getImage
@ -225,6 +178,7 @@ getImage(pTW_SESSION twSession)
/* Do some sanity checking first and bail /* Do some sanity checking first and bail
* if necessary. * if necessary.
*/ */
if (!twainIsAvailable()) { if (!twainIsAvailable()) {
LogMessage("TWAIN is not available for image capture\n"); LogMessage("TWAIN is not available for image capture\n");
return FALSE; return FALSE;
@ -421,11 +375,12 @@ setBufferedXfer(pTW_SESSION twSession)
/* Create the capability information */ /* Create the capability information */
bufXfer.Cap = ICAP_XFERMECH; bufXfer.Cap = ICAP_XFERMECH;
bufXfer.ConType = TWON_ONEVALUE; bufXfer.ConType = TWON_ONEVALUE;
bufXfer.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE)); bufXfer.hContainer = twainAllocHandle(sizeof(TW_ONEVALUE));
pvalOneValue = (pTW_ONEVALUE) GlobalLock(bufXfer.hContainer);
pvalOneValue = (pTW_ONEVALUE) twainLockHandle(bufXfer.hContainer);
pvalOneValue->ItemType = TWTY_UINT16; pvalOneValue->ItemType = TWTY_UINT16;
pvalOneValue->Item = TWSX_MEMORY; pvalOneValue->Item = TWSX_MEMORY;
GlobalUnlock(bufXfer.hContainer); twainUnlockHandle(bufXfer.hContainer);
/* Make the call to the source manager */ /* Make the call to the source manager */
twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession), twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
@ -433,7 +388,7 @@ setBufferedXfer(pTW_SESSION twSession)
(TW_MEMREF) &bufXfer); (TW_MEMREF) &bufXfer);
/* Free the container */ /* Free the container */
GlobalFree(bufXfer.hContainer); twainFreeHandle(bufXfer.hContainer);
/* Let the caller know what happened */ /* Let the caller know what happened */
return (twSession->twRC==TWRC_SUCCESS); return (twSession->twRC==TWRC_SUCCESS);
@ -447,7 +402,7 @@ setBufferedXfer(pTW_SESSION twSession)
* an image to actually be transferred. * an image to actually be transferred.
*/ */
int int
requestImageAcquire(pTW_SESSION twSession, BOOL showUI) requestImageAcquire(pTW_SESSION twSession, gboolean showUI)
{ {
/* Make sure in the correct state */ /* Make sure in the correct state */
if (DS_IS_CLOSED(twSession)) { if (DS_IS_CLOSED(twSession)) {
@ -455,6 +410,8 @@ requestImageAcquire(pTW_SESSION twSession, BOOL showUI)
return FALSE; return FALSE;
} }
twainSetupCallback(twSession);
/* Set the transfer mode */ /* Set the transfer mode */
if (setBufferedXfer(twSession)) { if (setBufferedXfer(twSession)) {
TW_USERINTERFACE ui; TW_USERINTERFACE ui;
@ -462,6 +419,7 @@ requestImageAcquire(pTW_SESSION twSession, BOOL showUI)
/* Set the UI information */ /* Set the UI information */
ui.ShowUI = TRUE; ui.ShowUI = TRUE;
ui.ModalUI = TRUE; ui.ModalUI = TRUE;
/* In Windows, the callbacks are sent to the window message handler */
ui.hParent = twSession->hwnd; ui.hParent = twSession->hwnd;
/* Make the call to the source manager */ /* Make the call to the source manager */
@ -579,7 +537,7 @@ closeDSM(pTW_SESSION twSession)
} else { } else {
twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL, twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM,
&(twSession->hwnd)); (TW_MEMREF)&(twSession->hwnd));
if (twSession->twRC != TWRC_SUCCESS) { if (twSession->twRC != TWRC_SUCCESS) {
LogMessage("CloseDSM failure -- %s\n", currentTwainError(twSession)); LogMessage("CloseDSM failure -- %s\n", currentTwainError(twSession));
@ -596,32 +554,6 @@ closeDSM(pTW_SESSION twSession)
return (twSession->twRC==TWRC_SUCCESS); return (twSession->twRC==TWRC_SUCCESS);
} }
/*
* unloadTwainLibrary
*
* Unload the TWAIN dynamic link library
*/
int
unloadTwainLibrary(pTW_SESSION twSession)
{
/* Explicitly free the SM library */
if (hDLL) {
FreeLibrary(hDLL);
hDLL=NULL;
}
/* the data source id will no longer be valid after
* twain is killed. If the id is left around the
* data source can not be found or opened
*/
DS_IDENTITY(twSession)->Id = 0;
/* We are now back at state 1 */
twSession->twainState = 1;
LogMessage("Source Manager successfully closed\n");
return TRUE;
}
/* /*
* beginImageTransfer * beginImageTransfer
@ -765,7 +697,7 @@ cancelPendingTransfers(pTW_SESSION twSession)
static int static int
endImageTransfer(pTW_SESSION twSession, int *pendingCount) endImageTransfer(pTW_SESSION twSession, int *pendingCount)
{ {
BOOL continueTransfers; gboolean continueTransfers;
int exitCode = twSession->twRC; int exitCode = twSession->twRC;
/* Have now exited the transfer for some reason... Figure out /* Have now exited the transfer for some reason... Figure out
@ -844,39 +776,10 @@ transferImages(pTW_SESSION twSession)
twSession->clientData); twSession->clientData);
} }
/* void
* TwainProcessMessage processTwainMessage(TW_UINT16 message, pTW_SESSION twSession)
*
* Returns TRUE if the application should process message as usual.
* Returns FALSE if the application should skip processing of this message
*/
int
TwainProcessMessage(LPMSG lpMsg, pTW_SESSION twSession)
{ {
TW_EVENT twEvent; switch (message) {
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: case MSG_XFERREADY:
LogMessage("Source says that data is ready\n"); LogMessage("Source says that data is ready\n");
transferImages(twSession); transferImages(twSession);
@ -899,32 +802,6 @@ TwainProcessMessage(LPMSG lpMsg, pTW_SESSION twSession)
default: default:
break; break;
} }
}
/* tell the caller what happened */
return (twSession->twRC == TWRC_DSEVENT);
}
/*
* twainMessageLoop
*
* Process Win32 window messages and provide special handling
* of TWAIN specific messages. This loop will not exit until
* the application exits.
*/
int
twainMessageLoop(pTW_SESSION twSession)
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
if (DS_IS_CLOSED(twSession) || !TwainProcessMessage(&msg, twSession)) {
TranslateMessage((LPMSG)&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
} }
/********************************************************************** /**********************************************************************
@ -965,7 +842,7 @@ newSession(pTW_IDENTITY appIdentity) {
* session. * session.
*/ */
void void
registerWindowHandle(pTW_SESSION session, HWND hwnd) registerWindowHandle(pTW_SESSION session, TW_HANDLE hwnd)
{ {
session->hwnd = hwnd; session->hwnd = hwnd;
} }

View File

@ -4,6 +4,10 @@
* Craig Setera <setera@home.com> * Craig Setera <setera@home.com>
* 03/31/1999 * 03/31/1999
* *
* Updated for Mac OS X support
* Brion Vibber <brion@pobox.com>
* 07/22/2004
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -36,16 +40,14 @@
* - Paletted images (both Gray and RGB) * - Paletted images (both Gray and RGB)
* *
* Prerequisites: * Prerequisites:
* This plug-in will not compile on anything other than a Win32 * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
* platform. Although the TWAIN documentation implies that there * also on 10.2).
* is TWAIN support available on Macintosh, I neither have a
* Macintosh nor the interest in porting this. If anyone else
* has an interest, consult www.twain.org for more information on
* interfacing to TWAIN.
* *
* Known problems: * Known problems:
* - Multiple image transfers will hang the plug-in. The current * - Multiple image transfers will hang the plug-in. The current
* configuration compiles with a maximum of single image transfers. * configuration compiles with a maximum of single image transfers.
* - On Mac OS X, canceling doesn't always close things out fully.
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
*/ */
/* /*
@ -55,11 +57,13 @@
* (02/15/99) v0.3 Added image dump and read support for debugging * (02/15/99) v0.3 Added image dump and read support for debugging
* (03/31/99) v0.5 Added support for multi-byte samples and paletted * (03/31/99) v0.5 Added support for multi-byte samples and paletted
* images. * images.
* (07/23/04) v0.6 Added Mac OS X support.
*/ */
#ifndef _TW_FUNC_H #ifndef _TW_FUNC_H
#define _TW_FUNC_H #define _TW_FUNC_H
#include "twain.h"
#include "tw_platform.h"
/* /*
* Pre-image transfer function type * Pre-image transfer function type
@ -147,8 +151,8 @@ typedef struct _TXFR_CB_FUNCS {
* session. * session.
*/ */
typedef struct _TWAIN_SESSION { typedef struct _TWAIN_SESSION {
/* The window handle related to the TWAIN application */ /* The window handle related to the TWAIN application on Win32 */
HWND hwnd; TW_HANDLE hwnd;
/* The current TWAIN return code */ /* The current TWAIN return code */
TW_UINT16 twRC; TW_UINT16 twRC;
@ -204,31 +208,27 @@ typedef struct _TWAIN_SESSION {
#define DS_IS_DISABLED(tw_session) (tw_session->twainState < 5) #define DS_IS_DISABLED(tw_session) (tw_session->twainState < 5)
/* Function declarations */ /* Function declarations */
TW_UINT16 callDSM(pTW_IDENTITY, pTW_IDENTITY,
TW_UINT32, TW_UINT16,
TW_UINT16, TW_MEMREF);
char *twainError(int); char *twainError(int);
char *currentTwainError(pTW_SESSION); char *currentTwainError(pTW_SESSION);
int twainIsAvailable(void);
int getImage(pTW_SESSION); int getImage(pTW_SESSION);
int loadTwainLibrary(pTW_SESSION); int loadTwainLibrary(pTW_SESSION);
int openDSM(pTW_SESSION); int openDSM(pTW_SESSION);
int selectDS(pTW_SESSION); int selectDS(pTW_SESSION);
int selectDefaultDS(pTW_SESSION); int selectDefaultDS(pTW_SESSION);
int openDS(pTW_SESSION); int openDS(pTW_SESSION);
int requestImageAcquire(pTW_SESSION, BOOL); int requestImageAcquire(pTW_SESSION, gboolean);
int disableDS(pTW_SESSION); int disableDS(pTW_SESSION);
int closeDS(pTW_SESSION); int closeDS(pTW_SESSION);
int closeDSM(pTW_SESSION); int closeDSM(pTW_SESSION);
int unloadTwainLibrary(pTW_SESSION);
int twainMessageLoop(pTW_SESSION);
void cancelPendingTransfers(pTW_SESSION); void cancelPendingTransfers(pTW_SESSION);
TW_FIX32 FloatToFix32(float); TW_FIX32 FloatToFix32(float);
float FIX32ToFloat(TW_FIX32); float FIX32ToFloat(TW_FIX32);
void processTwainMessage(TW_UINT16 message, pTW_SESSION twSession);
pTW_SESSION newSession(pTW_IDENTITY); pTW_SESSION newSession(pTW_IDENTITY);
void registerWindowHandle(pTW_SESSION, HWND); void registerWindowHandle(pTW_SESSION, TW_HANDLE);
void registerTransferCallbacks(pTW_SESSION, pTXFR_CB_FUNCS, void *); void registerTransferCallbacks(pTW_SESSION, pTXFR_CB_FUNCS, void *);
void setClientData(pTW_SESSION session, void *clientData); void setClientData(pTW_SESSION session, void *clientData);

49
plug-ins/twain/tw_local.h Normal file
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

@ -4,6 +4,10 @@
* Craig Setera <setera@home.com> * Craig Setera <setera@home.com>
* 03/31/1999 * 03/31/1999
* *
* Updated for Mac OS X support
* Brion Vibber <brion@pobox.com>
* 07/22/2004
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -36,16 +40,14 @@
* - Paletted images (both Gray and RGB) * - Paletted images (both Gray and RGB)
* *
* Prerequisites: * Prerequisites:
* This plug-in will not compile on anything other than a Win32 * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
* platform. Although the TWAIN documentation implies that there * also on 10.2).
* is TWAIN support available on Macintosh, I neither have a
* Macintosh nor the interest in porting this. If anyone else
* has an interest, consult www.twain.org for more information on
* interfacing to TWAIN.
* *
* Known problems: * Known problems:
* - Multiple image transfers will hang the plug-in. The current * - Multiple image transfers will hang the plug-in. The current
* configuration compiles with a maximum of single image transfers. * configuration compiles with a maximum of single image transfers.
* - On Mac OS X, canceling doesn't always close things out fully.
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
*/ */
/* /*
@ -55,15 +57,20 @@
* (02/15/99) v0.3 Added image dump and read support for debugging * (02/15/99) v0.3 Added image dump and read support for debugging
* (03/31/99) v0.5 Added support for multi-byte samples and paletted * (03/31/99) v0.5 Added support for multi-byte samples and paletted
* images. * images.
* (07/23/04) v0.6 Added Mac OS X support.
*/ */
#include "config.h"
#include <glib.h> /* Needed when compiling with gcc */ #include <glib.h> /* Needed when compiling with gcc */
#include <stdio.h> #include <stdio.h>
#include <windows.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include "tw_util.h" #include "tw_util.h"
#ifdef _DEBUG #ifdef _DEBUG
#include "tw_func.h" #include "tw_func.h"
@ -71,6 +78,7 @@ FILE *logFile = NULL;
#endif #endif
#ifdef _DEBUG #ifdef _DEBUG
/* /*
* LogMessage * LogMessage
*/ */
@ -83,7 +91,7 @@ LogMessage(char *format, ...)
/* Open the log file as necessary */ /* Open the log file as necessary */
if (!logFile) if (!logFile)
logFile = fopen("c:\\twain.log", "w"); logFile = fopen(DEBUG_LOGFILE, "w");
time_of_day = time(NULL); time_of_day = time(NULL);
ctime_string = ctime(&time_of_day); ctime_string = ctime(&time_of_day);
@ -96,36 +104,6 @@ LogMessage(char *format, ...)
va_end(args); va_end(args);
} }
/*
* LogLastWinError
*
* Log the last Windows error as returned by
* GetLastError.
*/
void
LogLastWinError(void)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
(LPTSTR) &lpMsgBuf,
0,
NULL
);
LogMessage("%s\n", lpMsgBuf);
/* Free the buffer. */
LocalFree( lpMsgBuf );
}
void void
logBegin(pTW_IMAGEINFO imageInfo, void *clientData) logBegin(pTW_IMAGEINFO imageInfo, void *clientData)
{ {
@ -190,15 +168,4 @@ LogMessage(char *format, ...)
{ {
} }
/*
* LogLastWinError
*
* Log the last Windows error as returned by
* GetLastError.
*/
void
LogLastWinError(void)
{
}
#endif /* DEBUG */ #endif /* DEBUG */

View File

@ -4,6 +4,10 @@
* Craig Setera <setera@home.com> * Craig Setera <setera@home.com>
* 03/31/1999 * 03/31/1999
* *
* Updated for Mac OS X support
* Brion Vibber <brion@pobox.com>
* 07/22/2004
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -36,16 +40,14 @@
* - Paletted images (both Gray and RGB) * - Paletted images (both Gray and RGB)
* *
* Prerequisites: * Prerequisites:
* This plug-in will not compile on anything other than a Win32 * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
* platform. Although the TWAIN documentation implies that there * also on 10.2).
* is TWAIN support available on Macintosh, I neither have a
* Macintosh nor the interest in porting this. If anyone else
* has an interest, consult www.twain.org for more information on
* interfacing to TWAIN.
* *
* Known problems: * Known problems:
* - Multiple image transfers will hang the plug-in. The current * - Multiple image transfers will hang the plug-in. The current
* configuration compiles with a maximum of single image transfers. * configuration compiles with a maximum of single image transfers.
* - On Mac OS X, canceling doesn't always close things out fully.
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
*/ */
/* /*
@ -55,13 +57,14 @@
* (02/15/99) v0.3 Added image dump and read support for debugging * (02/15/99) v0.3 Added image dump and read support for debugging
* (03/31/99) v0.5 Added support for multi-byte samples and paletted * (03/31/99) v0.5 Added support for multi-byte samples and paletted
* images. * images.
* (07/23/04) v0.6 Added Mac OS X support.
*/ */
#ifndef __TW_UTIL_H #ifndef __TW_UTIL_H
#define __TW_UTIL_H #define __TW_UTIL_H
#include "twain.h"
#include "tw_platform.h"
void LogMessage(char *, ...); void LogMessage(char *, ...);
void LogLastWinError(void) ;
#ifdef _DEBUG #ifdef _DEBUG
void logBegin(pTW_IMAGEINFO, void *); void logBegin(pTW_IMAGEINFO, void *);

453
plug-ins/twain/tw_win.c Normal file
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> * Craig Setera <setera@home.com>
* 03/31/1999 * 03/31/1999
* *
* Updated for Mac OS X support
* Brion Vibber <brion@pobox.com>
* 07/22/2004
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -36,16 +40,14 @@
* - Paletted images (both Gray and RGB) * - Paletted images (both Gray and RGB)
* *
* Prerequisites: * Prerequisites:
* This plug-in will not compile on anything other than a Win32 * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
* platform. Although the TWAIN documentation implies that there * also on 10.2).
* is TWAIN support available on Macintosh, I neither have a
* Macintosh nor the interest in porting this. If anyone else
* has an interest, consult www.twain.org for more information on
* interfacing to TWAIN.
* *
* Known problems: * Known problems:
* - Multiple image transfers will hang the plug-in. The current * - Multiple image transfers will hang the plug-in. The current
* configuration compiles with a maximum of single image transfers. * configuration compiles with a maximum of single image transfers.
* - On Mac OS X, canceling doesn't always close things out fully.
* - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
*/ */
/* /*
@ -55,6 +57,7 @@
* (02/15/99) v0.3 Added image dump and read support for debugging * (02/15/99) v0.3 Added image dump and read support for debugging
* (03/31/99) v0.5 Added support for multi-byte samples and paletted * (03/31/99) v0.5 Added support for multi-byte samples and paletted
* images. * images.
* (07/23/04) v0.6 Added Mac OS X support.
*/ */
#include "config.h" #include "config.h"
@ -63,7 +66,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <windows.h>
#include "tw_platform.h"
#include "tw_local.h"
#include "libgimp/gimp.h" #include "libgimp/gimp.h"
#include "libgimp/stdplugins-intl.h" #include "libgimp/stdplugins-intl.h"
@ -83,7 +88,7 @@
#define PLUG_IN_HELP "This plug-in will capture an image from a TWAIN datasource" #define PLUG_IN_HELP "This plug-in will capture an image from a TWAIN datasource"
#define PLUG_IN_AUTHOR "Craig Setera (setera@home.com)" #define PLUG_IN_AUTHOR "Craig Setera (setera@home.com)"
#define PLUG_IN_COPYRIGHT "Craig Setera" #define PLUG_IN_COPYRIGHT "Craig Setera"
#define PLUG_IN_VERSION "v0.5 (03/31/1999)" #define PLUG_IN_VERSION "v0.6 (07/22/2004)"
#ifdef _DEBUG #ifdef _DEBUG
#define PLUG_IN_D_NAME "twain-acquire-dump" #define PLUG_IN_D_NAME "twain-acquire-dump"
@ -93,10 +98,7 @@
/* /*
* Application definitions * Application definitions
*/ */
#define APP_NAME "TWAIN"
#define MAX_IMAGES 1 #define MAX_IMAGES 1
#define SHOW_WINDOW 0
#define WM_TRANSFER_IMAGE (WM_USER + 100)
/* /*
* Definition of the run states * Definition of the run states
@ -108,10 +110,10 @@
/* Global variables */ /* Global variables */
pTW_SESSION twSession = NULL; pTW_SESSION twSession = NULL;
static HWND hwnd = NULL;
static HINSTANCE hInst = NULL;
static char *destBuf = NULL; static char *destBuf = NULL;
#ifdef _DEBUG
static int twain_run_mode = RUN_STANDARD; static int twain_run_mode = RUN_STANDARD;
#endif
/* Forward declarations */ /* Forward declarations */
void preTransferCallback(void *); void preTransferCallback(void *);
@ -120,8 +122,6 @@ int dataTransferCallback(pTW_IMAGEINFO, pTW_IMAGEMEMXFER, void *);
int endTransferCallback(int, int, void *); int endTransferCallback(int, int, void *);
void postTransferCallback(int, void *); void postTransferCallback(int, void *);
static void init (void);
static void quit (void);
static void query (void); static void query (void);
static void run (const gchar *name, static void run (const gchar *name,
gint nparams, gint nparams,
@ -140,8 +140,6 @@ GimpPlugInInfo PLUG_IN_INFO =
extern void set_gimp_PLUG_IN_INFO_PTR(GimpPlugInInfo *); extern void set_gimp_PLUG_IN_INFO_PTR(GimpPlugInInfo *);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
/* Data structure holding data between runs */ /* Data structure holding data between runs */
/* Currently unused... Eventually may be used /* Currently unused... Eventually may be used
* to track dialog data. * to track dialog data.
@ -188,85 +186,34 @@ TXFR_CB_FUNCS dumperCbFuncs = {
dumpEndTransferCallback, dumpEndTransferCallback,
dumpPostTransferCallback }; dumpPostTransferCallback };
static void void
setRunMode(char *argv[]) setRunMode(char *argv[])
{ {
char *exeName = strrchr(argv[0], '\\') + 1; char *exeName = strrchr(argv[0], '\\') + 1;
LogMessage("Executable name: %s\n", exeName); LogMessage("Executable name: %s\n", exeName);
if (!_stricmp(exeName, "DTWAIN.EXE")) if (!_stricmp(exeName, DUMP_NAME))
twain_run_mode = RUN_DUMP; twain_run_mode = RUN_DUMP;
if (!_stricmp(exeName, "RTWAIN.EXE")) if (!_stricmp(exeName, RUNDUMP_NAME))
twain_run_mode = RUN_READDUMP; twain_run_mode = RUN_READDUMP;
} }
#endif /* _DEBUG */ #endif /* _DEBUG */
/****************************************************************** #ifndef TWAIN_ALTERNATE_MAIN
* Win32 entry point and setup... MAIN()
******************************************************************/ #endif
/* int
* WinMain scanImage (void)
*
* The standard gimp entry point won't quite cut it for
* this plug-in. This plug-in requires creation of a
* standard Win32 window (hidden) in order to receive
* and process window messages on behalf of the TWAIN
* datasource.
*/
int APIENTRY
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
/*
* Normally, we would do all of the Windows-ish set up of
* the window classes and stuff here in WinMain. But,
* the only time we really need the window and message
* queues is during the plug-in run. So, all of that will
* be done during run(). This avoids all of the Windows
* setup stuff for the query(). Stash the instance handle now
* so it is available from the run() procedure.
*/
hInst = hInstance;
#ifdef _DEBUG
/* When in debug version, we allow different run modes...
* make sure that it is correctly set.
*/
setRunMode(__argv);
#endif /* _DEBUG */
/*
* Now, call gimp_main... This is what the MAIN() macro
* would usually do.
*/
return gimp_main(&PLUG_IN_INFO, __argc, __argv);
}
/*
* main
*
* allow to build as console app as well
*/
int main (int argc, char *argv[])
{ {
#ifdef _DEBUG #ifdef _DEBUG
/* When in debug version, we allow different run modes... if (twain_run_mode == RUN_READDUMP)
* make sure that it is correctly set. return readDumpedImage (twSession);
*/ else
setRunMode(__argv);
#endif /* _DEBUG */ #endif /* _DEBUG */
return getImage (twSession);
/*
* Now, call gimp_main... This is what the MAIN() macro
* would usually do.
*/
return gimp_main(&PLUG_IN_INFO, __argc, __argv);
} }
/* /*
@ -286,13 +233,13 @@ getAppIdentity(void)
appIdentity->Version.MinorNum = 1; appIdentity->Version.MinorNum = 1;
appIdentity->Version.Language = TWLG_USA; appIdentity->Version.Language = TWLG_USA;
appIdentity->Version.Country = TWCY_USA; appIdentity->Version.Country = TWCY_USA;
strcpy(appIdentity->Version.Info, "GIMP TWAIN 0.5"); strcpy(appIdentity->Version.Info, "GIMP TWAIN 0.6");
appIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR; appIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
appIdentity->ProtocolMinor = TWON_PROTOCOLMINOR; appIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
appIdentity->SupportedGroups = DG_IMAGE; appIdentity->SupportedGroups = DG_IMAGE;
strcpy(appIdentity->Manufacturer, "Craig Setera"); strcpy(appIdentity->Manufacturer, "Craig Setera");
strcpy(appIdentity->ProductFamily, "GIMP"); strcpy(appIdentity->ProductFamily, "GIMP");
strcpy(appIdentity->ProductName, "GIMP for Win32"); strcpy(appIdentity->ProductName, "GIMP");
return appIdentity; return appIdentity;
} }
@ -305,7 +252,7 @@ getAppIdentity(void)
* something built by me on top of the standard TWAIN * something built by me on top of the standard TWAIN
* datasource manager calls. * datasource manager calls.
*/ */
void pTW_SESSION
initializeTwain(void) initializeTwain(void)
{ {
pTW_IDENTITY appIdentity; pTW_IDENTITY appIdentity;
@ -323,139 +270,7 @@ initializeTwain(void)
else else
#endif /* _DEBUG */ #endif /* _DEBUG */
registerTransferCallbacks(twSession, &standardCbFuncs, NULL); registerTransferCallbacks(twSession, &standardCbFuncs, NULL);
} return twSession;
/*
* InitApplication
*
* Initialize window data and register the window class
*/
BOOL
InitApplication(HINSTANCE hInstance)
{
WNDCLASS wc;
BOOL retValue;
/*
* Fill in window class structure with parameters to describe
* the main window.
*/
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszClassName = APP_NAME;
wc.lpszMenuName = NULL;
/* Register the window class and stash success/failure code. */
retValue = RegisterClass(&wc);
/* Log error */
if (!retValue)
LogLastWinError();
return retValue;
}
/*
* InitInstance
*
* Create the main window for the application. Used to
* interface with the TWAIN datasource.
*/
BOOL
InitInstance(HINSTANCE hInstance, int nCmdShow)
{
/* Create our window */
hwnd = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
if (!hwnd) {
return (FALSE);
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
return TRUE;
}
/*
* twainWinMain
*
* This is the function that represents the code that
* would normally reside in WinMain (see above). This
* function will get called during run() in order to set
* up the windowing environment necessary for TWAIN to
* operate.
*/
int
twainWinMain(void)
{
/* Initialize the twain information */
initializeTwain();
/* Perform instance initialization */
if (!InitApplication(hInst))
return (FALSE);
/* Perform application initialization */
if (!InitInstance(hInst, SHOW_WINDOW))
return (FALSE);
/*
* Call the main message processing loop...
* This call will not return until the application
* exits.
*/
return twainMessageLoop(twSession);
}
/*
* WndProc
*
* Process window message for the main window.
*/
LRESULT CALLBACK
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_CREATE:
/* Register our window handle with the TWAIN
* support.
*/
registerWindowHandle(twSession, hWnd);
/* Schedule the image transfer by posting a message */
PostMessage(hWnd, WM_TRANSFER_IMAGE, 0, 0);
break;
case WM_TRANSFER_IMAGE:
/* Get an image */
#ifdef _DEBUG
if (twain_run_mode == RUN_READDUMP)
readDumpedImage(twSession);
else
#endif /* _DEBUG */
getImage(twSession);
break;
case WM_DESTROY:
LogMessage("Exiting application\n");
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return 0;
} }
/****************************************************************** /******************************************************************
@ -625,7 +440,7 @@ run (const gchar *name,
/* Have we succeeded so far? */ /* Have we succeeded so far? */
if (values[0].data.d_status == GIMP_PDB_SUCCESS) if (values[0].data.d_status == GIMP_PDB_SUCCESS)
twainWinMain(); twainMain ();
/* Check to make sure we got at least one valid /* Check to make sure we got at least one valid
* image. * image.
@ -686,7 +501,6 @@ preTransferCallback(void *clientData)
int int
beginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData) beginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData)
{ {
int done = 0;
int imageType, layerType; int imageType, layerType;
pClientDataStruct theClientData = g_new (ClientDataStruct, 1); pClientDataStruct theClientData = g_new (ClientDataStruct, 1);
@ -749,6 +563,12 @@ beginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData)
theClientData->image_id = gimp_image_new(imageInfo->ImageWidth, theClientData->image_id = gimp_image_new(imageInfo->ImageWidth,
imageInfo->ImageLength, imageType); imageInfo->ImageLength, imageType);
/* Set the actual resolution */
gimp_image_set_resolution (theClientData->image_id,
FIX32ToFloat(imageInfo->XResolution),
FIX32ToFloat(imageInfo->YResolution));
gimp_image_set_unit (theClientData->image_id, GIMP_UNIT_INCH);
/* Create a layer */ /* Create a layer */
theClientData->layer_id = gimp_layer_new(theClientData->image_id, theClientData->layer_id = gimp_layer_new(theClientData->image_id,
_("Background"), _("Background"),
@ -905,11 +725,9 @@ twoBytesPerSampleTransferCallback(pTW_IMAGEINFO imageInfo,
{ {
static float ratio = 0.00390625; static float ratio = 0.00390625;
int row, col, sample; int row, col, sample;
char *srcBuf, *destByte; char *destByte;
int rows = imageMemXfer->Rows; int rows = imageMemXfer->Rows;
int cols = imageMemXfer->Columns; int cols = imageMemXfer->Columns;
int bitsPerSample = imageInfo->BitsPerPixel / imageInfo->SamplesPerPixel;
int bytesPerSample = bitsPerSample / 8;
TW_UINT16 *samplePtr; TW_UINT16 *samplePtr;
@ -1163,5 +981,5 @@ postTransferCallback(int pendingCount, void *clientData)
closeDSM(twSession); closeDSM(twSession);
/* Post a message to close up the application */ /* Post a message to close up the application */
PostQuitMessage(0); twainQuitApplication ();
} }