• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Konsole

Vt102Emulation.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of Konsole, an X terminal.
00003     
00004     Copyright 2007-2008 by Robert Knight <robert.knight@gmail.com>
00005     Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00020     02110-1301  USA.
00021 */
00022 
00023 // Own
00024 #include "Vt102Emulation.h"
00025 
00026 // XKB
00027 #include <config-konsole.h>
00028 #if defined(__osf__) || defined(__APPLE__)
00029     #define AVOID_XKB
00030 #endif
00031 
00032 // this allows konsole to be compiled without XKB and XTEST extensions
00033 // even though it might be available on a particular system.
00034 #if defined(AVOID_XKB)
00035     #undef HAVE_XKB
00036 #endif
00037 
00038 #if defined(HAVE_XKB)
00039     void scrolllock_set_off();
00040     void scrolllock_set_on();
00041 #endif
00042 
00043 // Standard 
00044 #include <stdio.h>
00045 #include <unistd.h>
00046 #include <assert.h>
00047 
00048 // Qt
00049 #include <QtCore/QEvent>
00050 #include <QtGui/QKeyEvent>
00051 #include <QtCore/QByteRef>
00052 
00053 // KDE
00054 #include <kdebug.h>
00055 #include <klocale.h>
00056 
00057 // Konsole
00058 #include "KeyboardTranslator.h"
00059 #include "Screen.h"
00060 
00061 
00062 using namespace Konsole;
00063 
00064 Vt102Emulation::Vt102Emulation() 
00065     : Emulation(),
00066      _titleUpdateTimer(new QTimer(this))
00067 {
00068   _titleUpdateTimer->setSingleShot(true);
00069   QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle()));
00070 
00071   initTokenizer();
00072   reset();
00073 }
00074 
00075 Vt102Emulation::~Vt102Emulation()
00076 {}
00077 
00078 void Vt102Emulation::clearEntireScreen()
00079 {
00080   _currentScreen->clearEntireScreen();
00081   bufferedUpdate(); 
00082 }
00083 
00084 void Vt102Emulation::reset()
00085 {
00086   resetTokenizer();
00087   resetModes();
00088   resetCharset(0);
00089   _screen[0]->reset();
00090   resetCharset(1);
00091   _screen[1]->reset();
00092   setCodec(LocaleCodec);
00093  
00094   bufferedUpdate();
00095 }
00096 
00097 /* ------------------------------------------------------------------------- */
00098 /*                                                                           */
00099 /*                     Processing the incoming byte stream                   */
00100 /*                                                                           */
00101 /* ------------------------------------------------------------------------- */
00102 
00103 /* Incoming Bytes Event pipeline
00104 
00105    This section deals with decoding the incoming character stream.
00106    Decoding means here, that the stream is first separated into `tokens'
00107    which are then mapped to a `meaning' provided as operations by the
00108    `Screen' class or by the emulation class itself.
00109 
00110    The pipeline proceeds as follows:
00111 
00112    - Tokenizing the ESC codes (onReceiveChar)
00113    - VT100 code page translation of plain characters (applyCharset)
00114    - Interpretation of ESC codes (processToken)
00115 
00116    The escape codes and their meaning are described in the
00117    technical reference of this program.
00118 */
00119 
00120 // Tokens ------------------------------------------------------------------ --
00121 
00122 /*
00123    Since the tokens are the central notion if this section, we've put them
00124    in front. They provide the syntactical elements used to represent the
00125    terminals operations as byte sequences.
00126 
00127    They are encodes here into a single machine word, so that we can later
00128    switch over them easily. Depending on the token itself, additional
00129    argument variables are filled with parameter values.
00130 
00131    The tokens are defined below:
00132 
00133    - CHR        - Printable characters     (32..255 but DEL (=127))
00134    - CTL        - Control characters       (0..31 but ESC (= 27), DEL)
00135    - ESC        - Escape codes of the form <ESC><CHR but `[]()+*#'>
00136    - ESC_DE     - Escape codes of the form <ESC><any of `()+*#%'> C
00137    - CSI_PN     - Escape codes of the form <ESC>'['     {Pn} ';' {Pn} C
00138    - CSI_PS     - Escape codes of the form <ESC>'['     {Pn} ';' ...  C
00139    - CSI_PR     - Escape codes of the form <ESC>'[' '?' {Pn} ';' ...  C
00140    - CSI_PE     - Escape codes of the form <ESC>'[' '!' {Pn} ';' ...  C
00141    - VT52       - VT52 escape codes
00142                   - <ESC><Chr>
00143                   - <ESC>'Y'{Pc}{Pc}
00144    - XTE_HA     - Xterm window/terminal attribute commands 
00145                   of the form <ESC>`]' {Pn} `;' {Text} <BEL>
00146                   (Note that these are handled differently to the other formats)
00147 
00148    The last two forms allow list of arguments. Since the elements of
00149    the lists are treated individually the same way, they are passed
00150    as individual tokens to the interpretation. Further, because the
00151    meaning of the parameters are names (althought represented as numbers),
00152    they are includes within the token ('N').
00153 
00154 */
00155 
00156 #define TY_CONSTRUCT(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
00157 
00158 #define TY_CHR(   )     TY_CONSTRUCT(0,0,0)
00159 #define TY_CTL(A  )     TY_CONSTRUCT(1,A,0)
00160 #define TY_ESC(A  )     TY_CONSTRUCT(2,A,0)
00161 #define TY_ESC_CS(A,B)  TY_CONSTRUCT(3,A,B)
00162 #define TY_ESC_DE(A  )  TY_CONSTRUCT(4,A,0)
00163 #define TY_CSI_PS(A,N)  TY_CONSTRUCT(5,A,N)
00164 #define TY_CSI_PN(A  )  TY_CONSTRUCT(6,A,0)
00165 #define TY_CSI_PR(A,N)  TY_CONSTRUCT(7,A,N)
00166 
00167 #define TY_VT52(A)    TY_CONSTRUCT(8,A,0)
00168 #define TY_CSI_PG(A)  TY_CONSTRUCT(9,A,0)
00169 #define TY_CSI_PE(A)  TY_CONSTRUCT(10,A,0)
00170 
00171 #define MAX_ARGUMENT 4096
00172 
00173 // Tokenizer --------------------------------------------------------------- --
00174 
00175 /* The tokenizer's state
00176 
00177    The state is represented by the buffer (tokenBuffer, tokenBufferPos),
00178    and accompanied by decoded arguments kept in (argv,argc).
00179    Note that they are kept internal in the tokenizer.
00180 */
00181 
00182 void Vt102Emulation::resetTokenizer()
00183 {
00184   tokenBufferPos = 0; 
00185   argc = 0; 
00186   argv[0] = 0; 
00187   argv[1] = 0;
00188 }
00189 
00190 void Vt102Emulation::addDigit(int digit)
00191 {
00192   if (argv[argc] < MAX_ARGUMENT)
00193       argv[argc] = 10*argv[argc] + digit;
00194 }
00195 
00196 void Vt102Emulation::addArgument()
00197 {
00198   argc = qMin(argc+1,MAXARGS-1);
00199   argv[argc] = 0;
00200 }
00201 
00202 void Vt102Emulation::addToCurrentToken(int cc)
00203 {
00204   tokenBuffer[tokenBufferPos] = cc;
00205   tokenBufferPos = qMin(tokenBufferPos+1,MAX_TOKEN_LENGTH-1);
00206 }
00207 
00208 // Character Class flags used while decoding
00209 
00210 #define CTL  1  // Control character
00211 #define CHR  2  // Printable character
00212 #define CPN  4  // TODO: Document me 
00213 #define DIG  8  // Digit
00214 #define SCS 16  // TODO: Document me  
00215 #define GRP 32  // TODO: Document me
00216 #define CPS 64  // Character which indicates end of window resize
00217                 // escape sequence '\e[8;<row>;<col>t'
00218 
00219 void Vt102Emulation::initTokenizer()
00220 { 
00221   int i; 
00222   quint8* s;
00223   for(i = 0;i < 256; i++) 
00224     charClass[i] = 0;
00225   for(i = 0;i < 32; i++) 
00226     charClass[i] |= CTL;
00227   for(i = 32;i < 256; i++) 
00228     charClass[i] |= CHR;
00229   for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; s++) 
00230     charClass[*s] |= CPN;
00231   // resize = \e[8;<row>;<col>t
00232   for(s = (quint8*)"t"; *s; s++) 
00233     charClass[*s] |= CPS;
00234   for(s = (quint8*)"0123456789"; *s; s++) 
00235     charClass[*s] |= DIG;
00236   for(s = (quint8*)"()+*%"; *s; s++) 
00237     charClass[*s] |= SCS;
00238   for(s = (quint8*)"()+*#[]%"; *s; s++) 
00239     charClass[*s] |= GRP;
00240 
00241   resetTokenizer();
00242 }
00243 
00244 /* Ok, here comes the nasty part of the decoder.
00245 
00246    Instead of keeping an explicit state, we deduce it from the
00247    token scanned so far. It is then immediately combined with
00248    the current character to form a scanning decision.
00249 
00250    This is done by the following defines.
00251 
00252    - P is the length of the token scanned so far.
00253    - L (often P-1) is the position on which contents we base a decision.
00254    - C is a character or a group of characters (taken from 'charClass').
00255    
00256    - 'cc' is the current character
00257    - 's' is a pointer to the start of the token buffer
00258    - 'p' is the current position within the token buffer 
00259 
00260    Note that they need to applied in proper order.
00261 */
00262 
00263 #define lec(P,L,C) (p == (P) && s[(L)] == (C))
00264 #define lun(     ) (p ==  1  && cc >= 32 )
00265 #define les(P,L,C) (p == (P) && s[L] < 256 && (charClass[s[(L)]] & (C)) == (C))
00266 #define eec(C)     (p >=  3  && cc == (C))
00267 #define ees(C)     (p >=  3  && cc < 256 && (charClass[cc] & (C)) == (C))
00268 #define eps(C)     (p >=  3  && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (charClass[cc] & (C)) == (C))
00269 #define epp( )     (p >=  3  && s[2] == '?')
00270 #define epe( )     (p >=  3  && s[2] == '!')
00271 #define egt( )     (p >=  3  && s[2] == '>')
00272 #define Xpe        (tokenBufferPos >= 2 && tokenBuffer[1] == ']')
00273 #define Xte        (Xpe      && cc ==  7 )
00274 #define ces(C)     (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte)
00275 
00276 #define ESC 27
00277 #define CNTL(c) ((c)-'@')
00278 
00279 // process an incoming unicode character
00280 void Vt102Emulation::receiveChar(int cc)
00281 { 
00282   if (cc == 127) 
00283     return; //VT100: ignore.
00284 
00285   if (ces(CTL))
00286   { 
00287     // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
00288     // This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do
00289     // of course. Guess this originates from a weakly layered handling of the X-on
00290     // X-off protocol, which comes really below this level.
00291     if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) 
00292         resetTokenizer(); //VT100: CAN or SUB
00293     if (cc != ESC)    
00294     { 
00295         processToken(TY_CTL(cc+'@' ),0,0); 
00296         return; 
00297     }
00298   }
00299   // advance the state
00300   addToCurrentToken(cc); 
00301 
00302   int* s = tokenBuffer;
00303   int  p = tokenBufferPos;
00304 
00305   if (getMode(MODE_Ansi)) 
00306   {
00307     if (lec(1,0,ESC)) { return; }
00308     if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('['); return; }
00309     if (les(2,1,GRP)) { return; }
00310     if (Xte         ) { processWindowAttributeChange(); resetTokenizer(); return; }
00311     if (Xpe         ) { return; }
00312     if (lec(3,2,'?')) { return; }
00313     if (lec(3,2,'>')) { return; }
00314     if (lec(3,2,'!')) { return; }
00315     if (lun(       )) { processToken( TY_CHR(), applyCharset(cc), 0);   resetTokenizer(); return; }
00316     if (lec(2,0,ESC)) { processToken( TY_ESC(s[1]), 0, 0);              resetTokenizer(); return; }
00317     if (les(3,1,SCS)) { processToken( TY_ESC_CS(s[1],s[2]), 0, 0);      resetTokenizer(); return; }
00318     if (lec(3,1,'#')) { processToken( TY_ESC_DE(s[2]), 0, 0);           resetTokenizer(); return; }
00319     if (eps(    CPN)) { processToken( TY_CSI_PN(cc), argv[0],argv[1]);  resetTokenizer(); return; }
00320 
00321     // resize = \e[8;<row>;<col>t
00322     if (eps(CPS)) 
00323     { 
00324         processToken( TY_CSI_PS(cc, argv[0]), argv[1], argv[2]);   
00325         resetTokenizer(); 
00326         return; 
00327     }
00328 
00329     if (epe(   )) { processToken( TY_CSI_PE(cc), 0, 0); resetTokenizer(); return; }
00330     if (ees(DIG)) { addDigit(cc-'0'); return; }
00331     if (eec(';')) { addArgument();    return; }
00332     for (int i=0;i<=argc;i++)
00333     {
00334         if (epp())  
00335             processToken( TY_CSI_PR(cc,argv[i]), 0, 0);
00336         else if (egt())   
00337             processToken( TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c
00338         else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)
00339         { 
00340             // ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m
00341             i += 2;
00342             processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i+1] << 8) | argv[i+2]);
00343             i += 2;
00344         }
00345         else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 5)
00346         { 
00347             // ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m
00348             i += 2;
00349             processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]);
00350         }
00351         else
00352             processToken( TY_CSI_PS(cc,argv[i]), 0, 0);
00353     }
00354     resetTokenizer();
00355   }
00356   else 
00357   {
00358     // VT52 Mode
00359     if (lec(1,0,ESC))                                                      
00360         return;
00361     if (les(1,0,CHR)) 
00362     { 
00363         processToken( TY_CHR(), s[0], 0); 
00364         resetTokenizer(); 
00365         return; 
00366     }
00367     if (lec(2,1,'Y'))                                                      
00368         return;
00369     if (lec(3,1,'Y'))                                                      
00370         return;
00371     if (p < 4) 
00372     { 
00373         processToken( TY_VT52(s[1] ), 0, 0); 
00374         resetTokenizer(); 
00375         return; 
00376     }
00377     processToken( TY_VT52(s[1]), s[2], s[3]); 
00378     resetTokenizer(); 
00379     return;
00380   }
00381 }
00382 void Vt102Emulation::processWindowAttributeChange()
00383 {
00384   // Describes the window or terminal session attribute to change
00385   // See Session::UserTitleChange for possible values
00386   int attributeToChange = 0;
00387   int i;
00388   for (i = 2; i < tokenBufferPos     && 
00389               tokenBuffer[i] >= '0'  && 
00390               tokenBuffer[i] <= '9'; i++)
00391   {
00392     attributeToChange = 10 * attributeToChange + (tokenBuffer[i]-'0');
00393   }
00394 
00395   if (tokenBuffer[i] != ';') 
00396   { 
00397     reportDecodingError(); 
00398     return; 
00399   }
00400   
00401   QString newValue;
00402   newValue.reserve(tokenBufferPos-i-2);
00403   for (int j = 0; j < tokenBufferPos-i-2; j++)
00404     newValue[j] = tokenBuffer[i+1+j];
00405  
00406   _pendingTitleUpdates[attributeToChange] = newValue;
00407   _titleUpdateTimer->start(20);
00408 }
00409 
00410 void Vt102Emulation::updateTitle()
00411 {
00412     QListIterator<int> iter( _pendingTitleUpdates.keys() );
00413     while (iter.hasNext()) {
00414         int arg = iter.next();
00415         emit titleChanged( arg , _pendingTitleUpdates[arg] );    
00416     }
00417     _pendingTitleUpdates.clear();    
00418 }
00419 
00420 // Interpreting Codes ---------------------------------------------------------
00421 
00422 /*
00423    Now that the incoming character stream is properly tokenized,
00424    meaning is assigned to them. These are either operations of
00425    the current _screen, or of the emulation class itself.
00426 
00427    The token to be interpreteted comes in as a machine word
00428    possibly accompanied by two parameters.
00429 
00430    Likewise, the operations assigned to, come with up to two
00431    arguments. One could consider to make up a proper table
00432    from the function below.
00433 
00434    The technical reference manual provides more information
00435    about this mapping.
00436 */
00437 
00438 void Vt102Emulation::processToken(int token, int p, int q)
00439 {
00440   switch (token)
00441   {
00442 
00443     case TY_CHR(         ) : _currentScreen->displayCharacter     (p         ); break; //UTF16
00444 
00445     //             127 DEL    : ignored on input
00446 
00447     case TY_CTL('@'      ) : /* NUL: ignored                      */ break;
00448     case TY_CTL('A'      ) : /* SOH: ignored                      */ break;
00449     case TY_CTL('B'      ) : /* STX: ignored                      */ break;
00450     case TY_CTL('C'      ) : /* ETX: ignored                      */ break;
00451     case TY_CTL('D'      ) : /* EOT: ignored                      */ break;
00452     case TY_CTL('E'      ) :      reportAnswerBack     (          ); break; //VT100
00453     case TY_CTL('F'      ) : /* ACK: ignored                      */ break;
00454     case TY_CTL('G'      ) : emit stateSet(NOTIFYBELL);
00455                                 break; //VT100
00456     case TY_CTL('H'      ) : _currentScreen->backspace            (          ); break; //VT100
00457     case TY_CTL('I'      ) : _currentScreen->tab                  (          ); break; //VT100
00458     case TY_CTL('J'      ) : _currentScreen->newLine              (          ); break; //VT100
00459     case TY_CTL('K'      ) : _currentScreen->newLine              (          ); break; //VT100
00460     case TY_CTL('L'      ) : _currentScreen->newLine              (          ); break; //VT100
00461     case TY_CTL('M'      ) : _currentScreen->toStartOfLine        (          ); break; //VT100
00462 
00463     case TY_CTL('N'      ) :      useCharset           (         1); break; //VT100
00464     case TY_CTL('O'      ) :      useCharset           (         0); break; //VT100
00465 
00466     case TY_CTL('P'      ) : /* DLE: ignored                      */ break;
00467     case TY_CTL('Q'      ) : /* DC1: XON continue                 */ break; //VT100
00468     case TY_CTL('R'      ) : /* DC2: ignored                      */ break;
00469     case TY_CTL('S'      ) : /* DC3: XOFF halt                    */ break; //VT100
00470     case TY_CTL('T'      ) : /* DC4: ignored                      */ break;
00471     case TY_CTL('U'      ) : /* NAK: ignored                      */ break;
00472     case TY_CTL('V'      ) : /* SYN: ignored                      */ break;
00473     case TY_CTL('W'      ) : /* ETB: ignored                      */ break;
00474     case TY_CTL('X'      ) : _currentScreen->displayCharacter     (    0x2592); break; //VT100
00475     case TY_CTL('Y'      ) : /* EM : ignored                      */ break;
00476     case TY_CTL('Z'      ) : _currentScreen->displayCharacter     (    0x2592); break; //VT100
00477     case TY_CTL('['      ) : /* ESC: cannot be seen here.         */ break;
00478     case TY_CTL('\\'     ) : /* FS : ignored                      */ break;
00479     case TY_CTL(']'      ) : /* GS : ignored                      */ break;
00480     case TY_CTL('^'      ) : /* RS : ignored                      */ break;
00481     case TY_CTL('_'      ) : /* US : ignored                      */ break;
00482 
00483     case TY_ESC('D'      ) : _currentScreen->index                (          ); break; //VT100
00484     case TY_ESC('E'      ) : _currentScreen->nextLine             (          ); break; //VT100
00485     case TY_ESC('H'      ) : _currentScreen->changeTabStop        (true      ); break; //VT100
00486     case TY_ESC('M'      ) : _currentScreen->reverseIndex         (          ); break; //VT100
00487     case TY_ESC('Z'      ) :      reportTerminalType   (          ); break;
00488     case TY_ESC('c'      ) :      reset                (          ); break;
00489 
00490     case TY_ESC('n'      ) :      useCharset           (         2); break;
00491     case TY_ESC('o'      ) :      useCharset           (         3); break;
00492     case TY_ESC('7'      ) :      saveCursor           (          ); break;
00493     case TY_ESC('8'      ) :      restoreCursor        (          ); break;
00494 
00495     case TY_ESC('='      ) :          setMode      (MODE_AppKeyPad); break;
00496     case TY_ESC('>'      ) :        resetMode      (MODE_AppKeyPad); break;
00497     case TY_ESC('<'      ) :          setMode      (MODE_Ansi     ); break; //VT100
00498 
00499     case TY_ESC_CS('(', '0') :      setCharset           (0,    '0'); break; //VT100
00500     case TY_ESC_CS('(', 'A') :      setCharset           (0,    'A'); break; //VT100
00501     case TY_ESC_CS('(', 'B') :      setCharset           (0,    'B'); break; //VT100
00502 
00503     case TY_ESC_CS(')', '0') :      setCharset           (1,    '0'); break; //VT100
00504     case TY_ESC_CS(')', 'A') :      setCharset           (1,    'A'); break; //VT100
00505     case TY_ESC_CS(')', 'B') :      setCharset           (1,    'B'); break; //VT100
00506 
00507     case TY_ESC_CS('*', '0') :      setCharset           (2,    '0'); break; //VT100
00508     case TY_ESC_CS('*', 'A') :      setCharset           (2,    'A'); break; //VT100
00509     case TY_ESC_CS('*', 'B') :      setCharset           (2,    'B'); break; //VT100
00510 
00511     case TY_ESC_CS('+', '0') :      setCharset           (3,    '0'); break; //VT100
00512     case TY_ESC_CS('+', 'A') :      setCharset           (3,    'A'); break; //VT100
00513     case TY_ESC_CS('+', 'B') :      setCharset           (3,    'B'); break; //VT100
00514 
00515     case TY_ESC_CS('%', 'G') :      setCodec             (Utf8Codec   ); break; //LINUX
00516     case TY_ESC_CS('%', '@') :      setCodec             (LocaleCodec ); break; //LINUX
00517 
00518     case TY_ESC_DE('3'      ) : /* Double height line, top half    */ 
00519                                 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
00520                                 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
00521                                     break;
00522     case TY_ESC_DE('4'      ) : /* Double height line, bottom half */ 
00523                                 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
00524                                 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
00525                                     break;
00526     case TY_ESC_DE('5'      ) : /* Single width, single height line*/
00527                                 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , false);
00528                                 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
00529                                 break;
00530     case TY_ESC_DE('6'      ) : /* Double width, single height line*/ 
00531                                 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true);    
00532                                 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
00533                                 break;
00534     case TY_ESC_DE('8'      ) : _currentScreen->helpAlign            (          ); break;
00535 
00536 // resize = \e[8;<row>;<col>t
00537     case TY_CSI_PS('t',   8) : setImageSize( q /* colums */, p /* lines */ );    break;
00538 
00539 // change tab text color : \e[28;<color>t  color: 0-16,777,215
00540     case TY_CSI_PS('t',   28) : emit changeTabTextColorRequest      ( p        );          break;
00541 
00542     case TY_CSI_PS('K',   0) : _currentScreen->clearToEndOfLine     (          ); break;
00543     case TY_CSI_PS('K',   1) : _currentScreen->clearToBeginOfLine   (          ); break;
00544     case TY_CSI_PS('K',   2) : _currentScreen->clearEntireLine      (          ); break;
00545     case TY_CSI_PS('J',   0) : _currentScreen->clearToEndOfScreen   (          ); break;
00546     case TY_CSI_PS('J',   1) : _currentScreen->clearToBeginOfScreen (          ); break;
00547     case TY_CSI_PS('J',   2) : _currentScreen->clearEntireScreen    (          ); break;
00548     case TY_CSI_PS('J',      3) : clearHistory();                            break;
00549     case TY_CSI_PS('g',   0) : _currentScreen->changeTabStop        (false     ); break; //VT100
00550     case TY_CSI_PS('g',   3) : _currentScreen->clearTabStops        (          ); break; //VT100
00551     case TY_CSI_PS('h',   4) : _currentScreen->    setMode      (MODE_Insert   ); break;
00552     case TY_CSI_PS('h',  20) :          setMode      (MODE_NewLine  ); break;
00553     case TY_CSI_PS('i',   0) : /* IGNORE: attached printer          */ break; //VT100
00554     case TY_CSI_PS('l',   4) : _currentScreen->  resetMode      (MODE_Insert   ); break;
00555     case TY_CSI_PS('l',  20) :        resetMode      (MODE_NewLine  ); break;
00556     case TY_CSI_PS('s',   0) :      saveCursor           (          ); break;
00557     case TY_CSI_PS('u',   0) :      restoreCursor        (          ); break;
00558 
00559     case TY_CSI_PS('m',   0) : _currentScreen->setDefaultRendition  (          ); break;
00560     case TY_CSI_PS('m',   1) : _currentScreen->  setRendition     (RE_BOLD     ); break; //VT100
00561     case TY_CSI_PS('m',   4) : _currentScreen->  setRendition     (RE_UNDERLINE); break; //VT100
00562     case TY_CSI_PS('m',   5) : _currentScreen->  setRendition     (RE_BLINK    ); break; //VT100
00563     case TY_CSI_PS('m',   7) : _currentScreen->  setRendition     (RE_REVERSE  ); break;
00564     case TY_CSI_PS('m',  10) : /* IGNORED: mapping related          */ break; //LINUX
00565     case TY_CSI_PS('m',  11) : /* IGNORED: mapping related          */ break; //LINUX
00566     case TY_CSI_PS('m',  12) : /* IGNORED: mapping related          */ break; //LINUX
00567     case TY_CSI_PS('m',  22) : _currentScreen->resetRendition     (RE_BOLD     ); break;
00568     case TY_CSI_PS('m',  24) : _currentScreen->resetRendition     (RE_UNDERLINE); break;
00569     case TY_CSI_PS('m',  25) : _currentScreen->resetRendition     (RE_BLINK    ); break;
00570     case TY_CSI_PS('m',  27) : _currentScreen->resetRendition     (RE_REVERSE  ); break;
00571 
00572     case TY_CSI_PS('m',   30) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  0); break;
00573     case TY_CSI_PS('m',   31) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  1); break;
00574     case TY_CSI_PS('m',   32) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  2); break;
00575     case TY_CSI_PS('m',   33) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  3); break;
00576     case TY_CSI_PS('m',   34) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  4); break;
00577     case TY_CSI_PS('m',   35) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  5); break;
00578     case TY_CSI_PS('m',   36) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  6); break;
00579     case TY_CSI_PS('m',   37) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  7); break;
00580 
00581     case TY_CSI_PS('m',   38) : _currentScreen->setForeColor         (p,       q); break;
00582 
00583     case TY_CSI_PS('m',   39) : _currentScreen->setForeColor         (COLOR_SPACE_DEFAULT,  0); break;
00584 
00585     case TY_CSI_PS('m',   40) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  0); break;
00586     case TY_CSI_PS('m',   41) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  1); break;
00587     case TY_CSI_PS('m',   42) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  2); break;
00588     case TY_CSI_PS('m',   43) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  3); break;
00589     case TY_CSI_PS('m',   44) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  4); break;
00590     case TY_CSI_PS('m',   45) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  5); break;
00591     case TY_CSI_PS('m',   46) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  6); break;
00592     case TY_CSI_PS('m',   47) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  7); break;
00593 
00594     case TY_CSI_PS('m',   48) : _currentScreen->setBackColor         (p,       q); break;
00595 
00596     case TY_CSI_PS('m',   49) : _currentScreen->setBackColor         (COLOR_SPACE_DEFAULT,  1); break;
00597 
00598     case TY_CSI_PS('m',   90) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  8); break;
00599     case TY_CSI_PS('m',   91) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  9); break;
00600     case TY_CSI_PS('m',   92) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 10); break;
00601     case TY_CSI_PS('m',   93) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 11); break;
00602     case TY_CSI_PS('m',   94) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 12); break;
00603     case TY_CSI_PS('m',   95) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 13); break;
00604     case TY_CSI_PS('m',   96) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 14); break;
00605     case TY_CSI_PS('m',   97) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 15); break;
00606 
00607     case TY_CSI_PS('m',  100) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  8); break;
00608     case TY_CSI_PS('m',  101) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  9); break;
00609     case TY_CSI_PS('m',  102) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 10); break;
00610     case TY_CSI_PS('m',  103) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 11); break;
00611     case TY_CSI_PS('m',  104) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 12); break;
00612     case TY_CSI_PS('m',  105) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 13); break;
00613     case TY_CSI_PS('m',  106) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 14); break;
00614     case TY_CSI_PS('m',  107) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 15); break;
00615 
00616     case TY_CSI_PS('n',   5) :      reportStatus         (          ); break;
00617     case TY_CSI_PS('n',   6) :      reportCursorPosition (          ); break;
00618     case TY_CSI_PS('q',   0) : /* IGNORED: LEDs off                 */ break; //VT100
00619     case TY_CSI_PS('q',   1) : /* IGNORED: LED1 on                  */ break; //VT100
00620     case TY_CSI_PS('q',   2) : /* IGNORED: LED2 on                  */ break; //VT100
00621     case TY_CSI_PS('q',   3) : /* IGNORED: LED3 on                  */ break; //VT100
00622     case TY_CSI_PS('q',   4) : /* IGNORED: LED4 on                  */ break; //VT100
00623     case TY_CSI_PS('x',   0) :      reportTerminalParms  (         2); break; //VT100
00624     case TY_CSI_PS('x',   1) :      reportTerminalParms  (         3); break; //VT100
00625 
00626     case TY_CSI_PN('@'      ) : _currentScreen->insertChars          (p         ); break;
00627     case TY_CSI_PN('A'      ) : _currentScreen->cursorUp             (p         ); break; //VT100
00628     case TY_CSI_PN('B'      ) : _currentScreen->cursorDown           (p         ); break; //VT100
00629     case TY_CSI_PN('C'      ) : _currentScreen->cursorRight          (p         ); break; //VT100
00630     case TY_CSI_PN('D'      ) : _currentScreen->cursorLeft           (p         ); break; //VT100
00631     case TY_CSI_PN('G'      ) : _currentScreen->setCursorX           (p         ); break; //LINUX
00632     case TY_CSI_PN('H'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100
00633     case TY_CSI_PN('I'      ) : _currentScreen->tab                  (p         ); break;
00634     case TY_CSI_PN('L'      ) : _currentScreen->insertLines          (p         ); break;
00635     case TY_CSI_PN('M'      ) : _currentScreen->deleteLines          (p         ); break;
00636     case TY_CSI_PN('P'      ) : _currentScreen->deleteChars          (p         ); break;
00637     case TY_CSI_PN('S'      ) : _currentScreen->scrollUp             (p         ); break;
00638     case TY_CSI_PN('T'      ) : _currentScreen->scrollDown           (p         ); break;
00639     case TY_CSI_PN('X'      ) : _currentScreen->eraseChars           (p         ); break;
00640     case TY_CSI_PN('Z'      ) : _currentScreen->backtab              (p         ); break;
00641     case TY_CSI_PN('c'      ) :      reportTerminalType   (          ); break; //VT100
00642     case TY_CSI_PN('d'      ) : _currentScreen->setCursorY           (p         ); break; //LINUX
00643     case TY_CSI_PN('f'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100
00644     case TY_CSI_PN('r'      ) :      setMargins           (p,      q); break; //VT100
00645     case TY_CSI_PN('y'      ) : /* IGNORED: Confidence test          */ break; //VT100
00646 
00647     case TY_CSI_PR('h',   1) :          setMode      (MODE_AppCuKeys); break; //VT100
00648     case TY_CSI_PR('l',   1) :        resetMode      (MODE_AppCuKeys); break; //VT100
00649     case TY_CSI_PR('s',   1) :         saveMode      (MODE_AppCuKeys); break; //FIXME
00650     case TY_CSI_PR('r',   1) :      restoreMode      (MODE_AppCuKeys); break; //FIXME
00651 
00652     case TY_CSI_PR('l',   2) :        resetMode      (MODE_Ansi     ); break; //VT100
00653 
00654     case TY_CSI_PR('h',   3) :          setMode      (MODE_132Columns);break; //VT100
00655     case TY_CSI_PR('l',   3) :        resetMode      (MODE_132Columns);break; //VT100
00656 
00657     case TY_CSI_PR('h',   4) : /* IGNORED: soft scrolling           */ break; //VT100
00658     case TY_CSI_PR('l',   4) : /* IGNORED: soft scrolling           */ break; //VT100
00659 
00660     case TY_CSI_PR('h',   5) : _currentScreen->    setMode      (MODE_Screen   ); break; //VT100
00661     case TY_CSI_PR('l',   5) : _currentScreen->  resetMode      (MODE_Screen   ); break; //VT100
00662 
00663     case TY_CSI_PR('h',   6) : _currentScreen->    setMode      (MODE_Origin   ); break; //VT100
00664     case TY_CSI_PR('l',   6) : _currentScreen->  resetMode      (MODE_Origin   ); break; //VT100
00665     case TY_CSI_PR('s',   6) : _currentScreen->   saveMode      (MODE_Origin   ); break; //FIXME
00666     case