using NTwain.Data; using NTwain.Internals; using NTwain.Triplets; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Text; using System.Threading; namespace NTwain { /// /// Represents a TWAIN data source. /// public partial class DataSource : IDataSource { ITwainSessionInternal _session; internal DataSource(ITwainSessionInternal session, TWIdentity sourceId) { _session = session; Identity = sourceId; ProtocolVersion = new Version(sourceId.ProtocolMajor, sourceId.ProtocolMinor); } /// /// Opens the source for capability negotiation. /// /// public ReturnCode Open() { var rc = ReturnCode.Failure; _session.MessageLoopHook.Invoke(() => { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenSource.", Thread.CurrentThread.ManagedThreadId)); rc = _session.DGControl.Identity.OpenDS(this); _session.UpdateCallback(); }); return rc; } /// /// Closes the source. /// /// public ReturnCode Close() { var rc = ReturnCode.Failure; _session.MessageLoopHook.Invoke(() => { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseSource.", Thread.CurrentThread.ManagedThreadId)); rc = _session.DGControl.Identity.CloseDS(); if (rc == ReturnCode.Success) { SupportedCaps = null; } _session.UpdateCallback(); }); return rc; } /// /// Enables the source to start transferring. /// /// The mode. /// if set to true any driver UI will display as modal. /// The window handle if modal. /// public ReturnCode Enable(SourceEnableMode mode, bool modal, IntPtr windowHandle) { return _session.EnableSource(mode, modal, windowHandle); } /// /// Gets the source status. Only call this at state 4 or higher. /// /// public TWStatus GetStatus() { TWStatus stat; _session.DGControl.Status.GetSource(out stat); return stat; } /// /// Gets the source status. Only call this at state 4 or higher. /// /// public TWStatusUtf8 GetStatusUtf8() { TWStatusUtf8 stat; _session.DGControl.StatusUtf8.GetSource(out stat); return stat; } #region properties internal TWIdentity Identity { get; private set; } /// /// Gets the source's product name. /// /// /// The name. /// public string Name { get { return Identity.ProductName; } } /// /// Gets the source's manufacturer name. /// /// /// The manufacturer. /// public string Manufacturer { get { return Identity.Manufacturer; } } /// /// Gets the source's product family. /// /// /// The product family. /// public string ProductFamily { get { return Identity.ProductFamily; } } /// /// Gets the source's version information. /// /// /// The version. /// public TWVersion Version { get { return Identity.Version; } } /// /// Gets the supported data group. /// /// /// The data group. /// public DataGroups DataGroup { get { return Identity.DataGroup; } } /// /// Gets the supported TWAIN protocol version. /// /// /// The protocol version. /// public Version ProtocolVersion { get; private set; } /// /// Gets a value indicating whether this data source has been opened. /// /// /// true if this data source is open; otherwise, false. /// public bool IsOpen { get { return _session.IsSourceOpen; } } static readonly CapabilityId[] _emptyCapList = new CapabilityId[0]; private IList _supportedCapsList; /// /// Gets the list of supported caps for this source. /// /// /// The supported caps. /// [Obsolete("Use CapSupportedCaps.Get() instead.")] public IList SupportedCaps { get { if (_supportedCapsList == null && _session.State > 3) { _supportedCapsList = CapSupportedCaps.Get(); } return _supportedCapsList ?? _emptyCapList; } private set { _supportedCapsList = value; //OnPropertyChanged("SupportedCaps"); } } /// /// Gets the triplet operations defined for control data group. /// public DGControl DGControl { get { return _session.DGControl; } } /// /// Gets the triplet operations defined for image data group. /// public DGImage DGImage { get { return _session.DGImage; } } /// /// Gets the direct triplet operation entry for custom values. /// public DGCustom DGCustom { get { return _session.DGCustom; } } #endregion //#region INotifyPropertyChanged Members ///// ///// Occurs when a property value changes. ///// //public event PropertyChangedEventHandler PropertyChanged; ///// ///// Raises the event. ///// ///// Name of the property. //protected void OnPropertyChanged(string propertyName) //{ // var syncer = Session.SynchronizationContext; // if (syncer == null) // { // try // { // var hand = PropertyChanged; // if (hand != null) { hand(this, new PropertyChangedEventArgs(propertyName)); } // } // catch { } // } // else // { // syncer.Post(o => // { // try // { // var hand = PropertyChanged; // if (hand != null) { hand(this, new PropertyChangedEventArgs(propertyName)); } // } // catch { } // }, null); // } //} //#endregion #region cameras /// /// [Experimental] Gets the cameras supported by the source. /// /// public IList GetCameras() { TWFileSystem fs = new TWFileSystem(); List cams = new List(); var rc = DGControl.FileSystem.GetFirstFile(fs); while (rc == ReturnCode.Success) { switch (fs.FileType) { case FileType.Camera: case FileType.CameraBottom: case FileType.CameraTop: case FileType.CameraPreview: cams.Add(fs.OutputName); break; } rc = DGControl.FileSystem.GetNextFile(fs); } return cams; } /// /// [Experimental] Sets the target camera for cap negotiation that can be set per camera. /// /// /// public ReturnCode SetCamera(string cameraName) { TWFileSystem fs = new TWFileSystem(); fs.InputName = cameraName; return DGControl.FileSystem.ChangeDirectory(fs); } #endregion } }