December 16, 2013 at 10:57 pm #22903
I’m trying to write a twain client that supports Mac OS X 10.7 and later. I have implemented a callback function which is Twain 2.x compliant and it appears to work with some Twain devices on the Mac, however, as I understand it Mac only supports up to Twain 1.9, which doesn’t use a callback function (it uses an event loop).
The Twain 1.9 spec gives sample code for the Carbon API, but not for Cocoa. As Carbon is now deprecated, is there any sample code for Cocoa so that I can see how to do an event loop that would be Twain 1.9 compliant?December 17, 2013 at 4:50 pm #26040
Mac OS X supports all versions of TWAIN, including the newly released 2.3. What it doesn’t currently have is an updated Data Source manager.
Fortunately, that version of the DSM does support DAT_CALLBACK. The main difference is that Mac OS X requires a driver to use DG_CONTROL / DAT_CALLBACK / MSG_INVOKE_CALLBACK to trigger a callback. The experience on the Application side is the same. Use DG_CONTROL / DAT_CALLBACK / MSG_REGISTER_CALLBACK to register for the callback.
We recommend using the TWAIN 2.3 TWAIN.H file (found on twain.org), rather than the older TWAIN.H file found in /System/Library/Frameworks/TWAIN.framework/Headers. It’s compatible with all drivers and applications on Mac OS X…December 17, 2013 at 6:00 pm #26041
Thanks for the reply!
I have Mac drivers for other Epson scanners that install fine but don’t appear to work with the callback, so I was figuring that I needed to support the old Twain 1.9 event loop for those scanners. This is where it appeared that I needed to use the deprecated Carbon framework to send Carbon events to the datasource.
Just to be perfectly clear, are you saying that I simply don’t need to support the old-style Mac event loop at all, even for older scanners?December 17, 2013 at 6:23 pm #26042
I wish I could be that confident. With the new open source DSM (which hasn’t been ported to the Mac yet) it doesn’t matter how the driver triggers an event, the DSM will report it through the appropriate mechanism to the application.
If Apple implemented it correctly, this should be the behavior for the Mac DSM, so if a driver uses DG_CONTROL / DAT_NULL to send a message to the DSM, then if a callback is registered, it should be invoked. Unfortunately, I can’t be sure Apple did that, and the use of a special MSG_INVOKE_CALLBACK hints that they may not have done it right.
So, sadly, the only way to know is to try it…December 17, 2013 at 6:31 pm #26043
Thanks Mark, I really appreciate your help on this.December 18, 2013 at 5:08 pm #26044
I tried the following code with no luck. I never receive any cocoa events of any kind. I also tried GetNextEvent and it also returns no events.
My code is part of a pluginprocess for the Safari Browser, so I’m wondering if I can even get any events.
// This method will look for a Mac event to dispatch to the DS.
NSAutoreleasePool *outerpool = [[NSAutoreleasePool alloc] init];
NSEvent *cocoaEvent =
// Convert to a carbon event
if (!([cocoaEvent eventRef] && ConvertEventRefToEventRecord((EventRef)[cocoaEvent eventRef], &carbonEvent)))
NSPoint where = cocoaEvent window] convertBaseToScreen:[cocoaEvent locationInWindow;
carbonEvent.what = nullEvent;
carbonEvent.message = 0;
carbonEvent.when = (UInt32)([cocoaEvent timestamp] * 60); // seconds to ticks
carbonEvent.where.h = (short)where.x;
carbonEvent.where.v = (short)(NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]) – where.y);
carbonEvent.modifiers = 0; //[self modifiersForEvent:cocoaEvent];
// send to data source
twEvent.pEvent = (TW_MEMREF)&carbonEvent;
twEvent.TWMessage = MSG_NULL;
S32 rc = m_twBase.TWAIN_DS(&CurrentDS(), DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, (TW_MEMREF)&twEvent);
if( rc < 0 )
WIC_WARN(g_sessnMacLog, “DataSource operation failed:%d”, rc);
else if( rc == TWRC_FAILURE )
TW_UINT16 cc = m_twBase.TWAIN_ConditionCode();
WIC_WARN(g_sessnMacLog, “DS operation returns error: %d/%d”, rc, cc);
if( rc == TWRC_DSEVENT )
WIC_TRACE(g_sessnMacLog, “DataSource consumes the message”);
}October 9, 2017 at 11:55 pm #30661