mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-15 18:02:58 +08:00
feat: Device Status Report (DSR)
This commit is contained in:
@@ -3,6 +3,7 @@ package app.termora
|
||||
import app.termora.terminal.PtyConnector
|
||||
import app.termora.terminal.Terminal
|
||||
import kotlinx.coroutines.delay
|
||||
import org.slf4j.LoggerFactory
|
||||
import javax.swing.SwingUtilities
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@@ -11,9 +12,14 @@ class PtyConnectorReader(
|
||||
private val terminal: Terminal,
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(PtyConnectorReader::class.java)
|
||||
}
|
||||
|
||||
suspend fun start() {
|
||||
var i: Int
|
||||
val buffer = CharArray(1024 * 8)
|
||||
|
||||
while ((ptyConnector.read(buffer).also { i = it }) != -1) {
|
||||
if (i == 0) {
|
||||
delay(10.milliseconds)
|
||||
@@ -22,6 +28,10 @@ class PtyConnectorReader(
|
||||
val text = String(buffer, 0, i)
|
||||
SwingUtilities.invokeLater { terminal.write(text) }
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled) {
|
||||
log.debug("PtyConnectorReader stopped")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,6 +27,10 @@ abstract class PtyHostTerminalTab(
|
||||
TerminalPanelFactory.getInstance(windowScope).createTerminalPanel(terminal, ptyConnectorDelegate)
|
||||
protected val ptyConnectorFactory get() = PtyConnectorFactory.getInstance(windowScope)
|
||||
|
||||
init {
|
||||
terminal.getTerminalModel().setData(DataKey.PtyConnector, ptyConnectorDelegate)
|
||||
}
|
||||
|
||||
override fun start() {
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package app.termora.terminal
|
||||
|
||||
import app.termora.assertEventDispatchThread
|
||||
import org.slf4j.LoggerFactory
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
@@ -13,7 +14,6 @@ class ControlSequenceIntroducerProcessor(terminal: Terminal, reader: TerminalRea
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(ControlSequenceIntroducerProcessor::class.java)
|
||||
private val styles = hashMapOf<TextStyle, TextStyle>()
|
||||
}
|
||||
|
||||
// 非法字符,需要重排序
|
||||
@@ -175,8 +175,9 @@ class ControlSequenceIntroducerProcessor(terminal: Terminal, reader: TerminalRea
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Device Status Report (DSR).
|
||||
// Device Status Report (DSR).
|
||||
'n' -> {
|
||||
processDeviceStatusReport()
|
||||
}
|
||||
|
||||
// ECSI Ps J Erase in Display (ED), VT100.
|
||||
@@ -464,6 +465,33 @@ class ControlSequenceIntroducerProcessor(terminal: Terminal, reader: TerminalRea
|
||||
return false
|
||||
}
|
||||
|
||||
private fun processDeviceStatusReport() {
|
||||
|
||||
assertEventDispatchThread()
|
||||
|
||||
if (args.startsWithQuestionMark()) {
|
||||
if (log.isWarnEnabled) {
|
||||
log.warn("Don't support DEC-specific Device Report Status")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (!terminalModel.hasData(DataKey.PtyConnector)) {
|
||||
return
|
||||
}
|
||||
|
||||
val ptyConnector = terminalModel.getData(DataKey.PtyConnector)
|
||||
|
||||
val m = args.first()
|
||||
if (m == '6') {
|
||||
val position = terminal.getCursorModel().getPosition()
|
||||
ptyConnector.write("${ControlCharacters.ESC}[${position.y};${position.x}R")
|
||||
} else if (m == '5') {
|
||||
ptyConnector.write("${ControlCharacters.ESC}[0n")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-?-Pm-h.1D0E
|
||||
*/
|
||||
@@ -580,7 +608,7 @@ class ControlSequenceIntroducerProcessor(terminal: Terminal, reader: TerminalRea
|
||||
25 -> {
|
||||
terminalModel.setData(DataKey.ShowCursor, enable)
|
||||
if (log.isDebugEnabled) {
|
||||
log.debug("Blinking cursor $enable")
|
||||
log.debug("Hide cursor (DECTCEM) $enable")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -929,7 +957,7 @@ class ControlSequenceIntroducerProcessor(terminal: Terminal, reader: TerminalRea
|
||||
|
||||
else -> {
|
||||
if (log.isWarnEnabled) {
|
||||
log.warn("Unknown SGR: $args")
|
||||
log.warn("Unknown SGR: $mode")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +180,11 @@ class DataKey<T : Any>(val clazz: KClass<T>) {
|
||||
* CSI Ps SP q Set cursor style (DECSCUSR), VT520.
|
||||
*/
|
||||
val CursorStyle = DataKey(app.termora.terminal.CursorStyle::class)
|
||||
|
||||
/**
|
||||
* Pty Connector
|
||||
*/
|
||||
val PtyConnector = DataKey(app.termora.terminal.PtyConnector::class)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package app.termora.terminal
|
||||
|
||||
import com.pty4j.PtyProcess
|
||||
import com.pty4j.WinSize
|
||||
import org.apache.commons.io.IOUtils
|
||||
import java.io.InputStreamReader
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets
|
||||
@@ -33,6 +34,7 @@ class PtyProcessConnector(private val process: PtyProcess, private val charset:
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
IOUtils.closeQuietly(reader)
|
||||
process.destroyForcibly()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user