@@ -79,6 +79,10 @@ public final class TerminalEmulator {
7979 private static final int ESC_CSI_SINGLE_QUOTE = 18 ;
8080 /** Escape processing: CSI ! */
8181 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 ;
8286
8387 /** The number of parameter arguments. This name comes from the ANSI standard for terminal escape codes. */
8488 private static final int MAX_ESCAPE_PARAMETERS = 16 ;
@@ -545,6 +549,15 @@ private void processByte(byte byteToProcess) {
545549 }
546550
547551 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+
548561 switch (b ) {
549562 case 0 : // Null character (NUL, ^@). Do nothing.
550563 break ;
@@ -1001,6 +1014,30 @@ private void doDeviceControl(int b) {
10011014 }
10021015 }
10031016
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+
10041041 private int nextTabStop (int numTabs ) {
10051042 for (int i = mCursorCol + 1 ; i < mColumns ; i ++)
10061043 if (mTabStop [i ] && --numTabs == 0 ) return Math .min (i , mRightMargin );
@@ -1396,6 +1433,9 @@ private void doEsc(int b) {
13961433 case '>' : // DECKPNM
13971434 setDecsetinternalBit (DECSET_BIT_APPLICATION_KEYPAD , false );
13981435 break ;
1436+ case '_' : // APC - Application Program Command.
1437+ continueSequence (ESC_APC );
1438+ break ;
13991439 default :
14001440 unknownSequence (b );
14011441 break ;
0 commit comments