@@ -79,6 +79,10 @@ public final class TerminalEmulator {
79
79
private static final int ESC_CSI_SINGLE_QUOTE = 18 ;
80
80
/** Escape processing: CSI ! */
81
81
private static final int ESC_CSI_EXCLAMATION = 19 ;
82
+ /** Escape processing: "ESC _" or Application Program Command (APC). */
83
+ private static final int ESC_APC = 20 ;
84
+ /** Escape processing: "ESC _" or Application Program Command (APC), followed by Escape. */
85
+ private static final int ESC_APC_ESCAPE = 21 ;
82
86
83
87
/** The number of parameter arguments. This name comes from the ANSI standard for terminal escape codes. */
84
88
private static final int MAX_ESCAPE_PARAMETERS = 16 ;
@@ -545,6 +549,15 @@ private void processByte(byte byteToProcess) {
545
549
}
546
550
547
551
public void processCodePoint (int b ) {
552
+ // The Application Program-Control (APC) string might be arbitrary non-printable characters, so handle that early.
553
+ if (mEscapeState == ESC_APC ) {
554
+ doApc (b );
555
+ return ;
556
+ } else if (mEscapeState == ESC_APC_ESCAPE ) {
557
+ doApcEscape (b );
558
+ return ;
559
+ }
560
+
548
561
switch (b ) {
549
562
case 0 : // Null character (NUL, ^@). Do nothing.
550
563
break ;
@@ -1001,6 +1014,30 @@ private void doDeviceControl(int b) {
1001
1014
}
1002
1015
}
1003
1016
1017
+ /**
1018
+ * When in {@link #ESC_APC} (APC, Application Program Command) sequence.
1019
+ */
1020
+ private void doApc (int b ) {
1021
+ if (b == 27 ) {
1022
+ continueSequence (ESC_APC_ESCAPE );
1023
+ }
1024
+ // Eat APC sequences silently for now.
1025
+ }
1026
+
1027
+ /**
1028
+ * When in {@link #ESC_APC} (APC, Application Program Command) sequence.
1029
+ */
1030
+ private void doApcEscape (int b ) {
1031
+ if (b == '\\' ) {
1032
+ // A String Terminator (ST), ending the APC escape sequence.
1033
+ finishSequence ();
1034
+ } else {
1035
+ // The Escape character was not the start of a String Terminator (ST),
1036
+ // but instead just data inside of the APC escape sequence.
1037
+ continueSequence (ESC_APC );
1038
+ }
1039
+ }
1040
+
1004
1041
private int nextTabStop (int numTabs ) {
1005
1042
for (int i = mCursorCol + 1 ; i < mColumns ; i ++)
1006
1043
if (mTabStop [i ] && --numTabs == 0 ) return Math .min (i , mRightMargin );
@@ -1396,6 +1433,9 @@ private void doEsc(int b) {
1396
1433
case '>' : // DECKPNM
1397
1434
setDecsetinternalBit (DECSET_BIT_APPLICATION_KEYPAD , false );
1398
1435
break ;
1436
+ case '_' : // APC - Application Program Command.
1437
+ continueSequence (ESC_APC );
1438
+ break ;
1399
1439
default :
1400
1440
unknownSequence (b );
1401
1441
break ;
0 commit comments