public CapVM(DataSource ds, CapabilityId cap) { _ds = ds; Cap = cap; var capName = cap.ToString(); var wrapProperty = ds.Capabilities.GetType().GetProperty(capName); if (wrapProperty != null) { _wrapper = wrapProperty.GetGetMethod().Invoke(ds.Capabilities, null); var wrapperType = _wrapper.GetType(); _getMethod = wrapperType.GetMethod("GetValues"); _getCurrentMethod = wrapperType.GetMethod("GetCurrent"); _setMethod = wrapperType.GetMethods().FirstOrDefault(m => m.Name == "SetValue"); } var supportTest = ds.Capabilities.QuerySupport(cap); if (supportTest.HasValue) { Supports = supportTest.Value; } else { if (_wrapper != null) { var wrapperType = _wrapper.GetType(); QuerySupports?supports = (QuerySupports?)wrapperType.GetProperty("SupportedActions").GetGetMethod().Invoke(_wrapper, null); Supports = supports.GetValueOrDefault(); } } }
/// <summary> /// Gets the minimum TWAIN protocol version for a capability. /// </summary> /// <param name="id">The capability type.</param> /// <returns></returns> public static Version GetMinimumVersion(CapabilityId id) { if (__capMinVersions.ContainsKey(id)) { return(__capMinVersions[id]); } return(v10); }
/// <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, hContainer = config.MemoryManager.Allocate((uint)Marshal.SizeOf(typeof(TW_ENUMERATION))) }; if (twCap.hContainer != IntPtr.Zero) { var listSz = value.Type.GetSize() * value.ItemList.Length; TW_ENUMERATION container = new TW_ENUMERATION { ItemType = (ushort)value.Type, NumItems = (uint)value.ItemList.Length, CurrentIndex = (uint)value.CurrentIndex, DefaultIndex = (uint)value.DefaultIndex, ItemList = config.MemoryManager.Allocate((uint)listSz) }; if (container.ItemList != IntPtr.Zero) { IntPtr baseAddr = config.MemoryManager.Lock(container.ItemList); try { int offset = 0; foreach (var it in value.ItemList) { baseAddr.WriteValue(ref offset, value.Type, it); } } finally { config.MemoryManager.Unlock(container.ItemList); } try { baseAddr = config.MemoryManager.Lock(twCap.hContainer); Marshal.StructureToPtr(container, baseAddr, false); } finally { config.MemoryManager.Unlock(twCap.hContainer); } } else { config.MemoryManager.Free(twCap.hContainer); } } return(twCap); }
/// <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> /// Initializes a new instance of the <see cref="CapWrapper{TValue}" /> class. /// </summary> /// <param name="source">The source.</param> /// <param name="capability">The capability.</param> /// <param name="getConversionRoutine">The value conversion routine in Get methods.</param> /// <param name="readOnly">if set to <c>true</c> then make this cap read-only.</param> /// <exception cref="ArgumentNullException"> /// source /// or /// getConversionRoutine /// </exception> /// <exception cref="System.ArgumentNullException">source /// or /// getConversionRoutine</exception> public CapWrapper(IDataSource source, CapabilityId capability, Func <object, TValue> getConversionRoutine, bool readOnly) { if (source == null) { throw new ArgumentNullException("source"); } if (getConversionRoutine == null) { throw new ArgumentNullException("getConversionRoutine"); } _source = source; _getConvertRoutine = getConversionRoutine; IsReadOnly = readOnly; Capability = capability; CheckSupports(); }
/// <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, TW_RANGE value) { var twCap = new TW_CAPABILITY { Capability = cap, ContainerType = ContainerType.Range, hContainer = config.MemoryManager.Allocate((uint)Marshal.SizeOf(typeof(TW_RANGE))) }; if (twCap.hContainer != IntPtr.Zero) { try { IntPtr baseAddr = config.MemoryManager.Lock(twCap.hContainer); Marshal.StructureToPtr(value, baseAddr, false); } finally { config.MemoryManager.Unlock(twCap.hContainer); } } return(twCap); }
/// <summary> /// Initializes a new instance of the <see cref="CapWrapper{TValue}" /> class. /// </summary> /// <param name="source">The source.</param> /// <param name="capability">The capability.</param> /// <param name="getConversionRoutine">The value conversion routine in Get methods.</param> /// <param name="setValueProvider">Callback to provide the capability object for set method.</param> /// <exception cref="System.ArgumentNullException"> /// source /// or /// getConversionRoutine /// or /// setValueProvider /// </exception> public CapWrapper(IDataSource source, CapabilityId capability, Func <object, TValue> getConversionRoutine, Func <TValue, TWOneValue> setValueProvider) { if (source == null) { throw new ArgumentNullException("source"); } if (getConversionRoutine == null) { throw new ArgumentNullException("getConversionRoutine"); } if (setValueProvider == null) { throw new ArgumentNullException("setValueProvider"); } _source = source; _getConvertRoutine = getConversionRoutine; _setOneValueFunc = setValueProvider; Capability = capability; CheckSupports(); }
/// <summary> /// Initializes a new instance of the <see cref="CapWrapper{TValue}" /> class. /// </summary> /// <param name="source">The source.</param> /// <param name="capability">The capability.</param> /// <param name="getConversionRoutine">The value conversion routine in Get methods.</param> /// <param name="setValueRoutine">Callback to perform set value.</param> /// <exception cref="System.ArgumentNullException"> /// source /// or /// getConversionRoutine /// or /// setValueRoutine /// </exception> public CapWrapper(IDataSource source, CapabilityId capability, Func <object, TValue> getConversionRoutine, Func <TValue, ReturnCode> setValueRoutine) { if (source == null) { throw new ArgumentNullException("source"); } if (getConversionRoutine == null) { throw new ArgumentNullException("getConversionRoutine"); } if (setValueRoutine == null) { throw new ArgumentNullException("setValueRoutine"); } _source = source; _getConvertRoutine = getConversionRoutine; _setCustomRoutine = setValueRoutine; Capability = capability; CheckSupports(); }