Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*max@home*/
Toshihiro Shimizu 890ddd
#ifdef __cplusplus
Toshihiro Shimizu 890ddd
extern "C" {
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <cocoa cocoa.h=""></cocoa>
Toshihiro Shimizu 890ddd
#include "ttwain_state.h"
Toshihiro Shimizu 890ddd
#include "ttwainP.h"
Toshihiro Shimizu 890ddd
//#define DEBUG
Toshihiro Shimizu 890ddd
#define PRINTF
Toshihiro Shimizu 890ddd
#if 1
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
extern int TTWAIN_MessageHook(void *lpmsg);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
OSErr CPSSetProcessName(ProcessSerialNumber *psn, char *processname);
Toshihiro Shimizu 890ddd
OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ScanDone = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void setupUI(void);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void *TTWAIN_GetValidHwndPD(void *hwnd)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setupUI();
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TTWAIN_EnableWindowPD(void *hwnd, int flag)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("%s\n", __PRETTY_FUNCTION__);
Toshihiro Shimizu 890ddd
	return 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int CallbackRegistered = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void unregisterTwainCallback(void)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("unregistering\n");
Toshihiro Shimizu 890ddd
	CallbackRegistered = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TW_UINT16 twainCallback(pTW_IDENTITY pOrigin,
Toshihiro Shimizu 890ddd
						pTW_IDENTITY pDest,
Toshihiro Shimizu 890ddd
						TW_UINT32 DG,
Toshihiro Shimizu 890ddd
						TW_UINT16 DAT,
Toshihiro Shimizu 890ddd
						TW_UINT16 MSG,
Toshihiro Shimizu 890ddd
						TW_MEMREF pData)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	PRINTF("%s msg=0x%x\n", __PRETTY_FUNCTION__, MSG);
Toshihiro Shimizu 890ddd
	TTWAIN_MessageHook((void *)MSG);
Toshihiro Shimizu 890ddd
	return TWRC_SUCCESS;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int exitTwainSession(void)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
EventQueueRef q = GetCurrentEventQueue();
Toshihiro Shimizu 890ddd
printf("flushing event queue\n");
Toshihiro Shimizu 890ddd
FlushEventQueue(q);
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
#ifdef __i386
Toshihiro Shimizu 890ddd
	/*At this time the HP Scan Pro DS (OSX on i386) need at least 1 sec to process closeUI msg
Toshihiro Shimizu 890ddd
  If we are too fast exiting from the application loop, the msg stay in the
Toshihiro Shimizu 890ddd
  queue and it will be processed the next time we open the ui !!!
Toshihiro Shimizu 890ddd
  Flusing the queue (see above) doesn't work, because is possible that we are
Toshihiro Shimizu 890ddd
too fast purging the queue.
Toshihiro Shimizu 890ddd
  1 sec seems to be ok
Toshihiro Shimizu 890ddd
  2 sec is safe :)
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	sleep(2);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	printf("calling QuitApplicationEventLoop\n");
Toshihiro Shimizu 890ddd
	//QuitApplicationEventLoop();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unregisterTwainCallback();
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void myEventLoopTimer()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("my event loop timer ScanDone = %d\n", ScanDone);
Toshihiro Shimizu 890ddd
	//if (ScanDone)
Toshihiro Shimizu 890ddd
	// QuitApplicationEventLoop ();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void setupUI(void)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ProcessSerialNumber psn;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	GetCurrentProcess(&psn);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* Need to do some magic here to get the UI to work */
Toshihiro Shimizu 890ddd
	CPSEnableForegroundOperation(&psn, 0x03, 0x3C, 0x2C, 0x1103);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SetFrontProcess(&psn);
Toshihiro Shimizu 890ddd
#ifndef HAVE_DOCK_TILE
Toshihiro Shimizu 890ddd
/* We end up with the ugly console dock icon; let's override it */
Toshihiro Shimizu 890ddd
/*char *iconfile = "/tmp/image.png";
Toshihiro Shimizu 890ddd
  CFURLRef url = CFURLCreateFromFileSystemRepresentation (kCFAllocatorDefault,
Toshihiro Shimizu 890ddd
                                                          (UInt8 *)iconfile,
Toshihiro Shimizu 890ddd
                                                          strlen (iconfile),
Toshihiro Shimizu 890ddd
                                                          FALSE);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  CGDataProviderRef png = CGDataProviderCreateWithURL (url);
Toshihiro Shimizu 890ddd
  CGImageRef icon = CGImageCreateWithPNGDataProvider (png, NULL, TRUE,
Toshihiro Shimizu 890ddd
                                             kCGRenderingIntentDefault);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  /* Voodoo magic fix inspired by java_swt launcher */
Toshihiro Shimizu 890ddd
/* Without this the icon setting doesn't work about half the time. */
Toshihiro Shimizu 890ddd
//CGrafPtr p = BeginQDContextForApplicationDockTile();
Toshihiro Shimizu 890ddd
//EndQDContextForApplicationDockTile(p);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//SetApplicationDockTileImage (icon);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	int numComponents = 4;
Toshihiro Shimizu 890ddd
	int bitsPerPixelChannel = 8;
Toshihiro Shimizu 890ddd
	int totalBitsPerPixel = bitsPerPixelChannel * numComponents;
Toshihiro Shimizu 890ddd
	int w = 32;
Toshihiro Shimizu 890ddd
	int h = 32;
Toshihiro Shimizu 890ddd
	char *buffer[w * h * numComponents];
Toshihiro Shimizu 890ddd
	CGContextRef context;
Toshihiro Shimizu 890ddd
	CGDataProviderRef provider;
Toshihiro Shimizu 890ddd
	CGColorSpaceRef colorSpace;
Toshihiro Shimizu 890ddd
	CGImageRef image;
Toshihiro Shimizu 890ddd
	int bytesPerRow = w * numComponents;
Toshihiro Shimizu 890ddd
	context = BeginCGContextForApplicationDockTile();
Toshihiro Shimizu 890ddd
	provider = CGDataProviderCreateWithData(0, buffer, (bytesPerRow * h), 0);
Toshihiro Shimizu 890ddd
	colorSpace = CGColorSpaceCreateDeviceRGB();
Toshihiro Shimizu 890ddd
	image = CGImageCreate(w, h, bitsPerPixelChannel, totalBitsPerPixel, bytesPerRow, colorSpace, kCGImageAlphaFirst, provider, 0, 0, kCGRenderingIntentDefault);
Toshihiro Shimizu 890ddd
	CGDataProviderRelease(provider);
Toshihiro Shimizu 890ddd
	CGColorSpaceRelease(colorSpace);
Toshihiro Shimizu 890ddd
	SetApplicationDockTileImage(image);
Toshihiro Shimizu 890ddd
	CGContextFlush(context);
Toshihiro Shimizu 890ddd
	CGImageRelease(image);
Toshihiro Shimizu 890ddd
	EndCGContextForApplicationDockTile(context);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define PRINTF
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void registerTwainCallback(void)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (TTWAIN_GetState() < TWAIN_SOURCE_OPEN) {
Toshihiro Shimizu 890ddd
		PRINTF("%s too early!, don't register\n", __FUNCTION__);
Toshihiro Shimizu 890ddd
		CallbackRegistered = 0;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (TTWAIN_GetState() != 4) {
Toshihiro Shimizu 890ddd
		PRINTF("%s state != 4, don't register\n", __FUNCTION__);
Toshihiro Shimizu 890ddd
		CallbackRegistered = 0;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!CallbackRegistered) {
Toshihiro Shimizu 890ddd
		int rc = 0;
Toshihiro Shimizu 890ddd
		TW_CALLBACK callback;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		PRINTF("%s registering\n", __FUNCTION__);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/* We need to set up our callback to receive messages */
Toshihiro Shimizu 890ddd
		callback.CallBackProc = (TW_MEMREF)twainCallback;
Toshihiro Shimizu 890ddd
		callback.RefCon = 0; /* user data */
Toshihiro Shimizu 890ddd
		callback.Message = 0;
Toshihiro Shimizu 890ddd
		printf("registering\n");
Toshihiro Shimizu 890ddd
		/*
Toshihiro Shimizu 890ddd
processed = TTWAIN_DS(DG_CONTROL, DAT_CALLBACK, MSG_REGISTER_CALLBACK,  (TW_MEMREF) &callback);
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		rc = TTwainData.resultCode = (*TTwainData.DSM_Entry)(&TTwainData.appId,
Toshihiro Shimizu 890ddd
															 0,
Toshihiro Shimizu 890ddd
															 DG_CONTROL, DAT_CALLBACK, MSG_REGISTER_CALLBACK, (TW_MEMREF)&callback);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//EventLoopTimerRef timer;
Toshihiro Shimizu 890ddd
		/*OSStatus err;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  // Set this up to run once the event loop is started
Toshihiro Shimizu 890ddd
  err = InstallEventLoopTimer (GetMainEventLoop (),
Toshihiro Shimizu 890ddd
                               0, 0, // Immediately, once only
Toshihiro Shimizu 890ddd
                               NewEventLoopTimerUPP (myEventLoopTimer),
Toshihiro Shimizu 890ddd
                               0, &timer);*/
Toshihiro Shimizu 890ddd
		CallbackRegistered = 1;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		PRINTF("%s already registered!, don't register\n", __FUNCTION__);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TTWAIN_EmptyMessageQueuePD(void)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ScanDone = 0;
Toshihiro Shimizu 890ddd
	registerTwainCallback();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TTWAIN_ModalEventLoopPD(void)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("%s\n", __PRETTY_FUNCTION__);
Toshihiro Shimizu 890ddd
	registerTwainCallback();
Toshihiro Shimizu 890ddd
	//RunApplicationEventLoop();
Toshihiro Shimizu 890ddd
	return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTwainData.breakModalLoop = FALSE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef __cplusplus
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif