File indexing completed on 2025-03-16 08:11:31
0001 /* 0002 This file is part of Konsole, an X terminal. 0003 0004 SPDX-FileCopyrightText: 2007-2008 Robert Knight <robert.knight@gmail.com> 0005 SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 GNU General Public License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program; if not, write to the Free Software 0016 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301 USA. 0018 */ 0019 0020 // Own 0021 #include "Vt102Emulation.h" 0022 #include "tools.h" 0023 0024 // XKB 0025 // #include <config-konsole.h> 0026 0027 // this allows konsole to be compiled without XKB and XTEST extensions 0028 // even though it might be available on a particular system. 0029 #if defined(AVOID_XKB) 0030 #undef HAVE_XKB 0031 #endif 0032 0033 #if defined(HAVE_XKB) 0034 void scrolllock_set_off(); 0035 void scrolllock_set_on(); 0036 #endif 0037 0038 // Standard 0039 #include <cstdio> 0040 #include <unistd.h> 0041 0042 // Qt 0043 #include <QDebug> 0044 #include <QEvent> 0045 #include <QKeyEvent> 0046 0047 // KDE 0048 // #include <kdebug.h> 0049 // #include <klocale.h> 0050 0051 // Konsole 0052 #include "KeyboardTranslator.h" 0053 #include "Screen.h" 0054 0055 using namespace Konsole; 0056 0057 Vt102Emulation::Vt102Emulation() 0058 : Emulation() 0059 , prevCC(0) 0060 , _titleUpdateTimer(new QTimer(this)) 0061 , _reportFocusEvents(false) 0062 { 0063 _titleUpdateTimer->setSingleShot(true); 0064 QObject::connect(_titleUpdateTimer, &QTimer::timeout, this, &Vt102Emulation::updateTitle); 0065 0066 initTokenizer(); 0067 reset(); 0068 } 0069 0070 Vt102Emulation::~Vt102Emulation() 0071 { 0072 } 0073 0074 void Vt102Emulation::clearEntireScreen() 0075 { 0076 _currentScreen->clearEntireScreen(); 0077 bufferedUpdate(); 0078 } 0079 0080 void Vt102Emulation::reset() 0081 { 0082 resetTokenizer(); 0083 resetModes(); 0084 resetCharset(0); 0085 _primaryScreen->reset(); 0086 resetCharset(1); 0087 _alternateScreen->reset(); 0088 setCodec(LocaleCodec); 0089 0090 bufferedUpdate(); 0091 } 0092 0093 /* ------------------------------------------------------------------------- */ 0094 /* */ 0095 /* Processing the incoming byte stream */ 0096 /* */ 0097 /* ------------------------------------------------------------------------- */ 0098 0099 /* Incoming Bytes Event pipeline 0100 0101 This section deals with decoding the incoming character stream. 0102 Decoding means here, that the stream is first separated into `tokens' 0103 which are then mapped to a `meaning' provided as operations by the 0104 `Screen' class or by the emulation class itself. 0105 0106 The pipeline proceeds as follows: 0107 0108 - Tokenizing the ESC codes (onReceiveChar) 0109 - VT100 code page translation of plain characters (applyCharset) 0110 - Interpretation of ESC codes (processToken) 0111 0112 The escape codes and their meaning are described in the 0113 technical reference of this program. 0114 */ 0115 0116 // Tokens ------------------------------------------------------------------ -- 0117 0118 /* 0119 Since the tokens are the central notion if this section, we've put them 0120 in front. They provide the syntactical elements used to represent the 0121 terminals operations as byte sequences. 0122 0123 They are encodes here into a single machine word, so that we can later 0124 switch over them easily. Depending on the token itself, additional 0125 argument variables are filled with parameter values. 0126 0127 The tokens are defined below: 0128 0129 - CHR - Printable characters (32..255 but DEL (=127)) 0130 - CTL - Control characters (0..31 but ESC (= 27), DEL) 0131 - ESC - Escape codes of the form <ESC><CHR but `[]()+*#'> 0132 - ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C 0133 - CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C 0134 - CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C 0135 - CSI_PS_SP - Escape codes of the form <ESC>'[' {Pn} ';' ... {Space} C 0136 - CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C 0137 - CSI_PE - Escape codes of the form <ESC>'[' '!' {Pn} ';' ... C 0138 - VT52 - VT52 escape codes 0139 - <ESC><Chr> 0140 - <ESC>'Y'{Pc}{Pc} 0141 - XTE_HA - Xterm window/terminal attribute commands 0142 of the form <ESC>`]' {Pn} `;' {Text} <BEL> 0143 (Note that these are handled differently to the other formats) 0144 0145 The last two forms allow list of arguments. Since the elements of 0146 the lists are treated individually the same way, they are passed 0147 as individual tokens to the interpretation. Further, because the 0148 meaning of the parameters are names (althought represented as numbers), 0149 they are includes within the token ('N'). 0150 0151 */ 0152 0153 #define TY_CONSTRUCT(T, A, N) (((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff)) 0154 0155 #define TY_CHR() TY_CONSTRUCT(0, 0, 0) 0156 #define TY_CTL(A) TY_CONSTRUCT(1, A, 0) 0157 #define TY_ESC(A) TY_CONSTRUCT(2, A, 0) 0158 #define TY_ESC_CS(A, B) TY_CONSTRUCT(3, A, B) 0159 #define TY_ESC_DE(A) TY_CONSTRUCT(4, A, 0) 0160 #define TY_CSI_PS(A, N) TY_CONSTRUCT(5, A, N) 0161 #define TY_CSI_PN(A) TY_CONSTRUCT(6, A, 0) 0162 #define TY_CSI_PR(A, N) TY_CONSTRUCT(7, A, N) 0163 #define TY_CSI_PS_SP(A, N) TY_CONSTRUCT(11, A, N) 0164 0165 #define TY_VT52(A) TY_CONSTRUCT(8, A, 0) 0166 #define TY_CSI_PG(A) TY_CONSTRUCT(9, A, 0) 0167 #define TY_CSI_PE(A) TY_CONSTRUCT(10, A, 0) 0168 0169 #define MAX_ARGUMENT 4096 0170 0171 // Tokenizer --------------------------------------------------------------- -- 0172 0173 /* The tokenizer's state 0174 0175 The state is represented by the buffer (tokenBuffer, tokenBufferPos), 0176 and accompanied by decoded arguments kept in (argv,argc). 0177 Note that they are kept internal in the tokenizer. 0178 */ 0179 0180 void Vt102Emulation::resetTokenizer() 0181 { 0182 tokenBufferPos = 0; 0183 argc = 0; 0184 argv[0] = 0; 0185 argv[1] = 0; 0186 prevCC = 0; 0187 } 0188 0189 void Vt102Emulation::addDigit(int digit) 0190 { 0191 if (argv[argc] < MAX_ARGUMENT) 0192 argv[argc] = 10 * argv[argc] + digit; 0193 } 0194 0195 void Vt102Emulation::addArgument() 0196 { 0197 argc = qMin(argc + 1, MAXARGS - 1); 0198 argv[argc] = 0; 0199 } 0200 0201 void Vt102Emulation::addToCurrentToken(char16_t cc) 0202 { 0203 tokenBuffer[tokenBufferPos] = cc; 0204 tokenBufferPos = qMin(tokenBufferPos + 1, MAX_TOKEN_LENGTH - 1); 0205 } 0206 0207 // Character Class flags used while decoding 0208 #define CTL 1 // Control character 0209 #define CHR 2 // Printable character 0210 #define CPN 4 // TODO: Document me 0211 #define DIG 8 // Digit 0212 #define SCS 16 // TODO: Document me 0213 #define GRP 32 // TODO: Document me 0214 #define CPS \ 0215 64 // Character which indicates end of window resize 0216 // escape sequence '\e[8;<row>;<col>t' 0217 0218 void Vt102Emulation::initTokenizer() 0219 { 0220 int i; 0221 quint8 *s; 0222 for (i = 0; i < 256; ++i) 0223 charClass[i] = 0; 0224 for (i = 0; i < 32; ++i) 0225 charClass[i] |= CTL; 0226 for (i = 32; i < 256; ++i) 0227 charClass[i] |= CHR; 0228 for (s = (quint8 *)"@ABCDGHILMPSTXZbcdfry"; *s; ++s) 0229 charClass[*s] |= CPN; 0230 // resize = \e[8;<row>;<col>t 0231 for (s = (quint8 *)"t"; *s; ++s) 0232 charClass[*s] |= CPS; 0233 for (s = (quint8 *)"0123456789"; *s; ++s) 0234 charClass[*s] |= DIG; 0235 for (s = (quint8 *)"()+*%"; *s; ++s) 0236 charClass[*s] |= SCS; 0237 for (s = (quint8 *)"()+*#[]%"; *s; ++s) 0238 charClass[*s] |= GRP; 0239 0240 resetTokenizer(); 0241 } 0242 0243 /* Ok, here comes the nasty part of the decoder. 0244 0245 Instead of keeping an explicit state, we deduce it from the 0246 token scanned so far. It is then immediately combined with 0247 the current character to form a scanning decision. 0248 0249 This is done by the following defines. 0250 0251 - P is the length of the token scanned so far. 0252 - L (often P-1) is the position on which contents we base a decision. 0253 - C is a character or a group of characters (taken from 'charClass'). 0254 0255 - 'cc' is the current character 0256 - 's' is a pointer to the start of the token buffer 0257 - 'p' is the current position within the token buffer 0258 0259 Note that they need to applied in proper order. 0260 */ 0261 0262 #define lec(P, L, C) (p == (P) && s[(L)] == (C)) 0263 #define lun() (p == 1 && cc >= 32) 0264 #define les(P, L, C) (p == (P) && s[L] < 256 && (charClass[s[(L)]] & (C)) == (C)) 0265 #define eec(C) (p >= 3 && cc == (C)) 0266 #define ees(C) (p >= 3 && cc < 256 && (charClass[cc] & (C)) == (C)) 0267 #define eps(C) (p >= 3 && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (charClass[cc] & (C)) == (C)) 0268 #define epp() (p >= 3 && s[2] == '?') 0269 #define epe() (p >= 3 && s[2] == '!') 0270 #define egt() (p >= 3 && s[2] == '>') 0271 #define esp() (p == 4 && s[3] == ' ') 0272 #define Xpe (tokenBufferPos >= 2 && tokenBuffer[1] == ']') 0273 #define Xte (Xpe && (cc == 7 || (prevCC == 27 && cc == 92))) // 27, 92 => "\e\\" (ST, String Terminator) 0274 #define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte) 0275 0276 #define CNTL(c) ((c) - '@') 0277 #define ESC 27 0278 #define DEL 127 0279 0280 // process an incoming unicode character 0281 void Vt102Emulation::receiveChar(QChar character) 0282 { 0283 char16_t cc = character.unicode(); 0284 0285 if (cc == DEL) 0286 return; // VT100: ignore. 0287 0288 if (ces(CTL)) { 0289 // ignore control characters in the text part of Xpe (aka OSC) "ESC]" 0290 // escape sequences; this matches what XTERM docs say 0291 if (Xpe) { 0292 prevCC = cc; 0293 return; 0294 } 0295 0296 // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100 0297 // This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do 0298 // of course. Guess this originates from a weakly layered handling of the X-on 0299 // X-off protocol, which comes really below this level. 0300 if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) 0301 resetTokenizer(); // VT100: CAN or SUB 0302 if (cc != ESC) { 0303 processToken(TY_CTL(cc + '@'), 0, 0); 0304 return; 0305 } 0306 } 0307 // advance the state 0308 addToCurrentToken(cc); 0309 0310 char16_t *s = tokenBuffer; 0311 int p = tokenBufferPos; 0312 0313 if (getMode(MODE_Ansi)) { 0314 if (lec(1, 0, ESC)) { 0315 return; 0316 } 0317 if (lec(1, 0, ESC + 128)) { 0318 s[0] = ESC; 0319 receiveChar(u'['); 0320 return; 0321 } 0322 if (les(2, 1, GRP)) { 0323 return; 0324 } 0325 if (Xte) { 0326 processWindowAttributeChange(); 0327 resetTokenizer(); 0328 return; 0329 } 0330 if (Xpe) { 0331 prevCC = cc; 0332 return; 0333 } 0334 if (lec(3, 2, '?')) { 0335 return; 0336 } 0337 if (lec(3, 2, '>')) { 0338 return; 0339 } 0340 if (lec(3, 2, '!')) { 0341 return; 0342 } 0343 if (lun()) { 0344 processToken(TY_CHR(), applyCharset(cc), 0); 0345 resetTokenizer(); 0346 return; 0347 } 0348 if (lec(2, 0, ESC)) { 0349 processToken(TY_ESC(s[1]), 0, 0); 0350 resetTokenizer(); 0351 return; 0352 } 0353 if (les(3, 1, SCS)) { 0354 processToken(TY_ESC_CS(s[1], s[2]), 0, 0); 0355 resetTokenizer(); 0356 return; 0357 } 0358 if (lec(3, 1, '#')) { 0359 processToken(TY_ESC_DE(s[2]), 0, 0); 0360 resetTokenizer(); 0361 return; 0362 } 0363 if (eps(CPN)) { 0364 processToken(TY_CSI_PN(cc), argv[0], argv[1]); 0365 resetTokenizer(); 0366 return; 0367 } 0368 if (esp()) { 0369 return; 0370 } 0371 if (lec(5, 4, 'q') && s[3] == ' ') { 0372 processToken(TY_CSI_PS_SP(cc, argv[0]), argv[0], 0); 0373 resetTokenizer(); 0374 return; 0375 } 0376 0377 // resize = \e[8;<row>;<col>t 0378 if (eps(CPS)) { 0379 processToken(TY_CSI_PS(cc, argv[0]), argv[1], argv[2]); 0380 resetTokenizer(); 0381 return; 0382 } 0383 0384 if (epe()) { 0385 processToken(TY_CSI_PE(cc), 0, 0); 0386 resetTokenizer(); 0387 return; 0388 } 0389 if (ees(DIG)) { 0390 addDigit(cc - '0'); 0391 return; 0392 } 0393 if (eec(';') || eec(':')) { 0394 addArgument(); 0395 return; 0396 } 0397 for (int i = 0; i <= argc; i++) { 0398 if (epp()) 0399 processToken(TY_CSI_PR(cc, argv[i]), 0, 0); 0400 else if (egt()) 0401 processToken(TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c 0402 else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i + 1] == 2) { 0403 // ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m 0404 i += 2; 0405 processToken(TY_CSI_PS(cc, argv[i - 2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i + 1] << 8) | argv[i + 2]); 0406 i += 2; 0407 } else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i + 1] == 5) { 0408 // ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m 0409 i += 2; 0410 processToken(TY_CSI_PS(cc, argv[i - 2]), COLOR_SPACE_256, argv[i]); 0411 } else 0412 processToken(TY_CSI_PS(cc, argv[i]), 0, 0); 0413 } 0414 resetTokenizer(); 0415 } else { 0416 // VT52 Mode 0417 if (lec(1, 0, ESC)) 0418 return; 0419 if (les(1, 0, CHR)) { 0420 processToken(TY_CHR(), s[0], 0); 0421 resetTokenizer(); 0422 return; 0423 } 0424 if (lec(2, 1, 'Y')) 0425 return; 0426 0427 if (lec(3, 1, 'Y')) 0428 return; 0429 0430 if (p < 4) { 0431 processToken(TY_VT52(s[1]), 0, 0); 0432 resetTokenizer(); 0433 return; 0434 } 0435 processToken(TY_VT52(s[1]), s[2], s[3]); 0436 resetTokenizer(); 0437 return; 0438 } 0439 } 0440 void Vt102Emulation::processWindowAttributeChange() 0441 { 0442 // Describes the window or terminal session attribute to change 0443 // See Session::UserTitleChange for possible values 0444 int attributeToChange = 0; 0445 int i; 0446 for (i = 2; i < tokenBufferPos && tokenBuffer[i] >= '0' && tokenBuffer[i] <= '9'; i++) { 0447 attributeToChange = 10 * attributeToChange + (tokenBuffer[i] - '0'); 0448 } 0449 0450 if (tokenBuffer[i] != ';') { 0451 reportDecodingError(); 0452 return; 0453 } 0454 0455 // copy from the first char after ';', and skipping the ending delimiter 0456 // 0x07 or 0x92. Note that as control characters in OSC text parts are 0457 // ignored, only the second char in ST ("\e\\") is appended to tokenBuffer. 0458 QString newValue = QString::fromUtf16(tokenBuffer + i + 1, tokenBufferPos - i - 2); 0459 0460 _pendingTitleUpdates[attributeToChange] = newValue; 0461 _titleUpdateTimer->start(20); 0462 } 0463 0464 void Vt102Emulation::updateTitle() 0465 { 0466 QListIterator<int> iter(_pendingTitleUpdates.keys()); 0467 while (iter.hasNext()) { 0468 int arg = iter.next(); 0469 Q_EMIT titleChanged(arg, _pendingTitleUpdates[arg]); 0470 } 0471 _pendingTitleUpdates.clear(); 0472 } 0473 0474 // Interpreting Codes --------------------------------------------------------- 0475 0476 /* 0477 Now that the incoming character stream is properly tokenized, 0478 meaning is assigned to them. These are either operations of 0479 the current _screen, or of the emulation class itself. 0480 0481 The token to be interpreteted comes in as a machine word 0482 possibly accompanied by two parameters. 0483 0484 Likewise, the operations assigned to, come with up to two 0485 arguments. One could consider to make up a proper table 0486 from the function below. 0487 0488 The technical reference manual provides more information 0489 about this mapping. 0490 */ 0491 0492 void Vt102Emulation::processToken(int token, char16_t p, int q) 0493 { 0494 switch (token) { 0495 case TY_CHR(): 0496 _currentScreen->displayCharacter(p); 0497 break; // UTF16 0498 0499 // 127 DEL : ignored on input 0500 0501 case TY_CTL('@'): /* NUL: ignored */ 0502 break; 0503 case TY_CTL('A'): /* SOH: ignored */ 0504 break; 0505 case TY_CTL('B'): /* STX: ignored */ 0506 break; 0507 case TY_CTL('C'): /* ETX: ignored */ 0508 break; 0509 case TY_CTL('D'): /* EOT: ignored */ 0510 break; 0511 case TY_CTL('E'): 0512 reportAnswerBack(); 0513 break; // VT100 0514 case TY_CTL('F'): /* ACK: ignored */ 0515 break; 0516 case TY_CTL('G'): 0517 Q_EMIT stateSet(NOTIFYBELL); 0518 break; // VT100 0519 case TY_CTL('H'): 0520 _currentScreen->backspace(); 0521 break; // VT100 0522 case TY_CTL('I'): 0523 _currentScreen->tab(); 0524 break; // VT100 0525 case TY_CTL('J'): 0526 _currentScreen->newLine(); 0527 break; // VT100 0528 case TY_CTL('K'): 0529 _currentScreen->newLine(); 0530 break; // VT100 0531 case TY_CTL('L'): 0532 _currentScreen->newLine(); 0533 break; // VT100 0534 case TY_CTL('M'): 0535 _currentScreen->toStartOfLine(); 0536 break; // VT100 0537 0538 case TY_CTL('N'): 0539 useCharset(1); 0540 break; // VT100 0541 case TY_CTL('O'): 0542 useCharset(0); 0543 break; // VT100 0544 0545 case TY_CTL('P'): /* DLE: ignored */ 0546 break; 0547 case TY_CTL('Q'): /* DC1: XON continue */ 0548 break; // VT100 0549 case TY_CTL('R'): /* DC2: ignored */ 0550 break; 0551 case TY_CTL('S'): /* DC3: XOFF halt */ 0552 break; // VT100 0553 case TY_CTL('T'): /* DC4: ignored */ 0554 break; 0555 case TY_CTL('U'): /* NAK: ignored */ 0556 break; 0557 case TY_CTL('V'): /* SYN: ignored */ 0558 break; 0559 case TY_CTL('W'): /* ETB: ignored */ 0560 break; 0561 case TY_CTL('X'): 0562 _currentScreen->displayCharacter(QChar(0x2592)); 0563 break; // VT100 0564 case TY_CTL('Y'): /* EM : ignored */ 0565 break; 0566 case TY_CTL('Z'): 0567 _currentScreen->displayCharacter(QChar(0x2592)); 0568 break; // VT100 0569 case TY_CTL('['): /* ESC: cannot be seen here. */ 0570 break; 0571 case TY_CTL('\\'): /* FS : ignored */ 0572 break; 0573 case TY_CTL(']'): /* GS : ignored */ 0574 break; 0575 case TY_CTL('^'): /* RS : ignored */ 0576 break; 0577 case TY_CTL('_'): /* US : ignored */ 0578 break; 0579 0580 case TY_ESC('D'): 0581 _currentScreen->index(); 0582 break; // VT100 0583 case TY_ESC('E'): 0584 _currentScreen->nextLine(); 0585 break; // VT100 0586 case TY_ESC('H'): 0587 _currentScreen->changeTabStop(true); 0588 break; // VT100 0589 case TY_ESC('M'): 0590 _currentScreen->reverseIndex(); 0591 break; // VT100 0592 case TY_ESC('Z'): 0593 reportTerminalType(); 0594 break; 0595 case TY_ESC('c'): 0596 reset(); 0597 break; 0598 0599 case TY_ESC('n'): 0600 useCharset(2); 0601 break; 0602 case TY_ESC('o'): 0603 useCharset(3); 0604 break; 0605 case TY_ESC('7'): 0606 saveCursor(); 0607 break; 0608 case TY_ESC('8'): 0609 restoreCursor(); 0610 break; 0611 0612 case TY_ESC('='): 0613 setMode(MODE_AppKeyPad); 0614 break; 0615 case TY_ESC('>'): 0616 resetMode(MODE_AppKeyPad); 0617 break; 0618 case TY_ESC('<'): 0619 setMode(MODE_Ansi); 0620 break; // VT100 0621 0622 case TY_ESC_CS('(', '0'): 0623 setCharset(0, '0'); 0624 break; // VT100 0625 case TY_ESC_CS('(', 'A'): 0626 setCharset(0, 'A'); 0627 break; // VT100 0628 case TY_ESC_CS('(', 'B'): 0629 setCharset(0, 'B'); 0630 break; // VT100 0631 0632 case TY_ESC_CS(')', '0'): 0633 setCharset(1, '0'); 0634 break; // VT100 0635 case TY_ESC_CS(')', 'A'): 0636 setCharset(1, 'A'); 0637 break; // VT100 0638 case TY_ESC_CS(')', 'B'): 0639 setCharset(1, 'B'); 0640 break; // VT100 0641 0642 case TY_ESC_CS('*', '0'): 0643 setCharset(2, '0'); 0644 break; // VT100 0645 case TY_ESC_CS('*', 'A'): 0646 setCharset(2, 'A'); 0647 break; // VT100 0648 case TY_ESC_CS('*', 'B'): 0649 setCharset(2, 'B'); 0650 break; // VT100 0651 0652 case TY_ESC_CS('+', '0'): 0653 setCharset(3, '0'); 0654 break; // VT100 0655 case TY_ESC_CS('+', 'A'): 0656 setCharset(3, 'A'); 0657 break; // VT100 0658 case TY_ESC_CS('+', 'B'): 0659 setCharset(3, 'B'); 0660 break; // VT100 0661 0662 case TY_ESC_CS('%', 'G'): 0663 setCodec(Utf8Codec); 0664 break; // LINUX 0665 case TY_ESC_CS('%', '@'): 0666 setCodec(LocaleCodec); 0667 break; // LINUX 0668 0669 case TY_ESC_DE('3'): /* Double height line, top half */ 0670 _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, true); 0671 _currentScreen->setLineProperty(LINE_DOUBLEHEIGHT, true); 0672 break; 0673 case TY_ESC_DE('4'): /* Double height line, bottom half */ 0674 _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, true); 0675 _currentScreen->setLineProperty(LINE_DOUBLEHEIGHT, true); 0676 break; 0677 case TY_ESC_DE('5'): /* Single width, single height line*/ 0678 _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, false); 0679 _currentScreen->setLineProperty(LINE_DOUBLEHEIGHT, false); 0680 break; 0681 case TY_ESC_DE('6'): /* Double width, single height line*/ 0682 _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, true); 0683 _currentScreen->setLineProperty(LINE_DOUBLEHEIGHT, false); 0684 break; 0685 case TY_ESC_DE('8'): 0686 _currentScreen->helpAlign(); 0687 break; 0688 0689 // resize = \e[8;<row>;<col>t 0690 case TY_CSI_PS('t', 8): 0691 setImageSize(p /*lines */, q /* columns */); 0692 Q_EMIT imageResizeRequest(QSize(q, p)); 0693 break; 0694 0695 // change tab text color : \e[28;<color>t color: 0-16,777,215 0696 case TY_CSI_PS('t', 28): 0697 Q_EMIT changeTabTextColorRequest(p); 0698 break; 0699 0700 case TY_CSI_PS('K', 0): 0701 _currentScreen->clearToEndOfLine(); 0702 break; 0703 case TY_CSI_PS('K', 1): 0704 _currentScreen->clearToBeginOfLine(); 0705 break; 0706 case TY_CSI_PS('K', 2): 0707 _currentScreen->clearEntireLine(); 0708 break; 0709 case TY_CSI_PS('J', 0): 0710 _currentScreen->clearToEndOfScreen(); 0711 break; 0712 case TY_CSI_PS('J', 1): 0713 _currentScreen->clearToBeginOfScreen(); 0714 break; 0715 case TY_CSI_PS('J', 2): 0716 _currentScreen->clearEntireScreen(); 0717 break; 0718 case TY_CSI_PS('J', 3): 0719 clearHistory(); 0720 break; 0721 case TY_CSI_PS('g', 0): 0722 _currentScreen->changeTabStop(false); 0723 break; // VT100 0724 case TY_CSI_PS('g', 3): 0725 _currentScreen->clearTabStops(); 0726 break; // VT100 0727 case TY_CSI_PS('h', 4): 0728 _currentScreen->setMode(MODE_Insert); 0729 break; 0730 case TY_CSI_PS('h', 20): 0731 setMode(MODE_NewLine); 0732 break; 0733 case TY_CSI_PS('i', 0): /* IGNORE: attached printer */ 0734 break; // VT100 0735 case TY_CSI_PS('l', 4): 0736 _currentScreen->resetMode(MODE_Insert); 0737 break; 0738 case TY_CSI_PS('l', 20): 0739 resetMode(MODE_NewLine); 0740 break; 0741 case TY_CSI_PS('s', 0): 0742 saveCursor(); 0743 break; 0744 case TY_CSI_PS('u', 0): 0745 restoreCursor(); 0746 break; 0747 0748 case TY_CSI_PS('m', 0): 0749 _currentScreen->setDefaultRendition(); 0750 break; 0751 case TY_CSI_PS('m', 1): 0752 _currentScreen->setRendition(RE_BOLD); 0753 break; // VT100 0754 case TY_CSI_PS('m', 2): 0755 _currentScreen->setRendition(RE_FAINT); 0756 break; 0757 case TY_CSI_PS('m', 3): 0758 _currentScreen->setRendition(RE_ITALIC); 0759 break; // VT100 0760 case TY_CSI_PS('m', 4): 0761 _currentScreen->setRendition(RE_UNDERLINE); 0762 break; // VT100 0763 case TY_CSI_PS('m', 5): 0764 _currentScreen->setRendition(RE_BLINK); 0765 break; // VT100 0766 case TY_CSI_PS('m', 7): 0767 _currentScreen->setRendition(RE_REVERSE); 0768 break; 0769 case TY_CSI_PS('m', 8): 0770 _currentScreen->setRendition(RE_CONCEAL); 0771 break; 0772 case TY_CSI_PS('m', 9): 0773 _currentScreen->setRendition(RE_STRIKEOUT); 0774 break; 0775 case TY_CSI_PS('m', 53): 0776 _currentScreen->setRendition(RE_OVERLINE); 0777 break; 0778 case TY_CSI_PS('m', 10): /* IGNORED: mapping related */ 0779 break; // LINUX 0780 case TY_CSI_PS('m', 11): /* IGNORED: mapping related */ 0781 break; // LINUX 0782 case TY_CSI_PS('m', 12): /* IGNORED: mapping related */ 0783 break; // LINUX 0784 case TY_CSI_PS('m', 21): 0785 _currentScreen->resetRendition(RE_BOLD); 0786 break; 0787 case TY_CSI_PS('m', 22): 0788 _currentScreen->resetRendition(RE_BOLD); 0789 _currentScreen->resetRendition(RE_FAINT); 0790 break; 0791 case TY_CSI_PS('m', 23): 0792 _currentScreen->resetRendition(RE_ITALIC); 0793 break; // VT100 0794 case TY_CSI_PS('m', 24): 0795 _currentScreen->resetRendition(RE_UNDERLINE); 0796 break; 0797 case TY_CSI_PS('m', 25): 0798 _currentScreen->resetRendition(RE_BLINK); 0799 break; 0800 case TY_CSI_PS('m', 27): 0801 _currentScreen->resetRendition(RE_REVERSE); 0802 break; 0803 case TY_CSI_PS('m', 28): 0804 _currentScreen->resetRendition(RE_CONCEAL); 0805 break; 0806 case TY_CSI_PS('m', 29): 0807 _currentScreen->resetRendition(RE_STRIKEOUT); 0808 break; 0809 case TY_CSI_PS('m', 55): 0810 _currentScreen->resetRendition(RE_OVERLINE); 0811 break; 0812 0813 case TY_CSI_PS('m', 30): 0814 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 0); 0815 break; 0816 case TY_CSI_PS('m', 31): 0817 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 1); 0818 break; 0819 case TY_CSI_PS('m', 32): 0820 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 2); 0821 break; 0822 case TY_CSI_PS('m', 33): 0823 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 3); 0824 break; 0825 case TY_CSI_PS('m', 34): 0826 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 4); 0827 break; 0828 case TY_CSI_PS('m', 35): 0829 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 5); 0830 break; 0831 case TY_CSI_PS('m', 36): 0832 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 6); 0833 break; 0834 case TY_CSI_PS('m', 37): 0835 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 7); 0836 break; 0837 0838 case TY_CSI_PS('m', 38): 0839 _currentScreen->setForeColor(p, q); 0840 break; 0841 0842 case TY_CSI_PS('m', 39): 0843 _currentScreen->setForeColor(COLOR_SPACE_DEFAULT, 0); 0844 break; 0845 0846 case TY_CSI_PS('m', 40): 0847 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 0); 0848 break; 0849 case TY_CSI_PS('m', 41): 0850 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 1); 0851 break; 0852 case TY_CSI_PS('m', 42): 0853 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 2); 0854 break; 0855 case TY_CSI_PS('m', 43): 0856 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 3); 0857 break; 0858 case TY_CSI_PS('m', 44): 0859 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 4); 0860 break; 0861 case TY_CSI_PS('m', 45): 0862 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 5); 0863 break; 0864 case TY_CSI_PS('m', 46): 0865 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 6); 0866 break; 0867 case TY_CSI_PS('m', 47): 0868 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 7); 0869 break; 0870 0871 case TY_CSI_PS('m', 48): 0872 _currentScreen->setBackColor(p, q); 0873 break; 0874 0875 case TY_CSI_PS('m', 49): 0876 _currentScreen->setBackColor(COLOR_SPACE_DEFAULT, 1); 0877 break; 0878 0879 case TY_CSI_PS('m', 90): 0880 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 8); 0881 break; 0882 case TY_CSI_PS('m', 91): 0883 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 9); 0884 break; 0885 case TY_CSI_PS('m', 92): 0886 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 10); 0887 break; 0888 case TY_CSI_PS('m', 93): 0889 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 11); 0890 break; 0891 case TY_CSI_PS('m', 94): 0892 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 12); 0893 break; 0894 case TY_CSI_PS('m', 95): 0895 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 13); 0896 break; 0897 case TY_CSI_PS('m', 96): 0898 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 14); 0899 break; 0900 case TY_CSI_PS('m', 97): 0901 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 15); 0902 break; 0903 0904 case TY_CSI_PS('m', 100): 0905 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 8); 0906 break; 0907 case TY_CSI_PS('m', 101): 0908 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 9); 0909 break; 0910 case TY_CSI_PS('m', 102): 0911 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 10); 0912 break; 0913 case TY_CSI_PS('m', 103): 0914 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 11); 0915 break; 0916 case TY_CSI_PS('m', 104): 0917 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 12); 0918 break; 0919 case TY_CSI_PS('m', 105): 0920 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 13); 0921 break; 0922 case TY_CSI_PS('m', 106): 0923 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 14); 0924 break; 0925 case TY_CSI_PS('m', 107): 0926 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 15); 0927 break; 0928 0929 case TY_CSI_PS('n', 5): 0930 reportStatus(); 0931 break; 0932 case TY_CSI_PS('n', 6): 0933 reportCursorPosition(); 0934 break; 0935 case TY_CSI_PS('q', 0): /* IGNORED: LEDs off */ 0936 break; // VT100 0937 case TY_CSI_PS('q', 1): /* IGNORED: LED1 on */ 0938 break; // VT100 0939 case TY_CSI_PS('q', 2): /* IGNORED: LED2 on */ 0940 break; // VT100 0941 case TY_CSI_PS('q', 3): /* IGNORED: LED3 on */ 0942 break; // VT100 0943 case TY_CSI_PS('q', 4): /* IGNORED: LED4 on */ 0944 break; // VT100 0945 case TY_CSI_PS('x', 0): 0946 reportTerminalParms(2); 0947 break; // VT100 0948 case TY_CSI_PS('x', 1): 0949 reportTerminalParms(3); 0950 break; // VT100 0951 0952 case TY_CSI_PS_SP('q', 0): /* fall through */ 0953 case TY_CSI_PS_SP('q', 1): 0954 Q_EMIT cursorChanged(KeyboardCursorShape::BlockCursor, true); 0955 break; 0956 case TY_CSI_PS_SP('q', 2): 0957 Q_EMIT cursorChanged(KeyboardCursorShape::BlockCursor, false); 0958 break; 0959 case TY_CSI_PS_SP('q', 3): 0960 Q_EMIT cursorChanged(KeyboardCursorShape::UnderlineCursor, true); 0961 break; 0962 case TY_CSI_PS_SP('q', 4): 0963 Q_EMIT cursorChanged(KeyboardCursorShape::UnderlineCursor, false); 0964 break; 0965 case TY_CSI_PS_SP('q', 5): 0966 Q_EMIT cursorChanged(KeyboardCursorShape::IBeamCursor, true); 0967 break; 0968 case TY_CSI_PS_SP('q', 6): 0969 Q_EMIT cursorChanged(KeyboardCursorShape::IBeamCursor, false); 0970 break; 0971 0972 case TY_CSI_PN('@'): 0973 _currentScreen->insertChars(p); 0974 break; 0975 case TY_CSI_PN('A'): 0976 _currentScreen->cursorUp(p); 0977 break; // VT100 0978 case TY_CSI_PN('B'): 0979 _currentScreen->cursorDown(p); 0980 break; // VT100 0981 case TY_CSI_PN('C'): 0982 _currentScreen->cursorRight(p); 0983 break; // VT100 0984 case TY_CSI_PN('D'): 0985 _currentScreen->cursorLeft(p); 0986 break; // VT100 0987 case TY_CSI_PN('E'): /* Not implemented: cursor next p lines */ 0988 break; // VT100 0989 case TY_CSI_PN('F'): /* Not implemented: cursor preceding p lines */ 0990 break; // VT100 0991 case TY_CSI_PN('G'): 0992 _currentScreen->setCursorX(p); 0993 break; // LINUX 0994 case TY_CSI_PN('H'): 0995 _currentScreen->setCursorYX(p, q); 0996 break; // VT100 0997 case TY_CSI_PN('I'): 0998 _currentScreen->tab(p); 0999 break; 1000 case TY_CSI_PN('L'): 1001 _currentScreen->insertLines(p); 1002 break; 1003 case TY_CSI_PN('M'): 1004 _currentScreen->deleteLines(p); 1005 break; 1006 case TY_CSI_PN('P'): 1007 _currentScreen->deleteChars(p); 1008 break; 1009 case TY_CSI_PN('S'): 1010 _currentScreen->scrollUp(p); 1011 break; 1012 case TY_CSI_PN('T'): 1013 _currentScreen->scrollDown(p); 1014 break; 1015 case TY_CSI_PN('X'): 1016 _currentScreen->eraseChars(p); 1017 break; 1018 case TY_CSI_PN('Z'): 1019 _currentScreen->backtab(p); 1020 break; 1021 case TY_CSI_PN('b'): 1022 _currentScreen->repeatChars(p); 1023 break; 1024 case TY_CSI_PN('c'): 1025 reportTerminalType(); 1026 break; // VT100 1027 case TY_CSI_PN('d'): 1028 _currentScreen->setCursorY(p); 1029 break; // LINUX 1030 case TY_CSI_PN('f'): 1031 _currentScreen->setCursorYX(p, q); 1032 break; // VT100 1033 case TY_CSI_PN('r'): 1034 setMargins(p, q); 1035 break; // VT100 1036 case TY_CSI_PN('y'): /* IGNORED: Confidence test */ 1037 break; // VT100 1038 1039 case TY_CSI_PR('h', 1): 1040 setMode(MODE_AppCuKeys); 1041 break; // VT100 1042 case TY_CSI_PR('l', 1): 1043 resetMode(MODE_AppCuKeys); 1044 break; // VT100 1045 case TY_CSI_PR('s', 1): 1046 saveMode(MODE_AppCuKeys); 1047 break; // FIXME 1048 case TY_CSI_PR('r', 1): 1049 restoreMode(MODE_AppCuKeys); 1050 break; // FIXME 1051 1052 case TY_CSI_PR('l', 2): 1053 resetMode(MODE_Ansi); 1054 break; // VT100 1055 1056 case TY_CSI_PR('h', 3): 1057 setMode(MODE_132Columns); 1058 break; // VT100 1059 case TY_CSI_PR('l', 3): 1060 resetMode(MODE_132Columns); 1061 break; // VT100 1062 1063 case TY_CSI_PR('h', 4): /* IGNORED: soft scrolling */ 1064 break; // VT100 1065 case TY_CSI_PR('l', 4): /* IGNORED: soft scrolling */ 1066 break; // VT100 1067 1068 case TY_CSI_PR('h', 5): 1069 _currentScreen->setMode(MODE_Screen); 1070 break; // VT100 1071 case TY_CSI_PR('l', 5): 1072 _currentScreen->resetMode(MODE_Screen); 1073 break; // VT100 1074 1075 case TY_CSI_PR('h', 6): 1076 _currentScreen->setMode(MODE_Origin); 1077 break; // VT100 1078 case TY_CSI_PR('l', 6): 1079 _currentScreen->resetMode(MODE_Origin); 1080 break; // VT100 1081 case TY_CSI_PR('s', 6): 1082 _currentScreen->saveMode(MODE_Origin); 1083 break; // FIXME 1084 case TY_CSI_PR('r', 6): 1085 _currentScreen->restoreMode(MODE_Origin); 1086 break; // FIXME 1087 1088 case TY_CSI_PR('h', 7): 1089 _currentScreen->setMode(MODE_Wrap); 1090 break; // VT100 1091 case TY_CSI_PR('l', 7): 1092 _currentScreen->resetMode(MODE_Wrap); 1093 break; // VT100 1094 case TY_CSI_PR('s', 7): 1095 _currentScreen->saveMode(MODE_Wrap); 1096 break; // FIXME 1097 case TY_CSI_PR('r', 7): 1098 _currentScreen->restoreMode(MODE_Wrap); 1099 break; // FIXME 1100 1101 case TY_CSI_PR('h', 8): /* IGNORED: autorepeat on */ 1102 break; // VT100 1103 case TY_CSI_PR('l', 8): /* IGNORED: autorepeat off */ 1104 break; // VT100 1105 case TY_CSI_PR('s', 8): /* IGNORED: autorepeat on */ 1106 break; // VT100 1107 case TY_CSI_PR('r', 8): /* IGNORED: autorepeat off */ 1108 break; // VT100 1109 1110 case TY_CSI_PR('h', 9): /* IGNORED: interlace */ 1111 break; // VT100 1112 case TY_CSI_PR('l', 9): /* IGNORED: interlace */ 1113 break; // VT100 1114 case TY_CSI_PR('s', 9): /* IGNORED: interlace */ 1115 break; // VT100 1116 case TY_CSI_PR('r', 9): /* IGNORED: interlace */ 1117 break; // VT100 1118 1119 case TY_CSI_PR('h', 12): /* IGNORED: Cursor blink */ 1120 break; // att610 1121 case TY_CSI_PR('l', 12): /* IGNORED: Cursor blink */ 1122 break; // att610 1123 case TY_CSI_PR('s', 12): /* IGNORED: Cursor blink */ 1124 break; // att610 1125 case TY_CSI_PR('r', 12): /* IGNORED: Cursor blink */ 1126 break; // att610 1127 1128 case TY_CSI_PR('h', 25): 1129 setMode(MODE_Cursor); 1130 break; // VT100 1131 case TY_CSI_PR('l', 25): 1132 resetMode(MODE_Cursor); 1133 break; // VT100 1134 case TY_CSI_PR('s', 25): 1135 saveMode(MODE_Cursor); 1136 break; // VT100 1137 case TY_CSI_PR('r', 25): 1138 restoreMode(MODE_Cursor); 1139 break; // VT100 1140 1141 case TY_CSI_PR('h', 40): 1142 setMode(MODE_Allow132Columns); 1143 break; // XTERM 1144 case TY_CSI_PR('l', 40): 1145 resetMode(MODE_Allow132Columns); 1146 break; // XTERM 1147 1148 case TY_CSI_PR('h', 41): /* IGNORED: obsolete more(1) fix */ 1149 break; // XTERM 1150 case TY_CSI_PR('l', 41): /* IGNORED: obsolete more(1) fix */ 1151 break; // XTERM 1152 case TY_CSI_PR('s', 41): /* IGNORED: obsolete more(1) fix */ 1153 break; // XTERM 1154 case TY_CSI_PR('r', 41): /* IGNORED: obsolete more(1) fix */ 1155 break; // XTERM 1156 1157 case TY_CSI_PR('h', 47): 1158 setMode(MODE_AppScreen); 1159 break; // VT100 1160 case TY_CSI_PR('l', 47): 1161 resetMode(MODE_AppScreen); 1162 break; // VT100 1163 case TY_CSI_PR('s', 47): 1164 saveMode(MODE_AppScreen); 1165 break; // XTERM 1166 case TY_CSI_PR('r', 47): 1167 restoreMode(MODE_AppScreen); 1168 break; // XTERM 1169 1170 case TY_CSI_PR('h', 67): /* IGNORED: DECBKM */ 1171 break; // XTERM 1172 case TY_CSI_PR('l', 67): /* IGNORED: DECBKM */ 1173 break; // XTERM 1174 case TY_CSI_PR('s', 67): /* IGNORED: DECBKM */ 1175 break; // XTERM 1176 case TY_CSI_PR('r', 67): /* IGNORED: DECBKM */ 1177 break; // XTERM 1178 1179 // XTerm defines the following modes: 1180 // SET_VT200_MOUSE 1000 1181 // SET_VT200_HIGHLIGHT_MOUSE 1001 1182 // SET_BTN_EVENT_MOUSE 1002 1183 // SET_ANY_EVENT_MOUSE 1003 1184 // 1185 1186 // Note about mouse modes: 1187 // There are four mouse modes which xterm-compatible terminals can support - 1000,1001,1002,1003 1188 // Konsole currently supports mode 1000 (basic mouse press and release) and mode 1002 (dragging the mouse). 1189 // TODO: Implementation of mouse modes 1001 (something called hilight tracking) and 1190 // 1003 (a slight variation on dragging the mouse) 1191 // 1192 1193 case TY_CSI_PR('h', 1000): 1194 setMode(MODE_Mouse1000); 1195 break; // XTERM 1196 case TY_CSI_PR('l', 1000): 1197 resetMode(MODE_Mouse1000); 1198 break; // XTERM 1199 case TY_CSI_PR('s', 1000): 1200 saveMode(MODE_Mouse1000); 1201 break; // XTERM 1202 case TY_CSI_PR('r', 1000): 1203 restoreMode(MODE_Mouse1000); 1204 break; // XTERM 1205 1206 case TY_CSI_PR('h', 1001): /* IGNORED: hilite mouse tracking */ 1207 break; // XTERM 1208 case TY_CSI_PR('l', 1001): 1209 resetMode(MODE_Mouse1001); 1210 break; // XTERM 1211 case TY_CSI_PR('s', 1001): /* IGNORED: hilite mouse tracking */ 1212 break; // XTERM 1213 case TY_CSI_PR('r', 1001): /* IGNORED: hilite mouse tracking */ 1214 break; // XTERM 1215 1216 case TY_CSI_PR('h', 1002): 1217 setMode(MODE_Mouse1002); 1218 break; // XTERM 1219 case TY_CSI_PR('l', 1002): 1220 resetMode(MODE_Mouse1002); 1221 break; // XTERM 1222 case TY_CSI_PR('s', 1002): 1223 saveMode(MODE_Mouse1002); 1224 break; // XTERM 1225 case TY_CSI_PR('r', 1002): 1226 restoreMode(MODE_Mouse1002); 1227 break; // XTERM 1228 1229 case TY_CSI_PR('h', 1003): 1230 setMode(MODE_Mouse1003); 1231 break; // XTERM 1232 case TY_CSI_PR('l', 1003): 1233 resetMode(MODE_Mouse1003); 1234 break; // XTERM 1235 case TY_CSI_PR('s', 1003): 1236 saveMode(MODE_Mouse1003); 1237 break; // XTERM 1238 case TY_CSI_PR('r', 1003): 1239 restoreMode(MODE_Mouse1003); 1240 break; // XTERM 1241 1242 case TY_CSI_PR('h', 1004): 1243 _reportFocusEvents = true; 1244 break; 1245 case TY_CSI_PR('l', 1004): 1246 _reportFocusEvents = false; 1247 break; 1248 1249 case TY_CSI_PR('h', 1005): 1250 setMode(MODE_Mouse1005); 1251 break; // XTERM 1252 case TY_CSI_PR('l', 1005): 1253 resetMode(MODE_Mouse1005); 1254 break; // XTERM 1255 case TY_CSI_PR('s', 1005): 1256 saveMode(MODE_Mouse1005); 1257 break; // XTERM 1258 case TY_CSI_PR('r', 1005): 1259 restoreMode(MODE_Mouse1005); 1260 break; // XTERM 1261 1262 case TY_CSI_PR('h', 1006): 1263 setMode(MODE_Mouse1006); 1264 break; // XTERM 1265 case TY_CSI_PR('l', 1006): 1266 resetMode(MODE_Mouse1006); 1267 break; // XTERM 1268 case TY_CSI_PR('s', 1006): 1269 saveMode(MODE_Mouse1006); 1270 break; // XTERM 1271 case TY_CSI_PR('r', 1006): 1272 restoreMode(MODE_Mouse1006); 1273 break; // XTERM 1274 1275 case TY_CSI_PR('h', 1015): 1276 setMode(MODE_Mouse1015); 1277 break; // URXVT 1278 case TY_CSI_PR('l', 1015): 1279 resetMode(MODE_Mouse1015); 1280 break; // URXVT 1281 case TY_CSI_PR('s', 1015): 1282 saveMode(MODE_Mouse1015); 1283 break; // URXVT 1284 case TY_CSI_PR('r', 1015): 1285 restoreMode(MODE_Mouse1015); 1286 break; // URXVT 1287 1288 case TY_CSI_PR('h', 1034): /* IGNORED: 8bitinput activation */ 1289 break; // XTERM 1290 1291 case TY_CSI_PR('h', 1047): 1292 setMode(MODE_AppScreen); 1293 break; // XTERM 1294 case TY_CSI_PR('l', 1047): 1295 _alternateScreen->clearEntireScreen(); 1296 resetMode(MODE_AppScreen); 1297 break; // XTERM 1298 case TY_CSI_PR('s', 1047): 1299 saveMode(MODE_AppScreen); 1300 break; // XTERM 1301 case TY_CSI_PR('r', 1047): 1302 restoreMode(MODE_AppScreen); 1303 break; // XTERM 1304 1305 // FIXME: Unitoken: save translations 1306 case TY_CSI_PR('h', 1048): 1307 saveCursor(); 1308 break; // XTERM 1309 case TY_CSI_PR('l', 1048): 1310 restoreCursor(); 1311 break; // XTERM 1312 case TY_CSI_PR('s', 1048): 1313 saveCursor(); 1314 break; // XTERM 1315 case TY_CSI_PR('r', 1048): 1316 restoreCursor(); 1317 break; // XTERM 1318 1319 // FIXME: every once new sequences like this pop up in xterm. 1320 // Here's a guess of what they could mean. 1321 case TY_CSI_PR('h', 1049): 1322 saveCursor(); 1323 _alternateScreen->clearEntireScreen(); 1324 setMode(MODE_AppScreen); 1325 break; // XTERM 1326 case TY_CSI_PR('l', 1049): 1327 resetMode(MODE_AppScreen); 1328 restoreCursor(); 1329 break; // XTERM 1330 1331 case TY_CSI_PR('h', 2004): 1332 setMode(MODE_BracketedPaste); 1333 break; // XTERM 1334 case TY_CSI_PR('l', 2004): 1335 resetMode(MODE_BracketedPaste); 1336 break; // XTERM 1337 case TY_CSI_PR('s', 2004): 1338 saveMode(MODE_BracketedPaste); 1339 break; // XTERM 1340 case TY_CSI_PR('r', 2004): 1341 restoreMode(MODE_BracketedPaste); 1342 break; // XTERM 1343 1344 // FIXME: weird DEC reset sequence 1345 case TY_CSI_PE('p'): /* IGNORED: reset ( ) */ 1346 break; 1347 1348 // FIXME: when changing between vt52 and ansi mode evtl do some resetting. 1349 case TY_VT52('A'): 1350 _currentScreen->cursorUp(1); 1351 break; // VT52 1352 case TY_VT52('B'): 1353 _currentScreen->cursorDown(1); 1354 break; // VT52 1355 case TY_VT52('C'): 1356 _currentScreen->cursorRight(1); 1357 break; // VT52 1358 case TY_VT52('D'): 1359 _currentScreen->cursorLeft(1); 1360 break; // VT52 1361 1362 case TY_VT52('F'): 1363 setAndUseCharset(0, '0'); 1364 break; // VT52 1365 case TY_VT52('G'): 1366 setAndUseCharset(0, 'B'); 1367 break; // VT52 1368 1369 case TY_VT52('H'): 1370 _currentScreen->setCursorYX(1, 1); 1371 break; // VT52 1372 case TY_VT52('I'): 1373 _currentScreen->reverseIndex(); 1374 break; // VT52 1375 case TY_VT52('J'): 1376 _currentScreen->clearToEndOfScreen(); 1377 break; // VT52 1378 case TY_VT52('K'): 1379 _currentScreen->clearToEndOfLine(); 1380 break; // VT52 1381 case TY_VT52('Y'): 1382 _currentScreen->setCursorYX(p - 31, q - 31); 1383 break; // VT52 1384 case TY_VT52('Z'): 1385 reportTerminalType(); 1386 break; // VT52 1387 case TY_VT52('<'): 1388 setMode(MODE_Ansi); 1389 break; // VT52 1390 case TY_VT52('='): 1391 setMode(MODE_AppKeyPad); 1392 break; // VT52 1393 case TY_VT52('>'): 1394 resetMode(MODE_AppKeyPad); 1395 break; // VT52 1396 1397 case TY_CSI_PG('c'): 1398 reportSecondaryAttributes(); 1399 break; // VT100 1400 1401 default: 1402 reportDecodingError(); 1403 break; 1404 }; 1405 } 1406 1407 void Vt102Emulation::clearScreenAndSetColumns(int columnCount) 1408 { 1409 setImageSize(_currentScreen->getLines(), columnCount); 1410 clearEntireScreen(); 1411 setDefaultMargins(); 1412 _currentScreen->setCursorYX(0, 0); 1413 } 1414 1415 void Vt102Emulation::sendString(const char *s, int length) 1416 { 1417 if (length >= 0) 1418 Q_EMIT sendData(s, length); 1419 else 1420 Q_EMIT sendData(s, strlen(s)); 1421 } 1422 1423 void Vt102Emulation::reportCursorPosition() 1424 { 1425 const size_t sz = 20; 1426 char tmp[sz]; 1427 const size_t r = snprintf(tmp, sz, "\033[%d;%dR", _currentScreen->getCursorY() + 1, _currentScreen->getCursorX() + 1); 1428 if (sz <= r) { 1429 qWarning("Vt102Emulation::reportCursorPosition: Buffer too small\n"); 1430 } 1431 sendString(tmp); 1432 } 1433 1434 void Vt102Emulation::reportTerminalType() 1435 { 1436 // Primary device attribute response (Request was: ^[[0c or ^[[c (from TT321 Users Guide)) 1437 // VT220: ^[[?63;1;2;3;6;7;8c (list deps on emul. capabilities) 1438 // VT100: ^[[?1;2c 1439 // VT101: ^[[?1;0c 1440 // VT102: ^[[?6v 1441 if (getMode(MODE_Ansi)) 1442 sendString("\033[?1;2c"); // I'm a VT100 1443 else 1444 sendString("\033/Z"); // I'm a VT52 1445 } 1446 1447 void Vt102Emulation::reportSecondaryAttributes() 1448 { 1449 // Seconday device attribute response (Request was: ^[[>0c or ^[[>c) 1450 if (getMode(MODE_Ansi)) 1451 sendString("\033[>0;115;0c"); // Why 115? ;) 1452 else 1453 sendString("\033/Z"); // FIXME I don't think VT52 knows about it but kept for 1454 // konsoles backward compatibility. 1455 } 1456 1457 void Vt102Emulation::reportTerminalParms(int p) 1458 // DECREPTPARM 1459 { 1460 const size_t sz = 100; 1461 char tmp[sz]; 1462 const size_t r = snprintf(tmp, sz, "\033[%d;1;1;112;112;1;0x", p); // not really true. 1463 if (sz <= r) { 1464 qWarning("Vt102Emulation::reportTerminalParms: Buffer too small\n"); 1465 } 1466 sendString(tmp); 1467 } 1468 1469 void Vt102Emulation::reportStatus() 1470 { 1471 sendString("\033[0n"); // VT100. Device status report. 0 = Ready. 1472 } 1473 1474 void Vt102Emulation::reportAnswerBack() 1475 { 1476 // FIXME - Test this with VTTEST 1477 // This is really obsolete VT100 stuff. 1478 const char *ANSWER_BACK = ""; 1479 sendString(ANSWER_BACK); 1480 } 1481 1482 /*! 1483 `cx',`cy' are 1-based. 1484 `cb' indicates the button pressed or released (0-2) or scroll event (4-5). 1485 1486 eventType represents the kind of mouse action that occurred: 1487 0 = Mouse button press 1488 1 = Mouse drag 1489 2 = Mouse button release 1490 */ 1491 1492 void Vt102Emulation::sendMouseEvent(int cb, int cx, int cy, int eventType) 1493 { 1494 if (cx < 1 || cy < 1) 1495 return; 1496 1497 // With the exception of the 1006 mode, button release is encoded in cb. 1498 // Note that if multiple extensions are enabled, the 1006 is used, so it's okay to check for only that. 1499 if (eventType == 2 && !getMode(MODE_Mouse1006)) 1500 cb = 3; 1501 1502 // normal buttons are passed as 0x20 + button, 1503 // mouse wheel (buttons 4,5) as 0x5c + button 1504 if (cb >= 4) 1505 cb += 0x3c; 1506 1507 // Mouse motion handling 1508 if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1) 1509 cb += 0x20; // add 32 to signify motion event 1510 1511 char command[32]; 1512 command[0] = '\0'; 1513 // Check the extensions in decreasing order of preference. Encoding the release event above assumes that 1006 comes first. 1514 if (getMode(MODE_Mouse1006)) { 1515 snprintf(command, sizeof(command), "\033[<%d;%d;%d%c", cb, cx, cy, eventType == 2 ? 'm' : 'M'); 1516 } else if (getMode(MODE_Mouse1015)) { 1517 snprintf(command, sizeof(command), "\033[%d;%d;%dM", cb + 0x20, cx, cy); 1518 } else if (getMode(MODE_Mouse1005)) { 1519 if (cx <= 2015 && cy <= 2015) { 1520 // The xterm extension uses UTF-8 (up to 2 bytes) to encode 1521 // coordinate+32, no matter what the locale is. We could easily 1522 // convert manually, but QString can also do it for us. 1523 QChar coords[2]; 1524 coords[0] = QChar(cx + 0x20); 1525 coords[1] = QChar(cy + 0x20); 1526 QString coordsStr = QString(coords, 2); 1527 QByteArray utf8 = coordsStr.toUtf8(); 1528 snprintf(command, sizeof(command), "\033[M%c%s", cb + 0x20, utf8.constData()); 1529 } 1530 } else if (cx <= 223 && cy <= 223) { 1531 snprintf(command, sizeof(command), "\033[M%c%c%c", cb + 0x20, cx + 0x20, cy + 0x20); 1532 } 1533 1534 sendString(command); 1535 } 1536 1537 /** 1538 * The focus lost event can be used by Vim (or other terminal applications) 1539 * to recognize that the konsole window has lost focus. 1540 * The escape sequence is also used by iTerm2. 1541 * Vim needs the following plugin to be installed to convert the escape 1542 * sequence into the FocusLost autocmd: https://github.com/sjl/vitality.vim 1543 */ 1544 void Vt102Emulation::focusLost(void) 1545 { 1546 if (_reportFocusEvents) 1547 sendString("\033[O"); 1548 } 1549 1550 /** 1551 * The focus gained event can be used by Vim (or other terminal applications) 1552 * to recognize that the konsole window has gained focus again. 1553 * The escape sequence is also used by iTerm2. 1554 * Vim needs the following plugin to be installed to convert the escape 1555 * sequence into the FocusGained autocmd: https://github.com/sjl/vitality.vim 1556 */ 1557 void Vt102Emulation::focusGained(void) 1558 { 1559 if (_reportFocusEvents) 1560 sendString("\033[I"); 1561 } 1562 1563 void Vt102Emulation::sendText(const QString &text) 1564 { 1565 if (!text.isEmpty()) { 1566 QKeyEvent event(QEvent::KeyPress, 0, Qt::NoModifier, text); 1567 sendKeyEvent(&event, false); // expose as a big fat keypress event 1568 } 1569 } 1570 //<<<<<<< HEAD 1571 1572 QKeyEvent *Vt102Emulation::remapKeyModifiersForMac(QKeyEvent *event) 1573 { 1574 Qt::KeyboardModifiers modifiers = event->modifiers(); 1575 1576 QFlags<Qt::KeyboardModifier> isTheLabeledKeyCommandPressed = modifiers & Qt::ControlModifier; 1577 QFlags<Qt::KeyboardModifier> isTheLabeledKeyControlPressed = modifiers & Qt::MetaModifier; 1578 if (isTheLabeledKeyCommandPressed) { 1579 qDebug("Command is pressed."); 1580 modifiers &= ~Qt::ControlModifier; 1581 modifiers |= Qt::MetaModifier; 1582 } else { 1583 modifiers &= ~Qt::MetaModifier; 1584 } 1585 1586 if (isTheLabeledKeyControlPressed) { 1587 qDebug("Control is pressed."); 1588 modifiers &= ~Qt::MetaModifier; 1589 modifiers |= Qt::ControlModifier; 1590 } else { 1591 modifiers &= ~Qt::ControlModifier; 1592 } 1593 1594 return new QKeyEvent(QEvent::None, 1595 event->key(), 1596 modifiers, 1597 event->nativeScanCode(), 1598 event->nativeVirtualKey(), 1599 event->nativeModifiers(), 1600 event->text(), 1601 event->isAutoRepeat(), 1602 event->count()); 1603 } 1604 1605 void Vt102Emulation::sendKeyEvent(QKeyEvent *origEvent, bool fromPaste) 1606 { 1607 #if defined(Q_OS_MAC) 1608 QScopedPointer<QKeyEvent> event(remapKeyModifiersForMac(origEvent)); 1609 #else 1610 QKeyEvent *event = origEvent; 1611 #endif 1612 Qt::KeyboardModifiers modifiers = event->modifiers(); 1613 KeyboardTranslator::States states = KeyboardTranslator::NoState; 1614 1615 // get current states 1616 if (getMode(MODE_NewLine)) 1617 states |= KeyboardTranslator::NewLineState; 1618 if (getMode(MODE_Ansi)) 1619 states |= KeyboardTranslator::AnsiState; 1620 if (getMode(MODE_AppCuKeys)) 1621 states |= KeyboardTranslator::CursorKeysState; 1622 if (getMode(MODE_AppScreen)) 1623 states |= KeyboardTranslator::AlternateScreenState; 1624 if (getMode(MODE_AppKeyPad) && (modifiers & Qt::KeypadModifier)) 1625 states |= KeyboardTranslator::ApplicationKeypadState; 1626 1627 // check flow control state 1628 if (modifiers & KeyboardTranslator::CTRL_MOD) { 1629 switch (event->key()) { 1630 case Qt::Key_S: 1631 Q_EMIT flowControlKeyPressed(true); 1632 break; 1633 case Qt::Key_Q: 1634 case Qt::Key_C: // cancel flow control 1635 Q_EMIT flowControlKeyPressed(false); 1636 break; 1637 } 1638 } 1639 1640 // lookup key binding 1641 if (_keyTranslator) { 1642 KeyboardTranslator::Entry entry = _keyTranslator->findEntry(event->key(), modifiers, states); 1643 // send result to terminal 1644 QByteArray textToSend; 1645 1646 // special handling for the Alt (aka. Meta) modifier. pressing 1647 // Alt+[Character] results in Esc+[Character] being sent 1648 // (unless there is an entry defined for this particular combination 1649 // in the keyboard modifier) 1650 1651 bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier; 1652 bool wantsMetaModifier = entry.modifiers() & entry.modifierMask() & Qt::MetaModifier; 1653 bool wantsAnyModifier = entry.state() & entry.stateMask() & KeyboardTranslator::AnyModifierState; 1654 1655 if (modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) && !event->text().isEmpty()) { 1656 textToSend.prepend("\033"); 1657 } 1658 if (modifiers & Qt::MetaModifier && !(wantsMetaModifier || wantsAnyModifier) && !event->text().isEmpty()) { 1659 textToSend.prepend("\030@s"); 1660 } 1661 1662 if (entry.command() != KeyboardTranslator::NoCommand) { 1663 if (entry.command() & KeyboardTranslator::EraseCommand) { 1664 textToSend += eraseChar(); 1665 } else { 1666 Q_EMIT handleCommandFromKeyboard(entry.command()); 1667 } 1668 1669 // TODO command handling 1670 } else if (!entry.text().isEmpty()) { 1671 textToSend += entry.text(true, modifiers); 1672 } else if ((modifiers & KeyboardTranslator::CTRL_MOD) && event->key() >= 0x40 && event->key() < 0x5f) { 1673 textToSend += (event->key() & 0x1f); 1674 } else if (event->key() == Qt::Key_Tab) { 1675 textToSend += 0x09; 1676 } else if (event->key() == Qt::Key_PageUp) { 1677 textToSend += "\033[5~"; 1678 } else if (event->key() == Qt::Key_PageDown) { 1679 textToSend += "\033[6~"; 1680 } else { 1681 textToSend += _codec->fromUnicode(event->text()); 1682 } 1683 1684 if (!fromPaste && textToSend.length()) { 1685 Q_EMIT outputFromKeypressEvent(); 1686 } 1687 Q_EMIT sendData(textToSend.constData(), textToSend.length()); 1688 } else { 1689 // print an error message to the terminal if no key translator has been 1690 // set 1691 QString translatorError = 1692 tr("No keyboard translator available. " 1693 "The information needed to convert key presses " 1694 "into characters to send to the terminal " 1695 "is missing."); 1696 reset(); 1697 receiveData(translatorError.toUtf8().constData(), translatorError.size()); 1698 } 1699 } 1700 1701 /* ------------------------------------------------------------------------- */ 1702 /* */ 1703 /* VT100 Charsets */ 1704 /* */ 1705 /* ------------------------------------------------------------------------- */ 1706 1707 // Character Set Conversion ------------------------------------------------ -- 1708 1709 /* 1710 The processing contains a VT100 specific code translation layer. 1711 It's still in use and mainly responsible for the line drawing graphics. 1712 1713 These and some other glyphs are assigned to codes (0x5f-0xfe) 1714 normally occupied by the latin letters. Since this codes also 1715 appear within control sequences, the extra code conversion 1716 does not permute with the tokenizer and is placed behind it 1717 in the pipeline. It only applies to tokens, which represent 1718 plain characters. 1719 1720 This conversion it eventually continued in TerminalDisplay.C, since 1721 it might involve VT100 enhanced fonts, which have these 1722 particular glyphs allocated in (0x00-0x1f) in their code page. 1723 */ 1724 1725 #define CHARSET _charset[_currentScreen == _alternateScreen.get()] 1726 1727 // assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i. 1728 1729 constexpr std::array<unsigned short, 32> vt100_graphics = { // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15 1730 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 1731 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534, 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7}; 1732 1733 // Apply current character map. 1734 1735 wchar_t Vt102Emulation::applyCharset(char16_t c) 1736 { 1737 if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) 1738 return vt100_graphics[c - 0x5f]; 1739 if (CHARSET.pound && c == '#') 1740 return 0xa3; // This mode is obsolete 1741 return c; 1742 } 1743 1744 /* 1745 "Charset" related part of the emulation state. 1746 This configures the VT100 charset filter. 1747 1748 While most operation work on the current _screen, 1749 the following two are different. 1750 */ 1751 1752 void Vt102Emulation::resetCharset(int scrno) 1753 { 1754 _charset[scrno].cu_cs = 0; 1755 qstrncpy(_charset[scrno].charset, "BBBB", 4); 1756 _charset[scrno].sa_graphic = false; 1757 _charset[scrno].sa_pound = false; 1758 _charset[scrno].graphic = false; 1759 _charset[scrno].pound = false; 1760 } 1761 1762 void Vt102Emulation::setCharset(int n, int cs) // on both screens. 1763 { 1764 _charset[0].charset[n & 3] = cs; 1765 useCharset(_charset[0].cu_cs); 1766 _charset[1].charset[n & 3] = cs; 1767 useCharset(_charset[1].cu_cs); 1768 } 1769 1770 void Vt102Emulation::setAndUseCharset(int n, int cs) 1771 { 1772 CHARSET.charset[n & 3] = cs; 1773 useCharset(n & 3); 1774 } 1775 1776 void Vt102Emulation::useCharset(int n) 1777 { 1778 CHARSET.cu_cs = n & 3; 1779 CHARSET.graphic = (CHARSET.charset[n & 3] == '0'); 1780 CHARSET.pound = (CHARSET.charset[n & 3] == 'A'); // This mode is obsolete 1781 } 1782 1783 void Vt102Emulation::setDefaultMargins() 1784 { 1785 _primaryScreen->setDefaultMargins(); 1786 _alternateScreen->setDefaultMargins(); 1787 } 1788 1789 void Vt102Emulation::setMargins(int t, int b) 1790 { 1791 _primaryScreen->setMargins(t, b); 1792 _alternateScreen->setMargins(t, b); 1793 } 1794 1795 void Vt102Emulation::saveCursor() 1796 { 1797 CHARSET.sa_graphic = CHARSET.graphic; 1798 CHARSET.sa_pound = CHARSET.pound; // This mode is obsolete 1799 // we are not clear about these 1800 // sa_charset = charsets[cScreen->_charset]; 1801 // sa_charset_num = cScreen->_charset; 1802 _currentScreen->saveCursor(); 1803 } 1804 1805 void Vt102Emulation::restoreCursor() 1806 { 1807 CHARSET.graphic = CHARSET.sa_graphic; 1808 CHARSET.pound = CHARSET.sa_pound; // This mode is obsolete 1809 _currentScreen->restoreCursor(); 1810 } 1811 1812 /* ------------------------------------------------------------------------- */ 1813 /* */ 1814 /* Mode Operations */ 1815 /* */ 1816 /* ------------------------------------------------------------------------- */ 1817 1818 /* 1819 Some of the emulations state is either added to the state of the screens. 1820 1821 This causes some scoping problems, since different emulations choose to 1822 located the mode either to the current _screen or to both. 1823 1824 For strange reasons, the extend of the rendition attributes ranges over 1825 all screens and not over the actual _screen. 1826 1827 We decided on the precise precise extend, somehow. 1828 */ 1829 1830 // "Mode" related part of the state. These are all booleans. 1831 1832 void Vt102Emulation::resetModes() 1833 { 1834 // MODE_Allow132Columns is not reset here 1835 // to match Xterm's behaviour (see Xterm's VTReset() function) 1836 1837 resetMode(MODE_132Columns); 1838 saveMode(MODE_132Columns); 1839 resetMode(MODE_Mouse1000); 1840 saveMode(MODE_Mouse1000); 1841 resetMode(MODE_Mouse1001); 1842 saveMode(MODE_Mouse1001); 1843 resetMode(MODE_Mouse1002); 1844 saveMode(MODE_Mouse1002); 1845 resetMode(MODE_Mouse1003); 1846 saveMode(MODE_Mouse1003); 1847 resetMode(MODE_Mouse1005); 1848 saveMode(MODE_Mouse1005); 1849 resetMode(MODE_Mouse1006); 1850 saveMode(MODE_Mouse1006); 1851 resetMode(MODE_Mouse1015); 1852 saveMode(MODE_Mouse1015); 1853 resetMode(MODE_BracketedPaste); 1854 saveMode(MODE_BracketedPaste); 1855 1856 resetMode(MODE_AppScreen); 1857 saveMode(MODE_AppScreen); 1858 resetMode(MODE_AppCuKeys); 1859 saveMode(MODE_AppCuKeys); 1860 resetMode(MODE_AppKeyPad); 1861 saveMode(MODE_AppKeyPad); 1862 resetMode(MODE_NewLine); 1863 setMode(MODE_Ansi); 1864 } 1865 1866 void Vt102Emulation::setMode(int m) 1867 { 1868 _currentModes.mode[m] = true; 1869 switch (m) { 1870 case MODE_132Columns: 1871 if (getMode(MODE_Allow132Columns)) 1872 clearScreenAndSetColumns(132); 1873 else 1874 _currentModes.mode[m] = false; 1875 break; 1876 case MODE_Mouse1000: 1877 case MODE_Mouse1001: 1878 case MODE_Mouse1002: 1879 case MODE_Mouse1003: 1880 Q_EMIT programUsesMouseChanged(false); 1881 break; 1882 1883 case MODE_BracketedPaste: 1884 Q_EMIT programBracketedPasteModeChanged(true); 1885 1886 break; 1887 1888 case MODE_AppScreen: 1889 _alternateScreen->clearSelection(); 1890 setScreen(1); 1891 break; 1892 } 1893 if (m < MODES_SCREEN || m == MODE_NewLine) { 1894 _primaryScreen->setMode(m); 1895 _alternateScreen->setMode(m); 1896 } 1897 } 1898 1899 void Vt102Emulation::resetMode(int m) 1900 { 1901 _currentModes.mode[m] = false; 1902 switch (m) { 1903 case MODE_132Columns: 1904 if (getMode(MODE_Allow132Columns)) 1905 clearScreenAndSetColumns(80); 1906 break; 1907 case MODE_Mouse1000: 1908 case MODE_Mouse1001: 1909 case MODE_Mouse1002: 1910 case MODE_Mouse1003: 1911 Q_EMIT programUsesMouseChanged(true); 1912 break; 1913 1914 case MODE_BracketedPaste: 1915 Q_EMIT programBracketedPasteModeChanged(false); 1916 break; 1917 1918 case MODE_AppScreen: 1919 _primaryScreen->clearSelection(); 1920 setScreen(0); 1921 break; 1922 } 1923 if (m < MODES_SCREEN || m == MODE_NewLine) { 1924 _primaryScreen->resetMode(m); 1925 _alternateScreen->resetMode(m); 1926 } 1927 } 1928 1929 void Vt102Emulation::saveMode(int m) 1930 { 1931 _savedModes.mode[m] = _currentModes.mode[m]; 1932 } 1933 1934 void Vt102Emulation::restoreMode(int m) 1935 { 1936 if (_savedModes.mode[m]) 1937 setMode(m); 1938 else 1939 resetMode(m); 1940 } 1941 1942 bool Vt102Emulation::getMode(int m) 1943 { 1944 return _currentModes.mode[m]; 1945 } 1946 1947 char Vt102Emulation::eraseChar() const 1948 { 1949 KeyboardTranslator::Entry entry = _keyTranslator->findEntry(Qt::Key_Backspace, Qt::NoModifier, KeyboardTranslator::NoState); 1950 if (entry.text().size() > 0) 1951 return entry.text().at(0); 1952 else 1953 return '\b'; 1954 } 1955 1956 void Vt102Emulation::reportDecodingError() 1957 { 1958 if (tokenBufferPos == 0 || (tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32)) 1959 return; 1960 qCDebug(qtermwidgetLogger) << "Undecodable sequence:" << QString::fromUtf16(tokenBuffer, tokenBufferPos); 1961 } 1962 1963 // #include "Vt102Emulation.moc"