00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00034
00035 #if defined(AVOID_XKB)
00036 #undef HAVE_XKB
00037 #endif
00038
00039
00040 #include <stdio.h>
00041 #include <unistd.h>
00042 #include <assert.h>
00043
00044
00045 #include <QtCore/QEvent>
00046 #include <QtGui/QKeyEvent>
00047 #include <QtCore/QByteRef>
00048
00049
00050 #include <kdebug.h>
00051 #include <klocale.h>
00052
00053
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
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
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
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
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
00207
00208
00209
00210
00211
00212
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
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
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
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
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
00294
00295 void Vt102Emulation::receiveChar(int cc)
00296 {
00297 int i;
00298 if (cc == 127) return;
00299
00300 if (ces( CTL))
00301 {
00302
00303
00304
00305 if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken();
00306 if (cc != ESC) { tau( TY_CTL(cc+'@' ), 0, 0); return; }
00307 }
00308
00309 pushToToken(cc);
00310
00311 int* s = pbuf;
00312 int p = ppos;
00313
00314 if (getMode(MODE_Ansi))
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
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); }
00339 else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)
00340 {
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 {
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
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
00374
00375
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
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
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;
00449
00450
00451
00452 case TY_CTL('@' ) : break;
00453 case TY_CTL('A' ) : break;
00454 case TY_CTL('B' ) : break;
00455 case TY_CTL('C' ) : break;
00456 case TY_CTL('D' ) : break;
00457 case TY_CTL('E' ) : reportAnswerBack ( ); break;
00458 case TY_CTL('F' ) : break;
00459 case TY_CTL('G' ) : emit stateSet(NOTIFYBELL);
00460 break;
00461 case TY_CTL('H' ) : _currentScreen->backspace ( ); break;
00462 case TY_CTL('I' ) : _currentScreen->tab ( ); break;
00463 case TY_CTL('J' ) : _currentScreen->newLine ( ); break;
00464 case TY_CTL('K' ) : _currentScreen->newLine ( ); break;
00465 case TY_CTL('L' ) : _currentScreen->newLine ( ); break;
00466 case TY_CTL('M' ) : _currentScreen->toStartOfLine ( ); break;
00467
00468 case TY_CTL('N' ) : useCharset ( 1); break;
00469 case TY_CTL('O' ) : useCharset ( 0); break;
00470
00471 case TY_CTL('P' ) : break;
00472 case TY_CTL('Q' ) : break;
00473 case TY_CTL('R' ) : break;
00474 case TY_CTL('S' ) : break;
00475 case TY_CTL('T' ) : break;
00476 case TY_CTL('U' ) : break;
00477 case TY_CTL('V' ) : break;
00478 case TY_CTL('W' ) : break;
00479 case TY_CTL('X' ) : _currentScreen->displayCharacter ( 0x2592); break;
00480 case TY_CTL('Y' ) : break;
00481 case TY_CTL('Z' ) : _currentScreen->displayCharacter ( 0x2592); break;
00482 case TY_CTL('[' ) : break;
00483 case TY_CTL('\\' ) : break;
00484 case TY_CTL(']' ) : break;
00485 case TY_CTL('^' ) : break;
00486 case TY_CTL('_' ) : break;
00487
00488 case TY_ESC('D' ) : _currentScreen->index ( ); break;
00489 case TY_ESC('E' ) : _currentScreen->nextLine ( ); break;
00490 case TY_ESC('H' ) : _currentScreen->changeTabStop (true ); break;
00491 case TY_ESC('M' ) : _currentScreen->reverseIndex ( ); break;
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;
00503
00504 case TY_ESC_CS('(', '0') : setCharset (0, '0'); break;
00505 case TY_ESC_CS('(', 'A') : setCharset (0, 'A'); break;
00506 case TY_ESC_CS('(', 'B') : setCharset (0, 'B'); break;
00507
00508 case TY_ESC_CS(')', '0') : setCharset (1, '0'); break;
00509 case TY_ESC_CS(')', 'A') : setCharset (1, 'A'); break;
00510 case TY_ESC_CS(')', 'B') : setCharset (1, 'B'); break;
00511
00512 case TY_ESC_CS('*', '0') : setCharset (2, '0'); break;
00513 case TY_ESC_CS('*', 'A') : setCharset (2, 'A'); break;
00514 case TY_ESC_CS('*', 'B') : setCharset (2, 'B'); break;
00515
00516 case TY_ESC_CS('+', '0') : setCharset (3, '0'); break;
00517 case TY_ESC_CS('+', 'A') : setCharset (3, 'A'); break;
00518 case TY_ESC_CS('+', 'B') : setCharset (3, 'B'); break;
00519
00520 case TY_ESC_CS('%', 'G') : setCodec (Utf8Codec ); break;
00521 case TY_ESC_CS('%', '@') : setCodec (LocaleCodec ); break;
00522
00523 case TY_ESC_DE('3' ) :
00524 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
00525 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
00526 break;
00527 case TY_ESC_DE('4' ) :
00528 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
00529 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
00530 break;
00531 case TY_ESC_DE('5' ) :
00532 _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , false);
00533 _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
00534 break;
00535 case TY_ESC_DE('6' ) :
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
00542 case TY_CSI_PS('t', 8) : setImageSize( q , p ); break;
00543
00544
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;
00555 case TY_CSI_PS('g', 3) : _currentScreen->clearTabStops ( ); break;
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) : break;
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;
00566 case TY_CSI_PS('m', 4) : _currentScreen-> setRendition (RE_UNDERLINE); break;
00567 case TY_CSI_PS('m', 5) : _currentScreen-> setRendition (RE_BLINK ); break;
00568 case TY_CSI_PS('m', 7) : _currentScreen-> setRendition (RE_REVERSE ); break;
00569 case TY_CSI_PS('m', 10) : break;
00570 case TY_CSI_PS('m', 11) : break;
00571 case TY_CSI_PS('m', 12) : break;
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) : break;
00624 case TY_CSI_PS('q', 1) : break;
00625 case TY_CSI_PS('q', 2) : break;
00626 case TY_CSI_PS('q', 3) : break;
00627 case TY_CSI_PS('q', 4) : break;
00628 case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break;
00629 case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break;
00630
00631 case TY_CSI_PN('@' ) : _currentScreen->insertChars (p ); break;
00632 case TY_CSI_PN('A' ) : _currentScreen->cursorUp (p ); break;
00633 case TY_CSI_PN('B' ) : _currentScreen->cursorDown (p ); break;
00634 case TY_CSI_PN('C' ) : _currentScreen->cursorRight (p ); break;
00635 case TY_CSI_PN('D' ) : _currentScreen->cursorLeft (p ); break;
00636 case TY_CSI_PN('G' ) : _currentScreen->setCursorX (p ); break;
00637 case TY_CSI_PN('H' ) : _currentScreen->setCursorYX (p, q); break;
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;
00647 case TY_CSI_PN('d' ) : _currentScreen->setCursorY (p ); break;
00648 case TY_CSI_PN('f' ) : _currentScreen->setCursorYX (p, q); break;
00649 case TY_CSI_PN('r' ) : setMargins (p, q); break;
00650 case TY_CSI_PN('y' ) : break;
00651
00652 case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break;
00653 case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break;
00654 case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break;
00655 case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break;
00656
00657 case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break;
00658
00659 case TY_CSI_PR('h', 3) : setMode (MODE_132Columns);break;
00660 case TY_CSI_PR('l', 3) : resetMode (MODE_132Columns);break;
00661
00662 case TY_CSI_PR('h', 4) : break;
00663 case TY_CSI_PR('l', 4) : break;
00664
00665 case TY_CSI_PR('h', 5) : _currentScreen-> setMode (MODE_Screen ); break;
00666 case TY_CSI_PR('l', 5) : _currentScreen-> resetMode (MODE_Screen ); break;
00667
00668 case TY_CSI_PR('h', 6) : _currentScreen-> setMode (MODE_Origin ); break;
00669 case TY_CSI_PR('l', 6) : _currentScreen-> resetMode (MODE_Origin ); break;
00670 case TY_CSI_PR('s', 6) : _currentScreen-> saveMode (MODE_Origin ); break;
00671 case TY_CSI_PR('r', 6) : _currentScreen->restoreMode (MODE_Origin ); break;
00672
00673 case TY_CSI_PR('h', 7) : _currentScreen-> setMode (MODE_Wrap ); break;
00674 case TY_CSI_PR('l', 7) : _currentScreen-> resetMode (MODE_Wrap ); break;
00675 case TY_CSI_PR('s', 7) : _currentScreen-> saveMode (MODE_Wrap ); break;
00676 case TY_CSI_PR('r', 7) : _currentScreen->restoreMode (MODE_Wrap ); break;
00677
00678 case TY_CSI_PR('h', 8) : break;
00679 case TY_CSI_PR('l', 8) : break;
00680 case TY_CSI_PR('s', 8) : break;
00681 case TY_CSI_PR('r', 8) : break;
00682
00683 case TY_CSI_PR('h', 9) : break;
00684 case TY_CSI_PR('l', 9) : break;
00685 case TY_CSI_PR('s', 9) : break;
00686 case TY_CSI_PR('r', 9) : break;
00687
00688 case TY_CSI_PR('h', 12) : break;
00689 case TY_CSI_PR('l', 12) : break;
00690 case TY_CSI_PR('s', 12) : break;
00691 case TY_CSI_PR('r', 12) : break;
00692
00693 case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break;
00694 case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break;
00695 case TY_CSI_PR('s', 25) : saveMode (MODE_Cursor ); break;
00696 case TY_CSI_PR('r', 25) : restoreMode (MODE_Cursor ); break;
00697
00698 case TY_CSI_PR('h', 40) : setMode(MODE_Allow132Columns ); break;
00699 case TY_CSI_PR('l', 40) : resetMode(MODE_Allow132Columns ); break;
00700
00701 case TY_CSI_PR('h', 41) : break;
00702 case TY_CSI_PR('l', 41) : break;
00703 case TY_CSI_PR('s', 41) : break;
00704 case TY_CSI_PR('r', 41) : break;
00705
00706 case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break;
00707 case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break;
00708 case TY_CSI_PR('s', 47) : saveMode (MODE_AppScreen); break;
00709 case TY_CSI_PR('r', 47) : restoreMode (MODE_AppScreen); break;
00710
00711 case TY_CSI_PR('h', 67) : break;
00712 case TY_CSI_PR('l', 67) : break;
00713 case TY_CSI_PR('s', 67) : break;
00714 case TY_CSI_PR('r', 67) : break;
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break;
00731 case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break;
00732 case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break;
00733 case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break;
00734
00735 case TY_CSI_PR('h', 1001) : break;
00736 case TY_CSI_PR('l', 1001) : resetMode (MODE_Mouse1001); break;
00737 case TY_CSI_PR('s', 1001) : break;
00738 case TY_CSI_PR('r', 1001) : break;
00739
00740 case TY_CSI_PR('h', 1002) : setMode (MODE_Mouse1002); break;
00741 case TY_CSI_PR('l', 1002) : resetMode (MODE_Mouse1002); break;
00742 case TY_CSI_PR('s', 1002) : saveMode (MODE_Mouse1002); break;
00743 case TY_CSI_PR('r', 1002) : restoreMode (MODE_Mouse1002); break;
00744
00745 case TY_CSI_PR('h', 1003) : setMode (MODE_Mouse1003); break;
00746 case TY_CSI_PR('l', 1003) : resetMode (MODE_Mouse1003); break;
00747 case TY_CSI_PR('s', 1003) : saveMode (MODE_Mouse1003); break;
00748 case TY_CSI_PR('r', 1003) : restoreMode (MODE_Mouse1003); break;
00749
00750 case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break;
00751 case TY_CSI_PR('l', 1047) : _screen[1]->clearEntireScreen(); resetMode(MODE_AppScreen); break;
00752 case TY_CSI_PR('s', 1047) : saveMode (MODE_AppScreen); break;
00753 case TY_CSI_PR('r', 1047) : restoreMode (MODE_AppScreen); break;
00754
00755
00756 case TY_CSI_PR('h', 1048) : saveCursor ( ); break;
00757 case TY_CSI_PR('l', 1048) : restoreCursor ( ); break;
00758 case TY_CSI_PR('s', 1048) : saveCursor ( ); break;
00759 case TY_CSI_PR('r', 1048) : restoreCursor ( ); break;
00760
00761
00762
00763 case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break;
00764 case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break;
00765
00766
00767 case TY_CSI_PE('p' ) : break;
00768
00769
00770 case TY_VT52('A' ) : _currentScreen->cursorUp ( 1); break;
00771 case TY_VT52('B' ) : _currentScreen->cursorDown ( 1); break;
00772 case TY_VT52('C' ) : _currentScreen->cursorRight ( 1); break;
00773 case TY_VT52('D' ) : _currentScreen->cursorLeft ( 1); break;
00774
00775 case TY_VT52('F' ) : setAndUseCharset (0, '0'); break;
00776 case TY_VT52('G' ) : setAndUseCharset (0, 'B'); break;
00777
00778 case TY_VT52('H' ) : _currentScreen->setCursorYX (1,1 ); break;
00779 case TY_VT52('I' ) : _currentScreen->reverseIndex ( ); break;
00780 case TY_VT52('J' ) : _currentScreen->clearToEndOfScreen ( ); break;
00781 case TY_VT52('K' ) : _currentScreen->clearToEndOfLine ( ); break;
00782 case TY_VT52('Y' ) : _currentScreen->setCursorYX (p-31,q-31 ); break;
00783 case TY_VT52('Z' ) : reportTerminalType ( ); break;
00784 case TY_VT52('<' ) : setMode (MODE_Ansi ); break;
00785 case TY_VT52('=' ) : setMode (MODE_AppKeyPad); break;
00786 case TY_VT52('>' ) : resetMode (MODE_AppKeyPad); break;
00787
00788 case TY_CSI_PG('c' ) : reportSecondaryAttributes( ); break;
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
00805
00806
00807
00808
00809
00810
00811
00812
00813
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
00828
00829
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
00842
00843
00844
00848 void Vt102Emulation::reportTerminalType()
00849 {
00850
00851
00852
00853
00854
00855 if (getMode(MODE_Ansi))
00856 sendString("\033[?1;2c");
00857 else
00858 sendString("\033/Z");
00859 }
00860
00861 void Vt102Emulation::reportSecondaryAttributes()
00862 {
00863
00864 if (getMode(MODE_Ansi))
00865 sendString("\033[>0;115;0c");
00866 else
00867 sendString("\033/Z");
00868
00869 }
00870
00871 void Vt102Emulation::reportTerminalParms(int p)
00872
00873 { char tmp[100];
00874 sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p);
00875 sendString(tmp);
00876 }
00877
00881 void Vt102Emulation::reportStatus()
00882 {
00883 sendString("\033[0n");
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
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
00918
00919 if (cb >= 4) cb += 0x3c;
00920
00921
00922 if ( (getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1 )
00923 cb += 0x20;
00924
00925 sprintf(tmp,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20);
00926 sendString(tmp);
00927 }
00928
00929
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);
00942 }
00943
00944 }
00945 void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
00946 {
00947 Qt::KeyboardModifiers modifiers = event->modifiers();
00948 KeyboardTranslator::States states = KeyboardTranslator::NoState;
00949
00950
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
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
00966 if ( _keyTranslator )
00967 {
00968 KeyboardTranslator::Entry entry = _keyTranslator->findEntry(
00969 event->key() ,
00970 modifiers,
00971 states );
00972
00973
00974 QByteArray textToSend;
00975
00976
00977
00978
00979
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
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
01008
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
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043 #define CHARSET _charset[_currentScreen==_screen[1]]
01044
01045
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;
01051 return c;
01052 }
01053
01054
01055
01056
01057
01058
01059
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)
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');
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;
01109
01110
01111
01112 _currentScreen->saveCursor();
01113 }
01114
01117 void Vt102Emulation::restoreCursor()
01118 {
01119 CHARSET.graphic = CHARSET.sa_graphic;
01120 CHARSET.pound = CHARSET.sa_pound;
01121 _currentScreen->restoreCursor();
01122 }
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144 void Vt102Emulation::resetModes()
01145 {
01146
01147
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
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
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