Started on caps support.

This commit is contained in:
Eugene Wang 2023-04-03 23:06:10 -04:00
parent a12abe7ab6
commit aea7ff4f05
7 changed files with 236 additions and 13 deletions

View File

@ -1148,7 +1148,7 @@ namespace NTwain.Data
/// Used by application to get/set capability from/in a data source.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)]
public struct TW_CAPABILITY
public partial struct TW_CAPABILITY
{
public CAP Cap;
public TWON ConType;
@ -2557,6 +2557,7 @@ namespace NTwain.Data
/// <summary>
/// Flags used in TW_MEMORY structure.
/// </summary>
[Flags]
public enum TWMF : ushort
{
APPOWNS = 0x0001,
@ -3778,6 +3779,7 @@ namespace NTwain.Data
/// <summary>
/// Data Groups...
/// </summary>
[Flags]
public enum DG : uint
{
CONTROL = 0x1,
@ -4327,6 +4329,7 @@ namespace NTwain.Data
/// bit patterns: for query the operation that are supported by the data source on a capability
/// Application gets these through DG_CONTROL/DAT_CAPABILITY/MSG_QUERYSUPPORT
/// </summary>
[Flags]
public enum TWQC : ushort
{
Unknown = 0,

View File

@ -606,16 +606,28 @@ namespace NTwain.Data
partial struct TW_STATUSUTF8
{
/// <summary>
/// Tries to read the text content and frees the memory.
/// Frees the memory if necessary.
/// </summary>
/// <param name="session"></param>
/// <param name="mgr"></param>
public void Free(IMemoryManager mgr)
{
// session already checks for zero
mgr.Free(UTF8string);
UTF8string = IntPtr.Zero;
}
/// <summary>
/// Tries to read the text content and optionally frees the memory.
/// </summary>
/// <param name="mgr"></param>
/// <param name="freeMemory">Whether to free the pointer after reads.</param>
/// <returns></returns>
public string? ReadAndFree(TwainSession session)
public string? Read(IMemoryManager mgr, bool freeMemory = true)
{
string? val = null;
if (UTF8string != IntPtr.Zero && Size > 0)
{
var locked = session.Lock(UTF8string);
var locked = mgr.Lock(UTF8string);
if (locked != IntPtr.Zero)
{
// does this work? who knows.
@ -637,22 +649,37 @@ namespace NTwain.Data
}
finally
{
session.Unlock(UTF8string);
mgr.Unlock(UTF8string);
}
}
}
Free(session);
if (freeMemory) Free(mgr);
return val;
}
}
partial struct TW_CAPABILITY
{
public TW_CAPABILITY(CAP cap)
{
Cap = cap;
ConType = (TWON)TwainConst.TWON_DONTCARE16;
}
/// <summary>
/// Frees the memory if necessary.
/// </summary>
/// <param name="session"></param>
public void Free(TwainSession session)
/// <param name="mgr"></param>
public void Free(IMemoryManager mgr)
{
session.Free(UTF8string);
UTF8string = IntPtr.Zero;
// session already checks for zero
mgr.Free(hContainer);
hContainer = IntPtr.Zero;
}
public void Read(IMemoryManager mgr, bool freeMemory = true)
{
if (freeMemory) Free(mgr);
}
}

View File

@ -0,0 +1,16 @@
using System;
namespace NTwain
{
/// <summary>
/// Something that can do the 4 memory mgmt
/// things required by TWAIN.
/// </summary>
public interface IMemoryManager
{
IntPtr Alloc(uint size);
void Free(IntPtr handle);
IntPtr Lock(IntPtr handle);
void Unlock(IntPtr handle);
}
}

View File

@ -28,6 +28,8 @@ namespace NTwain.Triplets.ControlDATs
=> DoIt(ref app, ref ds, MSG.RESETALL, ref data);
public STS Set(ref TW_IDENTITY_LEGACY app, ref TW_IDENTITY_LEGACY ds, ref TW_CAPABILITY data)
=> DoIt(ref app, ref ds, MSG.SET, ref data);
public STS SetConstraint(ref TW_IDENTITY_LEGACY app, ref TW_IDENTITY_LEGACY ds, ref TW_CAPABILITY data)
=> DoIt(ref app, ref ds, MSG.SETCONSTRAINT, ref data);
static STS DoIt(ref TW_IDENTITY_LEGACY app, ref TW_IDENTITY_LEGACY ds, MSG msg, ref TW_CAPABILITY data)
{

View File

@ -0,0 +1,175 @@
using NTwain.Data;
using NTwain.Triplets;
using System.Collections.Generic;
using System.Linq;
namespace NTwain
{
// this file contains capability mgmt methods
partial class TwainSession
{
///// <summary>
///// Gets all the supported caps for the current source.
///// </summary>
///// <returns></returns>
//public IEnumerable<CAP> GetAllCaps()
//{
// // just as a sample of how to read cap values
// if (GetCapValues(CAP.CAP_SUPPORTEDCAPS, out TW_CAPABILITY value) == STS.SUCCESS)
// {
// value.Read(this);
// }
// return Enumerable.Empty<CAP>();
//}
/// <summary>
/// Gets a CAP's actual supported operations.
/// This is not supported by all sources.
/// </summary>
/// <param name="cap"></param>
/// <returns></returns>
public TWQC QueryCapSupport(CAP cap)
{
var value = new TW_CAPABILITY(cap);
if (DGControl.Capability.QuerySupport(ref _appIdentity, ref _currentDS, ref value) == STS.SUCCESS)
{
value.Read(this);
}
return TWQC.Unknown;
}
/// <summary>
/// Gets a CAP's current value.
/// Caller will need to free the memory.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapCurrent(CAP cap, out TW_CAPABILITY value)
{
value = new TW_CAPABILITY(cap);
return DGControl.Capability.Get(ref _appIdentity, ref _currentDS, ref value);
}
/// <summary>
/// Gets a CAP's default value.
/// Caller will need to free the memory.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapDefault(CAP cap, out TW_CAPABILITY value)
{
value = new TW_CAPABILITY(cap);
return DGControl.Capability.GetDefault(ref _appIdentity, ref _currentDS, ref value);
}
/// <summary>
/// Gets a CAP's supported values.
/// Caller will need to free the memory.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapValues(CAP cap, out TW_CAPABILITY value)
{
value = new TW_CAPABILITY(cap);
return DGControl.Capability.Get(ref _appIdentity, ref _currentDS, ref value);
}
/// <summary>
/// Gets a CAP's help text (description).
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapHelp(CAP cap, out string? help)
{
help = null;
var value = new TW_CAPABILITY(cap);
var rc = DGControl.Capability.GetHelp(ref _appIdentity, ref _currentDS, ref value);
value.Free(this);
return rc;
}
/// <summary>
/// Gets a CAP's text name label.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapLabel(CAP cap, out string? label)
{
label = null;
var value = new TW_CAPABILITY(cap);
var rc = DGControl.Capability.GetLabel(ref _appIdentity, ref _currentDS, ref value);
value.Free(this);
return rc;
}
/// <summary>
/// Gets a CAP's value label texts.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapLabelEnum(CAP cap, out string[]? labels)
{
labels = null;
var value = new TW_CAPABILITY(cap);
var rc = DGControl.Capability.GetLabelEnum(ref _appIdentity, ref _currentDS, ref value);
value.Free(this);
return rc;
}
/// <summary>
/// Sets a CAP's current value.
/// </summary>
/// <param name="cap"></param>
/// <returns></returns>
public STS SetCap(ref TW_CAPABILITY value)
{
var rc = DGControl.Capability.Set(ref _appIdentity, ref _currentDS, ref value);
value.Free(this);
return rc;
}
/// <summary>
/// Sets a CAP's constraint values.
/// </summary>
/// <param name="cap"></param>
/// <returns></returns>
public STS SetConstraint(ref TW_CAPABILITY value)
{
var rc = DGControl.Capability.SetConstraint(ref _appIdentity, ref _currentDS, ref value);
value.Free(this);
return rc;
}
/// <summary>
/// Resets a CAP's current value to power-on default.
/// Caller will need to free the memory.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS ResetCap(CAP cap, out TW_CAPABILITY value)
{
value = new TW_CAPABILITY(cap);
return DGControl.Capability.Reset(ref _appIdentity, ref _currentDS, ref value);
}
/// <summary>
/// Resets all CAP values and constraint to power-on defaults.
/// </summary>
/// <returns></returns>
public STS ResetAllCaps()
{
var value = new TW_CAPABILITY(CAP.CAP_SUPPORTEDCAPS);
var rc = DGControl.Capability.ResetAll(ref _appIdentity, ref _currentDS, ref value);
return rc;
}
}
}

View File

@ -7,7 +7,7 @@ namespace NTwain
{
// this file contains memory methods
partial class TwainSession
partial class TwainSession : IMemoryManager
{
internal TW_ENTRYPOINT_DELEGATES _entryPoint;

View File

@ -256,7 +256,7 @@ namespace NTwain
{
if (DGControl.StatusUtf8.Get(ref _appIdentity, status, out TW_STATUSUTF8 extendedStatus) == STS.SUCCESS)
{
return extendedStatus.ReadAndFree(this);
return extendedStatus.Read(this);
}
return null;
}