mirror of https://github.com/GNOME/gimp.git
229 lines
5.9 KiB
C
229 lines
5.9 KiB
C
/*
|
|
* 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;
|
|
}
|
|
|