diff --git a/src/Vt102Emulation.cpp b/src/Vt102Emulation.cpp --- a/src/Vt102Emulation.cpp +++ b/src/Vt102Emulation.cpp @@ -341,9 +341,8 @@ #define egt( ) (p >= 3 && s[2] == '>') #define esp( ) (p >= 4 && s[2] == SP ) #define epsp( ) (p >= 5 && s[3] == SP ) -#define Xpe (tokenBufferPos >= 2 && tokenBuffer[1] == ']') -#define Xte (Xpe && (cc == 7 || cc == 27)) -#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte) +#define osc (tokenBufferPos >= 2 && tokenBuffer[1] == ']') +#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C)) #define dcs (p >= 2 && s[0] == ESC && s[1] == 'P') #define CNTL(c) ((c)-'@') @@ -360,23 +359,26 @@ if (ces(CTL)) { - // ignore control characters in the text part of Xpe (aka OSC) "ESC]" + // ignore control characters in the text part of osc (aka OSC) "ESC]" // escape sequences; this matches what XTERM docs say - if (Xpe) { + // Allow BEL and ESC here, it will either end the text or be removed later. + if (osc && cc != 0x1b && cc != 0x07) { return; } - // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100 - // This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do - // of course. Guess this originates from a weakly layered handling of the X-on - // X-off protocol, which comes really below this level. - if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) { - resetTokenizer(); //VT100: CAN or SUB - } - if (cc != ESC) - { - processToken(token_ctl(cc+'@'), 0, 0); - return; + if (!osc) { + // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100 + // This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do + // of course. Guess this originates from a weakly layered handling of the X-on + // X-off protocol, which comes really below this level. + if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) { + resetTokenizer(); //VT100: CAN or SUB + } + if (cc != ESC) + { + processToken(token_ctl(cc+'@'), 0, 0); + return; + } } } // advance the state @@ -390,8 +392,14 @@ if (lec(1,0,ESC)) { return; } if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('['); return; } if (les(2,1,GRP)) { return; } - if (Xte ) { processSessionAttributeRequest(); resetTokenizer(); return; } - if (Xpe ) { return; } + // ']' n ';' ... + if (osc && cc == 0x07) { processSessionAttributeRequest(); resetTokenizer(); return; } + // ']' n ';' ... + if (osc && p > 2 && s[p-2] == ESC && s[p-1]!='\\') { --tokenBufferPos; processSessionAttributeRequest(); resetTokenizer(); receiveChar(cc); return; } + // ']' n ';' ... '\' + if (osc && p > 2 && s[p-2] == ESC && s[p-1] == '\\') { --tokenBufferPos; processSessionAttributeRequest(); resetTokenizer(); return; } + // ']' n ';' ... + if (osc ) { return; } if (lec(3,2,'?')) { return; } if (lec(3,2,'>')) { return; } if (lec(3,2,'!')) { return; } @@ -477,6 +485,7 @@ // See Session::SessionAttributes for possible values int attribute = 0; int i; + // skip first two characters (ESC, ']') for (i = 2; i < tokenBufferPos && tokenBuffer[i] >= '0' && tokenBuffer[i] <= '9'; i++) @@ -489,11 +498,14 @@ reportDecodingError(); return; } + // skip ';' + ++i; QString value; - value.reserve(tokenBufferPos-i-2); - for (int j = 0; j < tokenBufferPos-i-2; j++) { - value[j] = tokenBuffer[i+1+j]; + // ignore last character (ESC or BEL) + value.reserve(tokenBufferPos-i-1); + for (int j = 0; j < tokenBufferPos-i-1; j++) { + value[j] = tokenBuffer[i+j]; } if (value == QLatin1String("?")) {