@@ -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 ;
@@ -548,6 +552,15 @@ private void processByte(byte byteToProcess) {
548
552
}
549
553
550
554
public void processCodePoint (int b ) {
555
+ // The Application Program-Control (APC) string might be arbitrary non-printable characters, so handle that early.
556
+ if (mEscapeState == ESC_APC ) {
557
+ doApc (b );
558
+ return ;
559
+ } else if (mEscapeState == ESC_APC_ESCAPE ) {
560
+ doApcEscape (b );
561
+ return ;
562
+ }
563
+
551
564
switch (b ) {
552
565
case 0 : // Null character (NUL, ^@). Do nothing.
553
566
break ;
@@ -1004,6 +1017,30 @@ private void doDeviceControl(int b) {
1004
1017
}
1005
1018
}
1006
1019
1020
+ /**
1021
+ * When in {@link #ESC_APC} (APC, Application Program Command) sequence.
1022
+ */
1023
+ private void doApc (int b ) {
1024
+ if (b == 27 ) {
1025
+ continueSequence (ESC_APC_ESCAPE );
1026
+ }
1027
+ // Eat APC sequences silently for now.
1028
+ }
1029
+
1030
+ /**
1031
+ * When in {@link #ESC_APC} (APC, Application Program Command) sequence.
1032
+ */
1033
+ private void doApcEscape (int b ) {
1034
+ if (b == '\\' ) {
1035
+ // A String Terminator (ST), ending the APC escape sequence.
1036
+ finishSequence ();
1037
+ } else {
1038
+ // The Escape character was not the start of a String Terminator (ST),
1039
+ // but instead just data inside of the APC escape sequence.
1040
+ continueSequence (ESC_APC );
1041
+ }
1042
+ }
1043
+
1007
1044
private int nextTabStop (int numTabs ) {
1008
1045
for (int i = mCursorCol + 1 ; i < mColumns ; i ++)
1009
1046
if (mTabStop [i ] && --numTabs == 0 ) return Math .min (i , mRightMargin );
@@ -1399,6 +1436,9 @@ private void doEsc(int b) {
1399
1436
case '>' : // DECKPNM
1400
1437
setDecsetinternalBit (DECSET_BIT_APPLICATION_KEYPAD , false );
1401
1438
break ;
1439
+ case '_' : // APC - Application Program Command.
1440
+ continueSequence (ESC_APC );
1441
+ break ;
1402
1442
default :
1403
1443
unknownSequence (b );
1404
1444
break ;
0 commit comments