public override KeyInfo ReadKey(ReadKeyOptions options)
 {
     if (this.externalRawUI == null)
     {
         this.ThrowNotInteractive();
     }
     KeyInfo info = new KeyInfo();
     try
     {
         info = this.externalRawUI.ReadKey(options);
     }
     catch (PipelineStoppedException)
     {
         LocalPipeline currentlyRunningPipeline = (LocalPipeline) ((RunspaceBase) this.parentHost.Context.CurrentRunspace).GetCurrentlyRunningPipeline();
         if (currentlyRunningPipeline == null)
         {
             throw;
         }
         currentlyRunningPipeline.Stopper.Stop();
     }
     return info;
 }
        ReadKey(ReadKeyOptions options)
        {
            if (_externalRawUI == null)
            {
                ThrowNotInteractive();
            }
            KeyInfo result = new KeyInfo();
            try
            {
                result = _externalRawUI.ReadKey(options);
            }
            catch (PipelineStoppedException)
            {
                //PipelineStoppedException is thrown by host when it wants 
                //to stop the pipeline. 
                LocalPipeline lpl = (LocalPipeline)((RunspaceBase)_parentHost.Context.CurrentRunspace).GetCurrentlyRunningPipeline();
                if (lpl == null)
                {
                    throw;
                }
                lpl.Stopper.Stop();
            }

            return result;
        }
 KEY_EVENT_RECORDToKeyInfo(ConsoleControl.KEY_EVENT_RECORD keyEventRecord, out KeyInfo keyInfo)
 {
     keyInfo = new KeyInfo(
         keyEventRecord.VirtualKeyCode,
         keyEventRecord.UnicodeChar,
         (ControlKeyStates)keyEventRecord.ControlKeyState,
         keyEventRecord.KeyDown);
 }
Example #4
0
        /// <summary>
        /// Thread method invoked from <see cref="ReadKey"/> that waits for the user to press a key.
        /// </summary>
        /// <param name="state"><see cref="Tuple{T1, T2}"/> object containing a <see cref="StreamConnection"/> object and a <see cref="ReadKeyOptions"/>
        /// object.</param>
        private void ReadInput(object state)
        {
            StreamConnection connection = (state as Tuple<StreamConnection, ReadKeyOptions>).Item1;
            ReadKeyOptions options = (state as Tuple<StreamConnection, ReadKeyOptions>).Item2;
            bool inEscapeSequence = false;
            bool readKey = false;

            while (!readKey)
            {
                if (connection.OutputQueue.Count > 0)
                {
                    while (connection.OutputQueue.Count > 0)
                    {
                        byte currentByte = connection.OutputQueue.Dequeue();

                        // Handle the backspace key
                        if (currentByte == 8)
                        {
                            _readKey = new KeyInfo
                                           {
                                               VirtualKeyCode = 8
                                           };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor left
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho && CursorPosition.X > 1)
                                CursorPosition = new Coordinates(CursorPosition.X - 1, CursorPosition.Y);

                            readKey = true;
                            break;
                        }

                            // The ^X character signifies the start of an ANSI escape sequence
                        else if (currentByte == 27)
                            inEscapeSequence = true;

                            // If we're in an escape sequence, read past the "[" and "~" characters
                        else if (currentByte == 91 && inEscapeSequence)
                        {
                        }

                        else if (currentByte == 126 && inEscapeSequence)
                        {
                        }

                            // ^X7 is the home key
                        else if (currentByte == 55 && inEscapeSequence)
                        {
                            _readKey = new KeyInfo
                                           {
                                               VirtualKeyCode = 0x24
                                           };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor to the start of the line
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho)
                                CursorPosition = new Coordinates(1, CursorPosition.Y);

                            readKey = true;
                            break;
                        }

                            // ^X8 or ^X3 is the end key
                        else if ((currentByte == 56 || currentByte == 51) && inEscapeSequence)
                        {
                            _readKey = new KeyInfo
                                           {
                                               VirtualKeyCode = 0x23
                                           };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor to the end of the line
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho)
                                CursorPosition = new Coordinates(BufferSize.Width, CursorPosition.Y);

                            readKey = true;
                            break;
                        }

                            // ^XD is the left arrow
                        else if (currentByte == 68 && inEscapeSequence)
                        {
                            _readKey = new KeyInfo
                                           {
                                               VirtualKeyCode = 0x25
                                           };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor left
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho && CursorPosition.X > 1)
                                CursorPosition = new Coordinates(CursorPosition.X - 1, CursorPosition.Y);

                            readKey = true;
                            break;
                        }

                            // ^XC is the right arrow
                        else if (currentByte == 67 && inEscapeSequence)
                        {
                            _readKey = new KeyInfo
                                           {
                                               VirtualKeyCode = 0x27
                                           };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor right
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho && CursorPosition.X < BufferSize.Width)
                                CursorPosition = new Coordinates(CursorPosition.X + 1, CursorPosition.Y);

                            readKey = true;
                            break;
                        }

                            // Handle the carriage return sequence
                        else if (currentByte == 13)
                        {
                            _readKey = new KeyInfo
                                           {
                                               Character = '\r',
                                               VirtualKeyCode = 0x0D
                                           };

                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho)
                                CursorPosition = new Coordinates(1, CursorPosition.Y);

                            readKey = true;
                            break;
                        }

                            // Otherwise, get the virtual key code and character and populate _readKey
                        else
                        {
                            short virtualKey = User32.VkKeyScan((char) currentByte);
                            int modifiers = virtualKey >> 8;
                            ControlKeyStates controlKeys = 0;

                            if ((modifiers & 2) != 0)
                                controlKeys |= ControlKeyStates.LeftCtrlPressed;

                            if ((modifiers & 4) != 0)
                                controlKeys |= ControlKeyStates.LeftAltPressed;

                            _readKey = new KeyInfo
                                           {
                                               Character = (char) currentByte,
                                               VirtualKeyCode = (virtualKey & 0xFF),
                                               ControlKeyState = controlKeys
                                           };

                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho)
                            {
                                _terminal.TerminalPane.ConnectionTag.Receiver.DataArrived(
                                    new byte[]
                                        {
                                            currentByte
                                        }, 0, 1);
                            }

                            readKey = true;
                            break;
                        }
                    }
                }

                // If we didn't read a key, sleep for a bit
                if (!readKey)
                    Thread.Sleep(50);
            }

            // Signal to ReadKey() that we've read a key
            _inputSemaphore.Set();
        }