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);
Shinya Kitaoka 120a6e
OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2,
Shinya Kitaoka 120a6e
                                   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
Shinya Kitaoka 120a6e
void *TTWAIN_GetValidHwndPD(void *hwnd) {
Shinya Kitaoka 120a6e
  setupUI();
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TTWAIN_EnableWindowPD(void *hwnd, int flag) {
Shinya Kitaoka 120a6e
  printf("%s\n", __PRETTY_FUNCTION__);
Shinya Kitaoka 120a6e
  return 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int CallbackRegistered = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void unregisterTwainCallback(void) {
Shinya Kitaoka 120a6e
  printf("unregistering\n");
Shinya Kitaoka 120a6e
  CallbackRegistered = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TW_UINT16 twainCallback(pTW_IDENTITY pOrigin, pTW_IDENTITY pDest, TW_UINT32 DG,
Shinya Kitaoka 120a6e
                        TW_UINT16 DAT, TW_UINT16 MSG, TW_MEMREF pData) {
Shinya Kitaoka 120a6e
  PRINTF("%s msg=0x%x\n", __PRETTY_FUNCTION__, MSG);
Shinya Kitaoka 120a6e
  TTWAIN_MessageHook((void *)MSG);
Shinya Kitaoka 120a6e
  return TWRC_SUCCESS;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int exitTwainSession(void) {
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
Shinya Kitaoka 120a6e
  /*At this time the HP Scan Pro DS (OSX on i386) need at least 1 sec to process
Shinya Kitaoka 120a6e
closeUI msg
Shinya Kitaoka 120a6e
If we are too fast exiting from the application loop, the msg stay in the
Shinya Kitaoka 120a6e
queue and it will be processed the next time we open the ui !!!
Shinya Kitaoka 120a6e
Flusing the queue (see above) doesn't work, because is possible that we are
Toshihiro Shimizu 890ddd
too fast purging the queue.
Shinya Kitaoka 120a6e
1 sec seems to be ok
Shinya Kitaoka 120a6e
2 sec is safe :)
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
  sleep(2);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  printf("calling QuitApplicationEventLoop\n");
Shinya Kitaoka 120a6e
  // QuitApplicationEventLoop();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  unregisterTwainCallback();
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
static void myEventLoopTimer() {
Shinya Kitaoka 120a6e
  printf("my event loop timer ScanDone = %d\n", ScanDone);
Shinya Kitaoka 120a6e
  // if (ScanDone)
Shinya Kitaoka 120a6e
  // QuitApplicationEventLoop ();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void setupUI(void) {
Shinya Kitaoka 120a6e
  ProcessSerialNumber psn;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  GetCurrentProcess(&psn);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* Need to do some magic here to get the UI to work */
Shinya Kitaoka 120a6e
  CPSEnableForegroundOperation(&psn, 0x03, 0x3C, 0x2C, 0x1103);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  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. */
Shinya Kitaoka 120a6e
// CGrafPtr p = BeginQDContextForApplicationDockTile();
Shinya Kitaoka 120a6e
// EndQDContextForApplicationDockTile(p);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// SetApplicationDockTileImage (icon);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  int numComponents       = 4;
Shinya Kitaoka 120a6e
  int bitsPerPixelChannel = 8;
Shinya Kitaoka 120a6e
  int totalBitsPerPixel   = bitsPerPixelChannel * numComponents;
Shinya Kitaoka 120a6e
  int w                   = 32;
Shinya Kitaoka 120a6e
  int h                   = 32;
Shinya Kitaoka 120a6e
  char *buffer[w * h * numComponents];
Shinya Kitaoka 120a6e
  CGContextRef context;
Shinya Kitaoka 120a6e
  CGDataProviderRef provider;
Shinya Kitaoka 120a6e
  CGColorSpaceRef colorSpace;
Shinya Kitaoka 120a6e
  CGImageRef image;
Shinya Kitaoka 120a6e
  int bytesPerRow = w * numComponents;
Shinya Kitaoka 120a6e
  context         = BeginCGContextForApplicationDockTile();
Shinya Kitaoka 120a6e
  provider   = CGDataProviderCreateWithData(0, buffer, (bytesPerRow * h), 0);
Shinya Kitaoka 120a6e
  colorSpace = CGColorSpaceCreateDeviceRGB();
Shinya Kitaoka 120a6e
  image      = CGImageCreate(w, h, bitsPerPixelChannel, totalBitsPerPixel,
Shinya Kitaoka 120a6e
                        bytesPerRow, colorSpace, kCGImageAlphaFirst, provider,
Shinya Kitaoka 120a6e
                        0, 0, kCGRenderingIntentDefault);
Shinya Kitaoka 120a6e
  CGDataProviderRelease(provider);
Shinya Kitaoka 120a6e
  CGColorSpaceRelease(colorSpace);
Shinya Kitaoka 120a6e
  SetApplicationDockTileImage(image);
Shinya Kitaoka 120a6e
  CGContextFlush(context);
Shinya Kitaoka 120a6e
  CGImageRelease(image);
Shinya Kitaoka 120a6e
  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
Shinya Kitaoka 120a6e
void registerTwainCallback(void) {
Shinya Kitaoka 120a6e
  if (TTWAIN_GetState() < TWAIN_SOURCE_OPEN) {
Shinya Kitaoka 120a6e
    PRINTF("%s too early!, don't register\n", __FUNCTION__);
Shinya Kitaoka 120a6e
    CallbackRegistered = 0;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TTWAIN_GetState() != 4) {
Shinya Kitaoka 120a6e
    PRINTF("%s state != 4, don't register\n", __FUNCTION__);
Shinya Kitaoka 120a6e
    CallbackRegistered = 0;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!CallbackRegistered) {
Shinya Kitaoka 120a6e
    int rc = 0;
Shinya Kitaoka 120a6e
    TW_CALLBACK callback;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    PRINTF("%s registering\n", __FUNCTION__);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /* We need to set up our callback to receive messages */
Shinya Kitaoka 120a6e
    callback.CallBackProc = (TW_MEMREF)twainCallback;
Shinya Kitaoka 120a6e
    callback.RefCon       = 0; /* user data */
Shinya Kitaoka 120a6e
    callback.Message      = 0;
Shinya Kitaoka 120a6e
    printf("registering\n");
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
processed = TTWAIN_DS(DG_CONTROL, DAT_CALLBACK, MSG_REGISTER_CALLBACK,
Shinya Kitaoka 120a6e
(TW_MEMREF) &callback);
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    rc = TTwainData.resultCode =
Shinya Kitaoka 120a6e
        (*TTwainData.DSM_Entry)(&TTwainData.appId, 0, DG_CONTROL, DAT_CALLBACK,
Shinya Kitaoka 120a6e
                                MSG_REGISTER_CALLBACK, (TW_MEMREF)&callback);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // EventLoopTimerRef timer;
Shinya Kitaoka 120a6e
    /*OSStatus err;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Set this up to run once the event loop is started
Shinya Kitaoka 120a6e
err = InstallEventLoopTimer (GetMainEventLoop (),
Shinya Kitaoka 120a6e
                   0, 0, // Immediately, once only
Shinya Kitaoka 120a6e
                   NewEventLoopTimerUPP (myEventLoopTimer),
Shinya Kitaoka 120a6e
                   0, &timer);*/
Shinya Kitaoka 120a6e
    CallbackRegistered = 1;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    PRINTF("%s already registered!, don't register\n", __FUNCTION__);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTWAIN_EmptyMessageQueuePD(void) {
Shinya Kitaoka 120a6e
  ScanDone = 0;
Shinya Kitaoka 120a6e
  registerTwainCallback();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTWAIN_ModalEventLoopPD(void) {
Shinya Kitaoka 120a6e
  printf("%s\n", __PRETTY_FUNCTION__);
Shinya Kitaoka 120a6e
  registerTwainCallback();
Shinya Kitaoka 120a6e
  // RunApplicationEventLoop();
Shinya Kitaoka 120a6e
  return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  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