• Skip to content
  • Skip to link menu
KDE 4.1 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 #include <config-konsole.h>
00027 
00028 
00029 #if defined(__osf__) || defined(__APPLE__)
00030 #define AVOID_XKB
00031 #endif
00032 
00033 // this allows konsole to be compiled without XKB and XTEST extensions
00034 // even though it might be available on a particular system.
00035 #if defined(AVOID_XKB)
00036 #undef HAVE_XKB
00037 #endif
00038 
00039 // Standard 
00040 #include <stdio.h>
00041 #include <unistd.h>
00042 #include <assert.h>
00043 
00044 // Qt
00045 #include <QtCore/QEvent>
00046 #include <QtGui/QKeyEvent>
00047 #include <QtCore/QByteRef>
00048 
00049 // KDE
00050 #include <kdebug.h>
00051 #include <klocale.h>
00052 
00053 // Konsole
00054 #include "KeyboardTranslator.h"
00055 #include "Screen.h"
00056 
00057 #if defined(HAVE_XKB)
00058 void scrolllock_set_off();
00059 void scrolllock_set_on();
00060 #endif
00061 
00062 using namespace Konsole;
00063 
00064 /* VT102 Terminal Emulation
00065 
00066    This class puts together the screens, the pty and the widget to a
00067    complete terminal emulation. Beside combining it's componentes, it
00068    handles the emulations's protocol.
00069 
00070    This module consists of the following sections:
00071 
00072    - Constructor/Destructor
00073    - Incoming Bytes Event pipeline
00074    - Outgoing Bytes
00075      - Mouse Events
00076      - Keyboard Events
00077    - Modes and Charset State
00078    - Diagnostics
00079 */
00080 
00081 /* ------------------------------------------------------------------------- */
00082 /*                                                                           */
00083 /*                       Constructor / Destructor                            */
00084 /*                                                                           */
00085 /* ------------------------------------------------------------------------- */
00086 
00087 
00088 Vt102Emulation::Vt102Emulation() 
00089     : Emulation(),
00090      _titleUpdateTimer(new QTimer(this))
00091 {
00092   _titleUpdateTimer->setSingleShot(true);
00093 
00094   QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle()));
00095 
00096   initTokenizer();
00097   reset();
00098 }
00099 
00100 DECpar::DECpar()
00101 {
00102     memset(&mode,false,MODE_total * sizeof(bool));
00103 }
00104 
00105 Vt102Emulation::~Vt102Emulation()
00106 {
00107 }
00108 
00109 void Vt102Emulation::clearEntireScreen()
00110 {
00111   _currentScreen->clearEntireScreen();
00112 
00113   bufferedUpdate(); 
00114 }
00115 
00116 void Vt102Emulation::reset()
00117 {
00118   resetToken();
00119   resetModes();
00120   resetCharset(0);
00121   _screen[0]->reset();
00122   resetCharset(1);
00123   _screen[1]->reset();
00124   setCodec(LocaleCodec);
00125  
00126   bufferedUpdate();
00127 }
00128 
00129 /* ------------------------------------------------------------------------- */
00130 /*                                                                           */
00131 /*                     Processing the incoming byte stream                   */
00132 /*                                                                           */
00133 /* ------------------------------------------------------------------------- */
00134 
00135 /* Incoming Bytes Event pipeline
00136 
00137    This section deals with decoding the incoming character stream.
00138    Decoding means here, that the stream is first separated into `tokens'
00139    which are then mapped to a `meaning' provided as operations by the
00140    `Screen' class or by the emulation class itself.
00141 
00142    The pipeline proceeds as follows:
00143 
00144    - Tokenizing the ESC codes (onReceiveChar)
00145    - VT100 code page translation of plain characters (applyCharset)
00146    - Interpretation of ESC codes (tau)
00147 
00148    The escape codes and their meaning are described in the
00149    technical reference of this program.
00150 */
00151 
00152 // Tokens ------------------------------------------------------------------ --
00153 
00154 /*
00155    Since the tokens are the central notion if this section, we've put them
00156    in front. They provide the syntactical elements used to represent the
00157    terminals operations as byte sequences.
00158 
00159    They are encodes here into a single machine word, so that we can later
00160    switch over them easily. Depending on the token itself, additional
00161    argument variables are filled with parameter values.
00162 
00163    The tokens are defined below:
00164 
00165    - CHR        - Printable characters     (32..255 but DEL (=127))
00166    - CTL        - Control characters       (0..31 but ESC (= 27), DEL)
00167    - ESC        - Escape codes of the form <ESC><CHR but `[]()+*#'>
00168    - ESC_DE     - Escape codes of the form <ESC><any of `()+*#%'> C
00169    - CSI_PN     - Escape codes of the form <ESC>'['     {Pn} ';' {Pn} C
00170    - CSI_PS     - Escape codes of the form <ESC>'['     {Pn} ';' ...  C
00171    - CSI_PR     - Escape codes of the form <ESC>'[' '?' {Pn} ';' ...  C
00172    - CSI_PE     - Escape codes of the form <ESC>'[' '!' {Pn} ';' ...  C
00173    - VT52       - VT52 escape codes
00174                   - <ESC><Chr>
00175                   - <ESC>'Y'{Pc}{Pc}
00176    - XTE_HA     - Xterm hacks              <ESC>`]' {Pn} `;' {Text} <BEL>
00177                   note that this is handled differently
00178 
00179    The last two forms allow list of arguments. Since the elements of
00180    the lists are treated individually the same way, they are passed
00181    as individual tokens to the interpretation. Further, because the
00182    meaning of the parameters are names (althought represented as numbers),
00183    they are includes within the token ('N').
00184 
00185 */
00186 
00187 #define TY_CONSTR(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
00188 
00189 #define TY_CHR(   )     TY_CONSTR(0,0,0)
00190 #define TY_CTL(A  )     TY_CONSTR(1,A,0)
00191 #define TY_ESC(A  )     TY_CONSTR(2,A,0)
00192 #define TY_ESC_CS(A,B)  TY_CONSTR(3,A,B)
00193 #define TY_ESC_DE(A  )  TY_CONSTR(4,A,0)
00194 #define TY_CSI_PS(A,N)  TY_CONSTR(5,A,N)
00195 #define TY_CSI_PN(A  )  TY_CONSTR(6,A,0)
00196 #define TY_CSI_PR(A,N)  TY_CONSTR(7,A,N)
00197 
00198 #define TY_VT52(A  )    TY_CONSTR(8,A,0)
00199 
00200 #define TY_CSI_PG(A  )  TY_CONSTR(9,A,0)
00201 
00202 #define TY_CSI_PE(A  )  TY_CONSTR(10,A,0)
00203 
00204 #define MAX_ARGUMENT    4096
00205 
00206 // Tokenizer --------------------------------------------------------------- --
00207 
00208 /* The tokenizers state
00209 
00210    The state is represented by the buffer (pbuf, ppos),
00211    and accompanied by decoded arguments kept in (argv,argc).
00212    Note that they are kept internal in the tokenizer.
00213 */
00214 
00215 void Vt102Emulation::resetToken()
00216 {
00217   ppos = 0; argc = 0; argv[0] = 0; argv[1] = 0;
00218 }
00219 
00220 void Vt102Emulation::addDigit(int dig)
00221 {
00222   if (argv[argc] < MAX_ARGUMENT)
00223       argv[argc] = 10*argv[argc] + dig;
00224 }
00225 
00226 void Vt102Emulation::addArgument()
00227 {
00228   argc = qMin(argc+1,MAXARGS-1);
00229   argv[argc] = 0;
00230 }
00231 
00232 void Vt102Emulation::pushToToken(int cc)
00233 {
00234   pbuf[ppos] = cc;
00235   ppos = qMin(ppos+1,MAXPBUF-1);
00236 }
00237 
00238 // Character Classes used while decoding
00239 
00240 #define CTL  1
00241 #define CHR  2
00242 #define CPN  4
00243 #define DIG  8
00244 #define SCS 16
00245 #define GRP 32
00246 #define CPS 64
00247 
00248 void Vt102Emulation::initTokenizer()
00249 { int i; quint8* s;
00250   for(i =  0;                      i < 256; i++) tbl[ i]  = 0;
00251   for(i =  0;                      i <  32; i++) tbl[ i] |= CTL;
00252   for(i = 32;                      i < 256; i++) tbl[ i] |= CHR;
00253   for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; s++) tbl[*s] |= CPN;
00254 // resize = \e[8;<row>;<col>t
00255   for(s = (quint8*)"t"; *s; s++) tbl[*s] |= CPS;
00256   for(s = (quint8*)"0123456789"        ; *s; s++) tbl[*s] |= DIG;
00257   for(s = (quint8*)"()+*%"             ; *s; s++) tbl[*s] |= SCS;
00258   for(s = (quint8*)"()+*#[]%"          ; *s; s++) tbl[*s] |= GRP;
00259   resetToken();
00260 }
00261 
00262 /* Ok, here comes the nasty part of the decoder.
00263 
00264    Instead of keeping an explicit state, we deduce it from the
00265    token scanned so far. It is then immediately combined with
00266    the current character to form a scanning decision.
00267 
00268    This is done by the following defines.
00269 
00270    - P is the length of the token scanned so far.
00271    - L (often P-1) is the position on which contents we base a decision.
00272    - C is a character or a group of characters (taken from 'tbl').
00273 
00274    Note that they need to applied in proper order.
00275 */
00276 
00277 #define lec(P,L,C) (p == (P) &&                     s[(L)]         == (C))
00278 #define lun(     ) (p ==  1  &&                       cc           >= 32 )
00279 #define les(P,L,C) (p == (P) && s[L] < 256  && (tbl[s[(L)]] & (C)) == (C))
00280 #define eec(C)     (p >=  3  &&        cc                          == (C))
00281 #define ees(C)     (p >=  3  && cc < 256 &&    (tbl[  cc  ] & (C)) == (C))
00282 #define eps(C)     (p >=  3  && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (tbl[  cc  ] & (C)) == (C))
00283 #define epp( )     (p >=  3  && s[2] == '?'                              )
00284 #define epe( )     (p >=  3  && s[2] == '!'                              )
00285 #define egt(     ) (p >=  3  && s[2] == '>'                              )
00286 #define Xpe        (ppos>=2  && pbuf[1] == ']'                           )
00287 #define Xte        (Xpe                        &&     cc           ==  7 )
00288 #define ces(C)     (            cc < 256 &&    (tbl[  cc  ] & (C)) == (C) && !Xte)
00289 
00290 #define ESC 27
00291 #define CNTL(c) ((c)-'@')
00292 
00293 // process an incoming unicode character
00294 
00295 void Vt102Emulation::receiveChar(int cc)
00296 { 
00297   int i;
00298   if (cc == 127) return; //VT100: ignore.
00299 
00300   if (ces(    CTL))
00301   { // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
00302     // This means, they do neither a resetToken nor a pushToToken. Some of them, do
00303     // of course. Guess this originates from a weakly layered handling of the X-on
00304     // X-off protocol, which comes really below this level.
00305     if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken(); //VT100: CAN or SUB
00306     if (cc != ESC)    { tau( TY_CTL(cc+'@' ),   0,  0); return; }
00307   }
00308 
00309   pushToToken(cc); // advance the state
00310 
00311   int* s = pbuf;
00312   int  p = ppos;
00313 
00314   if (getMode(MODE_Ansi)) // decide on proper action
00315   {
00316     if (lec(1,0,ESC)) {                                                       return; }
00317     if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('[');                   return; }
00318     if (les(2,1,GRP)) {                                                       return; }
00319     if (Xte         ) { XtermHack();                            resetToken(); return; }
00320     if (Xpe         ) {                                                       return; }
00321     if (lec(3,2,'?')) {                                                       return; }
00322     if (lec(3,2,'>')) {                                                       return; }
00323     if (lec(3,2,'!')) {                                                       return; }
00324     if (lun(       )) { tau( TY_CHR(), applyCharset(cc), 0); resetToken(); return; }
00325     if (lec(2,0,ESC)) { tau( TY_ESC(s[1]),   0,  0);       resetToken(); return; }
00326     if (les(3,1,SCS)) { tau( TY_ESC_CS(s[1],s[2]),   0,  0);  resetToken(); return; }
00327     if (lec(3,1,'#')) { tau( TY_ESC_DE(s[2]),   0,  0);       resetToken(); return; }
00328     if (eps(    CPN)) { tau( TY_CSI_PN(cc), argv[0],argv[1]);   resetToken(); return; }
00329 
00330 // resize = \e[8;<row>;<col>t
00331     if (eps(    CPS)) { tau( TY_CSI_PS(cc, argv[0]), argv[1], argv[2]);   resetToken(); return; }
00332 
00333     if (epe(       )) { tau( TY_CSI_PE(cc),     0,  0);       resetToken(); return; }
00334     if (ees(    DIG)) { addDigit(cc-'0');                                     return; }
00335     if (eec(    ';')) { addArgument();                                        return; }
00336     for (i=0;i<=argc;i++)
00337     if ( epp(     ))  { tau( TY_CSI_PR(cc,argv[i]),   0,  0); }
00338     else if(egt(    ))   { tau( TY_CSI_PG(cc     ),   0,  0); } // spec. case for ESC]>0c or ESC]>c
00339     else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)
00340     { // ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m
00341       i += 2;
00342       tau( 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     { // ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m
00347       i += 2;
00348       tau( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]);
00349     }
00350     else              { tau( TY_CSI_PS(cc,argv[i]),   0,  0); }
00351     resetToken();
00352   }
00353   else // mode VT52
00354   {
00355     if (lec(1,0,ESC))                                                      return;
00356     if (les(1,0,CHR)) { tau( TY_CHR(       ), s[0],  0); resetToken(); return; }
00357     if (lec(2,1,'Y'))                                                      return;
00358     if (lec(3,1,'Y'))                                                      return;
00359     if (p < 4)        { tau( TY_VT52(s[1]   ),   0,  0); resetToken(); return; }
00360                         tau( TY_VT52(s[1]   ), s[2],s[3]); resetToken(); return;
00361   }
00362 }
00363 
00364 void Vt102Emulation::XtermHack()
00365 { int i,arg = 0;
00366   for (i = 2; i < ppos && '0'<=pbuf[i] && pbuf[i]<'9' ; i++)
00367     arg = 10*arg + (pbuf[i]-'0');
00368   if (pbuf[i] != ';') { ReportErrorToken(); return; }
00369   QChar *str = new QChar[ppos-i-2];
00370   for (int j = 0; j < ppos-i-2; j++) str[j] = pbuf[i+1+j];
00371   QString unistr(str,ppos-i-2);
00372   
00373   // arg == 1 doesn't change the title. In XTerm it only changes the icon name
00374   // (btw: arg=0 changes title and icon, arg=1 only icon, arg=2 only title
00375 //  emit changeTitle(arg,unistr);
00376   _pendingTitleUpdates[arg] = unistr;
00377   _titleUpdateTimer->start(20);
00378 
00379   delete [] str;
00380 }
00381 
00382 void Vt102Emulation::updateTitle()
00383 {
00384     QListIterator<int> iter( _pendingTitleUpdates.keys() );
00385     while (iter.hasNext()) {
00386         int arg = iter.next();
00387         emit titleChanged( arg , _pendingTitleUpdates[arg] );   
00388     }
00389 
00390     _pendingTitleUpdates.clear();   
00391 }
00392 
00393 // Interpreting Codes ---------------------------------------------------------
00394 
00395 /*
00396    Now that the incoming character stream is properly tokenized,
00397    meaning is assigned to them. These are either operations of
00398    the current _screen, or of the emulation class itself.
00399 
00400    The token to be interpreteted comes in as a machine word
00401    possibly accompanied by two parameters.
00402 
00403    Likewise, the operations assigned to, come with up to two
00404    arguments. One could consider to make up a proper table
00405    from the function below.
00406 
00407    The technical reference manual provides more information
00408    about this mapping.
00409 */
00410 
00411 void Vt102Emulation::tau( int token, int p, int q )
00412 {
00413 #if 0
00414 int N = (token>>0)&0xff;
00415 int A = (token>>8)&0xff;
00416 switch( N )
00417 {
00418    case 0: printf("%c", (p < 128) ? p : '?');
00419            break;
00420    case 1: if (A == 'J') printf("\r");
00421            else if (A == 'M') printf("\n");
00422            else printf("CTL-%c ", (token>>8)&0xff);
00423            break;
00424    case 2: printf("ESC-%c ", (token>>8)&0xff);
00425            break;
00426    case 3: printf("ESC_CS-%c-%c ", (token>>8)&0xff, (token>>16)&0xff);
00427            break;
00428    case 4: printf("ESC_DE-%c ", (token>>8)&0xff);
00429            break;
00430    case 5: printf("CSI-PS-%c-%d", (token>>8)&0xff, (token>>16)&0xff );
00431            break;
00432    case 6: printf("CSI-PN-%c [%d]", (token>>8)&0xff, p);
00433            break;
00434    case 7: printf("CSI-PR-%c-%d", (token>>8)&0xff, (token>>16)&0xff );
00435            break;
00436    case 8: printf("VT52-%c", (token>>8)&0xff);
00437            break;
00438    case 9: printf("CSI-PG-%c", (token>>8)&0xff);
00439            break;
00440    case 10: printf("CSI-PE-%c", (token>>8)&0xff);
00441            break;
00442 }
00443 #endif
00444 
00445   switch (token)
00446   {
00447 
00448     case TY_CHR(         ) : _currentScreen->displayCharacter     (p         ); break; //UTF16
00449 
00450     //             127 DEL    : ignored on input
00451 
00452     case TY_CTL('@'      ) : /* NUL: ignored                      */ break;
00453     case TY_CTL('A'      ) : /* SOH: ignored                      */ break;
00454     case TY_CTL('B'      ) : /* STX: ignored                      */ break;
00455     case TY_CTL('C'      ) : /* ETX: ignored                      */ break;
00456     case TY_CTL('D'      ) : /* EOT: ignored                      */ break;
00457     case TY_CTL('E'      ) :      reportAnswerBack     (          ); break; //VT100
00458     case TY_CTL('F'      ) : /* ACK: ignored                      */ break;
00459     case TY_CTL('G'      ) : emit stateSet(NOTIFYBELL);
00460                                 break; //VT100
00461     case TY_CTL('H'      ) : _currentScreen->backspace            (          ); break; //VT100
00462     case TY_CTL('I'      ) : _currentScreen->tab                  (          ); break; //VT100
00463     case TY_CTL('J'      ) : _currentScreen->newLine              (          ); break; //VT100
00464     case TY_CTL('K'      ) : _currentScreen->newLine              (          ); break; //VT100
00465     case TY_CTL('L'      ) : _currentScreen->newLine              (          ); break; //VT100
00466     case TY_CTL('M'      ) : _currentScreen->toStartOfLine        (          ); break; //VT100
00467 
00468     case TY_CTL('N'      ) :      useCharset           (         1); break; //VT100
00469     case TY_CTL('O'      ) :      useCharset           (         0); break; //VT100
00470 
00471     case TY_CTL('P'      ) : /* DLE: ignored                      */ break;
00472     case TY_CTL('Q'      ) : /* DC1: XON continue                 */ break; //VT100
00473     case TY_CTL('R'      ) : /* DC2: ignored                      */ break;
00474     case TY_CTL('S'      ) : /* DC3: XOFF halt                    */ break; //VT100
00475     case TY_CTL('T'      ) : /* DC4: ignored                      */ break;
00476     case TY_CTL('U'      ) : /* NAK: ignored                      */ break;
00477     case TY_CTL('V'      ) : /* SYN: ignored                      */ break;
00478     case TY_CTL('W'      ) : /* ETB: ignored                      */ break;
00479     case TY_CTL('X'      ) : _currentScreen->displayCharacter     (    0x2592); break; //VT100
00480     case TY_CTL('Y'      ) : /* EM : ignored                      */ break;
00481     case TY_CTL('Z'      ) : _currentScreen->displayCharacter     (    0x2592); break; //VT100
00482     case TY_CTL('['      ) : /* ESC: cannot be seen here.         */ break;
00483     case TY_CTL('\\'     ) : /* FS : ignored                      */ break;
00484     case TY_CTL(']'      ) : /* GS : ignored                      */ break;
00485     case TY_CTL('^'      ) : /* RS : ignored                      */ break;
00486     case TY_CTL('_'      ) : /* US : ignored                      */ break;
00487 
00488     case TY_ESC('D'      ) : _currentScreen->index                (          ); break; //VT100
00489     case TY_ESC('E'      ) : _currentScreen->nextLine             (          ); break; //VT100
00490     case TY_ESC('H'      ) : _currentScreen->changeTabStop        (true      ); break; //VT100
00491     case TY_ESC('M'      ) : _currentScreen->reverseIndex         (          ); break; //VT100
00492     case TY_ESC('Z'      ) :      reportTerminalType   (          ); break;
00493     case TY_ESC('c'      ) :      reset                (          ); break;
00494 
00495     case TY_ESC('n'      ) :      useCharset           (         2); break;
00496     case TY_ESC('o'      ) :      useCharset           (         3); break;
00497     case TY_ESC('7'      ) :      saveCursor           (          ); break;
00498     case TY_ESC('8'      ) :      restoreCursor        (          ); break;
00499 
00500     case TY_ESC('='      ) :          setMode      (MODE_AppKeyPad); break;
00501     case TY_ESC('>'      ) :        resetMode      (MODE_AppKeyPad); break;
00502     case TY_ESC('<'      ) :          setMode      (MODE_Ansi     ); break; //VT100
00503 
00504     case TY_ESC_CS('(', '0') :      setCharset           (0,    '0'); break; //VT100
00505     case TY_ESC_CS('(', 'A') :      setCharset           (0,    'A'); break; //VT100
00506     case TY_ESC_CS('(', 'B') :      setCharset           (0,    'B'); break; //VT100
00507 
00508     case TY_ESC_CS(')', '0') :      setCharset           (1,    '0'); break; //VT100
00509     case TY_ESC_CS(')', 'A') :      setCharset           (1,    'A'); break; //VT100
00510     case TY_ESC_CS(')', 'B') :      setCharset           (1,    'B'); break; //VT100
00511 
00512     case TY_ESC_CS('*', '0') :      setCharset           (2,    '0'); break; //VT100
00513     case TY_ESC_CS('*', 'A') :      setCharset           (2,    'A'); break; //VT100
00514     case TY_ESC_CS('*', 'B') :      setCharset           (2,    'B'); break; //VT100
00515 
00516     case TY_ESC_CS('+', '0') :      setCharset           (3,    '0'); break; //VT100
00517     case TY_ESC_CS('+', 'A') :      setCharset           (3,    'A'); break; //VT100
00518     case TY_ESC_CS('+', 'B') :      setCharset           (3,    'B'); break; //VT100
00519 
00520     case TY_ESC_CS('%', 'G') :      setCodec             (Utf8Codec   ); break; //LINUX
00521     case TY_ESC_CS('%', '@') :      setCodec             (LocaleCodec ); break; //LINUX
00522 
00523     case TY_ESC_DE('3'      ) : /* Double height line, top half    */ 
00524                                 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
00525                                 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
00526                                     break;
00527     case TY_ESC_DE('4'      ) : /* Double height line, bottom half */ 
00528                                 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
00529                                 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
00530                                     break;
00531     case TY_ESC_DE('5'      ) : /* Single width, single height line*/
00532                                 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , false);
00533                                 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
00534                                 break;
00535     case TY_ESC_DE('6'      ) : /* Double width, single height line*/ 
00536                                 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true);  
00537                                 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
00538                                 break;
00539     case TY_ESC_DE('8'      ) : _currentScreen->helpAlign            (          ); break;
00540 
00541 // resize = \e[8;<row>;<col>t
00542     case TY_CSI_PS('t',   8) : setImageSize( q /* colums */, p /* lines */ );    break;
00543 
00544 // change tab text color : \e[28;<color>t  color: 0-16,777,215
00545     case TY_CSI_PS('t',   28) : emit changeTabTextColorRequest      ( p        );          break;
00546 
00547     case TY_CSI_PS('K',   0) : _currentScreen->clearToEndOfLine     (          ); break;
00548     case TY_CSI_PS('K',   1) : _currentScreen->clearToBeginOfLine   (          ); break;
00549     case TY_CSI_PS('K',   2) : _currentScreen->clearEntireLine      (          ); break;
00550     case TY_CSI_PS('J',   0) : _currentScreen->clearToEndOfScreen   (          ); break;
00551     case TY_CSI_PS('J',   1) : _currentScreen->clearToBeginOfScreen (          ); break;
00552     case TY_CSI_PS('J',   2) : _currentScreen->clearEntireScreen    (          ); break;
00553     case TY_CSI_PS('J',   3) : clearHistory();                         break;
00554     case TY_CSI_PS('g',   0) : _currentScreen->changeTabStop        (false     ); break; //VT100
00555     case TY_CSI_PS('g',   3) : _currentScreen->clearTabStops        (          ); break; //VT100
00556     case TY_CSI_PS('h',   4) : _currentScreen->    setMode      (MODE_Insert   ); break;
00557     case TY_CSI_PS('h',  20) :          setMode      (MODE_NewLine  ); break;
00558     case TY_CSI_PS('i',   0) : /* IGNORE: attached printer          */ break; //VT100
00559     case TY_CSI_PS('l',   4) : _currentScreen->  resetMode      (MODE_Insert   ); break;
00560     case TY_CSI_PS('l',  20) :        resetMode      (MODE_NewLine  ); break;
00561     case TY_CSI_PS('s',   0) :      saveCursor           (          ); break;
00562     case TY_CSI_PS('u',   0) :      restoreCursor        (          ); break;
00563 
00564     case TY_CSI_PS('m',   0) : _currentScreen->setDefaultRendition  (          ); break;
00565     case TY_CSI_PS('m',   1) : _currentScreen->  setRendition     (RE_BOLD     ); break; //VT100
00566     case TY_CSI_PS('m',   4) : _currentScreen->  setRendition     (RE_UNDERLINE); break; //VT100
00567     case TY_CSI_PS('m',   5) : _currentScreen->  setRendition     (RE_BLINK    ); break; //VT100
00568     case TY_CSI_PS('m',   7) : _currentScreen->  setRendition     (RE_REVERSE  ); break;
00569     case TY_CSI_PS('m',  10) : /* IGNORED: mapping related          */ break; //LINUX
00570     case TY_CSI_PS('m',  11) : /* IGNORED: mapping related          */ break; //LINUX
00571     case TY_CSI_PS('m',  12) : /* IGNORED: mapping related          */ break; //LINUX
00572     case TY_CSI_PS('m',  22) : _currentScreen->resetRendition     (RE_BOLD     ); break;
00573     case TY_CSI_PS('m',  24) : _currentScreen->resetRendition     (RE_UNDERLINE); break;
00574     case TY_CSI_PS('m',  25) : _currentScreen->resetRendition     (RE_BLINK    ); break;
00575     case TY_CSI_PS('m',  27) : _currentScreen->resetRendition     (RE_REVERSE  ); break;
00576 
00577     case TY_CSI_PS('m',   30) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  0); break;
00578     case TY_CSI_PS('m',   31) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  1); break;
00579     case TY_CSI_PS('m',   32) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  2); break;
00580     case TY_CSI_PS('m',   33) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  3); break;
00581     case TY_CSI_PS('m',   34) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  4); break;
00582     case TY_CSI_PS('m',   35) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  5); break;
00583     case TY_CSI_PS('m',   36) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  6); break;
00584     case TY_CSI_PS('m',   37) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  7); break;
00585 
00586     case TY_CSI_PS('m',   38) : _currentScreen->setForeColor         (p,       q); break;
00587 
00588     case TY_CSI_PS('m',   39) : _currentScreen->setForeColor         (COLOR_SPACE_DEFAULT,  0); break;
00589 
00590     case TY_CSI_PS('m',   40) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  0); break;
00591     case TY_CSI_PS('m',   41) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  1); break;
00592     case TY_CSI_PS('m',   42) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  2); break;
00593     case TY_CSI_PS('m',   43) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  3); break;
00594     case TY_CSI_PS('m',   44) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  4); break;
00595     case TY_CSI_PS('m',   45) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  5); break;
00596     case TY_CSI_PS('m',   46) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  6); break;
00597     case TY_CSI_PS('m',   47) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  7); break;
00598 
00599     case TY_CSI_PS('m',   48) : _currentScreen->setBackColor         (p,       q); break;
00600 
00601     case TY_CSI_PS('m',   49) : _currentScreen->setBackColor         (COLOR_SPACE_DEFAULT,  1); break;
00602 
00603     case TY_CSI_PS('m',   90) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  8); break;
00604     case TY_CSI_PS('m',   91) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  9); break;
00605     case TY_CSI_PS('m',   92) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 10); break;
00606     case TY_CSI_PS('m',   93) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 11); break;
00607     case TY_CSI_PS('m',   94) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 12); break;
00608     case TY_CSI_PS('m',   95) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 13); break;
00609     case TY_CSI_PS('m',   96) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 14); break;
00610     case TY_CSI_PS('m',   97) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 15); break;
00611 
00612     case TY_CSI_PS('m',  100) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  8); break;
00613     case TY_CSI_PS('m',  101) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  9); break;
00614     case TY_CSI_PS('m',  102) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 10); break;
00615     case TY_CSI_PS('m',  103) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 11); break;
00616     case TY_CSI_PS('m',  104) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 12); break;
00617     case TY_CSI_PS('m',  105) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 13); break;
00618     case TY_CSI_PS('m',  106) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 14); break;
00619     case TY_CSI_PS('m',  107) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 15); break;
00620 
00621     case TY_CSI_PS('n',   5) :      reportStatus         (          ); break;
00622     case TY_CSI_PS('n',   6) :      reportCursorPosition (          ); break;
00623     case TY_CSI_PS('q',   0) : /* IGNORED: LEDs off                 */ break; //VT100
00624     case TY_CSI_PS('q',   1) : /* IGNORED: LED1 on                  */ break; //VT100
00625     case TY_CSI_PS('q',   2) : /* IGNORED: LED2 on                  */ break; //VT100
00626     case TY_CSI_PS('q',   3) : /* IGNORED: LED3 on                  */ break; //VT100
00627     case TY_CSI_PS('q',   4) : /* IGNORED: LED4 on                  */ break; //VT100
00628     case TY_CSI_PS('x',   0) :      reportTerminalParms  (         2); break; //VT100
00629     case TY_CSI_PS('x',   1) :      reportTerminalParms  (         3); break; //VT100
00630 
00631     case TY_CSI_PN('@'      ) : _currentScreen->insertChars          (p         ); break;
00632     case TY_CSI_PN('A'      ) : _currentScreen->cursorUp             (p         ); break; //VT100
00633     case TY_CSI_PN('B'      ) : _currentScreen->cursorDown           (p         ); break; //VT100
00634     case TY_CSI_PN('C'      ) : _currentScreen->cursorRight          (p         ); break; //VT100
00635     case TY_CSI_PN('D'      ) : _currentScreen->cursorLeft           (p         ); break; //VT100
00636     case TY_CSI_PN('G'      ) : _currentScreen->setCursorX           (p         ); break; //LINUX
00637     case TY_CSI_PN('H'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100
00638     case TY_CSI_PN('I'      ) : _currentScreen->tab                  (p         ); break;
00639     case TY_CSI_PN('L'      ) : _currentScreen->insertLines          (p         ); break;
00640     case TY_CSI_PN('M'      ) : _currentScreen->deleteLines          (p         ); break;
00641     case TY_CSI_PN('P'      ) : _currentScreen->deleteChars          (p         ); break;
00642     case TY_CSI_PN('S'      ) : _currentScreen->scrollUp             (p         ); break;
00643     case TY_CSI_PN('T'      ) : _currentScreen->scrollDown           (p         ); break;
00644     case TY_CSI_PN('X'      ) : _currentScreen->eraseChars           (p         ); break;
00645     case TY_CSI_PN('Z'      ) : _currentScreen->backtab              (p         ); break;
00646     case TY_CSI_PN('c'      ) :      reportTerminalType   (          ); break; //VT100
00647     case TY_CSI_PN('d'      ) : _currentScreen->setCursorY           (p         ); break; //LINUX
00648     case TY_CSI_PN('f'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100
00649     case TY_CSI_PN('r'      ) :      setMargins           (p,      q); break; //VT100
00650     case TY_CSI_PN('y'      ) : /* IGNORED: Confidence test          */ break; //VT100
00651 
00652     case TY_CSI_PR('h',   1) :          setMode      (MODE_AppCuKeys); break; //VT100
00653     case TY_CSI_PR('l',   1) :        resetMode      (MODE_AppCuKeys); break; //VT100
00654     case TY_CSI_PR('s',   1) :         saveMode      (MODE_AppCuKeys); break; //FIXME
00655     case TY_CSI_PR('r',   1) :      restoreMode      (MODE_AppCuKeys); break; //FIXME
00656 
00657     case TY_CSI_PR('l',   2) :        resetMode      (MODE_Ansi     ); break; //VT100
00658 
00659     case TY_CSI_PR('h',   3) :          setMode      (MODE_132Columns);break; //VT100
00660     case TY_CSI_PR('l',   3) :        resetMode      (MODE_132Columns);break; //VT100
00661 
00662     case TY_CSI_PR('h',   4) : /* IGNORED: soft scrolling           */ break; //VT100
00663     case TY_CSI_PR('l',   4) : /* IGNORED: soft scrolling           */ break; //VT100
00664 
00665     case TY_CSI_PR('h',   5) : _currentScreen->    setMode      (MODE_Screen   ); break; //VT100
00666     case TY_CSI_PR('l',   5) : _currentScreen->  resetMode      (MODE_Screen   ); break; //VT100
00667 
00668     case TY_CSI_PR('h',   6) : _currentScreen->    setMode      (MODE_Origin   ); break; //VT100
00669     case TY_CSI_PR('l',   6) : _currentScreen->  resetMode      (MODE_Origin   ); break; //VT100
00670     case TY_CSI_PR('s',   6) : _currentScreen->   saveMode      (MODE_Origin   ); break; //FIXME
00671     case TY_CSI_PR('r',   6) : _currentScreen->restoreMode      (MODE_Origin   ); break; //FIXME
00672 
00673     case TY_CSI_PR('h',   7) : _currentScreen->    setMode      (MODE_Wrap     ); break; //VT100
00674     case TY_CSI_PR('l',   7) : _currentScreen->  resetMode      (MODE_Wrap     ); break; //VT100
00675     case TY_CSI_PR('s',   7) : _currentScreen->   saveMode      (MODE_Wrap     ); break; //FIXME
00676     case TY_CSI_PR('r',   7) : _currentScreen->restoreMode      (MODE_Wrap     ); break; //FIXME
00677 
00678     case TY_CSI_PR('h',   8) : /* IGNORED: autorepeat on            */ break; //VT100
00679     case TY_CSI_PR('l',   8) : /* IGNORED: autorepeat off           */ break; //VT100
00680     case TY_CSI_PR('s',   8) : /* IGNORED: autorepeat on            */ break; //VT100
00681     case TY_CSI_PR('r',   8) : /* IGNORED: autorepeat off           */ break; //VT100
00682 
00683     case TY_CSI_PR('h',   9) : /* IGNORED: interlace                */ break; //VT100
00684     case TY_CSI_PR('l',   9) : /* IGNORED: interlace                */ break; //VT100
00685     case TY_CSI_PR('s',   9) : /* IGNORED: interlace                */ break; //VT100
00686     case TY_CSI_PR('r',   9) : /* IGNORED: interlace                */ break; //VT100
00687 
00688     case TY_CSI_PR('h',  12) : /* IGNORED: Cursor blink             */ break; //att610
00689     case TY_CSI_PR('l',  12) : /* IGNORED: Cursor blink             */ break; //att610
00690     case TY_CSI_PR('s',  12) : /* IGNORED: Cursor blink             */ break; //att610
00691     case TY_CSI_PR('r',  12) : /* IGNORED: Cursor blink             */ break; //att610
00692 
00693     case TY_CSI_PR('h',  25) :          setMode      (MODE_Cursor   ); break; //VT100
00694     case TY_CSI_PR('l',  25) :        resetMode      (MODE_Cursor   ); break; //VT100
00695     case TY_CSI_PR('s',  25) :         saveMode      (MODE_Cursor   ); break; //VT100
00696     case TY_CSI_PR('r',  25) :      restoreMode      (MODE_Cursor   ); break; //VT100
00697 
00698     case TY_CSI_PR('h',  40) :         setMode(MODE_Allow132Columns ); break; // XTERM
00699     case TY_CSI_PR('l',  40) :       resetMode(MODE_Allow132Columns ); break; // XTERM
00700 
00701     case TY_CSI_PR('h',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
00702     case TY_CSI_PR('l',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
00703     case TY_CSI_PR('s',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
00704     case TY_CSI_PR('r',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
00705 
00706     case TY_CSI_PR('h',  47) :          setMode      (MODE_AppScreen); break; //VT100
00707     case TY_CSI_PR('l',  47) :        resetMode      (MODE_AppScreen); break; //VT100
00708     case TY_CSI_PR('s',  47) :         saveMode      (MODE_AppScreen); break; //XTERM
00709     case TY_CSI_PR('r',  47) :      restoreMode      (MODE_AppScreen); break; //XTERM
00710 
00711     case TY_CSI_PR('h',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
00712     case TY_CSI_PR('l',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
00713     case TY_CSI_PR('s',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
00714     case TY_CSI_PR('r',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
00715 
00716     // XTerm defines the following modes:
00717     // SET_VT200_MOUSE             1000
00718     // SET_VT200_HIGHLIGHT_MOUSE   1001
00719     // SET_BTN_EVENT_MOUSE         1002
00720     // SET_ANY_EVENT_MOUSE         1003
00721     //
00722     
00723     //Note about mouse modes:
00724     //There are four mouse modes which xterm-compatible terminals can support - 1000,1001,1002,1003
00725     //Konsole currently supports mode 1000 (basic mouse press and release) and mode 1002 (dragging the mouse).
00726     //TODO:  Implementation of mouse modes 1001 (something called hilight tracking) and 
00727     //1003 (a slight variation on dragging the mouse)
00728     //
00729  
00730     case TY_CSI_PR('h', 1000) :          setMode      (MODE_Mouse1000); break; //XTERM
00731     case TY_CSI_PR('l', 1000) :        resetMode      (MODE_Mouse1000); break; //XTERM
00732     case TY_CSI_PR('s', 1000) :         saveMode      (MODE_Mouse1000); break; //XTERM
00733     case TY_CSI_PR('r', 1000) :      restoreMode      (MODE_Mouse1000); break; //XTERM
00734 
00735     case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
00736     case TY_CSI_PR('l', 1001) :        resetMode      (MODE_Mouse1001); break; //XTERM
00737     case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
00738     case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
00739 
00740     case TY_CSI_PR('h', 1002) :          setMode      (MODE_Mouse1002); break; //XTERM
00741     case TY_CSI_PR('l', 1002) :        resetMode      (MODE_Mouse1002); break; //XTERM
00742     case TY_CSI_PR('s', 1002) :         saveMode      (MODE_Mouse1002); break; //XTERM
00743     case TY_CSI_PR('r', 1002) :      restoreMode      (MODE_Mouse1002); break; //XTERM
00744 
00745     case TY_CSI_PR('h', 1003) :          setMode      (MODE_Mouse1003); break; //XTERM
00746     case TY_CSI_PR('l', 1003) :        resetMode      (MODE_Mouse1003); break; //XTERM
00747     case TY_CSI_PR('s', 1003) :         saveMode      (MODE_Mouse1003); break; //XTERM
00748     case TY_CSI_PR('r', 1003) :      restoreMode      (MODE_Mouse1003); break; //XTERM
00749 
00750     case TY_CSI_PR('h', 1047) :          setMode      (MODE_AppScreen); break; //XTERM
00751     case TY_CSI_PR('l', 1047) : _screen[1]->clearEntireScreen(); resetMode(MODE_AppScreen); break; //XTERM
00752     case TY_CSI_PR('s', 1047) :         saveMode      (MODE_AppScreen); break; //XTERM
00753     case TY_CSI_PR('r', 1047) :      restoreMode      (MODE_AppScreen); break; //XTERM
00754 
00755     //FIXME: Unitoken: save translations
00756     case TY_CSI_PR('h', 1048) :      saveCursor           (          ); break; //XTERM
00757     case TY_CSI_PR('l', 1048) :      restoreCursor        (          ); break; //XTERM
00758     case TY_CSI_PR('s', 1048) :      saveCursor           (          ); break; //XTERM
00759     case TY_CSI_PR('r', 1048) :      restoreCursor        (          ); break; //XTERM
00760 
00761     //FIXME: every once new sequences like this pop up in xterm.
00762     //       Here's a guess of what they could mean.
00763     case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM
00764     case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM
00765 
00766     //FIXME: weird DEC reset sequence
00767     case TY_CSI_PE('p'      ) : /* IGNORED: reset         (        ) */ break;
00768 
00769     //FIXME: when changing between vt52 and ansi mode evtl do some resetting.
00770     case TY_VT52('A'      ) : _currentScreen->cursorUp             (         1); break; //VT52
00771     case TY_VT52('B'      ) : _currentScreen->cursorDown           (         1); break; //VT52
00772     case TY_VT52('C'      ) : _currentScreen->cursorRight          (         1); break; //VT52
00773     case TY_VT52('D'      ) : _currentScreen->cursorLeft           (         1); break; //VT52
00774 
00775     case TY_VT52('F'      ) :      setAndUseCharset     (0,    '0'); break; //VT52
00776     case TY_VT52('G'      ) :      setAndUseCharset     (0,    'B'); break; //VT52
00777 
00778     case TY_VT52('H'      ) : _currentScreen->setCursorYX          (1,1       ); break; //VT52
00779     case TY_VT52('I'      ) : _currentScreen->reverseIndex         (          ); break; //VT52
00780     case TY_VT52('J'      ) : _currentScreen->clearToEndOfScreen   (          ); break; //VT52
00781     case TY_VT52('K'      ) : _currentScreen->clearToEndOfLine     (          ); break; //VT52
00782     case TY_VT52('Y'      ) : _currentScreen->setCursorYX          (p-31,q-31 ); break; //VT52
00783     case TY_VT52('Z'      ) :      reportTerminalType   (           ); break; //VT52
00784     case TY_VT52('<'      ) :          setMode      (MODE_Ansi     ); break; //VT52
00785     case TY_VT52('='      ) :          setMode      (MODE_AppKeyPad); break; //VT52
00786     case TY_VT52('>'      ) :        resetMode      (MODE_AppKeyPad); break; //VT52
00787 
00788     case TY_CSI_PG('c'      ) :  reportSecondaryAttributes(          ); break; //VT100
00789 
00790     default : ReportErrorToken();    break;
00791   };
00792 }
00793 
00794 void Vt102Emulation::clearScreenAndSetColumns(int columnCount)
00795 {
00796     setImageSize(_currentScreen->getLines(),columnCount); 
00797     clearEntireScreen();
00798     setDefaultMargins(); 
00799     _currentScreen->setCursorYX(0,0);
00800 }
00801 
00802 /* ------------------------------------------------------------------------- */
00803 /*                                                                           */
00804 /*                          Terminal to Host protocol                        */
00805 /*                                                                           */
00806 /* ------------------------------------------------------------------------- */
00807 
00808 /* 
00809    Outgoing bytes originate from several sources:
00810 
00811    - Replies to Enquieries.
00812    - Mouse Events
00813    - Keyboard Events
00814 */
00815 
00819 void Vt102Emulation::sendString(const char* s , int length)
00820 {
00821   if ( length >= 0 )
00822     emit sendData(s,length);
00823   else
00824     emit sendData(s,strlen(s));
00825 }
00826 
00827 // Replies ----------------------------------------------------------------- --
00828 
00829 // This section copes with replies send as response to an enquiery control code.
00830 
00834 void Vt102Emulation::reportCursorPosition()
00835 { char tmp[20];
00836   sprintf(tmp,"\033[%d;%dR",_currentScreen->getCursorY()+1,_currentScreen->getCursorX()+1);
00837   sendString(tmp);
00838 }
00839 
00840 /*
00841    What follows here is rather obsolete and faked stuff.
00842    The correspondent enquieries are neverthenless issued.
00843 */
00844 
00848 void Vt102Emulation::reportTerminalType()
00849 {
00850   // Primary device attribute response (Request was: ^[[0c or ^[[c (from TT321 Users Guide))
00851   //   VT220:  ^[[?63;1;2;3;6;7;8c   (list deps on emul. capabilities)
00852   //   VT100:  ^[[?1;2c
00853   //   VT101:  ^[[?1;0c
00854   //   VT102:  ^[[?6v
00855   if (getMode(MODE_Ansi))
00856     sendString("\033[?1;2c");     // I'm a VT100
00857   else
00858     sendString("\033/Z");         // I'm a VT52
00859 }
00860 
00861 void Vt102Emulation::reportSecondaryAttributes()
00862 {
00863   // Seconday device attribute response (Request was: ^[[>0c or ^[[>c)
00864   if (getMode(MODE_Ansi))
00865     sendString("\033[>0;115;0c"); // Why 115?  ;)
00866   else
00867     sendString("\033/Z");         // FIXME I don't think VT52 knows about it but kept for
00868                                   // konsoles backward compatibility.
00869 }
00870 
00871 void Vt102Emulation::reportTerminalParms(int p)
00872 // DECREPTPARM
00873 { char tmp[100];
00874   sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
00875   sendString(tmp);
00876 }
00877 
00881 void Vt102Emulation::reportStatus()
00882 {
00883   sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
00884 }
00885 
00889 #define ANSWER_BACK "" // This is really obsolete VT100 stuff.
00890 
00891 void Vt102Emulation::reportAnswerBack()
00892 {
00893   sendString(ANSWER_BACK);
00894 }
00895 
00896 // Mouse Handling ---------------------------------------------------------- --
00897 
00914 void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
00915 { char tmp[20];
00916   if (  cx<1 || cy<1 ) return;
00917   // normal buttons are passed as 0x20 + button,
00918   // mouse wheel (buttons 4,5) as 0x5c + button
00919   if (cb >= 4) cb += 0x3c;
00920 
00921   //Mouse motion handling
00922   if ( (getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1 )
00923       cb += 0x20; //add 32 to signify motion event
00924 
00925   sprintf(tmp,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20);
00926   sendString(tmp);
00927 }
00928 
00929 // Keyboard Handling ------------------------------------------------------- --
00930 
00931 #define encodeMode(M,B) BITS(B,getMode(M))
00932 #define encodeStat(M,B) BITS(B,((ev->modifiers() & (M)) == (M)))
00933 
00934 void Vt102Emulation::sendText( const QString& text )
00935 {
00936   if (!text.isEmpty()) {
00937     QKeyEvent event(QEvent::KeyPress, 
00938                     0, 
00939                     Qt::NoModifier, 
00940                     text);
00941     sendKeyEvent(&event); // expose as a big fat keypress event
00942   }
00943 
00944 }
00945 void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
00946 {
00947     Qt::KeyboardModifiers modifiers = event->modifiers();
00948     KeyboardTranslator::States states = KeyboardTranslator::NoState;
00949 
00950     // get current states
00951     if ( getMode(MODE_NewLine)  ) states |= KeyboardTranslator::NewLineState;
00952     if ( getMode(MODE_Ansi)     ) states |= KeyboardTranslator::AnsiState;
00953     if ( getMode(MODE_AppCuKeys)) states |= KeyboardTranslator::CursorKeysState;
00954     if ( getMode(MODE_AppScreen)) states |= KeyboardTranslator::AlternateScreenState;
00955 
00956     // check flow control state
00957     if (modifiers & Qt::ControlModifier)
00958     {
00959         if (event->key() == Qt::Key_S)
00960             emit flowControlKeyPressed(true);
00961         else if (event->key() == Qt::Key_Q)
00962             emit flowControlKeyPressed(false);
00963     }
00964 
00965     // lookup key binding
00966     if ( _keyTranslator )
00967     {
00968     KeyboardTranslator::Entry entry = _keyTranslator->findEntry( 
00969                                                 event->key() , 
00970                                                 modifiers,
00971                                                 states );
00972 
00973         // send result to terminal
00974         QByteArray textToSend;
00975 
00976         // special handling for the Alt (aka. Meta) modifier.  pressing
00977         // Alt+[Character] results in Esc+[Character] being sent
00978         // (unless there is an entry defined for this particular combination
00979         //  in the keyboard modifier)
00980         bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier;
00981         bool wantsAnyModifier = entry.state() & entry.stateMask() & KeyboardTranslator::AnyModifierState;
00982 
00983         if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) 
00984              && !event->text().isEmpty() )
00985         {
00986             textToSend.prepend("\033");
00987         }
00988 
00989         if ( entry.command() != KeyboardTranslator::NoCommand )
00990         {
00991             if (entry.command() & KeyboardTranslator::EraseCommand)
00992                 textToSend += getErase();
00993 
00994             // TODO command handling
00995         }
00996         else if ( !entry.text().isEmpty() ) 
00997         {
00998             textToSend += _codec->fromUnicode(entry.text(true,modifiers));
00999         }
01000         else
01001             textToSend += _codec->fromUnicode(event->text());
01002 
01003         sendData( textToSend.constData() , textToSend.length() );
01004     }
01005     else
01006     {
01007         // print an error message to the terminal if no key translator has been
01008         // set
01009         QString translatorError =  i18n("No keyboard translator available.  "
01010                                          "The information needed to convert key presses "
01011                                          "into characters to send to the terminal " 
01012                                          "is missing.");
01013 
01014         reset();
01015         receiveData( translatorError.toAscii().constData() , translatorError.count() );
01016     }
01017 }
01018 
01019 /* ------------------------------------------------------------------------- */
01020 /*                                                                           */
01021 /*                                VT100 Charsets                             */
01022 /*                                                                           */
01023 /* ------------------------------------------------------------------------- */
01024 
01025 // Character Set Conversion ------------------------------------------------ --
01026 
01027 /* 
01028    The processing contains a VT100 specific code translation layer.
01029    It's still in use and mainly responsible for the line drawing graphics.
01030 
01031    These and some other glyphs are assigned to codes (0x5f-0xfe)
01032    normally occupied by the latin letters. Since this codes also
01033    appear within control sequences, the extra code conversion
01034    does not permute with the tokenizer and is placed behind it
01035    in the pipeline. It only applies to tokens, which represent
01036    plain characters.
01037 
01038    This conversion it eventually continued in TerminalDisplay.C, since 
01039    it might involve VT100 enhanced fonts, which have these
01040    particular glyphs allocated in (0x00-0x1f) in their code page.
01041 */
01042 
01043 #define CHARSET _charset[_currentScreen==_screen[1]]
01044 
01045 // Apply current character map.
01046 
01047 unsigned short Vt102Emulation::applyCharset(unsigned short c)
01048 {
01049   if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
01050   if (CHARSET.pound                && c == '#' ) return 0xa3; //This mode is obsolete
01051   return c;
01052 }
01053 
01054 /*
01055    "Charset" related part of the emulation state.
01056    This configures the VT100 _charset filter.
01057 
01058    While most operation work on the current _screen,
01059    the following two are different.
01060 */
01061 
01062 void Vt102Emulation::resetCharset(int scrno)
01063 {
01064   _charset[scrno].cu_cs   = 0;
01065   strncpy(_charset[scrno].charset,"BBBB",4);
01066   _charset[scrno].sa_graphic = false;
01067   _charset[scrno].sa_pound   = false;
01068   _charset[scrno].graphic = false;
01069   _charset[scrno].pound   = false;
01070 }
01071 
01072 void Vt102Emulation::setCharset(int n, int cs) // on both screens.
01073 {
01074   _charset[0].charset[n&3] = cs; useCharset(_charset[0].cu_cs);
01075   _charset[1].charset[n&3] = cs; useCharset(_charset[1].cu_cs);
01076 }
01077 
01078 void Vt102Emulation::setAndUseCharset(int n, int cs)
01079 {
01080   CHARSET.charset[n&3] = cs;
01081   useCharset(n&3);
01082 }
01083 
01084 void Vt102Emulation::useCharset(int n)
01085 {
01086   CHARSET.cu_cs   = n&3;
01087   CHARSET.graphic = (CHARSET.charset[n&3] == '0');
01088   CHARSET.pound   = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
01089 }
01090 
01091 void Vt102Emulation::setDefaultMargins()
01092 {
01093     _screen[0]->setDefaultMargins();
01094     _screen[1]->setDefaultMargins();
01095 }
01096 
01097 void Vt102Emulation::setMargins(int t, int b)
01098 {
01099   _screen[0]->setMargins(t, b);
01100   _screen[1]->setMargins(t, b);
01101 }
01102 
01105 void Vt102Emulation::saveCursor()
01106 {
01107   CHARSET.sa_graphic = CHARSET.graphic;
01108   CHARSET.sa_pound   = CHARSET.pound; //This mode is obsolete
01109   // we are not clear about these
01110   //sa_charset = charsets[cScreen->_charset];
01111   //sa_charset_num = cScreen->_charset;
01112   _currentScreen->saveCursor();
01113 }
01114 
01117 void Vt102Emulation::restoreCursor()
01118 {
01119   CHARSET.graphic = CHARSET.sa_graphic;
01120   CHARSET.pound   = CHARSET.sa_pound; //This mode is obsolete
01121   _currentScreen->restoreCursor();
01122 }
01123 
01124 /* ------------------------------------------------------------------------- */
01125 /*                                                                           */
01126 /*                                Mode Operations                            */
01127 /*                                                                           */
01128 /* ------------------------------------------------------------------------- */
01129 
01130 /*
01131    Some of the emulations state is either added to the state of the screens.
01132 
01133    This causes some scoping problems, since different emulations choose to
01134    located the mode either to the current _screen or to both.
01135 
01136    For strange reasons, the extend of the rendition attributes ranges over
01137    all screens and not over the actual _screen.
01138 
01139    We decided on the precise precise extend, somehow.
01140 */
01141 
01142 // "Mode" related part of the state. These are all booleans.
01143 
01144 void Vt102Emulation::resetModes()
01145 {
01146   // MODE_Allow132Columns is not reset here
01147   // to match Xterm's behaviour (see Xterm's VTReset() function)
01148 
01149   resetMode(MODE_132Columns); saveMode(MODE_132Columns);
01150   resetMode(MODE_Mouse1000);  saveMode(MODE_Mouse1000);
01151   resetMode(MODE_Mouse1001);  saveMode(MODE_Mouse1001);
01152   resetMode(MODE_Mouse1002);  saveMode(MODE_Mouse1002);
01153   resetMode(MODE_Mouse1003);  saveMode(MODE_Mouse1003);
01154 
01155   resetMode(MODE_AppScreen);  saveMode(MODE_AppScreen);
01156   // here come obsolete modes
01157   resetMode(MODE_AppCuKeys);  saveMode(MODE_AppCuKeys);
01158   resetMode(MODE_NewLine  );
01159     setMode(MODE_Ansi     );
01160 }
01161 
01162 void Vt102Emulation::setMode(int m)
01163 {
01164   _currParm.mode[m] = true;
01165   switch (m)
01166   {
01167     case MODE_132Columns:
01168         if (getMode(MODE_Allow132Columns))
01169             clearScreenAndSetColumns(132);
01170         else
01171             _currParm.mode[m] = false;
01172         break;
01173     case MODE_Mouse1000:
01174     case MODE_Mouse1001:
01175     case MODE_Mouse1002:
01176     case MODE_Mouse1003:
01177         emit programUsesMouseChanged(false); 
01178     break;
01179 
01180     case MODE_AppScreen : _screen[1]->clearSelection();
01181                           setScreen(1);
01182     break;
01183   }
01184   if (m < MODES_SCREEN || m == MODE_NewLine)
01185   {
01186     _screen[0]->setMode(m);
01187     _screen[1]->setMode(m);
01188   }
01189 }
01190 
01191 void Vt102Emulation::resetMode(int m)
01192 {
01193   _currParm.mode[m] = false;
01194   switch (m)
01195   {
01196     case MODE_132Columns:
01197         if (getMode(MODE_Allow132Columns))
01198             clearScreenAndSetColumns(80);
01199         break;
01200     case MODE_Mouse1000 : 
01201     case MODE_Mouse1001 :
01202     case MODE_Mouse1002 :
01203     case MODE_Mouse1003 :
01204         emit programUsesMouseChanged(true); 
01205     break;
01206 
01207     case MODE_AppScreen : _screen[0]->clearSelection();
01208                           setScreen(0);
01209     break;
01210   }
01211   if (m < MODES_SCREEN || m == MODE_NewLine)
01212   {
01213     _screen[0]->resetMode(m);
01214     _screen[1]->resetMode(m);
01215   }
01216 }
01217 
01218 void Vt102Emulation::saveMode(int m)
01219 {
01220   _saveParm.mode[m] = _currParm.mode[m];
01221 }
01222 
01223 void Vt102Emulation::restoreMode(int m)
01224 {
01225   if (_saveParm.mode[m]) 
01226       setMode(m); 
01227   else 
01228       resetMode(m);
01229 }
01230 
01231 bool Vt102Emulation::getMode(int m)
01232 {
01233   return _currParm.mode[m];
01234 }
01235 
01236 char Vt102Emulation::getErase() const
01237 {
01238   KeyboardTranslator::Entry entry = _keyTranslator->findEntry(
01239                                             Qt::Key_Backspace,
01240                                             0,
01241                                             0);
01242   if ( entry.text().count() > 0 )
01243       return entry.text()[0];
01244   else
01245       return '\b';
01246 }
01247 
01248 /* ------------------------------------------------------------------------- */
01249 /*                                                                           */
01250 /*                               Diagnostic                                  */
01251 /*                                                                           */
01252 /* ------------------------------------------------------------------------- */
01253 
01262 static void hexdump(int* s, int len)
01263 { int i;
01264   for (i = 0; i < len; i++)
01265   {
01266     if (s[i] == '\\')
01267       printf("\\\\");
01268     else
01269     if ((s[i]) > 32 && s[i] < 127)
01270       printf("%c",s[i]);
01271     else
01272       printf("\\%04x(hex)",s[i]);
01273   }
01274 }
01275 
01276 void Vt102Emulation::scan_buffer_report()
01277 {
01278   if (ppos == 0 || ( ppos == 1 && (pbuf[0] & 0xff) >= 32) ) return;
01279   printf("token: "); hexdump(pbuf,ppos); printf("\n");
01280 }
01281 
01285 void Vt102Emulation::ReportErrorToken()
01286 {
01287 #ifndef NDEBUG
01288   printf("undecodable "); scan_buffer_report();
01289 #endif
01290 }
01291 
01292 #include "Vt102Emulation.moc"
01293 

Konsole

Skip menu "Konsole"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • Konsole
  • Libraries
  •   libkonq
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal