Add callback reg after opening source.

This commit is contained in:
Eugene Wang 2023-04-02 07:43:10 -04:00
parent 94fc3f623c
commit 3fc0b97096
12 changed files with 305 additions and 14 deletions

View File

@ -93,5 +93,26 @@ namespace NTwain.DSM
MSG msg,
ref TW_CUSTOMDSDATA twcustomedsdata
);
[DllImport(DsmName, CharSet = CharSet.Ansi)]
internal static extern UInt16 DSM_Entry
(
ref TW_IDENTITY_MACOSX origin,
ref TW_IDENTITY_MACOSX dest,
DG dg,
DAT dat,
MSG msg,
ref TW_CALLBACK twcallback
);
[DllImport(DsmName, CharSet = CharSet.Ansi)]
internal static extern UInt16 DSM_Entry
(
ref TW_IDENTITY_MACOSX origin,
ref TW_IDENTITY_MACOSX dest,
DG dg,
DAT dat,
MSG msg,
ref TW_CALLBACK2 twcallback
);
}
}

View File

@ -93,5 +93,26 @@ namespace NTwain.DSM
MSG msg,
ref TW_CUSTOMDSDATA twcustomedsdata
);
[DllImport(DsmName, CharSet = CharSet.Ansi)]
internal static extern UInt16 DSM_Entry
(
ref TW_IDENTITY_MACOSX origin,
ref TW_IDENTITY_MACOSX dest,
DG dg,
DAT dat,
MSG msg,
ref TW_CALLBACK twcallback
);
[DllImport(DsmName, CharSet = CharSet.Ansi)]
internal static extern UInt16 DSM_Entry
(
ref TW_IDENTITY_MACOSX origin,
ref TW_IDENTITY_MACOSX dest,
DG dg,
DAT dat,
MSG msg,
ref TW_CALLBACK2 twcallback
);
}
}

View File

@ -93,5 +93,26 @@ namespace NTwain.DSM
MSG msg,
ref TW_CUSTOMDSDATA twcustomedsdata
);
[DllImport(DsmName, CharSet = CharSet.Ansi)]
internal static extern UInt16 DSM_Entry
(
ref TW_IDENTITY_LEGACY origin,
ref TW_IDENTITY_LEGACY dest,
DG dg,
DAT dat,
MSG msg,
ref TW_CALLBACK twcallback
);
[DllImport(DsmName, CharSet = CharSet.Ansi)]
internal static extern UInt16 DSM_Entry
(
ref TW_IDENTITY_LEGACY origin,
ref TW_IDENTITY_LEGACY dest,
DG dg,
DAT dat,
MSG msg,
ref TW_CALLBACK2 twcallback
);
}
}

View File

@ -93,5 +93,26 @@ namespace NTwain.DSM
MSG msg,
ref TW_CUSTOMDSDATA twcustomedsdata
);
[DllImport(DsmName, CharSet = CharSet.Ansi)]
internal static extern UInt16 DSM_Entry
(
ref TW_IDENTITY_LEGACY origin,
ref TW_IDENTITY_LEGACY dest,
DG dg,
DAT dat,
MSG msg,
ref TW_CALLBACK twcallback
);
[DllImport(DsmName, CharSet = CharSet.Ansi)]
internal static extern UInt16 DSM_Entry
(
ref TW_IDENTITY_LEGACY origin,
ref TW_IDENTITY_LEGACY dest,
DG dg,
DAT dat,
MSG msg,
ref TW_CALLBACK2 twcallback
);
}
}

View File

@ -0,0 +1,57 @@
using NTwain.DSM;
using TWAINWorkingGroup;
namespace NTwain.Triplets
{
/// <summary>
/// Contains calls used with <see cref="DG.CONTROL"/> and <see cref="DAT.CALLBACK"/>.
/// </summary>
public class DATCallback : TripletBase
{
public DATCallback(TwainSession session) : base(session)
{
}
/// <summary>
/// Registers the callback function.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public STS RegisterCallback(ref TW_CALLBACK data)
{
return DoIt(MSG.REGISTER_CALLBACK, ref data);
}
STS DoIt(MSG msg, ref TW_CALLBACK data)
{
var rc = STS.FAILURE;
if (TwainPlatform.IsWindows)
{
var app = Session.AppIdentity;
var ds = Session.CurrentSource;
if (TwainPlatform.Is32bit && TwainPlatform.PreferLegacyDSM)
{
rc = (STS)WinLegacyDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
}
else
{
rc = (STS)WinNewDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
}
}
else if (TwainPlatform.IsMacOSX)
{
TW_IDENTITY_MACOSX app = Session.AppIdentity;
TW_IDENTITY_MACOSX ds = Session.CurrentSource;
if (TwainPlatform.PreferLegacyDSM)
{
rc = (STS)OSXLegacyDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
}
else
{
rc = (STS)OSXNewDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
}
}
return rc;
}
}
}

View File

@ -0,0 +1,57 @@
using NTwain.DSM;
using TWAINWorkingGroup;
namespace NTwain.Triplets
{
/// <summary>
/// Contains calls used with <see cref="DG.CONTROL"/> and <see cref="DAT.CALLBACK2"/>.
/// </summary>
public class DATCallback2 : TripletBase
{
public DATCallback2(TwainSession session) : base(session)
{
}
/// <summary>
/// Registers the callback function.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public STS RegisterCallback(ref TW_CALLBACK2 data)
{
return DoIt(MSG.REGISTER_CALLBACK, ref data);
}
STS DoIt(MSG msg, ref TW_CALLBACK2 data)
{
var rc = STS.FAILURE;
if (TwainPlatform.IsWindows)
{
var app = Session.AppIdentity;
var ds = Session.CurrentSource;
if (TwainPlatform.Is32bit && TwainPlatform.PreferLegacyDSM)
{
rc = (STS)WinLegacyDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
}
else
{
rc = (STS)WinNewDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
}
}
else if (TwainPlatform.IsMacOSX)
{
TW_IDENTITY_MACOSX app = Session.AppIdentity;
TW_IDENTITY_MACOSX ds = Session.CurrentSource;
if (TwainPlatform.PreferLegacyDSM)
{
rc = (STS)OSXLegacyDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
}
else
{
rc = (STS)OSXNewDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
}
}
return rc;
}
}
}

View File

@ -24,16 +24,8 @@ namespace NTwain.Triplets
if ((rc = DoIt(MSG.OPENDS, ref ds)) == STS.SUCCESS)
{
Session.CurrentSource = ds;
Session.RegisterCallback();
Session.State = STATE.S4;
//// determine memory mgmt routines used
//if ((((DG)Session._appIdentity.SupportedGroups) & DG.DSM2) == DG.DSM2)
//{
// TW_ENTRYPOINT_DELEGATES entry = default;
// if (Session.DGControl.EntryPoint.Get(ref entry) == STS.SUCCESS)
// {
// Session._entryPoint = entry;
// }
//}
}
return rc;
}
@ -48,8 +40,8 @@ namespace NTwain.Triplets
var ds = Session.CurrentSource;
if ((rc = DoIt(MSG.CLOSEDS, ref ds)) == STS.SUCCESS)
{
Session.CurrentSource = default;
Session.State = STATE.S3;
Session.CurrentSource = default;
}
return rc;
}

View File

@ -24,7 +24,6 @@ namespace NTwain.Triplets
if ((rc = DoIt(MSG.OPENDSM, ref hwnd)) == STS.SUCCESS)
{
Session._hwnd = hwnd;
Session.State = STATE.S3;
// get default source
if (Session.DGControl.Identity.GetDefault(out TW_IDENTITY_LEGACY ds) == STS.SUCCESS)
@ -40,6 +39,7 @@ namespace NTwain.Triplets
Session._entryPoint = entry;
}
}
Session.State = STATE.S3;
}
return rc;
}
@ -54,9 +54,10 @@ namespace NTwain.Triplets
STS rc;
if ((rc = DoIt(MSG.CLOSEDSM, ref hwnd)) == STS.SUCCESS)
{
Session._hwnd = IntPtr.Zero;
Session._entryPoint = default;
Session.State = STATE.S2;
Session._entryPoint = default;
Session.DefaultSource = default;
Session._hwnd = IntPtr.Zero;
}
return rc;
}

View File

@ -30,5 +30,11 @@
private DATDeviceEvent? _deviceEvent;
public DATDeviceEvent DeviceEvent => _deviceEvent ??= new DATDeviceEvent(Session);
private DATCallback? _callback;
public DATCallback Callback => _callback ??= new DATCallback(Session);
private DATCallback2? _callback2;
public DATCallback2 Callback2 => _callback2 ??= new DATCallback2(Session);
}
}

View File

@ -0,0 +1,91 @@
using System;
using System.Runtime.InteropServices;
using TWAINWorkingGroup;
namespace NTwain
{
// this file contains callback methods
partial class TwainSession
{
// these are kept around while a callback ptr is registered so they
// don't get gc'd
readonly NativeMethods.WindowsDsmEntryCallbackDelegate _legacyCallbackDelegate;
readonly NativeMethods.MacosxDsmEntryCallbackDelegate _osxCallbackDelegate;
/// <summary>
/// Try to registers callbacks for after opening the source.
/// </summary>
internal void RegisterCallback()
{
IntPtr cbPtr = IntPtr.Zero;
if (TwainPlatform.IsMacOSX)
{
cbPtr = Marshal.GetFunctionPointerForDelegate(_osxCallbackDelegate);
}
else
{
cbPtr = Marshal.GetFunctionPointerForDelegate(_legacyCallbackDelegate);
}
var rc = STS.FAILURE;
// per the spec (pg 8-10), apps for 2.2 or higher uses callback2 so try this first
if (_appIdentity.ProtocolMajor > 2 || (_appIdentity.ProtocolMajor >= 2 && _appIdentity.ProtocolMinor >= 2))
{
var cb2 = new TW_CALLBACK2 { CallBackProc = cbPtr };
rc = DGControl.Callback2.RegisterCallback(ref cb2);
}
if (rc != STS.SUCCESS)
{
// always try old callback
var cb = new TW_CALLBACK { CallBackProc = cbPtr };
DGControl.Callback.RegisterCallback(ref cb);
}
}
private ushort LegacyCallbackHandler
(
ref TW_IDENTITY_LEGACY origin,
ref TW_IDENTITY_LEGACY dest,
DG dg,
DAT dat,
MSG msg,
IntPtr twnull
)
{
HandleSourceMsg(msg);
return (ushort)STS.SUCCESS;
}
private ushort OSXCallbackHandler
(
ref TW_IDENTITY_MACOSX origin,
ref TW_IDENTITY_MACOSX dest,
DG dg,
DAT dat,
MSG msg,
IntPtr twnull
)
{
HandleSourceMsg(msg);
return (ushort)STS.SUCCESS;
}
private void HandleSourceMsg(MSG msg)
{
switch (msg)
{
case MSG.XFERREADY:
break;
case MSG.DEVICEEVENT:
break;
case MSG.CLOSEDSOK:
break;
case MSG.CLOSEDSREQ:
break;
}
}
}
}

View File

@ -2,6 +2,7 @@
using System;
using System.Runtime.InteropServices;
using TWAINWorkingGroup;
using static System.Collections.Specialized.BitVector32;
namespace NTwain
{
@ -151,6 +152,5 @@ namespace NTwain
/// Fires when <see cref="CurrentSource"/> changes.
/// </summary>
public event Action<TwainSession, TW_IDENTITY_LEGACY>? CurrentSourceChanged;
}
}

View File

@ -81,6 +81,9 @@ namespace NTwain
DGControl = new DGControl(this);
DGImage = new DGImage(this);
DGAudio = new DGAudio(this);
_legacyCallbackDelegate = LegacyCallbackHandler;
_osxCallbackDelegate = OSXCallbackHandler;
}
internal IntPtr _hwnd;