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