1 
2 
3 /*max@home*/
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 #include <Cocoa/Cocoa.h>
9 #include "ttwain_state.h"
10 #include "ttwainP.h"
11 //#define DEBUG
12 #ifndef _WIN32
13 #define PRINTF(args...)
14 #else
15 #define PRINTF
16 #endif
17 #if 1
18 
19 extern int TTWAIN_MessageHook(void *lpmsg);
20 
21 OSErr CPSSetProcessName(ProcessSerialNumber *psn, char *processname);
22 OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2,
23                                    UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
24 
25 int ScanDone = 0;
26 
27 void setupUI(void);
28 
29 /*---------------------------------------------------------------------------*/
30 
TTWAIN_GetValidHwndPD(void * hwnd)31 void *TTWAIN_GetValidHwndPD(void *hwnd) {
32   setupUI();
33   return 0;
34 }
35 
36 /*---------------------------------------------------------------------------*/
37 
TTWAIN_EnableWindowPD(void * hwnd,int flag)38 int TTWAIN_EnableWindowPD(void *hwnd, int flag) {
39   printf("%s\n", __PRETTY_FUNCTION__);
40   return 1;
41 }
42 
43 /*---------------------------------------------------------------------------*/
44 
45 static int CallbackRegistered = false;
46 
unregisterTwainCallback(void)47 void unregisterTwainCallback(void) {
48   printf("unregistering\n");
49   CallbackRegistered = 0;
50 }
51 
52 /*---------------------------------------------------------------------------*/
53 
twainCallback(pTW_IDENTITY pOrigin,pTW_IDENTITY pDest,TW_UINT32 DG,TW_UINT16 DAT,TW_UINT16 MSG,TW_MEMREF pData)54 TW_UINT16 twainCallback(pTW_IDENTITY pOrigin, pTW_IDENTITY pDest, TW_UINT32 DG,
55                         TW_UINT16 DAT, TW_UINT16 MSG, TW_MEMREF pData) {
56   PRINTF("%s msg=0x%x\n", __PRETTY_FUNCTION__, MSG);
57   TTWAIN_MessageHook((void *)MSG);
58   return TWRC_SUCCESS;
59 }
60 
61 /*---------------------------------------------------------------------------*/
62 
exitTwainSession(void)63 int exitTwainSession(void) {
64 /*
65 EventQueueRef q = GetCurrentEventQueue();
66 printf("flushing event queue\n");
67 FlushEventQueue(q);
68 */
69 #ifdef __i386
70   /*At this time the HP Scan Pro DS (OSX on i386) need at least 1 sec to process
71 closeUI msg
72 If we are too fast exiting from the application loop, the msg stay in the
73 queue and it will be processed the next time we open the ui !!!
74 Flusing the queue (see above) doesn't work, because is possible that we are
75 too fast purging the queue.
76 1 sec seems to be ok
77 2 sec is safe :)
78 */
79   sleep(2);
80 #endif
81   printf("calling QuitApplicationEventLoop\n");
82   // QuitApplicationEventLoop();
83 
84   unregisterTwainCallback();
85   return 0;
86 }
87 
88 /*---------------------------------------------------------------------------*/
89 
myEventLoopTimer()90 static void myEventLoopTimer() {
91   printf("my event loop timer ScanDone = %d\n", ScanDone);
92   // if (ScanDone)
93   // QuitApplicationEventLoop ();
94 }
95 
96 /*---------------------------------------------------------------------------*/
97 
setupUI(void)98 void setupUI(void) {
99   ProcessSerialNumber psn;
100 
101   GetCurrentProcess(&psn);
102 
103   /* Need to do some magic here to get the UI to work */
104   CPSEnableForegroundOperation(&psn, 0x03, 0x3C, 0x2C, 0x1103);
105 
106   SetFrontProcess(&psn);
107 #ifndef HAVE_DOCK_TILE
108 /* We end up with the ugly console dock icon; let's override it */
109 /*char *iconfile = "/tmp/image.png";
110   CFURLRef url = CFURLCreateFromFileSystemRepresentation (kCFAllocatorDefault,
111                                                           (UInt8 *)iconfile,
112                                                           strlen (iconfile),
113                                                           FALSE);
114 
115   CGDataProviderRef png = CGDataProviderCreateWithURL (url);
116   CGImageRef icon = CGImageCreateWithPNGDataProvider (png, NULL, TRUE,
117                                              kCGRenderingIntentDefault);
118 
119   /* Voodoo magic fix inspired by java_swt launcher */
120 /* Without this the icon setting doesn't work about half the time. */
121 // CGrafPtr p = BeginQDContextForApplicationDockTile();
122 // EndQDContextForApplicationDockTile(p);
123 
124 // SetApplicationDockTileImage (icon);
125 #else
126   int numComponents       = 4;
127   int bitsPerPixelChannel = 8;
128   int totalBitsPerPixel   = bitsPerPixelChannel * numComponents;
129   int w                   = 32;
130   int h                   = 32;
131   char *buffer[w * h * numComponents];
132   CGContextRef context;
133   CGDataProviderRef provider;
134   CGColorSpaceRef colorSpace;
135   CGImageRef image;
136   int bytesPerRow = w * numComponents;
137   context         = BeginCGContextForApplicationDockTile();
138   provider   = CGDataProviderCreateWithData(0, buffer, (bytesPerRow * h), 0);
139   colorSpace = CGColorSpaceCreateDeviceRGB();
140   image      = CGImageCreate(w, h, bitsPerPixelChannel, totalBitsPerPixel,
141                         bytesPerRow, colorSpace, kCGImageAlphaFirst, provider,
142                         0, 0, kCGRenderingIntentDefault);
143   CGDataProviderRelease(provider);
144   CGColorSpaceRelease(colorSpace);
145   SetApplicationDockTileImage(image);
146   CGContextFlush(context);
147   CGImageRelease(image);
148   EndCGContextForApplicationDockTile(context);
149 #endif
150 }
151 
152 /*---------------------------------------------------------------------------*/
153 
registerTwainCallback(void)154 void registerTwainCallback(void) {
155   if (TTWAIN_GetState() < TWAIN_SOURCE_OPEN) {
156     PRINTF("%s too early!, don't register\n", __FUNCTION__);
157     CallbackRegistered = 0;
158     return;
159   }
160 
161   if (TTWAIN_GetState() != 4) {
162     PRINTF("%s state != 4, don't register\n", __FUNCTION__);
163     CallbackRegistered = 0;
164     return;
165   }
166 
167   if (!CallbackRegistered) {
168     int rc = 0;
169     TW_CALLBACK callback;
170 
171     PRINTF("%s registering\n", __FUNCTION__);
172 
173     /* We need to set up our callback to receive messages */
174     callback.CallBackProc = (TW_MEMREF)twainCallback;
175     callback.RefCon       = 0; /* user data */
176     callback.Message      = 0;
177     printf("registering\n");
178     /*
179 processed = TTWAIN_DS(DG_CONTROL, DAT_CALLBACK, MSG_REGISTER_CALLBACK,
180 (TW_MEMREF) &callback);
181 */
182 
183     rc = TTwainData.resultCode =
184         (*TTwainData.DSM_Entry)(&TTwainData.appId, 0, DG_CONTROL, DAT_CALLBACK,
185                                 MSG_REGISTER_CALLBACK, (TW_MEMREF)&callback);
186 
187     // NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
188 
189     // EventLoopTimerRef timer;
190     /*OSStatus err;
191 
192 // Set this up to run once the event loop is started
193 err = InstallEventLoopTimer (GetMainEventLoop (),
194                    0, 0, // Immediately, once only
195                    NewEventLoopTimerUPP (myEventLoopTimer),
196                    0, &timer);*/
197     CallbackRegistered = 1;
198   } else {
199     PRINTF("%s already registered!, don't register\n", __FUNCTION__);
200   }
201 }
202 
203 /*---------------------------------------------------------------------------*/
204 
TTWAIN_EmptyMessageQueuePD(void)205 void TTWAIN_EmptyMessageQueuePD(void) {
206   ScanDone = 0;
207   registerTwainCallback();
208 }
209 
210 /*---------------------------------------------------------------------------*/
211 
TTWAIN_ModalEventLoopPD(void)212 void TTWAIN_ModalEventLoopPD(void) {
213   printf("%s\n", __PRETTY_FUNCTION__);
214   registerTwainCallback();
215   // RunApplicationEventLoop();
216   return;
217 
218   TTwainData.breakModalLoop = FALSE;
219 }
220 
221 #endif
222 
223 #ifdef __cplusplus
224 }
225 #endif
226