mirror of
https://github.com/soukoku/ntwain.git
synced 2025-07-16 09:18:32 +08:00
First attempt with TW_CAPABILITY generator with one value support.
This commit is contained in:
parent
60138217cd
commit
b4e1435987
199
src/NTwain/CapWriter.cs
Normal file
199
src/NTwain/CapWriter.cs
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
using NTwain.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NTwain
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// CLass that can generate <see cref="TW_CAPABILITY"/> for use in capability negotiation.
|
||||||
|
/// </summary>
|
||||||
|
public class CapWriter
|
||||||
|
{
|
||||||
|
private readonly TwainConfig config;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="CapWriter"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
internal CapWriter(TwainConfig config)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a <see cref="TW_CAPABILITY"/> using single value (aka TW_ONEVALUE).
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="cap"></param>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TW_CAPABILITY Generate<T>(CapabilityId cap, ItemType type, T value)
|
||||||
|
{
|
||||||
|
// size of data + uint16 item type
|
||||||
|
var valueSz = type.GetSize();
|
||||||
|
if (valueSz < 4) valueSz = 4; // onevalue container value minimum is 32bit
|
||||||
|
var memSz = valueSz + 2; // + item type field
|
||||||
|
|
||||||
|
var twCap = new TW_CAPABILITY
|
||||||
|
{
|
||||||
|
Capability = cap,
|
||||||
|
ContainerType = ContainerType.OneValue,
|
||||||
|
hContainer = config.MemoryManager.Allocate((uint)memSz)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (twCap.hContainer != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
IntPtr baseAddr = config.MemoryManager.Lock(twCap.hContainer);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
// TODO: type size may be different on mac
|
||||||
|
baseAddr.WriteValue(ref offset, ItemType.UInt16, value);
|
||||||
|
// ONEVALUE is special in value can be uint32 or string
|
||||||
|
// if less than uint32 put it in lower word
|
||||||
|
// (string value seems undocumented but internet says put it as-is and not a pointer)
|
||||||
|
if (valueSz < 4)
|
||||||
|
{
|
||||||
|
Marshal.WriteInt16(baseAddr, offset, 0);
|
||||||
|
offset += 2;
|
||||||
|
}
|
||||||
|
baseAddr.WriteValue(ref offset, type, value);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
config.MemoryManager.Unlock(twCap.hContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return twCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// Generates a <see cref="TW_CAPABILITY"/> for use in capability negotiation
|
||||||
|
///// using TWAIN's array value.
|
||||||
|
///// </summary>
|
||||||
|
///// <typeparam name="T"></typeparam>
|
||||||
|
///// <param name="cap"></param>
|
||||||
|
///// <param name="value"></param>
|
||||||
|
///// <returns></returns>
|
||||||
|
//public TW_CAPABILITY Generate<T>(CapabilityId cap, ArrayValue<T> value)
|
||||||
|
//{
|
||||||
|
// var twCap = new TW_CAPABILITY
|
||||||
|
// {
|
||||||
|
// Capability = cap,
|
||||||
|
// ContainerType = ContainerType.Array
|
||||||
|
// };
|
||||||
|
// SetOneValue()
|
||||||
|
// return twCap;
|
||||||
|
//}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// Generates a <see cref="TW_CAPABILITY"/> for use in capability negotiation
|
||||||
|
///// using TWAIN's enum value.
|
||||||
|
///// </summary>
|
||||||
|
///// <typeparam name="T"></typeparam>
|
||||||
|
///// <param name="cap"></param>
|
||||||
|
///// <param name="value"></param>
|
||||||
|
///// <returns></returns>
|
||||||
|
//public TW_CAPABILITY Generate<T>(CapabilityId cap, EnumValue<T> value)
|
||||||
|
//{
|
||||||
|
// var twCap = new TW_CAPABILITY
|
||||||
|
// {
|
||||||
|
// Capability = cap,
|
||||||
|
// ContainerType = ContainerType.Enum
|
||||||
|
// };
|
||||||
|
|
||||||
|
// return twCap;
|
||||||
|
//}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// Generates a <see cref="TW_CAPABILITY"/> for use in capability negotiation
|
||||||
|
///// using TWAIN's range value.
|
||||||
|
///// </summary>
|
||||||
|
///// <param name="cap"></param>
|
||||||
|
///// <param name="value"></param>
|
||||||
|
///// <returns></returns>
|
||||||
|
//public TW_CAPABILITY Generate(CapabilityId cap, RangeValue value)
|
||||||
|
//{
|
||||||
|
// var twCap = new TW_CAPABILITY
|
||||||
|
// {
|
||||||
|
// Capability = cap,
|
||||||
|
// ContainerType = ContainerType.Range
|
||||||
|
// };
|
||||||
|
|
||||||
|
// return twCap;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
//void SetEnumValue(TW_ENUMERATION value, IMemoryManager memoryManager)
|
||||||
|
//{
|
||||||
|
// if (value == null) { throw new ArgumentNullException("value"); }
|
||||||
|
// ContainerType = ContainerType.Enum;
|
||||||
|
|
||||||
|
|
||||||
|
// Int32 valueSize = TW_ENUMERATION.ItemOffset + value.ItemList.Length * TypeExtensions.GetItemTypeSize(value.ItemType);
|
||||||
|
|
||||||
|
// int offset = 0;
|
||||||
|
// _hContainer = memoryManager.Allocate((uint)valueSize);
|
||||||
|
// if (_hContainer != IntPtr.Zero)
|
||||||
|
// {
|
||||||
|
// IntPtr baseAddr = memoryManager.Lock(_hContainer);
|
||||||
|
|
||||||
|
// // can't safely use StructureToPtr here so write it our own
|
||||||
|
// baseAddr.WriteValue(ref offset, ItemType.UInt16, value.ItemType);
|
||||||
|
// baseAddr.WriteValue(ref offset, ItemType.UInt32, (uint)value.ItemList.Length);
|
||||||
|
// baseAddr.WriteValue(ref offset, ItemType.UInt32, value.CurrentIndex);
|
||||||
|
// baseAddr.WriteValue(ref offset, ItemType.UInt32, value.DefaultIndex);
|
||||||
|
// foreach (var item in value.ItemList)
|
||||||
|
// {
|
||||||
|
// baseAddr.WriteValue(ref offset, value.ItemType, item);
|
||||||
|
// }
|
||||||
|
// memoryManager.Unlock(_hContainer);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void SetRangeValue(TW_RANGE value, IMemoryManager memoryManager)
|
||||||
|
//{
|
||||||
|
// if (value == null) { throw new ArgumentNullException("value"); }
|
||||||
|
// ContainerType = ContainerType.Range;
|
||||||
|
|
||||||
|
// // since range value can only house UInt32 we will not allow type size > 4
|
||||||
|
// if (TypeExtensions.GetItemTypeSize(value.ItemType) > 4) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.BadValueType, "TW_RANGE")); }
|
||||||
|
|
||||||
|
// _hContainer = memoryManager.Allocate((uint)Marshal.SizeOf(value));
|
||||||
|
// if (_hContainer != IntPtr.Zero)
|
||||||
|
// {
|
||||||
|
// Marshal.StructureToPtr(value, _hContainer, false);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void SetArrayValue(TW_ARRAY value, IMemoryManager memoryManager)
|
||||||
|
//{
|
||||||
|
// if (value == null) { throw new ArgumentNullException("value"); }
|
||||||
|
// ContainerType = ContainerType.Array;
|
||||||
|
|
||||||
|
// Int32 valueSize = 6 + value.ItemList.Length * TypeExtensions.GetItemTypeSize(value.ItemType);
|
||||||
|
|
||||||
|
// int offset = 0;
|
||||||
|
// _hContainer = memoryManager.Allocate((uint)valueSize);
|
||||||
|
// if (_hContainer != IntPtr.Zero)
|
||||||
|
// {
|
||||||
|
// IntPtr baseAddr = memoryManager.Lock(_hContainer);
|
||||||
|
|
||||||
|
// // can't safely use StructureToPtr here so write it our own
|
||||||
|
// baseAddr.WriteValue(ref offset, ItemType.UInt16, value.ItemType);
|
||||||
|
// baseAddr.WriteValue(ref offset, ItemType.UInt32, (uint)value.ItemList.Length);
|
||||||
|
// foreach (var item in value.ItemList)
|
||||||
|
// {
|
||||||
|
// baseAddr.WriteValue(ref offset, value.ItemType, item);
|
||||||
|
// }
|
||||||
|
// memoryManager.Unlock(_hContainer);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -35,17 +35,17 @@ namespace NTwain.Data
|
|||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
partial struct TW_FIX32
|
partial struct TW_FIX32
|
||||||
{
|
{
|
||||||
TW_INT16 _whole;
|
internal TW_INT16 Whole;
|
||||||
TW_UINT16 _frac;
|
internal TW_UINT16 Fraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
partial struct TW_FRAME
|
partial struct TW_FRAME
|
||||||
{
|
{
|
||||||
TW_FIX32 _left;
|
internal TW_FIX32 _left;
|
||||||
TW_FIX32 _top;
|
internal TW_FIX32 _top;
|
||||||
TW_FIX32 _right;
|
internal TW_FIX32 _right;
|
||||||
TW_FIX32 _bottom;
|
internal TW_FIX32 _bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
@ -111,7 +111,7 @@ namespace NTwain.Data
|
|||||||
{
|
{
|
||||||
TW_UINT16 _cap;
|
TW_UINT16 _cap;
|
||||||
TW_UINT16 _conType;
|
TW_UINT16 _conType;
|
||||||
TW_HANDLE _hContainer;
|
internal TW_HANDLE hContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
@ -427,13 +427,13 @@ namespace NTwain.Data
|
|||||||
TW_UINT32 _sheetCount;
|
TW_UINT32 _sheetCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
//[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
partial class TW_ONEVALUE
|
//partial class TW_ONEVALUE
|
||||||
{
|
//{
|
||||||
// TODO: mac is different?
|
// // TODO: mac is different?
|
||||||
public TW_UINT16 ItemType;
|
// public TW_UINT16 ItemType;
|
||||||
public TW_UINT32 Item;
|
// public TW_UINT32 Item;
|
||||||
}
|
//}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
partial struct TW_PALETTE8
|
partial struct TW_PALETTE8
|
||||||
|
@ -32,19 +32,19 @@ namespace NTwain.Data
|
|||||||
|
|
||||||
float ToFloat()
|
float ToFloat()
|
||||||
{
|
{
|
||||||
return (float)_whole + _frac / 65536f;
|
return (float)Whole + Fraction / 65536f;
|
||||||
}
|
}
|
||||||
TW_FIX32(float value)
|
TW_FIX32(float value)
|
||||||
{
|
{
|
||||||
//int temp = (int)(value * 65536.0 + 0.5);
|
//int temp = (int)(value * 65536.0 + 0.5);
|
||||||
//_whole = (short)(temp >> 16);
|
//Whole = (short)(temp >> 16);
|
||||||
//_frac = (ushort)(temp & 0x0000ffff);
|
//Fraction = (ushort)(temp & 0x0000ffff);
|
||||||
|
|
||||||
// different version from twain faq
|
// different version from twain faq
|
||||||
bool sign = value < 0;
|
bool sign = value < 0;
|
||||||
int temp = (int)(value * 65536.0 + (sign ? (-0.5) : 0.5));
|
int temp = (int)(value * 65536.0 + (sign ? (-0.5) : 0.5));
|
||||||
_whole = (short)(temp >> 16);
|
Whole = (short)(temp >> 16);
|
||||||
_frac = (ushort)(temp & 0x0000ffff);
|
Fraction = (ushort)(temp & 0x0000ffff);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,33 +59,6 @@ namespace NTwain.Data
|
|||||||
return ToFloat().ToString(CultureInfo.InvariantCulture);
|
return ToFloat().ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Converts this to <see cref="TW_ONEVALUE"/> for capability set methods.
|
|
||||||
///// </summary>
|
|
||||||
///// <returns></returns>
|
|
||||||
//public TW_ONEVALUE ToOneValue()
|
|
||||||
//{
|
|
||||||
// // copy struct parts as-is.
|
|
||||||
// // probably has a faster way but can't think now
|
|
||||||
|
|
||||||
// byte[] array = new byte[4];
|
|
||||||
// var part = BitConverter.GetBytes(Whole);
|
|
||||||
// Buffer.BlockCopy(part, 0, array, 0, 2);
|
|
||||||
|
|
||||||
// part = BitConverter.GetBytes(Fraction);
|
|
||||||
// Buffer.BlockCopy(part, 0, array, 2, 2);
|
|
||||||
|
|
||||||
// var converted = BitConverter.ToUInt32(array, 0);
|
|
||||||
|
|
||||||
// return new TW_ONEVALUE
|
|
||||||
// {
|
|
||||||
// ItemType = ItemType.Fix32,
|
|
||||||
// Item = converted
|
|
||||||
// // old wrong conversion
|
|
||||||
// // (uint)this,// ((uint)dpi) << 16;
|
|
||||||
// };
|
|
||||||
//}
|
|
||||||
|
|
||||||
#region equals
|
#region equals
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -109,7 +82,7 @@ namespace NTwain.Data
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool Equals(TW_FIX32 other)
|
public bool Equals(TW_FIX32 other)
|
||||||
{
|
{
|
||||||
return _whole == other._whole && _frac == other._frac;
|
return Whole == other.Whole && Fraction == other.Fraction;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a hash code for this instance.
|
/// Returns a hash code for this instance.
|
||||||
@ -119,7 +92,7 @@ namespace NTwain.Data
|
|||||||
/// </returns>
|
/// </returns>
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return _whole ^ _frac;
|
return Whole ^ Fraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -621,16 +594,14 @@ namespace NTwain.Data
|
|||||||
|
|
||||||
// #region properties
|
// #region properties
|
||||||
|
|
||||||
// /// <summary>
|
/// <summary>
|
||||||
// /// Id of capability to set or get.
|
/// Id of capability to set or get.
|
||||||
// /// </summary>
|
/// </summary>
|
||||||
// public CapabilityId Capability { get { return (CapabilityId)_cap; } set { _cap = (ushort)value; } }
|
public CapabilityId Capability { get { return (CapabilityId)_cap; } internal set { _cap = (ushort)value; } }
|
||||||
// /// <summary>
|
/// <summary>
|
||||||
// /// The type of the container structure referenced by the pointer internally. The container
|
/// The type of the container structure referenced by the pointer internally.
|
||||||
// /// will be one of four types: <see cref="TW_ARRAY"/>, <see cref="TW_ENUMERATION"/>,
|
/// </summary>
|
||||||
// /// <see cref="TW_ONEVALUE"/>, or <see cref="TW_RANGE"/>.
|
public ContainerType ContainerType { get { return (ContainerType)_conType; } internal set { _conType = (ushort)value; } }
|
||||||
// /// </summary>
|
|
||||||
// public ContainerType ContainerType { get { return (ContainerType)_conType; } set { _conType = (ushort)value; } }
|
|
||||||
|
|
||||||
// internal IntPtr Container { get { return _hContainer; } }
|
// internal IntPtr Container { get { return _hContainer; } }
|
||||||
|
|
||||||
|
@ -84,19 +84,19 @@ namespace NTwain.Data
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The container is <see cref="TW_ARRAY"/>.
|
/// The container is TW_ARRAY.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Array = 3,
|
Array = 3,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The container is <see cref="TW_ENUMERATION"/>.
|
/// The container is TW_ENUMERATION.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Enum = 4,
|
Enum = 4,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The container is <see cref="TW_ONEVALUE"/>.
|
/// The container is TW_ONEVALUE.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
OneValue = 5,
|
OneValue = 5,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The container is <see cref="TW_RANGE"/>.
|
/// The container is TW_RANGE.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Range = 6,
|
Range = 6,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
190
src/NTwain/Data/TypeExtensions.cs
Normal file
190
src/NTwain/Data/TypeExtensions.cs
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NTwain.Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains extension methods for reading/writing primitive
|
||||||
|
/// TWAIN data types.
|
||||||
|
/// </summary>
|
||||||
|
static class TypeExtensions
|
||||||
|
{
|
||||||
|
static readonly Dictionary<ItemType, int> _sizes = new Dictionary<ItemType, int>
|
||||||
|
{
|
||||||
|
{ ItemType.Int8, 1 },
|
||||||
|
{ ItemType.UInt8, 1 },
|
||||||
|
{ ItemType.Int16, 2 },
|
||||||
|
{ ItemType.UInt16, 2 },
|
||||||
|
{ ItemType.Int32, 4 },
|
||||||
|
{ ItemType.UInt32, 4 },
|
||||||
|
{ ItemType.Bool, 2 },
|
||||||
|
{ ItemType.Fix32, Marshal.SizeOf(typeof(TW_FIX32)) },
|
||||||
|
{ ItemType.Frame, Marshal.SizeOf(typeof(TW_FRAME)) },
|
||||||
|
{ ItemType.String128, TwainConst.String128 },
|
||||||
|
{ ItemType.String255, TwainConst.String255 },
|
||||||
|
{ ItemType.String32, TwainConst.String32 },
|
||||||
|
{ ItemType.String64, TwainConst.String64 },
|
||||||
|
// TODO: find out if it should be fixed 4 bytes or intptr size
|
||||||
|
{ ItemType.Handle, IntPtr.Size },
|
||||||
|
};
|
||||||
|
|
||||||
|
public static int GetSize(this ItemType type)
|
||||||
|
{
|
||||||
|
if(_sizes.TryGetValue(type, out int size)) return size;
|
||||||
|
|
||||||
|
throw new NotSupportedException($"Unsupported item type {type}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region writes
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a TWAIN value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseAddr">The base addr.</param>
|
||||||
|
/// <param name="offset">The offset.</param>
|
||||||
|
/// <param name="type">The TWAIN type.</param>
|
||||||
|
/// <param name="value">The value.</param>
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "1#"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||||
|
public static void WriteValue(this IntPtr baseAddr, ref int offset, ItemType type, object value)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case ItemType.Int8:
|
||||||
|
case ItemType.UInt8:
|
||||||
|
Marshal.WriteByte(baseAddr, offset, Convert.ToByte(value, CultureInfo.InvariantCulture));// (byte)value);
|
||||||
|
break;
|
||||||
|
case ItemType.Bool:
|
||||||
|
case ItemType.Int16:
|
||||||
|
case ItemType.UInt16:
|
||||||
|
Marshal.WriteInt16(baseAddr, offset, Convert.ToInt16(value, CultureInfo.InvariantCulture));//(short)value);
|
||||||
|
break;
|
||||||
|
case ItemType.UInt32:
|
||||||
|
case ItemType.Int32:
|
||||||
|
Marshal.WriteInt32(baseAddr, offset, Convert.ToInt32(value, CultureInfo.InvariantCulture));//(int)value);
|
||||||
|
break;
|
||||||
|
case ItemType.Fix32:
|
||||||
|
TW_FIX32 f32 = (TW_FIX32)value;
|
||||||
|
WriteFix32(baseAddr, ref offset, f32);
|
||||||
|
return; // no need to update offset for this
|
||||||
|
case ItemType.Frame:
|
||||||
|
TW_FRAME frame = (TW_FRAME)value;
|
||||||
|
WriteFix32(baseAddr, ref offset, frame._left);
|
||||||
|
WriteFix32(baseAddr, ref offset, frame._top);
|
||||||
|
WriteFix32(baseAddr, ref offset, frame._right);
|
||||||
|
WriteFix32(baseAddr, ref offset, frame._bottom);
|
||||||
|
return; // no need to update offset for this
|
||||||
|
//case ItemType.String1024:
|
||||||
|
// WriteString(baseAddr, offset, value as string, 1024);
|
||||||
|
// break;
|
||||||
|
case ItemType.String128:
|
||||||
|
WriteString(baseAddr, offset, (string)value, 128);
|
||||||
|
break;
|
||||||
|
case ItemType.String255:
|
||||||
|
WriteString(baseAddr, offset, (string)value, 255);
|
||||||
|
break;
|
||||||
|
case ItemType.String32:
|
||||||
|
WriteString(baseAddr, offset, (string)value, 32);
|
||||||
|
break;
|
||||||
|
case ItemType.String64:
|
||||||
|
WriteString(baseAddr, offset, (string)value, 64);
|
||||||
|
break;
|
||||||
|
//case ItemType.Unicode512:
|
||||||
|
// WriteUString(baseAddr, offset, value as string, 512);
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
offset += type.GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteFix32(IntPtr baseAddr, ref int offset, TW_FIX32 f32)
|
||||||
|
{
|
||||||
|
Marshal.WriteInt16(baseAddr, offset, f32.Whole);
|
||||||
|
if (f32.Fraction > Int16.MaxValue)
|
||||||
|
{
|
||||||
|
Marshal.WriteInt16(baseAddr, offset + 2, (Int16)(f32.Fraction - 32768));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Marshal.WriteInt16(baseAddr, offset + 2, (Int16)f32.Fraction);
|
||||||
|
}
|
||||||
|
offset += _sizes[ItemType.Fix32];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes string value. THIS MAY BE WRONG.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseAddr"></param>
|
||||||
|
/// <param name="offset"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="maxLength"></param>
|
||||||
|
static void WriteString(IntPtr baseAddr, int offset, string value, int maxLength)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
// write zero
|
||||||
|
Marshal.WriteByte(baseAddr, offset, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < maxLength; i++)
|
||||||
|
{
|
||||||
|
if (i == value.Length)
|
||||||
|
{
|
||||||
|
// string end reached, so write \0 and quit
|
||||||
|
Marshal.WriteByte(baseAddr, offset, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Marshal.WriteByte(baseAddr, offset, (byte)value[i]);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// when ended normally also write \0
|
||||||
|
Marshal.WriteByte(baseAddr, offset, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///// <summary>
|
||||||
|
///// Writes unicode string value.
|
||||||
|
///// </summary>
|
||||||
|
///// <param name="baseAddr"></param>
|
||||||
|
///// <param name="offset"></param>
|
||||||
|
///// <param name="item"></param>
|
||||||
|
///// <param name="maxLength"></param>
|
||||||
|
//[EnvironmentPermissionAttribute(SecurityAction.LinkDemand)]
|
||||||
|
//private void WriteUString(IntPtr baseAddr, int offset, string item, int maxLength)
|
||||||
|
//{
|
||||||
|
// if (string.IsNullOrEmpty(item))
|
||||||
|
// {
|
||||||
|
// // write zero
|
||||||
|
// Marshal.WriteInt16(baseAddr, offset, (char)0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // use 2 bytes per char
|
||||||
|
// for (int i = 0; i < maxLength; i++)
|
||||||
|
// {
|
||||||
|
// if (i == item.Length)
|
||||||
|
// {
|
||||||
|
// // string end reached, so write \0 and quit
|
||||||
|
// Marshal.WriteInt16(baseAddr, offset, (char)0);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Marshal.WriteInt16(baseAddr, offset, item[i]);
|
||||||
|
// offset += 2;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // when ended normally also write \0
|
||||||
|
// Marshal.WriteByte(baseAddr, offset, 0);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@ namespace NTwain.Internals
|
|||||||
{
|
{
|
||||||
// probably wrong
|
// probably wrong
|
||||||
|
|
||||||
class LinuxMemoryManager : IMemoryManager
|
class MarshalMemoryManager : IMemoryManager
|
||||||
{
|
{
|
||||||
public IntPtr Allocate(uint size)
|
public IntPtr Allocate(uint size)
|
||||||
{
|
{
|
||||||
@ -22,6 +22,7 @@ namespace NTwain.Internals
|
|||||||
|
|
||||||
public IntPtr Lock(IntPtr handle)
|
public IntPtr Lock(IntPtr handle)
|
||||||
{
|
{
|
||||||
|
// no op
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ namespace NTwain.Threading
|
|||||||
{
|
{
|
||||||
action();
|
action();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
// TODO: do something
|
// TODO: do something
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ namespace NTwain.Triplets.Control
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return all of the labels for a capability of type <see cref="TW_ARRAY"/> or <see cref="TW_ENUMERATION"/>, for example
|
/// Return all of the labels for a capability of type TW_ARRAY or TW_ENUMERATION, for example
|
||||||
/// "US Letter" for ICapSupportedSizes’ TWSS_USLETTER.
|
/// "US Letter" for ICapSupportedSizes’ TWSS_USLETTER.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="capability">The capability.</param>
|
/// <param name="capability">The capability.</param>
|
||||||
@ -145,8 +145,8 @@ namespace NTwain.Triplets.Control
|
|||||||
/// Changes the Current Value(s) and Available Values of the specified capability to those specified
|
/// Changes the Current Value(s) and Available Values of the specified capability to those specified
|
||||||
/// by the application. As of TWAIN 2.2 this only modifies the Current Value of the specified capability, constraints cannot be
|
/// by the application. As of TWAIN 2.2 this only modifies the Current Value of the specified capability, constraints cannot be
|
||||||
/// changed with this.
|
/// changed with this.
|
||||||
/// Current Values are set when the container is a <see cref="TW_ONEVALUE"/> or <see cref="TW_ARRAY"/>. Available and
|
/// Current Values are set when the container is a TW_ONEVALUE or TW_ARRAY. Available and
|
||||||
/// Current Values are set when the container is a <see cref="TW_ENUMERATION"/> or <see cref="TW_RANGE"/>.
|
/// Current Values are set when the container is a TW_ENUMERATION or TW_RANGE.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="capability">The capability.</param>
|
/// <param name="capability">The capability.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@ -159,8 +159,8 @@ namespace NTwain.Triplets.Control
|
|||||||
/// Changes the Current Value(s) and Available Value(s) of the specified capability to those specified
|
/// Changes the Current Value(s) and Available Value(s) of the specified capability to those specified
|
||||||
/// by the application.
|
/// by the application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// Current Values are set when the container is a <see cref="TW_ONEVALUE"/> or <see cref="TW_ARRAY"/>. Available and
|
/// Current Values are set when the container is a TW_ONEVALUE or TW_ARRAY. Available and
|
||||||
/// Current Values are set when the container is a <see cref="TW_ENUMERATION"/> or <see cref="TW_RANGE"/>.
|
/// Current Values are set when the container is a TW_ENUMERATION or TW_RANGE.
|
||||||
/// <param name="capability">The capability.</param>
|
/// <param name="capability">The capability.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public ReturnCode SetConstraint(ref TW_CAPABILITY capability)
|
public ReturnCode SetConstraint(ref TW_CAPABILITY capability)
|
||||||
|
@ -14,17 +14,34 @@ namespace NTwain
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class TwainConfig
|
public class TwainConfig
|
||||||
{
|
{
|
||||||
internal TwainConfig() { }
|
internal TwainConfig(PlatformID platform, bool is32Bit)
|
||||||
|
{
|
||||||
|
Platform = platform;
|
||||||
|
Is32Bit = is32Bit;
|
||||||
|
|
||||||
|
// initial default until twain entry is available
|
||||||
|
switch (platform)
|
||||||
|
{
|
||||||
|
case PlatformID.Win32NT:
|
||||||
|
_defaultMemoryManager = new WinMemoryManager();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_defaultMemoryManager = new MarshalMemoryManager();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly IMemoryManager _defaultMemoryManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether the app is running in 32bit.
|
/// Gets whether the app is running in 32bit.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Is32Bit { get; internal set; }
|
public bool Is32Bit { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the platform the app is running on.
|
/// Gets the platform the app is running on.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PlatformID Platform { get; internal set; }
|
public PlatformID Platform { get; private set; }
|
||||||
|
|
||||||
//public bool PreferLegacyDsm { get; internal set; }
|
//public bool PreferLegacyDsm { get; internal set; }
|
||||||
|
|
||||||
@ -43,11 +60,9 @@ namespace NTwain
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _memMgr ?? DefaultMemoryManager;
|
return _memMgr ?? _defaultMemoryManager;
|
||||||
}
|
}
|
||||||
internal set { _memMgr = value; }
|
internal set { _memMgr = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IMemoryManager DefaultMemoryManager { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ namespace NTwain
|
|||||||
private string _companyName;
|
private string _companyName;
|
||||||
private Language _lang;
|
private Language _lang;
|
||||||
private DataGroups _dg = DataGroups.Image;
|
private DataGroups _dg = DataGroups.Image;
|
||||||
private bool _32bit;
|
readonly bool _32bit;
|
||||||
private PlatformID _platform;
|
readonly PlatformID _platform;
|
||||||
private Country _country;
|
private Country _country;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -106,17 +106,12 @@ namespace NTwain
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public TwainConfig Build()
|
public TwainConfig Build()
|
||||||
{
|
{
|
||||||
var config = new TwainConfig
|
var config = new TwainConfig(_platform, _32bit);
|
||||||
{
|
|
||||||
Platform = _platform,
|
|
||||||
Is32Bit = _32bit
|
|
||||||
};
|
|
||||||
|
|
||||||
// todo: change id based on platform
|
// todo: change id based on platform
|
||||||
switch (_platform)
|
switch (_platform)
|
||||||
{
|
{
|
||||||
case PlatformID.Win32NT:
|
case PlatformID.Win32NT:
|
||||||
config.DefaultMemoryManager = new WinMemoryManager(); // initial default
|
|
||||||
config.App32 = new TW_IDENTITY
|
config.App32 = new TW_IDENTITY
|
||||||
{
|
{
|
||||||
DataFlags = DataFlags.App2,
|
DataFlags = DataFlags.App2,
|
||||||
|
@ -43,6 +43,15 @@ namespace NTwain
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal DGAudio DGAudio => dgAudio ?? (dgAudio = new DGAudio(this));
|
internal DGAudio DGAudio => dgAudio ?? (dgAudio = new DGAudio(this));
|
||||||
|
|
||||||
|
|
||||||
|
//public CapReader CapReader { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="TW_CAPABILITY"/> generator.
|
||||||
|
/// </summary>
|
||||||
|
public CapWriter CapWriter { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when an enabled source has been disabled (back to state 4).
|
/// Occurs when an enabled source has been disabled (back to state 4).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -51,6 +51,8 @@ namespace NTwain
|
|||||||
_callback32Delegate = new Callback32(Handle32BitCallback);
|
_callback32Delegate = new Callback32(Handle32BitCallback);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
//CapReader = new CapReader(this);
|
||||||
|
CapWriter = new CapWriter(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user