Example #1
0
 public static extern ReturnCode DsmWinNew(
     [In, Out] TWIdentity origin,
     [In, Out] TWIdentity destination,
     DataGroups dg,
     DataArgumentType dat,
     Message msg,
     [In, Out] TWPendingXfers data);
Example #2
0
 public static ReturnCode DsmEntry(
     TWIdentity origin,
     TWIdentity destination,
     Message msg,
     TWPendingXfers data)
 {
     if (PlatformInfo.Current.IsWindows)
     {
         if (PlatformInfo.Current.UseNewWinDSM)
         {
             return(NativeMethods.DsmWinNew(origin, destination, DataGroups.Control, DataArgumentType.PendingXfers, msg, data));
         }
         else
         {
             return(NativeMethods.DsmWinOld(origin, destination, DataGroups.Control, DataArgumentType.PendingXfers, msg, data));
         }
     }
     else if (PlatformInfo.Current.IsLinux)
     {
         return(NativeMethods.DsmLinux(origin, destination, DataGroups.Control, DataArgumentType.PendingXfers, msg, data));
     }
     throw new PlatformNotSupportedException();
 }
 /// <summary>
 /// If CapAutoScan is TRUE, this command will stop the operation of the scanner’s automatic
 /// feeder. No other action is taken.
 /// </summary>
 /// <param name="pendingXfers">The pending xfers.</param>
 /// <returns></returns>
 public ReturnCode StopFeeder(TWPendingXfers pendingXfers)
 {
     Session.VerifyState(6, 6, DataGroups.Control, DataArgumentType.PendingXfers, Message.StopFeeder);
     return(Dsm.DsmEntry(Session.AppId, Session.CurrentSource.Identity, Message.StopFeeder, pendingXfers));
 }
 /// <summary>
 /// Sets the number of pending transfers in the Source to zero.
 /// </summary>
 /// <param name="pendingXfers">The pending xfers.</param>
 /// <returns></returns>
 internal ReturnCode Reset(TWPendingXfers pendingXfers)
 {
     Session.VerifyState(6, 6, DataGroups.Control, DataArgumentType.PendingXfers, Message.Reset);
     return(Dsm.DsmEntry(Session.AppId, Session.CurrentSource.Identity, Message.Reset, pendingXfers));
 }
Example #5
0
        /// <summary>
        /// Forces the stepping down of an opened source when things gets out of control.
        /// Used when session state and source state become out of sync.
        /// </summary>
        /// <param name="targetState">State of the target.</param>
        public void ForceStepDown(int targetState)
        {
            PlatformInfo.Current.Log.Debug("Thread {0}: ForceStepDown.", Thread.CurrentThread.ManagedThreadId);

            bool origFlag = EnforceState;

            EnforceState = false;

            // From the twain spec
            // Stepping Back Down the States
            // DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER → state 7 to 6
            // DG_CONTROL / DAT_PENDINGXFERS / MSG_RESET → state 6 to 5
            // DG_CONTROL / DAT_USERINTERFACE / MSG_DISABLEDS → state 5 to 4
            // DG_CONTROL / DAT_IDENTITY / MSG_CLOSEDS → state 4 to 3
            // Ignore the status returns from the calls prior to the one yielding the desired state. For instance, if a
            // call during scanning returns TWCC_SEQERROR and the desire is to return to state 5, then use the
            // following commands.
            // DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER → state 7 to 6
            // DG_CONTROL / DAT_PENDINGXFERS / MSG_RESET → state 6 to 5
            // Being sure to confirm that DG_CONTROL / DAT_PENDINGXFERS / MSG_RESET returned
            // success, the return status from DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER may
            // be ignored.

            _msgLoopHook?.Invoke(() =>
            {
                if (targetState < 7 && CurrentSource != null)
                {
                    // not sure if really necessary but can't hurt to pin it
                    var pending = new TWPendingXfers();
                    var handle  = GCHandle.Alloc(pending, GCHandleType.Pinned);
                    try
                    {
                        ((ITwainSessionInternal)this).DGControl.PendingXfers.EndXfer(pending);
                    }
                    finally
                    {
                        handle.Free();
                    }
                }
                if (targetState < 6 && CurrentSource != null)
                {
                    var pending = new TWPendingXfers();
                    var handle  = GCHandle.Alloc(pending, GCHandleType.Pinned);
                    try
                    {
                        ((ITwainSessionInternal)this).DGControl.PendingXfers.Reset(pending);
                    }
                    finally
                    {
                        handle.Free();
                    }
                }
                if (targetState < 5 && CurrentSource != null)
                {
                    ((ITwainSessionInternal)this).DisableSource();
                }
                if (targetState < 4 && CurrentSource != null)
                {
                    CurrentSource.Close();
                }
                if (targetState < 3)
                {
                    Close();
                }
            });
            EnforceState = origFlag;
        }
Example #6
0
        /// <summary>
        /// Performs the TWAIN transfer routine at state 6.
        /// </summary>
        public static void DoTransferRoutine(ITwainSessionInternal session)
        {
            #region get xfer types

            bool       xferImage   = true; // default to always xfer image
            bool       xferAudio   = false;
            DataGroups xferGroup   = DataGroups.None;
            XferMech   imgXferMech = XferMech.Native;
            XferMech   audXferMech = XferMech.Native;
            if (session.DGControl.XferGroup.Get(ref xferGroup) == ReturnCode.Success)
            {
                xferAudio = (xferGroup & DataGroups.Audio) == DataGroups.Audio;
                // check for Plustek OpticSlim 2680H, this scanner returns wrong xferGroup after first scanning
                if (session.CurrentSource.Identity.ProductName.IndexOf("Plustek", StringComparison.OrdinalIgnoreCase) > -1 &&
                    session.CurrentSource.Identity.ProductName.IndexOf("OpticSlim", StringComparison.OrdinalIgnoreCase) > -1 &&
                    session.CurrentSource.Identity.ProductName.IndexOf("2680H", StringComparison.OrdinalIgnoreCase) > -1)
                {
                    xferImage = true;
                }
                else
                {
                    xferImage = xferGroup == DataGroups.None || (xferGroup & DataGroups.Image) == DataGroups.Image;
                }
            }
            // some DS end up getting none but we will assume it's image
            if (xferImage)
            {
                imgXferMech = session.CurrentSource.Capabilities.ICapXferMech.GetCurrent();
            }
            if (xferAudio)
            {
                var mech = session.CurrentSource.Capabilities.ACapXferMech.GetCurrent();
            }

            #endregion

            var pending = new TWPendingXfers();
            var rc      = session.DGControl.PendingXfers.Get(pending);
            if (rc == ReturnCode.Success)
            {
                do
                {
                    #region raise xfer ready

                    var preXferArgs = new TransferReadyEventArgs(session.CurrentSource, pending.Count, pending.EndOfJob);;
                    session.SafeSyncableRaiseEvent(preXferArgs);

                    #endregion

                    #region actually handle xfer

                    if (preXferArgs.CancelAll || session.CloseDSRequested)
                    {
                        rc = session.DGControl.PendingXfers.Reset(pending);
                    }
                    else
                    {
                        if (!preXferArgs.CancelCurrent)
                        {
                            if (xferImage)
                            {
                                switch (imgXferMech)
                                {
                                case XferMech.Memory:
                                    rc = DoImageMemoryXfer(session);
                                    break;

                                case XferMech.File:
                                    rc = DoImageFileXfer(session);
                                    break;

                                case XferMech.MemFile:
                                    rc = DoImageMemoryFileXfer(session);
                                    break;

                                case XferMech.Native:
                                default:     // always assume native
                                    rc = DoImageNativeXfer(session);
                                    break;
                                }
                            }
                            if (xferAudio)
                            {
                                switch (audXferMech)
                                {
                                case XferMech.File:
                                    rc = DoAudioFileXfer(session);
                                    break;

                                case XferMech.Native:
                                default:     // always assume native
                                    rc = DoAudioNativeXfer(session);
                                    break;
                                }
                            }
                        }

                        if (rc != ReturnCode.Success && session.StopOnTransferError)
                        {
                            // end xfer without setting rc to exit (good/bad?)
                            session.DGControl.PendingXfers.Reset(pending);
                        }
                        else
                        {
                            rc = session.DGControl.PendingXfers.EndXfer(pending);
                        }
                    }
                    #endregion
                } while (rc == ReturnCode.Success && pending.Count != 0 && !session.CloseDSRequested);
            }
            else
            {
                HandleReturnCode(session, rc);
            }

            // some poorly written scanner drivers return failure on EndXfer so also check for pending count now.
            // this may break with other sources but we'll see
            if (//pending.Count == 0 &&
                session.State > 5)
            {
                session.ChangeState(5, true);
                session.DisableSource();
            }
        }