Example #1
0
 /// <summary>
 /// Hande mouse action.
 /// </summary>
 /// <param name="action">Action type</param>
 /// <param name="button">Which mouse button caused the event</param>
 /// <param name="modifierKeys">Modifier keys (Shift, Ctrl or Alt) being pressed</param>
 /// <param name="row">Row index (zero based)</param>
 /// <param name="col">Column index (zero based)</param>
 /// <returns>True if mouse action was processed.</returns>
 public virtual bool ProcessMouse(TerminalMouseAction action, MouseButtons button, Keys modifierKeys, int row, int col)
 {
     return(false);
 }
Example #2
0
        public override bool ProcessMouse(TerminalMouseAction action, MouseButtons button, Keys modKeys, int row, int col)
        {
            MouseTrackingState currentState = _mouseTrackingState;  // copy value because _mouseTrackingState may be changed in another thread.

            if (currentState == MouseTrackingState.Off)
            {
                return(false);
            }

            // Note: from here, return value must be true even if nothing has been processed actually.

            MouseTrackingProtocol protocol = _mouseTrackingProtocol; // copy value because _mouseTrackingProtocol may be changed in another thread.

            int posLimit = protocol == MouseTrackingProtocol.Normal ? MOUSE_POS_LIMIT : MOUSE_POS_EXT_LIMIT;

            if (row < 0)
            {
                row = 0;
            }
            else if (row > posLimit)
            {
                row = posLimit;
            }

            if (col < 0)
            {
                col = 0;
            }
            else if (col > posLimit)
            {
                col = posLimit;
            }

            int statBits;

            switch (action)
            {
            case TerminalMouseAction.ButtonDown:
                if (_mouseButton != MouseButtons.None)
                {
                    return(true);       // another button is already pressed
                }
                switch (button)
                {
                case MouseButtons.Left:
                    statBits = 0x00;
                    break;

                case MouseButtons.Middle:
                    statBits = 0x01;
                    break;

                case MouseButtons.Right:
                    statBits = 0x02;
                    break;

                default:
                    return(true);           // unsupported button
                }

                _mouseButton = button;
                break;

            case TerminalMouseAction.ButtonUp:
                if (button != _mouseButton)
                {
                    return(true);       // ignore
                }
                if (protocol == MouseTrackingProtocol.Sgr)
                {
                    switch (button)
                    {
                    case MouseButtons.Left:
                        statBits = 0x00;
                        break;

                    case MouseButtons.Middle:
                        statBits = 0x01;
                        break;

                    case MouseButtons.Right:
                        statBits = 0x02;
                        break;

                    default:
                        return(true);           // unsupported button
                    }
                }
                else
                {
                    statBits = 0x03;
                }

                _mouseButton = MouseButtons.None;
                break;

            case TerminalMouseAction.WheelUp:
                statBits = 0x40;
                break;

            case TerminalMouseAction.WheelDown:
                statBits = 0x41;
                break;

            case TerminalMouseAction.MouseMove:
                if (currentState != MouseTrackingState.Any && currentState != MouseTrackingState.Drag)
                {
                    return(true);       // no need to send
                }
                if (currentState == MouseTrackingState.Drag && _mouseButton == MouseButtons.None)
                {
                    return(true);       // no need to send
                }
                if (row == _prevMouseRow && col == _prevMouseCol)
                {
                    return(true);       // no need to send
                }
                switch (_mouseButton)
                {
                case MouseButtons.Left:
                    statBits = 0x20;
                    break;

                case MouseButtons.Middle:
                    statBits = 0x21;
                    break;

                case MouseButtons.Right:
                    statBits = 0x22;
                    break;

                default:
                    statBits = 0x20;
                    break;
                }
                break;

            default:
                return(true);       // unknown action
            }

            if ((modKeys & Keys.Shift) != Keys.None)
            {
                statBits |= 0x04;
            }

            if ((modKeys & Keys.Alt) != Keys.None)
            {
                statBits |= 0x08;   // Meta key
            }
            if ((modKeys & Keys.Control) != Keys.None)
            {
                statBits |= 0x10;
            }

            if (protocol != MouseTrackingProtocol.Sgr)
            {
                statBits += 0x20;
            }

            _prevMouseRow = row;
            _prevMouseCol = col;

            byte[] data;
            int    dataLen;

            switch (protocol)
            {
            case MouseTrackingProtocol.Normal:
                data = new byte[] {
                    (byte)27,     // ESCAPE
                    (byte)91,     // [
                    (byte)77,     // M
                    (byte)statBits,
                    (col == posLimit) ?
                    (byte)0 :                           // emulate xterm's bug
                    (byte)(col + (1 + 0x20)),           // column 0 --> send as 1
                    (row == posLimit) ?
                    (byte)0 :                           // emulate xterm's bug
                    (byte)(row + (1 + 0x20)),           // row 0 --> send as 1
                };
                dataLen = 6;
                break;

            case MouseTrackingProtocol.Utf8:
                data = new byte[8] {
                    (byte)27,     // ESCAPE
                    (byte)91,     // [
                    (byte)77,     // M
                    (byte)statBits,
                    0, 0, 0, 0,
                };

                dataLen = 4;

                if (col < MOUSE_POS_EXT_START)
                {
                    data[dataLen++] = (byte)(col + (1 + 0x20)); // column 0 --> send as 1
                }
                else                                            // encode in UTF-8
                {
                    int val = col + 1 + 0x20;
                    data[dataLen++] = (byte)(0xc0 + (val >> 6));
                    data[dataLen++] = (byte)(0x80 + (val & 0x3f));
                }

                if (row < MOUSE_POS_EXT_START)
                {
                    data[dataLen++] = (byte)(row + (1 + 0x20)); // row 0 --> send as 1
                }
                else                                            // encode in UTF-8
                {
                    int val = row + (1 + 0x20);
                    data[dataLen++] = (byte)(0xc0 + (val >> 6));
                    data[dataLen++] = (byte)(0x80 + (val & 0x3f));
                }
                break;

            case MouseTrackingProtocol.Urxvt:
                data = Encoding.ASCII.GetBytes(
                    new StringBuilder()
                    .Append("\x1b[")
                    .Append(statBits.ToString(NumberFormatInfo.InvariantInfo))
                    .Append(';')
                    .Append(col.ToString(NumberFormatInfo.InvariantInfo))
                    .Append(';')
                    .Append(row.ToString(NumberFormatInfo.InvariantInfo))
                    .Append("M")
                    .ToString());
                dataLen = data.Length;
                break;

            case MouseTrackingProtocol.Sgr:
                data = Encoding.ASCII.GetBytes(
                    new StringBuilder()
                    .Append("\x1b[<")
                    .Append(statBits.ToString(NumberFormatInfo.InvariantInfo))
                    .Append(';')
                    .Append(col.ToString(NumberFormatInfo.InvariantInfo))
                    .Append(';')
                    .Append(row.ToString(NumberFormatInfo.InvariantInfo))
                    .Append(action == TerminalMouseAction.ButtonUp ? 'm' : 'M')
                    .ToString());
                dataLen = data.Length;
                break;

            default:
                return(true);       // unknown protocol
            }

            TransmitDirect(data, 0, dataLen);

            return(true);
        }
Example #3
0
        public override bool ProcessMouse(TerminalMouseAction action, MouseButtons button, Keys modKeys, int row, int col)
        {
            MouseTrackingState currentState = _mouseTrackingState;  // copy value because _mouseTrackingState may be changed in another thread.
            if (currentState == MouseTrackingState.Off)
                return false;

            // Note: from here, return value must be true even if nothing has been processed actually.

            MouseTrackingProtocol protocol = _mouseTrackingProtocol; // copy value because _mouseTrackingProtocol may be changed in another thread.

            int posLimit = protocol == MouseTrackingProtocol.Normal ? MOUSE_POS_LIMIT : MOUSE_POS_EXT_LIMIT;

            if (row < 0)
                row = 0;
            else if (row > posLimit)
                row = posLimit;

            if (col < 0)
                col = 0;
            else if (col > posLimit)
                col = posLimit;

            int statBits;
            switch (action) {
                case TerminalMouseAction.ButtonDown:
                    if (_mouseButton != MouseButtons.None)
                        return true;    // another button is already pressed

                    switch (button) {
                        case MouseButtons.Left:
                            statBits = 0x00;
                            break;
                        case MouseButtons.Middle:
                            statBits = 0x01;
                            break;
                        case MouseButtons.Right:
                            statBits = 0x02;
                            break;
                        default:
                            return true;    // unsupported button
                    }

                    _mouseButton = button;
                    break;

                case TerminalMouseAction.ButtonUp:
                    if (button != _mouseButton)
                        return true;    // ignore

                    if (protocol == MouseTrackingProtocol.Sgr) {
                        switch (button) {
                            case MouseButtons.Left:
                                statBits = 0x00;
                                break;
                            case MouseButtons.Middle:
                                statBits = 0x01;
                                break;
                            case MouseButtons.Right:
                                statBits = 0x02;
                                break;
                            default:
                                return true;    // unsupported button
                        }
                    }
                    else {
                        statBits = 0x03;
                    }

                    _mouseButton = MouseButtons.None;
                    break;

                case TerminalMouseAction.WheelUp:
                    statBits = 0x40;
                    break;

                case TerminalMouseAction.WheelDown:
                    statBits = 0x41;
                    break;

                case TerminalMouseAction.MouseMove:
                    if (currentState != MouseTrackingState.Any && currentState != MouseTrackingState.Drag)
                        return true;    // no need to send

                    if (currentState == MouseTrackingState.Drag && _mouseButton == MouseButtons.None)
                        return true;    // no need to send

                    if (row == _prevMouseRow && col == _prevMouseCol)
                        return true;    // no need to send

                    switch (_mouseButton) {
                        case MouseButtons.Left:
                            statBits = 0x20;
                            break;
                        case MouseButtons.Middle:
                            statBits = 0x21;
                            break;
                        case MouseButtons.Right:
                            statBits = 0x22;
                            break;
                        default:
                            statBits = 0x20;
                            break;
                    }
                    break;

                default:
                    return true;    // unknown action
            }

            if ((modKeys & Keys.Shift) != Keys.None)
                statBits |= 0x04;

            if ((modKeys & Keys.Alt) != Keys.None)
                statBits |= 0x08;   // Meta key

            if ((modKeys & Keys.Control) != Keys.None)
                statBits |= 0x10;

            if (protocol != MouseTrackingProtocol.Sgr)
                statBits += 0x20;

            _prevMouseRow = row;
            _prevMouseCol = col;

            byte[] data;
            int dataLen;

            switch (protocol) {

                case MouseTrackingProtocol.Normal:
                    data = new byte[] {
                        (byte)27, // ESCAPE
                        (byte)91, // [
                        (byte)77, // M
                        (byte)statBits,
                        (col == posLimit) ?
                            (byte)0 :                   // emulate xterm's bug
                            (byte)(col + (1 + 0x20)),   // column 0 --> send as 1
                        (row == posLimit) ?
                            (byte)0 :                   // emulate xterm's bug
                            (byte)(row + (1 + 0x20)),   // row 0 --> send as 1
                    };
                    dataLen = 6;
                    break;

                case MouseTrackingProtocol.Utf8:
                    data = new byte[8] {
                        (byte)27, // ESCAPE
                        (byte)91, // [
                        (byte)77, // M
                        (byte)statBits,
                        0,0,0,0,
                    };

                    dataLen = 4;

                    if (col < MOUSE_POS_EXT_START)
                        data[dataLen++] = (byte)(col + (1 + 0x20));     // column 0 --> send as 1
                    else { // encode in UTF-8
                        int val = col + 1 + 0x20;
                        data[dataLen++] = (byte)(0xc0 + (val >> 6));
                        data[dataLen++] = (byte)(0x80 + (val & 0x3f));
                    }

                    if (row < MOUSE_POS_EXT_START)
                        data[dataLen++] = (byte)(row + (1 + 0x20));     // row 0 --> send as 1
                    else { // encode in UTF-8
                        int val = row + (1 + 0x20);
                        data[dataLen++] = (byte)(0xc0 + (val >> 6));
                        data[dataLen++] = (byte)(0x80 + (val & 0x3f));
                    }
                    break;

                case MouseTrackingProtocol.Urxvt:
                    data = Encoding.ASCII.GetBytes(
                        new StringBuilder()
                            .Append("\x1b[")
                            .Append(statBits.ToString(NumberFormatInfo.InvariantInfo))
                            .Append(';')
                            .Append((col+1).ToString(NumberFormatInfo.InvariantInfo))
                            .Append(';')
                            .Append((row+1).ToString(NumberFormatInfo.InvariantInfo))
                            .Append("M")
                            .ToString());
                    dataLen = data.Length;
                    break;

                case MouseTrackingProtocol.Sgr:
                    data = Encoding.ASCII.GetBytes(
                        new StringBuilder()
                            .Append("\x1b[<")
                            .Append(statBits.ToString(NumberFormatInfo.InvariantInfo))
                            .Append(';')
                            .Append((col+1).ToString(NumberFormatInfo.InvariantInfo))
                            .Append(';')
                            .Append((row+1).ToString(NumberFormatInfo.InvariantInfo))
                            .Append(action == TerminalMouseAction.ButtonUp ? 'm' : 'M')
                            .ToString());
                    dataLen = data.Length;
                    break;

                default:
                    return true;    // unknown protocol
            }

            TransmitDirect(data, 0, dataLen);

            return true;
        }
Example #4
0
 /// <summary>
 /// Hande mouse action.
 /// </summary>
 /// <param name="action">Action type</param>
 /// <param name="button">Which mouse button caused the event</param>
 /// <param name="modifierKeys">Modifier keys (Shift, Ctrl or Alt) being pressed</param>
 /// <param name="row">Row index (zero based)</param>
 /// <param name="col">Column index (zero based)</param>
 /// <returns>True if mouse action was processed.</returns>
 public virtual bool ProcessMouse(TerminalMouseAction action, MouseButtons button, Keys modifierKeys, int row, int col)
 {
     return false;
 }