protected override ProcessCharResult ProcessDECSET(string param, char code) { ProcessCharResult v = base.ProcessDECSET(param, code); if (v != ProcessCharResult.Unsupported) { return(v); } bool set = code == 'h'; switch (param) { case "1047": //Alternate Buffer if (set) { SwitchBuffer(true); // XTerm doesn't clear screen. } else { ClearScreen(); SwitchBuffer(false); } return(ProcessCharResult.Processed); case "1048": //Save/Restore Cursor if (set) { SaveCursor(); } else { RestoreCursor(); } return(ProcessCharResult.Processed); case "1049": //Save/Restore Cursor and Alternate Buffer if (set) { SaveCursor(); SwitchBuffer(true); ClearScreen(); } else { // XTerm doesn't clear screen for enabling copy/paste from the alternate buffer. // But we need ClearScreen for emulating the buffer-switch. ClearScreen(); SwitchBuffer(false); RestoreCursor(); } return(ProcessCharResult.Processed); case "1000": // DEC VT200 compatible: Send button press and release event with mouse position. ResetMouseTracking((set) ? MouseTrackingState.Normal : MouseTrackingState.Off); return(ProcessCharResult.Processed); case "1001": // DEC VT200 highlight tracking // Not supported ResetMouseTracking(MouseTrackingState.Off); return(ProcessCharResult.Processed); case "1002": // Button-event tracking: Send button press, release, and drag event. ResetMouseTracking((set) ? MouseTrackingState.Drag : MouseTrackingState.Off); return(ProcessCharResult.Processed); case "1003": // Any-event tracking: Send button press, release, and motion. ResetMouseTracking((set) ? MouseTrackingState.Any : MouseTrackingState.Off); return(ProcessCharResult.Processed); case "1004": // Send FocusIn/FocusOut events // Not supported ResetMouseTracking(MouseTrackingState.Off); return(ProcessCharResult.Processed); case "1005": // Enable UTF8 Mouse Mode if (set) { _mouseTrackingProtocol = MouseTrackingProtocol.Utf8; } else { _mouseTrackingProtocol = MouseTrackingProtocol.Normal; } return(ProcessCharResult.Processed); case "1006": // Enable SGR Extended Mouse Mode if (set) { _mouseTrackingProtocol = MouseTrackingProtocol.Sgr; } else { _mouseTrackingProtocol = MouseTrackingProtocol.Normal; } return(ProcessCharResult.Processed); case "1015": // Enable UTF8 Extended Mouse Mode if (set) { _mouseTrackingProtocol = MouseTrackingProtocol.Urxvt; } else { _mouseTrackingProtocol = MouseTrackingProtocol.Normal; } return(ProcessCharResult.Processed); case "1034": // Input 8 bits return(ProcessCharResult.Processed); case "3": //132 Column Mode return(ProcessCharResult.Processed); case "4": //Smooth Scroll なんのことやら return(ProcessCharResult.Processed); case "5": SetReverseVideo(set); return(ProcessCharResult.Processed); case "6": //Origin Mode _scrollRegionRelative = set; return(ProcessCharResult.Processed); case "7": _wrapAroundMode = set; return(ProcessCharResult.Processed); case "12": //一応報告あったので。SETMODEの12ならローカルエコーなんだがな return(ProcessCharResult.Processed); case "47": if (set) { SwitchBuffer(true); } else { SwitchBuffer(false); } return(ProcessCharResult.Processed); default: return(ProcessCharResult.Unsupported); } }
protected override ProcessCharResult ProcessDECSET(string param, char code) { ProcessCharResult v = base.ProcessDECSET(param, code); if (v != ProcessCharResult.Unsupported) return v; bool set = code == 'h'; switch (param) { case "1047": //Alternate Buffer if (set) { SwitchBuffer(true); // XTerm doesn't clear screen. } else { ClearScreen(); SwitchBuffer(false); } return ProcessCharResult.Processed; case "1048": //Save/Restore Cursor if (set) SaveCursor(); else RestoreCursor(); return ProcessCharResult.Processed; case "1049": //Save/Restore Cursor and Alternate Buffer if (set) { SaveCursor(); SwitchBuffer(true); ClearScreen(); } else { // XTerm doesn't clear screen for enabling copy/paste from the alternate buffer. // But we need ClearScreen for emulating the buffer-switch. ClearScreen(); SwitchBuffer(false); RestoreCursor(); } return ProcessCharResult.Processed; case "1000": // DEC VT200 compatible: Send button press and release event with mouse position. ResetMouseTracking((set) ? MouseTrackingState.Normal : MouseTrackingState.Off); return ProcessCharResult.Processed; case "1001": // DEC VT200 highlight tracking // Not supported ResetMouseTracking(MouseTrackingState.Off); return ProcessCharResult.Processed; case "1002": // Button-event tracking: Send button press, release, and drag event. ResetMouseTracking((set) ? MouseTrackingState.Drag : MouseTrackingState.Off); return ProcessCharResult.Processed; case "1003": // Any-event tracking: Send button press, release, and motion. ResetMouseTracking((set) ? MouseTrackingState.Any : MouseTrackingState.Off); return ProcessCharResult.Processed; case "1004": // Send FocusIn/FocusOut events _focusReportingMode = set; return ProcessCharResult.Processed; case "1005": // Enable UTF8 Mouse Mode if (set) { _mouseTrackingProtocol = MouseTrackingProtocol.Utf8; } else { _mouseTrackingProtocol = MouseTrackingProtocol.Normal; } return ProcessCharResult.Processed; case "1006": // Enable SGR Extended Mouse Mode if (set) { _mouseTrackingProtocol = MouseTrackingProtocol.Sgr; } else { _mouseTrackingProtocol = MouseTrackingProtocol.Normal; } return ProcessCharResult.Processed; case "1015": // Enable UTF8 Extended Mouse Mode if (set) { _mouseTrackingProtocol = MouseTrackingProtocol.Urxvt; } else { _mouseTrackingProtocol = MouseTrackingProtocol.Normal; } return ProcessCharResult.Processed; case "1034": // Input 8 bits return ProcessCharResult.Processed; case "3": //132 Column Mode return ProcessCharResult.Processed; case "4": //Smooth Scroll なんのことやら return ProcessCharResult.Processed; case "5": SetReverseVideo(set); return ProcessCharResult.Processed; case "6": //Origin Mode _scrollRegionRelative = set; return ProcessCharResult.Processed; case "7": _wrapAroundMode = set; return ProcessCharResult.Processed; case "12": //一応報告あったので。SETMODEの12ならローカルエコーなんだがな return ProcessCharResult.Processed; case "47": if (set) SwitchBuffer(true); else SwitchBuffer(false); return ProcessCharResult.Processed; default: return ProcessCharResult.Unsupported; } }
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); }