Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

TEmuVt102.cpp

Go to the documentation of this file.
00001 /* ------------------------------------------------------------------------- */
00002 /*                                                                           */
00003 /* [TEmuVt102.C]            VT102 Terminal Emulation                         */
00004 /*                                                                           */
00005 /* ------------------------------------------------------------------------- */
00006 /*                                                                           */
00007 /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>           */
00008 /*                                                                           */
00009 /* This file is part of Konsole - an X terminal for KDE                      */
00010 /*                                                                           */
00011 /* ------------------------------------------------------------------------- */
00012 /*                        */
00013 /* Ported Konsole to Qt/Embedded                                              */
00014 /*                        */
00015 /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com>                  */
00016 /*                        */
00017 /* -------------------------------------------------------------------------- */
00018 
00026 #include "TEmuVt102.h"
00027 
00028 #include <stdio.h>
00029 #include <unistd.h>
00030 
00031 
00032 /* VT102 Terminal Emulation
00033 
00034    This class puts together the screens, the pty and the widget to a
00035    complete terminal emulation. Beside combining it's componentes, it
00036    handles the emulations's protocol.
00037 
00038    This module consists of the following sections:
00039 
00040    - Constructor/Destructor
00041    - Incoming Bytes Event pipeline
00042    - Outgoing Bytes
00043      - Mouse Events
00044      - Keyboard Events
00045    - Modes and Charset State
00046    - Diagnostics
00047 */
00048 
00049 
00050 /* ------------------------------------------------------------------------- */
00051 /*                                                                           */
00052 /*                       Constructor / Destructor                            */
00053 /*                                                                           */
00054 /* ------------------------------------------------------------------------- */
00055 
00056 /*
00057    Nothing really intesting happens here.
00058 */
00059 
00063 TEmuVt102::TEmuVt102(TEWidget* gui) : TEmulation(gui)
00064 {
00065   QObject::connect(gui,SIGNAL(mouseSignal(int,int,int)),
00066                    this,SLOT(onMouse(int,int,int)));
00067   initTokenizer();
00068   reset();
00069 }
00070 
00074 TEmuVt102::~TEmuVt102()
00075 {
00076 }
00077 
00081 void TEmuVt102::reset()
00082 {
00083   resetToken();
00084   resetModes();
00085   resetCharset(0); screen[0]->reset();
00086   resetCharset(1); screen[0]->reset();
00087   setCodec(0);
00088   setKeytrans("linux.keytab");
00089 }
00090 
00091 /* ------------------------------------------------------------------------- */
00092 /*                                                                           */
00093 /*                     Processing the incoming byte stream                   */
00094 /*                                                                           */
00095 /* ------------------------------------------------------------------------- */
00096 
00097 /* Incoming Bytes Event pipeline
00098 
00099    This section deals with decoding the incoming character stream.
00100    Decoding means here, that the stream is first seperated into `tokens'
00101    which are then mapped to a `meaning' provided as operations by the
00102    `TEScreen' class or by the emulation class itself.
00103 
00104    The pipeline proceeds as follows:
00105 
00106    - Tokenizing the ESC codes (onRcvChar)
00107    - VT100 code page translation of plain characters (applyCharset)
00108    - Interpretation of ESC codes (tau)
00109 
00110    The escape codes and their meaning are described in the
00111    technical reference of this program.
00112 */
00113 
00114 // Tokens ------------------------------------------------------------------ --
00115 
00116 /*
00117    Since the tokens are the central notion if this section, we've put them
00118    in front. They provide the syntactical elements used to represent the
00119    terminals operations as byte sequences.
00120 
00121    They are encodes here into a single machine word, so that we can later
00122    switch over them easily. Depending on the token itself, additional
00123    argument variables are filled with parameter values.
00124 
00125    The tokens are defined below:
00126 
00127    - CHR        - Printable characters     (32..255 but DEL (=127))
00128    - CTL        - Control characters       (0..31 but ESC (= 27), DEL)
00129    - ESC        - Escape codes of the form <ESC><CHR but `[]()+*#'>
00130    - ESC_DE     - Escape codes of the form <ESC><any of `()+*#%'> C
00131    - CSI_PN     - Escape codes of the form <ESC>'['     {Pn} ';' {Pn} C
00132    - CSI_PS     - Escape codes of the form <ESC>'['     {Pn} ';' ...  C
00133    - CSI_PR     - Escape codes of the form <ESC>'[' '?' {Pn} ';' ...  C
00134    - VT52       - VT52 escape codes
00135                   - <ESC><Chr>
00136                   - <ESC>'Y'{Pc}{Pc}
00137    - XTE_HA     - Xterm hacks              <ESC>`]' {Pn} `;' {Text} <BEL>
00138                   note that this is handled differently
00139 
00140    The last two forms allow list of arguments. Since the elements of
00141    the lists are treated individually the same way, they are passed
00142    as individual tokens to the interpretation. Further, because the
00143    meaning of the parameters are names (althought represented as numbers),
00144    they are includes within the token ('N').
00145 
00146 */
00147 
00148 #define TY_CONSTR(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
00149 
00150 #define TY_CHR___(   )  TY_CONSTR(0,0,0)
00151 #define TY_CTL___(A  )  TY_CONSTR(1,A,0)
00152 #define TY_ESC___(A  )  TY_CONSTR(2,A,0)
00153 #define TY_ESC_CS(A,B)  TY_CONSTR(3,A,B)
00154 #define TY_ESC_DE(A  )  TY_CONSTR(4,A,0)
00155 #define TY_CSI_PS(A,N)  TY_CONSTR(5,A,N)
00156 #define TY_CSI_PN(A  )  TY_CONSTR(6,A,0)
00157 #define TY_CSI_PR(A,N)  TY_CONSTR(7,A,N)
00158 
00159 #define TY_VT52__(A  )  TY_CONSTR(8,A,0)
00160 
00161 // Tokenizer --------------------------------------------------------------- --
00162 
00163 /* The tokenizers state
00164 
00165    The state is represented by the buffer (pbuf, ppos),
00166    and accompanied by decoded arguments kept in (argv,argc).
00167    Note that they are kept internal in the tokenizer.
00168 */
00169 
00170 void TEmuVt102::resetToken()
00171 {
00172   ppos = 0; argc = 0; argv[0] = 0; argv[1] = 0;
00173 }
00174 
00175 void TEmuVt102::addDigit(int dig)
00176 {
00177   argv[argc] = 10*argv[argc] + dig;
00178 }
00179 
00180 void TEmuVt102::addArgument()
00181 {
00182   argc = QMIN(argc+1,MAXARGS-1);
00183   argv[argc] = 0;
00184 }
00185 
00186 void TEmuVt102::pushToToken(int cc)
00187 {
00188   pbuf[ppos] = cc;
00189   ppos = QMIN(ppos+1,MAXPBUF-1);
00190 }
00191 
00192 // Character Classes used while decoding
00193 
00194 #define CTL  1
00195 #define CHR  2
00196 #define CPN  4
00197 #define DIG  8
00198 #define SCS 16
00199 #define GRP 32
00200 
00201 void TEmuVt102::initTokenizer()
00202 { int i; UINT8* s;
00203   for(i =  0;                    i < 256; i++) tbl[ i]  = 0;
00204   for(i =  0;                    i <  32; i++) tbl[ i] |= CTL;
00205   for(i = 32;                    i < 256; i++) tbl[ i] |= CHR;
00206   for(s = (UINT8*)"@ABCDGHLMPXcdfry"; *s; s++) tbl[*s] |= CPN;
00207   for(s = (UINT8*)"0123456789"      ; *s; s++) tbl[*s] |= DIG;
00208   for(s = (UINT8*)"()+*%"           ; *s; s++) tbl[*s] |= SCS;
00209   for(s = (UINT8*)"()+*#[]%"        ; *s; s++) tbl[*s] |= GRP;
00210   resetToken();
00211 }
00212 
00213 /* Ok, here comes the nasty part of the decoder.
00214 
00215    Instead of keeping an explicit state, we deduce it from the
00216    token scanned so far. It is then immediately combined with
00217    the current character to form a scanning decision.
00218 
00219    This is done by the following defines.
00220 
00221    - P is the length of the token scanned so far.
00222    - L (often P-1) is the position on which contents we base a decision.
00223    - C is a character or a group of characters (taken from 'tbl').
00224 
00225    Note that they need to applied in proper order.
00226 */
00227 
00228 #define lec(P,L,C) (p == (P) &&                     s[(L)]         == (C))
00229 #define lun(     ) (p ==  1  &&                       cc           >= 32 )
00230 #define les(P,L,C) (p == (P) && s[L] < 256  && (tbl[s[(L)]] & (C)) == (C))
00231 #define eec(C)     (p >=  3  &&        cc                          == (C))
00232 #define ees(C)     (p >=  3  && cc < 256 &&    (tbl[  cc  ] & (C)) == (C))
00233 #define eps(C)     (p >=  3  && s[2] != '?' && cc < 256 && (tbl[  cc  ] & (C)) == (C))
00234 #define epp( )     (p >=  3  && s[2] == '?'                              )
00235 #define egt(     ) (p ==  3  && s[2] == '>'                              )
00236 #define Xpe        (ppos>=2  && pbuf[1] == ']'                           )
00237 #define Xte        (Xpe                        &&     cc           ==  7 )
00238 #define ces(C)     (            cc < 256 &&    (tbl[  cc  ] & (C)) == (C) && !Xte)
00239 
00240 #define ESC 27
00241 #define CNTL(c) ((c)-'@')
00242 
00243 // process an incoming unicode character
00244 
00245 void TEmuVt102::onRcvChar(int cc)
00246 { int i;
00247 
00248   if (cc == 127) return; //VT100: ignore.
00249 
00250   if (ces(    CTL))
00251   { // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
00252     // This means, they do neither a resetToken nor a pushToToken. Some of them, do
00253     // of course. Guess this originates from a weakly layered handling of the X-on
00254     // X-off protocol, which comes really below this level.
00255     if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken(); //VT100: CAN or SUB
00256     if (cc != ESC)    { tau( TY_CTL___(cc+'@' ),    0,   0); return; }
00257   }
00258 
00259   pushToToken(cc); // advance the state
00260 
00261   int* s = pbuf;
00262   int  p = ppos;
00263 
00264   if (getMode(MODE_Ansi)) // decide on proper action
00265   {
00266     if (lec(1,0,ESC)) {                                                       return; }
00267     if (les(2,1,GRP)) {                                                       return; }
00268     if (Xte         ) { XtermHack();                            resetToken(); return; }
00269     if (Xpe         ) {                                                       return; }
00270     if (lec(3,2,'?')) {                                                       return; }
00271     if (lec(3,2,'>')) {                                                       return; }
00272     if (lun(       )) { tau( TY_CHR___(), applyCharset(cc), 0); resetToken(); return; }
00273     if (lec(2,0,ESC)) { tau( TY_ESC___(s[1]),    0,   0);       resetToken(); return; }
00274     if (les(3,1,SCS)) { tau( TY_ESC_CS(s[1],s[2]),    0,   0);  resetToken(); return; }
00275     if (lec(3,1,'#')) { tau( TY_ESC_DE(s[2]),    0,   0);       resetToken(); return; }
00276 //  if (egt(       )) { tau( TY_CSI_PG(cc       ),  '>',   0);  resetToken(); return; }
00277     if (eps(    CPN)) { tau( TY_CSI_PN(cc), argv[0],argv[1]);   resetToken(); return; }
00278     if (ees(    DIG)) { addDigit(cc-'0');                                     return; }
00279     if (eec(    ';')) { addArgument();                                        return; }
00280     for (i=0;i<=argc;i++)
00281     if (epp(       ))   tau( TY_CSI_PR(cc,argv[i]),    0,   0);          else
00282                         tau( TY_CSI_PS(cc,argv[i]),    0,   0);
00283     resetToken();
00284   }
00285   else // mode VT52
00286   {
00287     if (lec(1,0,ESC))                                                      return;
00288     if (les(1,0,CHR)) { tau( TY_CHR___(       ), s[0],   0); resetToken(); return; }
00289     if (lec(2,1,'Y'))                                                      return;
00290     if (lec(3,1,'Y'))                                                      return;
00291     if (p < 4)        { tau( TY_VT52__(s[1]   ),    0,   0); resetToken(); return; }
00292                         tau( TY_VT52__(s[1]   ), s[2],s[3]); resetToken(); return;
00293   }
00294 }
00295 
00296 void TEmuVt102::XtermHack()
00297 { int i,arg = 0;
00298   for (i = 2; i < ppos && '0'<=pbuf[i] && pbuf[i]<'9' ; i++)
00299     arg = 10*arg + (pbuf[i]-'0');
00300   if (pbuf[i] != ';') { ReportErrorToken(); return; }
00301   QChar *str = new QChar[ppos-i-2];
00302   for (int j = 0; j < ppos-i-2; j++) str[j] = pbuf[i+1+j];
00303   QString unistr(str,ppos-i-2);
00304   // arg == 1 doesn't change the title. In XTerm it only changes the icon name
00305   // (btw: arg=0 changes title and icon, arg=1 only icon, arg=2 only title
00306   if (arg == 0 || arg == 2) emit changeTitle(arg,unistr);
00307   delete [] str;
00308 }
00309 
00310 // Interpreting Codes ---------------------------------------------------------
00311 
00312 /*
00313    Now that the incoming character stream is properly tokenized,
00314    meaning is assigned to them. These are either operations of
00315    the current screen, or of the emulation class itself.
00316 
00317    The token to be interpreteted comes in as a machine word
00318    possibly accompanied by two parameters.
00319 
00320    Likewise, the operations assigned to, come with up to two
00321    arguments. One could consider to make up a proper table
00322    from the function below.
00323 
00324    The technical reference manual provides more informations
00325    about this mapping.
00326 */
00327 
00328 void TEmuVt102::tau( int token, int p, int q )
00329 {
00330 //scan_buffer_report();
00331 //if (token == TY_CHR___()) printf("%c",p); else
00332 //printf("tau(%d,%d,%d, %d,%d)\n",(token>>0)&0xff,(token>>8)&0xff,(token>>16)&0xffff,p,q);
00333   switch (token)
00334   {
00335 
00336     case TY_CHR___(         ) : scr->ShowCharacter        (p         ); break; //UTF16
00337 
00338     //             127 DEL    : ignored on input
00339 
00340     case TY_CTL___('@'      ) : /* NUL: ignored                      */ break;
00341     case TY_CTL___('A'      ) : /* SOH: ignored                      */ break;
00342     case TY_CTL___('B'      ) : /* STX: ignored                      */ break;
00343     case TY_CTL___('C'      ) : /* ETX: ignored                      */ break;
00344     case TY_CTL___('D'      ) : /* EOT: ignored                      */ break;
00345     case TY_CTL___('E'      ) :      reportAnswerBack     (          ); break; //VT100
00346     case TY_CTL___('F'      ) : /* ACK: ignored                      */ break;
00347     case TY_CTL___('G'      ) : gui->Bell                 (          ); break; //VT100
00348     case TY_CTL___('H'      ) : scr->BackSpace            (          ); break; //VT100
00349     case TY_CTL___('I'      ) : scr->Tabulate             (          ); break; //VT100
00350     case TY_CTL___('J'      ) : scr->NewLine              (          ); break; //VT100
00351     case TY_CTL___('K'      ) : scr->NewLine              (          ); break; //VT100
00352     case TY_CTL___('L'      ) : scr->NewLine              (          ); break; //VT100
00353     case TY_CTL___('M'      ) : scr->Return               (          ); break; //VT100
00354 
00355     case TY_CTL___('N'      ) :      useCharset           (         1); break; //VT100
00356     case TY_CTL___('O'      ) :      useCharset           (         0); break; //VT100
00357 
00358     case TY_CTL___('P'      ) : /* DLE: ignored                      */ break;
00359     case TY_CTL___('Q'      ) : /* DC1: XON continue                 */ break; //VT100
00360     case TY_CTL___('R'      ) : /* DC2: ignored                      */ break;
00361     case TY_CTL___('S'      ) : /* DC3: XOFF halt                    */ break; //VT100
00362     case TY_CTL___('T'      ) : /* DC4: ignored                      */ break;
00363     case TY_CTL___('U'      ) : /* NAK: ignored                      */ break;
00364     case TY_CTL___('V'      ) : /* SYN: ignored                      */ break;
00365     case TY_CTL___('W'      ) : /* ETB: ignored                      */ break;
00366     case TY_CTL___('X'      ) : scr->ShowCharacter        (    0x2592); break; //VT100
00367     case TY_CTL___('Y'      ) : /* EM : ignored                      */ break;
00368     case TY_CTL___('Z'      ) : scr->ShowCharacter        (    0x2592); break; //VT100
00369     case TY_CTL___('['      ) : /* ESC: cannot be seen here.         */ break;
00370     case TY_CTL___('\\'     ) : /* FS : ignored                      */ break;
00371     case TY_CTL___(']'      ) : /* GS : ignored                      */ break;
00372     case TY_CTL___('^'      ) : /* RS : ignored                      */ break;
00373     case TY_CTL___('_'      ) : /* US : ignored                      */ break;
00374 
00375     case TY_ESC___('D'      ) : scr->index                (          ); break; //VT100
00376     case TY_ESC___('E'      ) : scr->NextLine             (          ); break; //VT100
00377     case TY_ESC___('H'      ) : scr->changeTabStop        (TRUE      ); break; //VT100
00378     case TY_ESC___('M'      ) : scr->reverseIndex         (          ); break; //VT100
00379     case TY_ESC___('Z'      ) :      reportTerminalType   (          ); break;
00380     case TY_ESC___('c'      ) :      reset                (          ); break;
00381 
00382     case TY_ESC___('n'      ) :      useCharset           (         2); break;
00383     case TY_ESC___('o'      ) :      useCharset           (         3); break;
00384     case TY_ESC___('7'      ) :      saveCursor           (          ); break;
00385     case TY_ESC___('8'      ) :      restoreCursor        (          ); break;
00386 
00387     case TY_ESC___('='      ) :          setMode      (MODE_AppKeyPad); break;
00388     case TY_ESC___('>'      ) :        resetMode      (MODE_AppKeyPad); break;
00389     case TY_ESC___('<'      ) :          setMode      (MODE_Ansi     ); break; //VT100
00390 
00391     case TY_ESC_CS('(',  '0') :      setCharset           (0,     '0'); break; //VT100
00392     case TY_ESC_CS('(',  'A') :      setCharset           (0,     'A'); break; //VT100
00393     case TY_ESC_CS('(',  'B') :      setCharset           (0,     'B'); break; //VT100
00394 
00395     case TY_ESC_CS(')',  '0') :      setCharset           (1,     '0'); break; //VT100
00396     case TY_ESC_CS(')',  'A') :      setCharset           (1,     'A'); break; //VT100
00397     case TY_ESC_CS(')',  'B') :      setCharset           (1,     'B'); break; //VT100
00398 
00399     case TY_ESC_CS('*',  '0') :      setCharset           (2,     '0'); break; //VT100
00400     case TY_ESC_CS('*',  'A') :      setCharset           (2,     'A'); break; //VT100
00401     case TY_ESC_CS('*',  'B') :      setCharset           (2,     'B'); break; //VT100
00402 
00403     case TY_ESC_CS('+',  '0') :      setCharset           (3,     '0'); break; //VT100
00404     case TY_ESC_CS('+',  'A') :      setCharset           (3,     'A'); break; //VT100
00405     case TY_ESC_CS('+',  'B') :      setCharset           (3,     'B'); break; //VT100
00406 
00407     case TY_ESC_CS('%',  'G') :      setCodec             (1         ); break; //LINUX
00408     case TY_ESC_CS('%',  '@') :      setCodec             (0         ); break; //LINUX
00409 
00410     case TY_ESC_DE('3'      ) : /* IGNORED: double high, top half    */ break;
00411     case TY_ESC_DE('4'      ) : /* IGNORED: double high, bottom half */ break;
00412     case TY_ESC_DE('5'      ) : /* IGNORED: single width, single high*/ break;
00413     case TY_ESC_DE('6'      ) : /* IGNORED: double width, single high*/ break;
00414     case TY_ESC_DE('8'      ) : scr->helpAlign            (          ); break;
00415 
00416     case TY_CSI_PS('K',    0) : scr->clearToEndOfLine     (          ); break;
00417     case TY_CSI_PS('K',    1) : scr->clearToBeginOfLine   (          ); break;
00418     case TY_CSI_PS('K',    2) : scr->clearEntireLine      (          ); break;
00419     case TY_CSI_PS('J',    0) : scr->clearToEndOfScreen   (          ); break;
00420     case TY_CSI_PS('J',    1) : scr->clearToBeginOfScreen (          ); break;
00421     case TY_CSI_PS('J',    2) : scr->clearEntireScreen    (          ); break;
00422     case TY_CSI_PS('g',    0) : scr->changeTabStop        (FALSE     ); break; //VT100
00423     case TY_CSI_PS('g',    3) : scr->clearTabStops        (          ); break; //VT100
00424     case TY_CSI_PS('h',    4) : scr->    setMode      (MODE_Insert   ); break;
00425     case TY_CSI_PS('h',   20) :          setMode      (MODE_NewLine  ); break;
00426     case TY_CSI_PS('i',    0) : /* IGNORE: attached printer          */ break; //VT100
00427     case TY_CSI_PS('l',    4) : scr->  resetMode      (MODE_Insert   ); break;
00428     case TY_CSI_PS('l',   20) :        resetMode      (MODE_NewLine  ); break;
00429 
00430     case TY_CSI_PS('m',    0) : scr->setDefaultRendition  (          ); break;
00431     case TY_CSI_PS('m',    1) : scr->  setRendition     (RE_BOLD     ); break; //VT100
00432     case TY_CSI_PS('m',    4) : scr->  setRendition     (RE_UNDERLINE); break; //VT100
00433     case TY_CSI_PS('m',    5) : scr->  setRendition     (RE_BLINK    ); break; //VT100
00434     case TY_CSI_PS('m',    7) : scr->  setRendition     (RE_REVERSE  ); break;
00435     case TY_CSI_PS('m',   10) : /* IGNORED: mapping related          */ break; //LINUX
00436     case TY_CSI_PS('m',   11) : /* IGNORED: mapping related          */ break; //LINUX
00437     case TY_CSI_PS('m',   12) : /* IGNORED: mapping related          */ break; //LINUX
00438     case TY_CSI_PS('m',   22) : scr->resetRendition     (RE_BOLD     ); break;
00439     case TY_CSI_PS('m',   24) : scr->resetRendition     (RE_UNDERLINE); break;
00440     case TY_CSI_PS('m',   25) : scr->resetRendition     (RE_BLINK    ); break;
00441     case TY_CSI_PS('m',   27) : scr->resetRendition     (RE_REVERSE  ); break;
00442 
00443     case TY_CSI_PS('m',   30) : scr->setForeColor         (         0); break;
00444     case TY_CSI_PS('m',   31) : scr->setForeColor         (         1); break;
00445     case TY_CSI_PS('m',   32) : scr->setForeColor         (         2); break;
00446     case TY_CSI_PS('m',   33) : scr->setForeColor         (         3); break;
00447     case TY_CSI_PS('m',   34) : scr->setForeColor         (         4); break;
00448     case TY_CSI_PS('m',   35) : scr->setForeColor         (         5); break;
00449     case TY_CSI_PS('m',   36) : scr->setForeColor         (         6); break;
00450     case TY_CSI_PS('m',   37) : scr->setForeColor         (         7); break;
00451     case TY_CSI_PS('m',   39) : scr->setForeColorToDefault(          ); break;
00452 
00453     case TY_CSI_PS('m',   40) : scr->setBackColor         (         0); break;
00454     case TY_CSI_PS('m',   41) : scr->setBackColor         (         1); break;
00455     case TY_CSI_PS('m',   42) : scr->setBackColor         (         2); break;
00456     case TY_CSI_PS('m',   43) : scr->setBackColor         (         3); break;
00457     case TY_CSI_PS('m',   44) : scr->setBackColor         (         4); break;
00458     case TY_CSI_PS('m',   45) : scr->setBackColor         (         5); break;
00459     case TY_CSI_PS('m',   46) : scr->setBackColor         (         6); break;
00460     case TY_CSI_PS('m',   47) : scr->setBackColor         (         7); break;
00461     case TY_CSI_PS('m',   49) : scr->setBackColorToDefault(          ); break;
00462 
00463     case TY_CSI_PS('m',   90) : scr->setForeColor         (         8); break;
00464     case TY_CSI_PS('m',   91) : scr->setForeColor         (         9); break;
00465     case TY_CSI_PS('m',   92) : scr->setForeColor         (        10); break;
00466     case TY_CSI_PS('m',   93) : scr->setForeColor         (        11); break;
00467     case TY_CSI_PS('m',   94) : scr->setForeColor         (        12); break;
00468     case TY_CSI_PS('m',   95) : scr->setForeColor         (        13); break;
00469     case TY_CSI_PS('m',   96) : scr->setForeColor         (        14); break;
00470     case TY_CSI_PS('m',   97) : scr->setForeColor         (        15); break;
00471 
00472     case TY_CSI_PS('m',  100) : scr->setBackColor         (         8); break;
00473     case TY_CSI_PS('m',  101) : scr->setBackColor         (         9); break;
00474     case TY_CSI_PS('m',  102) : scr->setBackColor         (        10); break;
00475     case TY_CSI_PS('m',  103) : scr->setBackColor         (        11); break;
00476     case TY_CSI_PS('m',  104) : scr->setBackColor         (        12); break;
00477     case TY_CSI_PS('m',  105) : scr->setBackColor         (        13); break;
00478     case TY_CSI_PS('m',  106) : scr->setBackColor         (        14); break;
00479     case TY_CSI_PS('m',  107) : scr->setBackColor         (        15); break;
00480 
00481     case TY_CSI_PS('n',    5) :      reportStatus         (          ); break;
00482     case TY_CSI_PS('n',    6) :      reportCursorPosition (          ); break;
00483     case TY_CSI_PS('q',    0) : /* IGNORED: LEDs off                 */ break; //VT100
00484     case TY_CSI_PS('q',    1) : /* IGNORED: LED1 on                  */ break; //VT100
00485     case TY_CSI_PS('q',    2) : /* IGNORED: LED2 on                  */ break; //VT100
00486     case TY_CSI_PS('q',    3) : /* IGNORED: LED3 on                  */ break; //VT100
00487     case TY_CSI_PS('q',    4) : /* IGNORED: LED4 on                  */ break; //VT100
00488     case TY_CSI_PS('x',    0) :      reportTerminalParms  (         2); break; //VT100
00489     case TY_CSI_PS('x',    1) :      reportTerminalParms  (         3); break; //VT100
00490 
00491     case TY_CSI_PN('@'      ) : scr->insertChars          (p         ); break;
00492     case TY_CSI_PN('A'      ) : scr->cursorUp             (p         ); break; //VT100
00493     case TY_CSI_PN('B'      ) : scr->cursorDown           (p         ); break; //VT100
00494     case TY_CSI_PN('C'      ) : scr->cursorRight          (p         ); break; //VT100
00495     case TY_CSI_PN('D'      ) : scr->cursorLeft           (p         ); break; //VT100
00496     case TY_CSI_PN('G'      ) : scr->setCursorX           (p         ); break; //LINUX
00497     case TY_CSI_PN('H'      ) : scr->setCursorYX          (p,       q); break; //VT100
00498     case TY_CSI_PN('L'      ) : scr->insertLines          (p         ); break;
00499     case TY_CSI_PN('M'      ) : scr->deleteLines          (p         ); break;
00500     case TY_CSI_PN('P'      ) : scr->deleteChars          (p         ); break;
00501     case TY_CSI_PN('X'      ) : scr->eraseChars           (p         ); break;
00502     case TY_CSI_PN('c'      ) :      reportTerminalType   (          ); break; //VT100
00503     case TY_CSI_PN('d'      ) : scr->setCursorY           (p         ); break; //LINUX
00504     case TY_CSI_PN('f'      ) : scr->setCursorYX          (p,       q); break; //VT100
00505     case TY_CSI_PN('r'      ) : scr->setMargins           (p,       q); break; //VT100
00506     case TY_CSI_PN('y'      ) : /* IGNORED: Confidence test          */ break; //VT100
00507 
00508     case TY_CSI_PR('h',    1) :          setMode      (MODE_AppCuKeys); break; //VT100
00509     case TY_CSI_PR('l',    1) :        resetMode      (MODE_AppCuKeys); break; //VT100
00510     case TY_CSI_PR('s',    1) :         saveMode      (MODE_AppCuKeys); break; //FIXME
00511     case TY_CSI_PR('r',    1) :      restoreMode      (MODE_AppCuKeys); break; //FIXME
00512 
00513     case TY_CSI_PR('l',    2) :        resetMode      (MODE_Ansi     ); break; //VT100
00514 
00515     case TY_CSI_PR('h',    3) :      setColumns           (       132); break; //VT100
00516     case TY_CSI_PR('l',    3) :      setColumns           (        80); break; //VT100
00517 
00518     case TY_CSI_PR('h',    4) : /* IGNORED: soft scrolling           */ break; //VT100
00519     case TY_CSI_PR('l',    4) : /* IGNORED: soft scrolling           */ break; //VT100
00520 
00521     case TY_CSI_PR('h',    5) : scr->    setMode      (MODE_Screen   ); break; //VT100
00522     case TY_CSI_PR('l',    5) : scr->  resetMode      (MODE_Screen   ); break; //VT100
00523 
00524     case TY_CSI_PR('h',    6) : scr->    setMode      (MODE_Origin   ); break; //VT100
00525     case TY_CSI_PR('l',    6) : scr->  resetMode      (MODE_Origin   ); break; //VT100
00526     case TY_CSI_PR('s',    6) : scr->   saveMode      (MODE_Origin   ); break; //FIXME
00527     case TY_CSI_PR('r',    6) : scr->restoreMode      (MODE_Origin   ); break; //FIXME
00528 
00529     case TY_CSI_PR('h',    7) : scr->    setMode      (MODE_Wrap     ); break; //VT100
00530     case TY_CSI_PR('l',    7) : scr->  resetMode      (MODE_Wrap     ); break; //VT100
00531     case TY_CSI_PR('s',    7) : scr->   saveMode      (MODE_Wrap     ); break; //FIXME
00532     case TY_CSI_PR('r',    7) : scr->restoreMode      (MODE_Wrap     ); break; //FIXME
00533 
00534     case TY_CSI_PR('h',    8) : /* IGNORED: autorepeat on            */ break; //VT100
00535     case TY_CSI_PR('l',    8) : /* IGNORED: autorepeat off           */ break; //VT100
00536 
00537     case TY_CSI_PR('h',    9) : /* IGNORED: interlace                */ break; //VT100
00538     case TY_CSI_PR('l',    9) : /* IGNORED: interlace                */ break; //VT100
00539 
00540     case TY_CSI_PR('h',   25) :          setMode      (MODE_Cursor   ); break; //VT100
00541     case TY_CSI_PR('l',   25) :        resetMode      (MODE_Cursor   ); break; //VT100
00542 
00543     case TY_CSI_PR('h',   41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
00544     case TY_CSI_PR('l',   41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
00545     case TY_CSI_PR('s',   41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
00546     case TY_CSI_PR('r',   41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
00547 
00548     case TY_CSI_PR('h',   47) :          setMode      (MODE_AppScreen); break; //VT100
00549     case TY_CSI_PR('l',   47) :        resetMode      (MODE_AppScreen); break; //VT100
00550 
00551     case TY_CSI_PR('h', 1000) :          setMode      (MODE_Mouse1000); break; //XTERM
00552     case TY_CSI_PR('l', 1000) :        resetMode      (MODE_Mouse1000); break; //XTERM
00553     case TY_CSI_PR('s', 1000) :         saveMode      (MODE_Mouse1000); break; //XTERM
00554     case TY_CSI_PR('r', 1000) :      restoreMode      (MODE_Mouse1000); break; //XTERM
00555 
00556     case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
00557     case TY_CSI_PR('l', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
00558     case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
00559     case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
00560 
00561     case TY_CSI_PR('h', 1047) :          setMode      (MODE_AppScreen); break; //XTERM
00562     case TY_CSI_PR('l', 1047) :        resetMode      (MODE_AppScreen); break; //XTERM
00563 
00564     //FIXME: Unitoken: save translations
00565     case TY_CSI_PR('h', 1048) :      saveCursor           (          ); break; //XTERM
00566     case TY_CSI_PR('l', 1048) :      restoreCursor        (          ); break; //XTERM
00567 
00568     //FIXME: every once new sequences like this pop up in xterm.
00569     //       Here's a guess of what they could mean.
00570     case TY_CSI_PR('h', 1049) :          setMode      (MODE_AppScreen); break; //XTERM
00571     case TY_CSI_PR('l', 1049) :        resetMode      (MODE_AppScreen); break; //XTERM
00572 
00573     //FIXME: when changing between vt52 and ansi mode evtl do some resetting.
00574     case TY_VT52__('A'      ) : scr->cursorUp             (         1); break; //VT52
00575     case TY_VT52__('B'      ) : scr->cursorDown           (         1); break; //VT52
00576     case TY_VT52__('C'      ) : scr->cursorRight          (         1); break; //VT52
00577     case TY_VT52__('D'      ) : scr->cursorLeft           (         1); break; //VT52
00578 
00579     case TY_VT52__('F'      ) :      setAndUseCharset     (0,     '0'); break; //VT52
00580     case TY_VT52__('G'      ) :      setAndUseCharset     (0,     'B'); break; //VT52
00581 
00582     case TY_VT52__('H'      ) : scr->setCursorYX          (1,1       ); break; //VT52
00583     case TY_VT52__('I'      ) : scr->reverseIndex         (          ); break; //VT52
00584     case TY_VT52__('J'      ) : scr->clearToEndOfScreen   (          ); break; //VT52
00585     case TY_VT52__('K'      ) : scr->clearToEndOfLine     (          ); break; //VT52
00586     case TY_VT52__('Y'      ) : scr->setCursorYX          (p-31,q-31 ); break; //VT52
00587     case TY_VT52__('Z'      ) :      reportTerminalType   (          ); break; //VT52
00588     case TY_VT52__('<'      ) :          setMode      (MODE_Ansi     ); break; //VT52
00589     case TY_VT52__('='      ) :          setMode      (MODE_AppKeyPad); break; //VT52
00590     case TY_VT52__('>'      ) :        resetMode      (MODE_AppKeyPad); break; //VT52
00591 
00592     default : ReportErrorToken();    break;
00593   };
00594 }
00595 
00596 /* ------------------------------------------------------------------------- */
00597 /*                                                                           */
00598 /*                          Terminal to Host protocol                        */
00599 /*                                                                           */
00600 /* ------------------------------------------------------------------------- */
00601 
00602 /* 
00603    Outgoing bytes originate from several sources:
00604 
00605    - Replies to Enquieries.
00606    - Mouse Events
00607    - Keyboard Events
00608 */
00609 
00613 void TEmuVt102::sendString(const char* s)
00614 {
00615   emit sndBlock(s,strlen(s));
00616 }
00617 
00618 // Replies ----------------------------------------------------------------- --
00619 
00620 // This section copes with replies send as response to an enquiery control code.
00621 
00625 void TEmuVt102::reportCursorPosition()
00626 { char tmp[20];
00627   sprintf(tmp,"\033[%d;%dR",scr->getCursorY()+1,scr->getCursorX()+1);
00628   sendString(tmp);
00629 }
00630 
00631 /*
00632    What follows here is rather obsolete and faked stuff.
00633    The correspondent enquieries are neverthenless issued.
00634 */
00635 
00639 void TEmuVt102::reportTerminalType()
00640 {
00641 //FIXME: should change?
00642   if (getMode(MODE_Ansi))
00643 //  sendString("\033[?1;2c");     // I'm a VT100 with AP0 //FIXME: send only in response to ^[[0c
00644     sendString("\033[>0;115;0c"); // I'm a VT220          //FIXME: send only in response to ^[[>c
00645   else
00646     sendString("\033/Z");         // I'm a VT52
00647 }
00648 
00649 void TEmuVt102::reportTerminalParms(int p)
00650 // DECREPTPARM
00651 { char tmp[100];
00652   sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
00653   sendString(tmp);
00654 }
00655 
00659 void TEmuVt102::reportStatus()
00660 {
00661   sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
00662 }
00663 
00667 #define ANSWER_BACK "" // This is really obsolete VT100 stuff.
00668 
00669 void TEmuVt102::reportAnswerBack()
00670 {
00671   sendString(ANSWER_BACK);
00672 }
00673 
00674 // Mouse Handling ---------------------------------------------------------- --
00675 
00688 void TEmuVt102::onMouse( int cb, int cx, int cy )
00689 { char tmp[20];
00690   if (!connected) return;
00691   sprintf(tmp,"\033[M%c%c%c",cb+040,cx+040,cy+040);
00692   sendString(tmp);
00693 }
00694 
00695 // Keyboard Handling ------------------------------------------------------- --
00696 
00697 #define encodeMode(M,B) BITS(B,getMode(M))
00698 #define encodeStat(M,B) BITS(B,((ev->state() & (M)) == (M)))
00699 
00700 /*
00701    Keyboard event handling has been simplified somewhat by pushing
00702    the complications towards a configuration file [see KeyTrans class].
00703 */
00704 
00705 void TEmuVt102::onKeyPress( QKeyEvent* ev )
00706 {
00707   if (!connected) return; // someone else gets the keys
00708 
00709 //printf("State/Key: 0x%04x 0x%04x (%d,%d)\n",ev->state(),ev->key(),ev->text().length(),ev->text().length()?ev->text().ascii()[0]:0);
00710 
00711   // revert to non-history when typing
00712   if (scr->getHistCursor() != scr->getHistLines());
00713     scr->setHistCursor(scr->getHistLines());
00714 
00715   // lookup in keyboard translation table ...
00716   int cmd; const char* txt; int len;
00717   if (keytrans->findEntry(ev->key(), encodeMode(MODE_NewLine  , BITS_NewLine   ) + // OLD,
00718                                      encodeMode(MODE_Ansi     , BITS_Ansi      ) + // OBSOLETE,
00719                                      encodeMode(MODE_AppCuKeys, BITS_AppCuKeys ) + // VT100 stuff
00720                                      encodeStat(ControlButton , BITS_Control   ) +
00721                                      encodeStat(ShiftButton   , BITS_Shift     ) +
00722                                      encodeStat(AltButton     , BITS_Alt       ),
00723                           &cmd, &txt, &len ))
00724 //printf("cmd: %d, %s, %d\n",cmd,txt,len);
00725   switch(cmd) // ... and execute if found.
00726   {
00727     case CMD_emitSelection  : gui->emitSelection();           return;
00728     case CMD_scrollPageUp   : gui->doScroll(-gui->Lines()/2); return;
00729     case CMD_scrollPageDown : gui->doScroll(+gui->Lines()/2); return;
00730     case CMD_scrollLineUp   : gui->doScroll(-1             ); return;
00731     case CMD_scrollLineDown : gui->doScroll(+1             ); return;
00732     case CMD_send           : emit sndBlock(txt,len);         return;
00733     case CMD_prevSession    : emit prevSession();             return;
00734     case CMD_nextSession    : emit nextSession();             return;
00735   }
00736 
00737   // fall back handling
00738   if (!ev->text().isEmpty())
00739   {
00740     if (ev->state() & AltButton) sendString("\033"); // ESC, this is the ALT prefix
00742      if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='A')) sendString("\01");
00743      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='B')) sendString("\02");
00744      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='C')) sendString("\03");
00745      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='D')) sendString("\04");
00746      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='E')) sendString("\05");
00747      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='F')) sendString("\06");
00748      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='G')) sendString("\07");
00749      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='H')) sendString("\010");
00750      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='I')) sendString("\011");
00751      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='J')) sendString("\012");
00752      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='K')) sendString("\013");
00753      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='L')) sendString("\014");
00754      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='M')) sendString("\015");
00755      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='N')) sendString("\016");
00756      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='O')) sendString("\017");
00757      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='P')) sendString("\020");
00758      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='Q')) sendString("\021");
00759      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='R')) sendString("\022");
00760      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='S')) sendString("\023");
00761      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='T')) sendString("\024");
00762      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='U')) sendString("\025");
00763      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='V')) sendString("\026");
00764      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='W')) sendString("\027");
00765      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='X')) sendString("\030");
00766      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='Y')) sendString("\031");
00767      else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='Z')) sendString("\032");
00768    else {
00769    QCString s = codec->fromUnicode(ev->text());     // encode for application
00770     emit sndBlock(s.data(),s.length());              // we may well have s.length() > 1
00771    }
00772     return;
00773   }
00774 }
00775 
00776 /* ------------------------------------------------------------------------- */
00777 /*                                                                           */
00778 /*                                VT100 Charsets                             */
00779 /*                                                                           */
00780 /* ------------------------------------------------------------------------- */
00781 
00782 // Character Set Conversion ------------------------------------------------ --
00783 
00784 /* 
00785    The processing contains a VT100 specific code translation layer.
00786    It's still in use and mainly responsible for the line drawing graphics.
00787 
00788    These and some other glyphs are assigned to codes (0x5f-0xfe)
00789    normally occupied by the latin letters. Since this codes also
00790    appear within control sequences, the extra code conversion
00791    does not permute with the tokenizer and is placed behind it
00792    in the pipeline. It only applies to tokens, which represent
00793    plain characters.
00794 
00795    This conversion it eventually continued in TEWidget.C, since 
00796    it might involve VT100 enhanced fonts, which have these
00797    particular glyphs allocated in (0x00-0x1f) in their code page.
00798 */
00799 
00800 #define CHARSET charset[scr==screen[1]]
00801 
00802 // Apply current character map.
00803 
00804 unsigned short TEmuVt102::applyCharset(unsigned short c)
00805 {
00806   if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
00807   if (CHARSET.pound                && c == '#' ) return 0xa3; //This mode is obsolete
00808   return c;
00809 }
00810 
00811 /*
00812    "Charset" related part of the emulation state.
00813    This configures the VT100 charset filter.
00814 
00815    While most operation work on the current screen,
00816    the following two are different.
00817 */
00818 
00819 void TEmuVt102::resetCharset(int scrno)
00820 {
00821   charset[scrno].cu_cs   = 0;
00822   strncpy(charset[scrno].charset,"BBBB",4);
00823   charset[scrno].sa_graphic = FALSE;
00824   charset[scrno].sa_pound   = FALSE;
00825   charset[scrno].graphic = FALSE;
00826   charset[scrno].pound   = FALSE;
00827 }
00828 
00832 void TEmuVt102::setCharset(int n, int cs) // on both screens.
00833 {
00834   charset[0].charset[n&3] = cs; useCharset(charset[0].cu_cs);
00835   charset[1].charset[n&3] = cs; useCharset(charset[1].cu_cs);
00836 }
00837 
00841 void TEmuVt102::setAndUseCharset(int n, int cs)
00842 {
00843   CHARSET.charset[n&3] = cs;
00844   useCharset(n&3);
00845 }
00846 
00850 void TEmuVt102::useCharset(int n)
00851 {
00852   CHARSET.cu_cs   = n&3;
00853   CHARSET.graphic = (CHARSET.charset[n&3] == '0');
00854   CHARSET.pound   = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
00855 }
00856 
00859 void TEmuVt102::saveCursor()
00860 {
00861   CHARSET.sa_graphic = CHARSET.graphic;
00862   CHARSET.sa_pound   = CHARSET.pound; //This mode is obsolete
00863   // we are not clear about these
00864   //sa_charset = charsets[cScreen->charset];
00865   //sa_charset_num = cScreen->charset;
00866   scr->saveCursor();
00867 }
00868 
00871 void TEmuVt102::restoreCursor()
00872 {
00873   CHARSET.graphic = CHARSET.sa_graphic;
00874   CHARSET.pound   = CHARSET.sa_pound; //This mode is obsolete
00875   scr->restoreCursor();
00876 }
00877 
00878 /* ------------------------------------------------------------------------- */
00879 /*                                                                           */
00880 /*                                Mode Operations                            */
00881 /*                                                                           */
00882 /* ------------------------------------------------------------------------- */
00883 
00884 /*
00885    Some of the emulations state is either added to the state of the screens.
00886 
00887    This causes some scoping problems, since different emulations choose to
00888    located the mode either to the current screen or to both.
00889 
00890    For strange reasons, the extend of the rendition attributes ranges over
00891    all screens and not over the actual screen.
00892 
00893    We decided on the precise precise extend, somehow.
00894 */
00895 
00896 // "Mode" related part of the state. These are all booleans.
00897 
00898 void TEmuVt102::resetModes()
00899 {
00900   resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000);
00901   resetMode(MODE_AppScreen); saveMode(MODE_AppScreen);
00902   // here come obsolete modes
00903   resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys);
00904   resetMode(MODE_NewLine  );
00905     setMode(MODE_Ansi     );
00906 }
00907 
00908 void TEmuVt102::setMode(int m)
00909 {
00910   currParm.mode[m] = TRUE;
00911   switch (m)
00912   {
00913     case MODE_Mouse1000 : gui->setMouseMarks(FALSE);
00914     break;
00915     case MODE_AppScreen : screen[1]->clearSelection();
00916                           screen[1]->clearEntireScreen();
00917                           setScreen(1);
00918     break;
00919   }
00920   if (m < MODES_SCREEN || m == MODE_NewLine)
00921   {
00922     screen[0]->setMode(m);
00923     screen[1]->setMode(m);
00924   }
00925 }
00926 
00927 void TEmuVt102::resetMode(int m)
00928 {
00929   currParm.mode[m] = FALSE;
00930   switch (m)
00931   {
00932     case MODE_Mouse1000 : gui->setMouseMarks(TRUE);
00933     break;
00934     case MODE_AppScreen : screen[0]->clearSelection();
00935                           setScreen(0);
00936     break;
00937   }
00938   if (m < MODES_SCREEN || m == MODE_NewLine)
00939   {
00940     screen[0]->resetMode(m);
00941     screen[1]->resetMode(m);
00942   }
00943 }
00944 
00945 void TEmuVt102::saveMode(int m)
00946 {
00947   saveParm.mode[m] = currParm.mode[m];
00948 }
00949 
00950 void TEmuVt102::restoreMode(int m)
00951 {
00952   if(saveParm.mode[m]) setMode(m); else resetMode(m);
00953 }
00954 
00955 BOOL TEmuVt102::getMode(int m)
00956 {
00957   return currParm.mode[m];
00958 }
00959 
00960 void TEmuVt102::setConnect(bool c)
00961 {
00962   TEmulation::setConnect(c);
00963   if (c)
00964   { // refresh mouse mode
00965     if (getMode(MODE_Mouse1000))
00966       setMode(MODE_Mouse1000);
00967     else
00968       resetMode(MODE_Mouse1000);
00969   }
00970 }
00971 
00972 /* ------------------------------------------------------------------------- */
00973 /*                                                                           */
00974 /*                               Diagnostic                                  */
00975 /*                                                                           */
00976 /* ------------------------------------------------------------------------- */
00977 
00989 static void hexdump(int* s, int len)
00990 { int i;
00991   for (i = 0; i < len; i++)
00992   {
00993     if (s[i] == '\\')
00994       printf("\\\\");
00995     else
00996     if ((s[i]) > 32 && s[i] < 127)
00997       printf("%c",s[i]);
00998     else
00999       printf("\\%04x(hex)",s[i]);
01000   }
01001 }
01002 
01003 void TEmuVt102::scan_buffer_report()
01004 {
01005   if (ppos == 0 || ppos == 1 && (pbuf[0] & 0xff) >= 32) return;
01006   printf("token: "); hexdump(pbuf,ppos); printf("\n");
01007 }
01008 
01012 void TEmuVt102::ReportErrorToken()
01013 {
01014   printf("undecodable "); scan_buffer_report();
01015 }

Generated on Sat Nov 5 16:15:27 2005 for OPIE by  doxygen 1.4.2