public static extern ReturnCode DsmWin32( [In, Out] TW_IDENTITY origin, [In, Out] TW_IDENTITY destination, DataGroups dg, DataArgumentType dat, Message msg, ref TW_CALLBACK data);
internal void RegisterCallback() { // TODO: support other platforms var callbackPtr = Marshal.GetFunctionPointerForDelegate(_callback32Delegate); // try new callback first var cb2 = new TW_CALLBACK2 { CallBackProc = callbackPtr }; var rc = DGControl.Callback2.RegisterCallback(ref cb2); if (rc == ReturnCode.Success) { Debug.WriteLine("Registed Callback2 success."); } else { var status = GetStatus(); Debug.WriteLine($"Register Callback2 failed with condition code: {status.ConditionCode}."); } if (rc != ReturnCode.Success) { // always register old callback var cb = new TW_CALLBACK { CallBackProc = callbackPtr }; rc = DGControl.Callback.RegisterCallback(ref cb); if (rc == ReturnCode.Success) { Debug.WriteLine("Registed Callback success."); } else { var status = GetStatus(); Debug.WriteLine($"Register Callback failed with {status.ConditionCode}."); } } }
public ReturnCode RegisterCallback(ref TW_CALLBACK callback) { if (Is32Bit) { if (IsWin) { return(NativeMethods.DsmWin32(Session.Config.App32, Session.CurrentSource.Identity32, DataGroups.Control, DataArgumentType.Callback, Message.RegisterCallback, ref callback)); } if (IsLinux) { return(NativeMethods.DsmLinux32(Session.Config.App32, Session.CurrentSource.Identity32, DataGroups.Control, DataArgumentType.Callback, Message.RegisterCallback, ref callback)); } if (IsMac) { return(NativeMethods.DsmMac32(Session.Config.App32, Session.CurrentSource.Identity32, DataGroups.Control, DataArgumentType.Callback, Message.RegisterCallback, ref callback)); } } if (IsWin) { return(NativeMethods.DsmWin64(Session.Config.App32, Session.CurrentSource.Identity32, DataGroups.Control, DataArgumentType.Callback, Message.RegisterCallback, ref callback)); } if (IsLinux) { return(NativeMethods.DsmLinux64(Session.Config.App32, Session.CurrentSource.Identity32, DataGroups.Control, DataArgumentType.Callback, Message.RegisterCallback, ref callback)); } if (IsMac) { return(NativeMethods.DsmMac64(Session.Config.App32, Session.CurrentSource.Identity32, DataGroups.Control, DataArgumentType.Callback, Message.RegisterCallback, ref callback)); } return(ReturnCode.Failure); }
/// <summary> /// Convert the contents of a string to an callback structure... /// </summary> /// <param name="a_twcallback">A TWAIN structure</param> /// <param name="a_szCallback">A CSV string of the TWAIN structure</param> /// <returns>True if the conversion is successful</returns> public bool CsvToCallback(ref TW_CALLBACK a_twcallback, string a_szCallback) { // Init stuff... a_twcallback = default(TW_CALLBACK); // Build the string... try { string[] asz = CSV.Parse(a_szCallback); // Grab the values... a_twcallback.CallBackProc = (IntPtr)UInt64.Parse(asz[0]); a_twcallback.RefCon = uint.Parse(asz[1]); a_twcallback.Message = ushort.Parse(asz[2]); } catch { return (false); } // All done... return (true); }
/////////////////////////////////////////////////////////////////////////////// // Public Helper Functions, we're mapping TWAIN structures to strings to // make it easier for the application to work with the data. All of the // functions that do that are located here... /////////////////////////////////////////////////////////////////////////////// #region Public Helper Functions... /// <summary> /// Convert the contents of a callback to a string that we can show in /// our simple GUI... /// </summary> /// <param name="a_twcallback">A TWAIN structure</param> /// <returns>A CSV string of the TWAIN structure</returns> public string CallbackToCsv(TW_CALLBACK a_twcallback) { try { CSV csv = new CSV(); csv.Add(a_twcallback.CallBackProc.ToString()); csv.Add(a_twcallback.RefCon.ToString()); csv.Add(a_twcallback.Message.ToString()); return (csv.Get()); } catch { return ("***error***"); } }
/// <summary> /// Issue identity commands... /// </summary> /// <param name="a_dg">Data group</param> /// <param name="a_msg">Operation</param> /// <param name="a_twidentity">IDENTITY structure</param> /// <returns>TWAIN status</returns> public STS DatIdentity(DG a_dg, MSG a_msg, ref TW_IDENTITY a_twidentity) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twidentity = a_twidentity; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.IDENTITY; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twidentity = m_twaincommand.Get(lIndex).twidentity; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.IDENTITY.ToString(), a_msg.ToString(), ((a_msg == MSG.OPENDS) ? IdentityToCsv(a_twidentity) : "")); } // Windows... if (ms_platform == Platform.WINDOWS) { TW_IDENTITY_LEGACY twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)WindowsTwain32DsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); } else { sts = (STS)WindowsTwaindsmDsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); } } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (GetMachineWordBitSize() == 32) { TW_IDENTITY_LEGACY twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); sts = (STS)LinuxDsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); } else { sts = (STS)Linux64DsmEntryIdentity(ref m_twidentityApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref a_twidentity); } } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { TW_IDENTITY_MACOSX twidentitymacosx = TwidentityToTwidentitymacosx(a_twidentity); // Issue the command... try { sts = (STS)MacosxDsmEntryIdentity(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitymacosx); } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } a_twidentity = TwidentitymacosxToTwidentity(twidentitymacosx); } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts.ToString(), IdentityToCsv(a_twidentity)); } // If we opened, go to state 4... if (a_msg == MSG.OPENDS) { if (sts == STS.SUCCESS) { // Change our state, and record the identity we picked... m_state = STATE.S4; m_twidentityDs = a_twidentity; m_twidentitylegacyDs = TwidentityToTwidentitylegacy(m_twidentityDs); m_twidentitymacosxDs = TwidentityToTwidentitymacosx(m_twidentityDs); // Register for callbacks... // Windows... if (ms_platform == Platform.WINDOWS) { if (m_blUseCallbacks) { TW_CALLBACK twcallback = new TW_CALLBACK(); twcallback.CallBackProc = Marshal.GetFunctionPointerForDelegate(m_windowsdsmentrycontrolcallbackdelegate); // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CALLBACK.ToString(), a_msg.ToString(), CallbackToCsv(twcallback)); } // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)WindowsTwain32DsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } else { sts = (STS)WindowsTwaindsmDsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts.ToString(), ""); } } } // Linux... else if (ms_platform == Platform.LINUX) { TW_CALLBACK twcallback = new TW_CALLBACK(); twcallback.CallBackProc = Marshal.GetFunctionPointerForDelegate(m_linuxdsmentrycontrolcallbackdelegate); // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CALLBACK.ToString(), MSG.REGISTER_CALLBACK.ToString(), CallbackToCsv(twcallback)); } // Issue the command... try { if (TWAIN.GetMachineWordBitSize() == 32) { sts = (STS)LinuxDsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } else { sts = (STS)Linux64DsmEntryCallback(ref m_twidentityApp, ref m_twidentityDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts.ToString(), ""); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { IntPtr intptr = IntPtr.Zero; TW_CALLBACK twcallback = new TW_CALLBACK(); twcallback.CallBackProc = Marshal.GetFunctionPointerForDelegate(m_macosxdsmentrycontrolcallbackdelegate); // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CALLBACK.ToString(), a_msg.ToString(), CallbackToCsv(twcallback)); } // Issue the command... try { sts = (STS)MacosxDsmEntryCallback(ref m_twidentitymacosxApp, intptr, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts.ToString(), ""); } } } } // If we closed, go to state 3... else if (a_msg == MSG.CLOSEDS) { if (sts == STS.SUCCESS) { m_state = STATE.S3; } } // All done... return (AutoDatStatus(sts)); }
/// <summary> /// Issue callback commands... /// </summary> /// <param name="a_dg">Data group</param> /// <param name="a_msg">Operation</param> /// <param name="a_twcallback">Callback structure</param> /// <returns>TWAIN status</returns> public STS DatCallback(DG a_dg, MSG a_msg, ref TW_CALLBACK a_twcallback) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twcallback = a_twcallback; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.CALLBACK; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twcallback = m_twaincommand.Get(lIndex).twcallback; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CALLBACK.ToString(), a_msg.ToString(), CallbackToCsv(a_twcallback)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)WindowsTwain32DsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } else { sts = (STS)WindowsTwaindsmDsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (GetMachineWordBitSize() == 32) { sts = (STS)LinuxDsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } else { sts = (STS)Linux64DsmEntryCallback(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { sts = (STS)MacosxDsmEntryCallback(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts.ToString(), CallbackToCsv(a_twcallback)); } // All done... return (AutoDatStatus(sts)); }
private static extern UInt16 MacosxDsmEntryCallback ( ref TW_IDENTITY_MACOSX origin, IntPtr dest, DG dg, DAT dat, MSG msg, ref TW_CALLBACK twcallback );
private static extern UInt16 Linux64DsmEntryCallback ( ref TW_IDENTITY origin, ref TW_IDENTITY dest, DG dg, DAT dat, MSG msg, ref TW_CALLBACK twcallback );
private static extern UInt16 WindowsTwaindsmDsmEntryCallback ( ref TW_IDENTITY_LEGACY origin, ref TW_IDENTITY_LEGACY dest, DG dg, DAT dat, MSG msg, ref TW_CALLBACK twcallback );