mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-05 20:59:23 +08:00
Another attempt, starting with only the defined types.
This commit is contained in:
parent
1610e39d2d
commit
64e631bd2a
27
NTwain.sln
27
NTwain.sln
@ -11,14 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_common", "_common", "{4CE0
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NTwain", "src\NTwain\NTwain.csproj", "{B391C1B7-5647-4B7A-9079-81E835E633DD}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Net5Console", "samples\Net5Console\Net5Console.csproj", "{9F6C1B39-D0C9-4466-96A0-AB41C58762A9}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{707B4313-8EF8-4D0F-A95E-590783422187}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NTwain.Win", "src\NTwain.Win\NTwain.Win.csproj", "{F836149E-E64D-476E-A325-478D18BE1CC7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_twain-doc", "_twain-doc", "{0C94E5AD-E226-4A30-92B4-C28FE5B7FC23}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
twain-doc\TWAIN-2.5-Features.pdf = twain-doc\TWAIN-2.5-Features.pdf
|
||||
@ -26,31 +20,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_twain-doc", "_twain-doc",
|
||||
twain-doc\twain2.5.h = twain-doc\twain2.5.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NTwain", "src\NTwain\NTwain.csproj", "{3C8A3CF9-A60D-4F21-B866-D291A7AABD4A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B391C1B7-5647-4B7A-9079-81E835E633DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B391C1B7-5647-4B7A-9079-81E835E633DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B391C1B7-5647-4B7A-9079-81E835E633DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B391C1B7-5647-4B7A-9079-81E835E633DD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9F6C1B39-D0C9-4466-96A0-AB41C58762A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9F6C1B39-D0C9-4466-96A0-AB41C58762A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9F6C1B39-D0C9-4466-96A0-AB41C58762A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9F6C1B39-D0C9-4466-96A0-AB41C58762A9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F836149E-E64D-476E-A325-478D18BE1CC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F836149E-E64D-476E-A325-478D18BE1CC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F836149E-E64D-476E-A325-478D18BE1CC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F836149E-E64D-476E-A325-478D18BE1CC7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3C8A3CF9-A60D-4F21-B866-D291A7AABD4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3C8A3CF9-A60D-4F21-B866-D291A7AABD4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3C8A3CF9-A60D-4F21-B866-D291A7AABD4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3C8A3CF9-A60D-4F21-B866-D291A7AABD4A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{9F6C1B39-D0C9-4466-96A0-AB41C58762A9} = {707B4313-8EF8-4D0F-A95E-590783422187}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {7459323B-44F6-4E07-8574-E1B4B525086B}
|
||||
EndGlobalSection
|
||||
|
20
src/NTwain-temp/NTwain-temp.csproj
Normal file
20
src/NTwain-temp/NTwain-temp.csproj
Normal file
@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageId>NTwain</PackageId>
|
||||
<Description>Library containing the TWAIN API for dotnet.</Description>
|
||||
<TargetFrameworks>net462;netcoreapp3.1;net5.0;net6.0;net7.0;netstandard2.0</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>11</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
|
||||
<PackageReference Include="System.Security.Permissions" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
|
||||
</ItemGroup>-->
|
||||
</Project>
|
4
src/NTwain-temp/TWAINWorkingGroup/README.md
Normal file
4
src/NTwain-temp/TWAINWorkingGroup/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
This namespace contains types and utilities from the [twaincs project](https://github.com/twain/twain-cs)
|
||||
that's been modified with partials.
|
||||
|
||||
Version initially used is 2.5.0.0.
|
1621
src/NTwain-temp/TWAINWorkingGroup/TWAIN CS.rtf
Normal file
1621
src/NTwain-temp/TWAINWorkingGroup/TWAIN CS.rtf
Normal file
File diff suppressed because it is too large
Load Diff
15540
src/NTwain-temp/TWAINWorkingGroup/TWAIN.cs
Normal file
15540
src/NTwain-temp/TWAINWorkingGroup/TWAIN.cs
Normal file
File diff suppressed because it is too large
Load Diff
8381
src/NTwain-temp/TWAINWorkingGroup/TWAINH.cs
Normal file
8381
src/NTwain-temp/TWAINWorkingGroup/TWAINH.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -29,22 +29,22 @@ namespace NTwain
|
||||
object Invoke(Delegate work, params object[] args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Async calls are marshalled to threadpool thread.
|
||||
/// Should only be used in non-UI apps.
|
||||
/// </summary>
|
||||
public class ThreadPoolMarshaller : IThreadMarshaller
|
||||
{
|
||||
public bool InvokeRequired => throw new NotImplementedException();
|
||||
///// <summary>
|
||||
///// Async calls are marshalled to threadpool thread.
|
||||
///// Should only be used in non-UI apps.
|
||||
///// </summary>
|
||||
//public class ThreadPoolMarshaller : IThreadMarshaller
|
||||
//{
|
||||
// public bool InvokeRequired => throw new NotImplementedException();
|
||||
|
||||
public void BeginInvoke(Delegate work, params object[] args)
|
||||
{
|
||||
Task.Run(() => work.DynamicInvoke(args));
|
||||
}
|
||||
// public void BeginInvoke(Delegate work, params object[] args)
|
||||
// {
|
||||
// Task.Run(() => work.DynamicInvoke(args));
|
||||
// }
|
||||
|
||||
public object Invoke(Delegate work, params object[] args)
|
||||
{
|
||||
return work.DynamicInvoke(args);
|
||||
}
|
||||
}
|
||||
// public object Invoke(Delegate work, params object[] args)
|
||||
// {
|
||||
// return work.DynamicInvoke(args);
|
||||
// }
|
||||
//}
|
||||
}
|
@ -105,7 +105,7 @@ namespace NTwain
|
||||
|
||||
private void HandleUIThreadAction(Action action)
|
||||
{
|
||||
DebugThreadInfo("begin");
|
||||
DebugThreadInfo("begin UI thread action");
|
||||
|
||||
_threadMarshaller.Invoke(action);
|
||||
}
|
||||
@ -118,7 +118,7 @@ namespace NTwain
|
||||
// Drain the event queue...
|
||||
while (true)
|
||||
{
|
||||
DebugThreadInfo("in loop");
|
||||
DebugThreadInfo("in device event loop");
|
||||
|
||||
// Try to get an event...
|
||||
twdeviceevent = default;
|
||||
@ -143,92 +143,92 @@ namespace NTwain
|
||||
|
||||
private STS HandleScanEvent(bool closing)
|
||||
{
|
||||
DebugThreadInfo("begin");
|
||||
DebugThreadInfo("scan event begin");
|
||||
|
||||
// the scan event needs to return asap since it can come from msg loop
|
||||
// so fire off the handling work to another thread
|
||||
_threadMarshaller.BeginInvoke(new Action<bool>(HandleScanEventReal), closing);
|
||||
//_threadMarshaller.BeginInvoke(new Action<bool>(HandleScanEventReal), closing);
|
||||
return STS.SUCCESS;
|
||||
}
|
||||
|
||||
void HandleScanEventReal(bool closing)
|
||||
{
|
||||
DebugThreadInfo("begin");
|
||||
//void HandleScanEventReal(bool closing)
|
||||
//{
|
||||
// DebugThreadInfo("begin");
|
||||
|
||||
if (_twain == null || State <= STATE.S4 || closing) return;
|
||||
// if (_twain == null || State <= STATE.S4 || closing) return;
|
||||
|
||||
if (_twain.IsMsgCloseDsReq() || _twain.IsMsgCloseDsOk())
|
||||
{
|
||||
_twain.Rollback(STATE.S4);
|
||||
return;
|
||||
}
|
||||
// if (_twain.IsMsgCloseDsReq() || _twain.IsMsgCloseDsOk())
|
||||
// {
|
||||
// _twain.Rollback(STATE.S4);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// all except mem xfer will run this once and raise event.
|
||||
// mem xfer will run this multiple times until complete image is assembled
|
||||
if (_twain.IsMsgXferReady())
|
||||
{
|
||||
TW_PENDINGXFERS pending = default;
|
||||
var sts = _twain.DatPendingxfers(DG.CONTROL, MSG.GET, ref pending);
|
||||
if (sts != STS.SUCCESS)
|
||||
{
|
||||
try
|
||||
{
|
||||
TransferError?.Invoke(this, new TransferErrorEventArgs(sts));
|
||||
}
|
||||
catch { }
|
||||
return; // do more?
|
||||
}
|
||||
// // all except mem xfer will run this once and raise event.
|
||||
// // mem xfer will run this multiple times until complete image is assembled
|
||||
// if (_twain.IsMsgXferReady())
|
||||
// {
|
||||
// TW_PENDINGXFERS pending = default;
|
||||
// var sts = _twain.DatPendingxfers(DG.CONTROL, MSG.GET, ref pending);
|
||||
// if (sts != STS.SUCCESS)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// TransferError?.Invoke(this, new TransferErrorEventArgs(sts));
|
||||
// }
|
||||
// catch { }
|
||||
// return; // do more?
|
||||
// }
|
||||
|
||||
var xferMech = Capabilities.ICAP_XFERMECH.GetCurrent();
|
||||
// var xferMech = Capabilities.ICAP_XFERMECH.GetCurrent();
|
||||
|
||||
var readyArgs = new TransferReadyEventArgs(_twain, pending.Count, (TWEJ)pending.EOJ);
|
||||
try
|
||||
{
|
||||
TransferReady?.Invoke(this, readyArgs);
|
||||
}
|
||||
catch { }
|
||||
// var readyArgs = new TransferReadyEventArgs(_twain, pending.Count, (TWEJ)pending.EOJ);
|
||||
// try
|
||||
// {
|
||||
// TransferReady?.Invoke(this, readyArgs);
|
||||
// }
|
||||
// catch { }
|
||||
|
||||
if (readyArgs.CancelCapture == CancelType.Immediate)
|
||||
{
|
||||
sts = _twain.DatPendingxfers(DG.CONTROL, MSG.RESET, ref pending);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (readyArgs.CancelCapture == CancelType.Graceful) StopCapture();
|
||||
// if (readyArgs.CancelCapture == CancelType.Immediate)
|
||||
// {
|
||||
// sts = _twain.DatPendingxfers(DG.CONTROL, MSG.RESET, ref pending);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (readyArgs.CancelCapture == CancelType.Graceful) StopCapture();
|
||||
|
||||
if (!readyArgs.SkipCurrent)
|
||||
{
|
||||
switch (xferMech)
|
||||
{
|
||||
case TWSX.NATIVE:
|
||||
RunImageNativeXfer();
|
||||
break;
|
||||
case TWSX.MEMFILE:
|
||||
RunImageMemFileXfer();
|
||||
break;
|
||||
case TWSX.FILE:
|
||||
RunImageFileXfer();
|
||||
break;
|
||||
case TWSX.MEMORY:
|
||||
RunImageMemoryXfer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
sts = _twain.DatPendingxfers(DG.CONTROL, MSG.ENDXFER, ref pending);
|
||||
}
|
||||
// if (!readyArgs.SkipCurrent)
|
||||
// {
|
||||
// switch (xferMech)
|
||||
// {
|
||||
// case TWSX.NATIVE:
|
||||
// RunImageNativeXfer();
|
||||
// break;
|
||||
// case TWSX.MEMFILE:
|
||||
// RunImageMemFileXfer();
|
||||
// break;
|
||||
// case TWSX.FILE:
|
||||
// RunImageFileXfer();
|
||||
// break;
|
||||
// case TWSX.MEMORY:
|
||||
// RunImageMemoryXfer();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// sts = _twain.DatPendingxfers(DG.CONTROL, MSG.ENDXFER, ref pending);
|
||||
// }
|
||||
|
||||
// TODO: may be wrong for now
|
||||
if (pending.Count == 0 || sts == STS.CANCEL || sts == STS.XFERDONE)
|
||||
{
|
||||
_twain.Rollback(STATE.S4);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleScanEvent(State <= STATE.S3);
|
||||
}
|
||||
}
|
||||
// // TODO: may be wrong for now
|
||||
// if (pending.Count == 0 || sts == STS.CANCEL || sts == STS.XFERDONE)
|
||||
// {
|
||||
// _twain.Rollback(STATE.S4);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// HandleScanEvent(State <= STATE.S3);
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void DebugThreadInfo(string description, [CallerMemberName] string callerName = "")
|
@ -51,7 +51,7 @@ namespace NTwain
|
||||
{
|
||||
TWTY itemType;
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Crack the container...
|
||||
var onevalue = MarshalTo<TW_ONEVALUE_MACOSX>(lockedPtr);
|
||||
@ -88,7 +88,7 @@ namespace NTwain
|
||||
int count = 0;
|
||||
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Crack the container...
|
||||
var twenumerationmacosx = MarshalTo<TW_ENUMERATION_MACOSX>(lockedPtr);
|
||||
@ -99,7 +99,7 @@ namespace NTwain
|
||||
lockedPtr += Marshal.SizeOf(twenumerationmacosx);
|
||||
}
|
||||
// Windows or the 2.4+ Linux DSM...
|
||||
else if ((PlatformInfo.IsWindows) || ((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
|
||||
else if (TWAIN.GetPlatform() == Platform.WINDOWS || ((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
|
||||
{
|
||||
// Crack the container...
|
||||
var twenumeration = MarshalTo<TW_ENUMERATION>(lockedPtr);
|
||||
@ -153,7 +153,7 @@ namespace NTwain
|
||||
uint count;
|
||||
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Crack the container...
|
||||
var twarraymacosx = MarshalTo<TW_ARRAY_MACOSX>(lockedPtr);
|
||||
@ -197,7 +197,7 @@ namespace NTwain
|
||||
TW_RANGE_FIX32 twrangefix32 = default;
|
||||
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
var twrangemacosx = MarshalTo<TW_RANGE_MACOSX>(lockedPtr);
|
||||
var twrangefix32macosx = MarshalTo<TW_RANGE_FIX32_MACOSX>(lockedPtr);
|
||||
@ -215,7 +215,7 @@ namespace NTwain
|
||||
twrangefix32.CurrentValue = twrangefix32macosx.CurrentValue;
|
||||
}
|
||||
// Windows or the 2.4+ Linux DSM...
|
||||
else if ((PlatformInfo.IsWindows) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm) ||
|
||||
else if (TWAIN.GetPlatform() == Platform.WINDOWS || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm) ||
|
||||
((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
|
||||
{
|
||||
twrange = MarshalTo<TW_RANGE>(lockedPtr);
|
||||
@ -295,7 +295,7 @@ namespace NTwain
|
||||
{
|
||||
TWTY itemType;
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Crack the container...
|
||||
var onevalue = MarshalTo<TW_ONEVALUE_MACOSX>(lockedPtr);
|
@ -72,7 +72,7 @@ namespace NTwain
|
||||
TWTY itemType = GetItemType<TValue>();
|
||||
|
||||
// Allocate the container (go for worst case, which is TW_STR255)...
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE_MACOSX)) + Marshal.SizeOf(default(TW_STR255))));
|
||||
lockedPtr = twain.DsmMemLock(twCap.hContainer);
|
||||
@ -113,7 +113,7 @@ namespace NTwain
|
||||
TWTY itemType = GetItemType<TValue>();
|
||||
|
||||
// Allocate the container (go for worst case, which is TW_STR255)...
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Allocate...
|
||||
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ARRAY_MACOSX)) + ((values.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
|
||||
@ -166,7 +166,7 @@ namespace NTwain
|
||||
TWTY itemType = GetItemType<TValue>();
|
||||
|
||||
// Allocate the container (go for worst case, which is TW_STR255)...
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Allocate...
|
||||
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_MACOSX)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
|
||||
@ -184,7 +184,7 @@ namespace NTwain
|
||||
lockedPtr += Marshal.SizeOf(twenumerationmacosx);
|
||||
}
|
||||
// Windows or the 2.4+ Linux DSM...
|
||||
else if ((PlatformInfo.IsWindows) ||
|
||||
else if (TWAIN.GetPlatform() == Platform.WINDOWS ||
|
||||
(twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm) ||
|
||||
((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
|
||||
{
|
||||
@ -244,14 +244,14 @@ namespace NTwain
|
||||
TWTY itemType = GetItemType<TValue>();
|
||||
|
||||
// Allocate the container (go for worst case, which is TW_STR255)...
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Allocate...
|
||||
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_RANGE_MACOSX))));
|
||||
lockedPtr = twain.DsmMemLock(twCap.hContainer);
|
||||
}
|
||||
// Windows or the 2.4+ Linux DSM...
|
||||
else if ((PlatformInfo.IsWindows) ||
|
||||
else if (TWAIN.GetPlatform() == Platform.WINDOWS ||
|
||||
(twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm) ||
|
||||
((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
|
||||
{
|
||||
@ -289,7 +289,7 @@ namespace NTwain
|
||||
default:
|
||||
throw new NotSupportedException($"{itemType} is not supported for range.");
|
||||
case TWTY.INT8:
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
twrangemacosx.ItemType = (uint)itemType;
|
||||
twrangemacosx.MinValue = (uint)Convert.ToSByte(value.MinValue);
|
||||
@ -321,7 +321,7 @@ namespace NTwain
|
||||
}
|
||||
break;
|
||||
case TWTY.UINT8:
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
twrangemacosx.ItemType = (uint)itemType;
|
||||
twrangemacosx.MinValue = Convert.ToByte(value.MinValue);
|
||||
@ -353,7 +353,7 @@ namespace NTwain
|
||||
}
|
||||
break;
|
||||
case TWTY.INT16:
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
twrangemacosx.ItemType = (uint)itemType;
|
||||
twrangemacosx.MinValue = (uint)Convert.ToInt16(value.MinValue);
|
||||
@ -386,7 +386,7 @@ namespace NTwain
|
||||
break;
|
||||
case TWTY.BOOL:
|
||||
case TWTY.UINT16:
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
twrangemacosx.ItemType = (uint)itemType;
|
||||
twrangemacosx.MinValue = Convert.ToUInt16(value.MinValue);
|
||||
@ -418,7 +418,7 @@ namespace NTwain
|
||||
}
|
||||
break;
|
||||
case TWTY.INT32:
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
twrangemacosx.ItemType = (uint)itemType;
|
||||
twrangemacosx.MinValue = (uint)Convert.ToInt32(value.MinValue);
|
||||
@ -450,7 +450,7 @@ namespace NTwain
|
||||
}
|
||||
break;
|
||||
case TWTY.UINT32:
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
twrangemacosx.ItemType = (uint)itemType;
|
||||
twrangemacosx.MinValue = Convert.ToUInt32(value.MinValue);
|
||||
@ -487,7 +487,7 @@ namespace NTwain
|
||||
double step = Convert.ToDouble(value.StepSize);
|
||||
double def = Convert.ToDouble(value.DefaultValue);
|
||||
double current = Convert.ToDouble(value.CurrentValue);
|
||||
if (PlatformInfo.IsMacOSX)
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
TW_RANGE_FIX32_MACOSX twrangefix32macosx = default;
|
||||
twrangefix32macosx.ItemType = (uint)itemType;
|
@ -1,43 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NTwain
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains info on current platform, process, and TWAIN stuff.
|
||||
/// </summary>
|
||||
public static class PlatformInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the current OS is windows.
|
||||
/// </summary>
|
||||
public static bool IsWindows { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the current OS is linux.
|
||||
/// </summary>
|
||||
public static bool IsLinux { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the current OS is MacOSX.
|
||||
/// </summary>
|
||||
public static bool IsMacOSX { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the application is running in 64-bit.
|
||||
/// </summary>
|
||||
public static bool IsApp64Bit { get; set; }
|
||||
|
||||
static PlatformInfo()
|
||||
{
|
||||
var platform = Environment.OSVersion.Platform;
|
||||
IsWindows = platform == PlatformID.Win32NT;
|
||||
IsLinux = platform == PlatformID.Unix;
|
||||
IsMacOSX = platform == PlatformID.MacOSX;
|
||||
IsApp64Bit = IntPtr.Size == 8;
|
||||
}
|
||||
}
|
||||
}
|
3858
src/NTwain/TWAINWorkingGroup/NativeMethods.cs
Normal file
3858
src/NTwain/TWAINWorkingGroup/NativeMethods.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
This namespace contains types and utilities from the [twaincs project](https://github.com/twain/twain-cs)
|
||||
that's been modified with partials.
|
||||
This namespace contains types and utilities that were modified
|
||||
from the [twaincs project](https://github.com/twain/twain-cs).
|
||||
|
||||
Version initially used is 2.5.0.0.
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
535
src/NTwain/TWAINWorkingGroup/TWAINH_EXTRAS.cs
Normal file
535
src/NTwain/TWAINWorkingGroup/TWAINH_EXTRAS.cs
Normal file
@ -0,0 +1,535 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace TWAINWorkingGroup
|
||||
{
|
||||
// this contains my additions under the TWAINWorkingGroup namespace
|
||||
// that makes some twain types easier to work with.
|
||||
|
||||
/// <summary>
|
||||
/// Contains platform info for twain use.
|
||||
/// </summary>
|
||||
public static class TwainPlatform
|
||||
{
|
||||
static TwainPlatform()
|
||||
{
|
||||
Is64bit = IntPtr.Size == 8;
|
||||
|
||||
#if NETFRAMEWORK
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
{
|
||||
IsWindows = true;
|
||||
}
|
||||
else if (System.IO.Directory.Exists("/Library/Application Support"))
|
||||
{
|
||||
IsMacOSX = true;
|
||||
}
|
||||
else if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
IsLinux = true;
|
||||
}
|
||||
|
||||
#else
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
IsWindows = true;
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
IsMacOSX = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the code is running under Linux.
|
||||
/// </summary>
|
||||
public static bool IsLinux { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the code is running under MacOSX.
|
||||
/// </summary>
|
||||
public static bool IsMacOSX { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the code is running under Windows.
|
||||
/// </summary>
|
||||
public static bool IsWindows { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the code is running in 64bit or 32bit.
|
||||
/// </summary>
|
||||
public static bool Is64bit { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains value that don't fit into enums nicely.
|
||||
/// </summary>
|
||||
public class TwainConst
|
||||
{
|
||||
/// <summary>
|
||||
/// Don't care values...
|
||||
/// </summary>
|
||||
public const byte TWON_DONTCARE8 = 0xff;
|
||||
public const ushort TWON_DONTCARE16 = 0xff;
|
||||
public const uint TWON_DONTCARE32 = 0xffffffff;
|
||||
/// <summary>
|
||||
/// We're departing from a strict translation of H so that
|
||||
/// we can achieve a unified status return type.
|
||||
/// </summary>
|
||||
public const int STSCC = 0x10000; // get us past the custom space
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TWAIN's boolean values.
|
||||
/// </summary>
|
||||
public enum BoolType : ushort
|
||||
{
|
||||
/// <summary>
|
||||
/// The false value (0).
|
||||
/// </summary>
|
||||
False = 0,
|
||||
/// <summary>
|
||||
/// The true value (1).
|
||||
/// </summary>
|
||||
True = 1
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A more dotnet-friendly representation of <see cref="TW_METRICS"/>.
|
||||
/// </summary>
|
||||
public struct Metrics
|
||||
{
|
||||
/// <summary>
|
||||
/// Return code of querying the metrics.
|
||||
/// </summary>
|
||||
public STS ReturnCode;
|
||||
|
||||
/// <summary>
|
||||
/// The number of sheets of paper processed by the scanner.
|
||||
/// </summary>
|
||||
public int Sheets;
|
||||
|
||||
/// <summary>
|
||||
/// The number of images made available for transfer by the driver. This is not
|
||||
/// necessarily the same as the number of images actually transferred, since the
|
||||
/// application may opt to skip transfers or to end without transferring all images.
|
||||
/// </summary>
|
||||
public int Images;
|
||||
}
|
||||
|
||||
public struct TwainDirectTaskResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Return code of task.
|
||||
/// </summary>
|
||||
public STS ReturnCode;
|
||||
|
||||
/// <summary>
|
||||
/// The response of the task in JSON if successful.
|
||||
/// </summary>
|
||||
public string ResponseJson;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public class Enumeration<TValue> where TValue : struct
|
||||
{
|
||||
public int CurrentIndex;
|
||||
|
||||
public int DefaultIndex;
|
||||
|
||||
public TValue[] Items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A more dotnet-friendly representation of <see cref="TW_RANGE"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public partial class Range<TValue> : IEnumerable<TValue> where TValue : struct
|
||||
{
|
||||
public TValue MinValue;
|
||||
public TValue MaxValue;
|
||||
public TValue StepSize;
|
||||
public TValue DefaultValue;
|
||||
public TValue CurrentValue;
|
||||
|
||||
IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
|
||||
{
|
||||
if (!(MinValue is IConvertible))
|
||||
throw new NotSupportedException($"The value type {typeof(TValue).Name} is not supported for range enumeration.");
|
||||
|
||||
return new DynamicEnumerator(MinValue, MaxValue, StepSize);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<TValue>)this).GetEnumerator();
|
||||
}
|
||||
|
||||
// dynamic is a cheap hack to sidestep the compiler restrictions if I know TValue is numeric
|
||||
class DynamicEnumerator : IEnumerator<TValue>
|
||||
{
|
||||
private readonly TValue _min;
|
||||
private readonly TValue _max;
|
||||
private readonly TValue _step;
|
||||
private TValue _cur;
|
||||
bool started = false;
|
||||
|
||||
public DynamicEnumerator(TValue min, TValue max, TValue step)
|
||||
{
|
||||
_min = min;
|
||||
_max = max;
|
||||
_step = step;
|
||||
_cur = min;
|
||||
}
|
||||
|
||||
public TValue Current => _cur;
|
||||
|
||||
object IEnumerator.Current => this.Current;
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (!started)
|
||||
{
|
||||
started = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
var next = _cur + (dynamic)_step;
|
||||
if (next == _cur || next < _min || next > _max) return false;
|
||||
|
||||
_cur = next;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_cur = _min;
|
||||
started = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
partial struct TW_FIX32 : IEquatable<TW_FIX32>, IConvertible
|
||||
{
|
||||
// this conversion logic is found in the twain spec.
|
||||
|
||||
float ToFloat()
|
||||
{
|
||||
return Whole + Frac / 65536f;
|
||||
}
|
||||
double ToDouble()
|
||||
{
|
||||
return Whole + Frac / 65536.0;
|
||||
}
|
||||
public TW_FIX32(double value)
|
||||
{
|
||||
Whole = (short)value;
|
||||
Frac = (ushort)((value - Whole) * 65536.0);
|
||||
}
|
||||
public TW_FIX32(float value)
|
||||
{
|
||||
//int temp = (int)(value * 65536.0 + 0.5);
|
||||
//Whole = (short)(temp >> 16);
|
||||
//Fraction = (ushort)(temp & 0x0000ffff);
|
||||
|
||||
// different version from twain faq
|
||||
bool sign = value < 0;
|
||||
int temp = (int)(value * 65536.0 + (sign ? (-0.5) : 0.5));
|
||||
Whole = (short)(temp >> 16);
|
||||
Frac = (ushort)(temp & 0x0000ffff);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToFloat().ToString();
|
||||
}
|
||||
|
||||
public bool Equals(TW_FIX32 other)
|
||||
{
|
||||
return Whole == other.Whole && Frac == other.Frac;
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is TW_FIX32 other)
|
||||
{
|
||||
return Equals(other);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Whole ^ Frac;
|
||||
}
|
||||
|
||||
|
||||
#region IConvertable
|
||||
|
||||
TypeCode IConvertible.GetTypeCode()
|
||||
{
|
||||
return TypeCode.Single;
|
||||
}
|
||||
|
||||
bool IConvertible.ToBoolean(IFormatProvider provider)
|
||||
{
|
||||
return this != 0;
|
||||
}
|
||||
|
||||
byte IConvertible.ToByte(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToByte((float)this);
|
||||
}
|
||||
|
||||
char IConvertible.ToChar(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToChar((float)this);
|
||||
}
|
||||
|
||||
DateTime IConvertible.ToDateTime(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToDateTime((float)this);
|
||||
}
|
||||
|
||||
decimal IConvertible.ToDecimal(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToDecimal((float)this);
|
||||
}
|
||||
|
||||
double IConvertible.ToDouble(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToDouble((float)this);
|
||||
}
|
||||
|
||||
short IConvertible.ToInt16(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToInt16((float)this);
|
||||
}
|
||||
|
||||
int IConvertible.ToInt32(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToInt32((float)this);
|
||||
}
|
||||
|
||||
long IConvertible.ToInt64(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToInt64((float)this);
|
||||
}
|
||||
|
||||
sbyte IConvertible.ToSByte(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToSByte((float)this);
|
||||
}
|
||||
|
||||
float IConvertible.ToSingle(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToSingle((float)this);
|
||||
}
|
||||
|
||||
string IConvertible.ToString(IFormatProvider provider)
|
||||
{
|
||||
return this.ToString();
|
||||
}
|
||||
|
||||
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
|
||||
{
|
||||
return Convert.ChangeType((float)this, conversionType, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
ushort IConvertible.ToUInt16(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToUInt16((float)this);
|
||||
}
|
||||
|
||||
uint IConvertible.ToUInt32(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToUInt32((float)this);
|
||||
}
|
||||
|
||||
ulong IConvertible.ToUInt64(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToUInt64((float)this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static implicit operator float(TW_FIX32 value) => value.ToFloat();
|
||||
public static implicit operator TW_FIX32(float value) => new TW_FIX32(value);
|
||||
|
||||
public static implicit operator double(TW_FIX32 value) => value.ToDouble();
|
||||
public static implicit operator TW_FIX32(double value) => new TW_FIX32((float)value);
|
||||
|
||||
public static bool operator ==(TW_FIX32 value1, TW_FIX32 value2) => value1.Equals(value2);
|
||||
public static bool operator !=(TW_FIX32 value1, TW_FIX32 value2) => !value1.Equals(value2);
|
||||
}
|
||||
|
||||
partial struct TW_FRAME : IEquatable<TW_FRAME>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates <see cref="TW_FRAME"/> from a string representation of it.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public TW_FRAME(string value) : this()
|
||||
{
|
||||
var parts = value.Split(',');
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
Left = float.Parse(parts[0]);
|
||||
Top = float.Parse(parts[1]);
|
||||
Right = float.Parse(parts[2]);
|
||||
Bottom = float.Parse(parts[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException($"Cannot create frame from \"{value}\".");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representation of Left,Top,Right,Bottom.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Left},{Top},{Right},{Bottom}";
|
||||
}
|
||||
|
||||
public bool Equals(TW_FRAME other)
|
||||
{
|
||||
return Left == other.Left && Top == other.Top &&
|
||||
Right == other.Right && Bottom == other.Bottom;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is TW_FRAME other)
|
||||
{
|
||||
return Equals(other);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Left.GetHashCode() ^ Top.GetHashCode() ^
|
||||
Right.GetHashCode() ^ Bottom.GetHashCode();
|
||||
}
|
||||
|
||||
|
||||
public static bool operator ==(TW_FRAME value1, TW_FRAME value2)
|
||||
{
|
||||
return value1.Equals(value2);
|
||||
}
|
||||
public static bool operator !=(TW_FRAME value1, TW_FRAME value2)
|
||||
{
|
||||
return !value1.Equals(value2);
|
||||
}
|
||||
}
|
||||
|
||||
partial struct TW_STR32
|
||||
{
|
||||
public const int Size = 34;
|
||||
|
||||
public TW_STR32(string value) : this()
|
||||
{
|
||||
Set(value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
public static implicit operator string(TW_STR32 value) => value.ToString();
|
||||
public static explicit operator TW_STR32(string value) => new TW_STR32(value);
|
||||
|
||||
}
|
||||
|
||||
partial struct TW_STR64
|
||||
{
|
||||
public const int Size = 66;
|
||||
|
||||
public TW_STR64(string value) : this()
|
||||
{
|
||||
Set(value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
public static implicit operator string(TW_STR64 value) => value.ToString();
|
||||
public static explicit operator TW_STR64(string value) => new TW_STR64(value);
|
||||
}
|
||||
|
||||
partial struct TW_STR128
|
||||
{
|
||||
public const int Size = 130;
|
||||
|
||||
public TW_STR128(string value) : this()
|
||||
{
|
||||
Set(value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
public static implicit operator string(TW_STR128 value) => value.ToString();
|
||||
public static explicit operator TW_STR128(string value) => new TW_STR128(value);
|
||||
}
|
||||
|
||||
partial struct TW_STR255
|
||||
{
|
||||
public const int Size = 256;
|
||||
|
||||
public TW_STR255(string value) : this()
|
||||
{
|
||||
Set(value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
public static implicit operator string(TW_STR255 value) => value.ToString();
|
||||
public static explicit operator TW_STR255(string value) => new TW_STR255(value);
|
||||
}
|
||||
|
||||
partial struct TW_IDENTITY
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Manufacturer} - {ProductFamily} - {ProductName} {Version} (TWAIN {ProtocolMajor}.{ProtocolMinor})";
|
||||
}
|
||||
}
|
||||
|
||||
partial struct TW_VERSION
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{MajorNum}.{MinorNum}";
|
||||
}
|
||||
}
|
||||
|
||||
//partial struct TW_DEVICEEVENT
|
||||
//{
|
||||
// public TWDE Event { get { return (TWDE)_event; } }
|
||||
// public TWFL FlashUsed2 { get { return (TWFL)_flashUsed2; } }
|
||||
//}
|
||||
}
|
Loading…
Reference in New Issue
Block a user