2
This file is part of Konsole, an X terminal.
4
Copyright 2007-2008 by Robert Knight <robert.knight@gmail.com>
5
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24
#include "Vt102Emulation.h"
27
//#include <config-konsole.h>
29
// this allows konsole to be compiled without XKB and XTEST extensions
30
// even though it might be available on a particular system.
31
#if defined(AVOID_XKB)
36
void scrolllock_set_off();
37
void scrolllock_set_on();
52
//#include <klocale.h>
55
#include "KeyboardTranslator.h"
59
using namespace Konsole;
61
Vt102Emulation::Vt102Emulation()
63
_titleUpdateTimer(new QTimer(this))
65
_titleUpdateTimer->setSingleShot(true);
66
QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle()));
72
Vt102Emulation::~Vt102Emulation()
75
void Vt102Emulation::clearEntireScreen()
77
_currentScreen->clearEntireScreen();
81
void Vt102Emulation::reset()
89
setCodec(LocaleCodec);
94
/* ------------------------------------------------------------------------- */
96
/* Processing the incoming byte stream */
98
/* ------------------------------------------------------------------------- */
100
/* Incoming Bytes Event pipeline
102
This section deals with decoding the incoming character stream.
103
Decoding means here, that the stream is first separated into `tokens'
104
which are then mapped to a `meaning' provided as operations by the
105
`Screen' class or by the emulation class itself.
107
The pipeline proceeds as follows:
109
- Tokenizing the ESC codes (onReceiveChar)
110
- VT100 code page translation of plain characters (applyCharset)
111
- Interpretation of ESC codes (processToken)
113
The escape codes and their meaning are described in the
114
technical reference of this program.
117
// Tokens ------------------------------------------------------------------ --
120
Since the tokens are the central notion if this section, we've put them
121
in front. They provide the syntactical elements used to represent the
122
terminals operations as byte sequences.
124
They are encodes here into a single machine word, so that we can later
125
switch over them easily. Depending on the token itself, additional
126
argument variables are filled with parameter values.
128
The tokens are defined below:
130
- CHR - Printable characters (32..255 but DEL (=127))
131
- CTL - Control characters (0..31 but ESC (= 27), DEL)
132
- ESC - Escape codes of the form <ESC><CHR but `[]()+*#'>
133
- ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C
134
- CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C
135
- CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C
136
- CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C
137
- CSI_PE - Escape codes of the form <ESC>'[' '!' {Pn} ';' ... C
138
- VT52 - VT52 escape codes
141
- XTE_HA - Xterm window/terminal attribute commands
142
of the form <ESC>`]' {Pn} `;' {Text} <BEL>
143
(Note that these are handled differently to the other formats)
145
The last two forms allow list of arguments. Since the elements of
146
the lists are treated individually the same way, they are passed
147
as individual tokens to the interpretation. Further, because the
148
meaning of the parameters are names (althought represented as numbers),
149
they are includes within the token ('N').
153
#define TY_CONSTRUCT(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
155
#define TY_CHR( ) TY_CONSTRUCT(0,0,0)
156
#define TY_CTL(A ) TY_CONSTRUCT(1,A,0)
157
#define TY_ESC(A ) TY_CONSTRUCT(2,A,0)
158
#define TY_ESC_CS(A,B) TY_CONSTRUCT(3,A,B)
159
#define TY_ESC_DE(A ) TY_CONSTRUCT(4,A,0)
160
#define TY_CSI_PS(A,N) TY_CONSTRUCT(5,A,N)
161
#define TY_CSI_PN(A ) TY_CONSTRUCT(6,A,0)
162
#define TY_CSI_PR(A,N) TY_CONSTRUCT(7,A,N)
164
#define TY_VT52(A) TY_CONSTRUCT(8,A,0)
165
#define TY_CSI_PG(A) TY_CONSTRUCT(9,A,0)
166
#define TY_CSI_PE(A) TY_CONSTRUCT(10,A,0)
168
#define MAX_ARGUMENT 4096
170
// Tokenizer --------------------------------------------------------------- --
172
/* The tokenizer's state
174
The state is represented by the buffer (tokenBuffer, tokenBufferPos),
175
and accompanied by decoded arguments kept in (argv,argc).
176
Note that they are kept internal in the tokenizer.
179
void Vt102Emulation::resetTokenizer()
187
void Vt102Emulation::addDigit(int digit)
189
if (argv[argc] < MAX_ARGUMENT)
190
argv[argc] = 10*argv[argc] + digit;
193
void Vt102Emulation::addArgument()
195
argc = qMin(argc+1,MAXARGS-1);
199
void Vt102Emulation::addToCurrentToken(int cc)
201
tokenBuffer[tokenBufferPos] = cc;
202
tokenBufferPos = qMin(tokenBufferPos+1,MAX_TOKEN_LENGTH-1);
205
// Character Class flags used while decoding
207
#define CTL 1 // Control character
208
#define CHR 2 // Printable character
209
#define CPN 4 // TODO: Document me
210
#define DIG 8 // Digit
211
#define SCS 16 // TODO: Document me
212
#define GRP 32 // TODO: Document me
213
#define CPS 64 // Character which indicates end of window resize
214
// escape sequence '\e[8;<row>;<col>t'
216
void Vt102Emulation::initTokenizer()
220
for(i = 0;i < 256; ++i)
222
for(i = 0;i < 32; ++i)
224
for(i = 32;i < 256; ++i)
226
for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; ++s)
227
charClass[*s] |= CPN;
228
// resize = \e[8;<row>;<col>t
229
for(s = (quint8*)"t"; *s; ++s)
230
charClass[*s] |= CPS;
231
for(s = (quint8*)"0123456789"; *s; ++s)
232
charClass[*s] |= DIG;
233
for(s = (quint8*)"()+*%"; *s; ++s)
234
charClass[*s] |= SCS;
235
for(s = (quint8*)"()+*#[]%"; *s; ++s)
236
charClass[*s] |= GRP;
241
/* Ok, here comes the nasty part of the decoder.
243
Instead of keeping an explicit state, we deduce it from the
244
token scanned so far. It is then immediately combined with
245
the current character to form a scanning decision.
247
This is done by the following defines.
249
- P is the length of the token scanned so far.
250
- L (often P-1) is the position on which contents we base a decision.
251
- C is a character or a group of characters (taken from 'charClass').
253
- 'cc' is the current character
254
- 's' is a pointer to the start of the token buffer
255
- 'p' is the current position within the token buffer
257
Note that they need to applied in proper order.
260
#define lec(P,L,C) (p == (P) && s[(L)] == (C))
261
#define lun( ) (p == 1 && cc >= 32 )
262
#define les(P,L,C) (p == (P) && s[L] < 256 && (charClass[s[(L)]] & (C)) == (C))
263
#define eec(C) (p >= 3 && cc == (C))
264
#define ees(C) (p >= 3 && cc < 256 && (charClass[cc] & (C)) == (C))
265
#define eps(C) (p >= 3 && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (charClass[cc] & (C)) == (C))
266
#define epp( ) (p >= 3 && s[2] == '?')
267
#define epe( ) (p >= 3 && s[2] == '!')
268
#define egt( ) (p >= 3 && s[2] == '>')
269
#define Xpe (tokenBufferPos >= 2 && tokenBuffer[1] == ']')
270
#define Xte (Xpe && cc == 7 )
271
#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte)
274
#define CNTL(c) ((c)-'@')
276
// process an incoming unicode character
277
void Vt102Emulation::receiveChar(int cc)
280
return; //VT100: ignore.
284
// DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
285
// This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do
286
// of course. Guess this originates from a weakly layered handling of the X-on
287
// X-off protocol, which comes really below this level.
288
if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC)
289
resetTokenizer(); //VT100: CAN or SUB
292
processToken(TY_CTL(cc+'@' ),0,0);
297
addToCurrentToken(cc);
299
int* s = tokenBuffer;
300
int p = tokenBufferPos;
302
if (getMode(MODE_Ansi))
304
if (lec(1,0,ESC)) { return; }
305
if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('['); return; }
306
if (les(2,1,GRP)) { return; }
307
if (Xte ) { processWindowAttributeChange(); resetTokenizer(); return; }
308
if (Xpe ) { return; }
309
if (lec(3,2,'?')) { return; }
310
if (lec(3,2,'>')) { return; }
311
if (lec(3,2,'!')) { return; }
312
if (lun( )) { processToken( TY_CHR(), applyCharset(cc), 0); resetTokenizer(); return; }
313
if (lec(2,0,ESC)) { processToken( TY_ESC(s[1]), 0, 0); resetTokenizer(); return; }
314
if (les(3,1,SCS)) { processToken( TY_ESC_CS(s[1],s[2]), 0, 0); resetTokenizer(); return; }
315
if (lec(3,1,'#')) { processToken( TY_ESC_DE(s[2]), 0, 0); resetTokenizer(); return; }
316
if (eps( CPN)) { processToken( TY_CSI_PN(cc), argv[0],argv[1]); resetTokenizer(); return; }
318
// resize = \e[8;<row>;<col>t
321
processToken( TY_CSI_PS(cc, argv[0]), argv[1], argv[2]);
326
if (epe( )) { processToken( TY_CSI_PE(cc), 0, 0); resetTokenizer(); return; }
327
if (ees(DIG)) { addDigit(cc-'0'); return; }
328
if (eec(';')) { addArgument(); return; }
329
for (int i=0;i<=argc;i++)
332
processToken( TY_CSI_PR(cc,argv[i]), 0, 0);
334
processToken( TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c
335
else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)
337
// ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m
339
processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i+1] << 8) | argv[i+2]);
342
else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 5)
344
// ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m
346
processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]);
349
processToken( TY_CSI_PS(cc,argv[i]), 0, 0);
360
processToken( TY_CHR(), s[0], 0);
370
processToken( TY_VT52(s[1] ), 0, 0);
374
processToken( TY_VT52(s[1]), s[2], s[3]);
379
void Vt102Emulation::processWindowAttributeChange()
381
// Describes the window or terminal session attribute to change
382
// See Session::UserTitleChange for possible values
383
int attributeToChange = 0;
385
for (i = 2; i < tokenBufferPos &&
386
tokenBuffer[i] >= '0' &&
387
tokenBuffer[i] <= '9'; i++)
389
attributeToChange = 10 * attributeToChange + (tokenBuffer[i]-'0');
392
if (tokenBuffer[i] != ';')
394
reportDecodingError();
399
newValue.reserve(tokenBufferPos-i-2);
400
for (int j = 0; j < tokenBufferPos-i-2; j++)
401
newValue[j] = tokenBuffer[i+1+j];
403
_pendingTitleUpdates[attributeToChange] = newValue;
404
_titleUpdateTimer->start(20);
407
void Vt102Emulation::updateTitle()
409
QListIterator<int> iter( _pendingTitleUpdates.keys() );
410
while (iter.hasNext()) {
411
int arg = iter.next();
412
emit titleChanged( arg , _pendingTitleUpdates[arg] );
414
_pendingTitleUpdates.clear();
417
// Interpreting Codes ---------------------------------------------------------
420
Now that the incoming character stream is properly tokenized,
421
meaning is assigned to them. These are either operations of
422
the current _screen, or of the emulation class itself.
424
The token to be interpreteted comes in as a machine word
425
possibly accompanied by two parameters.
427
Likewise, the operations assigned to, come with up to two
428
arguments. One could consider to make up a proper table
429
from the function below.
431
The technical reference manual provides more information
435
void Vt102Emulation::processToken(int token, int p, int q)
440
case TY_CHR( ) : _currentScreen->displayCharacter (p ); break; //UTF16
442
// 127 DEL : ignored on input
444
case TY_CTL('@' ) : /* NUL: ignored */ break;
445
case TY_CTL('A' ) : /* SOH: ignored */ break;
446
case TY_CTL('B' ) : /* STX: ignored */ break;
447
case TY_CTL('C' ) : /* ETX: ignored */ break;
448
case TY_CTL('D' ) : /* EOT: ignored */ break;
449
case TY_CTL('E' ) : reportAnswerBack ( ); break; //VT100
450
case TY_CTL('F' ) : /* ACK: ignored */ break;
451
case TY_CTL('G' ) : emit stateSet(NOTIFYBELL);
453
case TY_CTL('H' ) : _currentScreen->backspace ( ); break; //VT100
454
case TY_CTL('I' ) : _currentScreen->tab ( ); break; //VT100
455
case TY_CTL('J' ) : _currentScreen->newLine ( ); break; //VT100
456
case TY_CTL('K' ) : _currentScreen->newLine ( ); break; //VT100
457
case TY_CTL('L' ) : _currentScreen->newLine ( ); break; //VT100
458
case TY_CTL('M' ) : _currentScreen->toStartOfLine ( ); break; //VT100
460
case TY_CTL('N' ) : useCharset ( 1); break; //VT100
461
case TY_CTL('O' ) : useCharset ( 0); break; //VT100
463
case TY_CTL('P' ) : /* DLE: ignored */ break;
464
case TY_CTL('Q' ) : /* DC1: XON continue */ break; //VT100
465
case TY_CTL('R' ) : /* DC2: ignored */ break;
466
case TY_CTL('S' ) : /* DC3: XOFF halt */ break; //VT100
467
case TY_CTL('T' ) : /* DC4: ignored */ break;
468
case TY_CTL('U' ) : /* NAK: ignored */ break;
469
case TY_CTL('V' ) : /* SYN: ignored */ break;
470
case TY_CTL('W' ) : /* ETB: ignored */ break;
471
case TY_CTL('X' ) : _currentScreen->displayCharacter ( 0x2592); break; //VT100
472
case TY_CTL('Y' ) : /* EM : ignored */ break;
473
case TY_CTL('Z' ) : _currentScreen->displayCharacter ( 0x2592); break; //VT100
474
case TY_CTL('[' ) : /* ESC: cannot be seen here. */ break;
475
case TY_CTL('\\' ) : /* FS : ignored */ break;
476
case TY_CTL(']' ) : /* GS : ignored */ break;
477
case TY_CTL('^' ) : /* RS : ignored */ break;
478
case TY_CTL('_' ) : /* US : ignored */ break;
480
case TY_ESC('D' ) : _currentScreen->index ( ); break; //VT100
481
case TY_ESC('E' ) : _currentScreen->nextLine ( ); break; //VT100
482
case TY_ESC('H' ) : _currentScreen->changeTabStop (true ); break; //VT100
483
case TY_ESC('M' ) : _currentScreen->reverseIndex ( ); break; //VT100
484
case TY_ESC('Z' ) : reportTerminalType ( ); break;
485
case TY_ESC('c' ) : reset ( ); break;
487
case TY_ESC('n' ) : useCharset ( 2); break;
488
case TY_ESC('o' ) : useCharset ( 3); break;
489
case TY_ESC('7' ) : saveCursor ( ); break;
490
case TY_ESC('8' ) : restoreCursor ( ); break;
492
case TY_ESC('=' ) : setMode (MODE_AppKeyPad); break;
493
case TY_ESC('>' ) : resetMode (MODE_AppKeyPad); break;
494
case TY_ESC('<' ) : setMode (MODE_Ansi ); break; //VT100
496
case TY_ESC_CS('(', '0') : setCharset (0, '0'); break; //VT100
497
case TY_ESC_CS('(', 'A') : setCharset (0, 'A'); break; //VT100
498
case TY_ESC_CS('(', 'B') : setCharset (0, 'B'); break; //VT100
500
case TY_ESC_CS(')', '0') : setCharset (1, '0'); break; //VT100
501
case TY_ESC_CS(')', 'A') : setCharset (1, 'A'); break; //VT100
502
case TY_ESC_CS(')', 'B') : setCharset (1, 'B'); break; //VT100
504
case TY_ESC_CS('*', '0') : setCharset (2, '0'); break; //VT100
505
case TY_ESC_CS('*', 'A') : setCharset (2, 'A'); break; //VT100
506
case TY_ESC_CS('*', 'B') : setCharset (2, 'B'); break; //VT100
508
case TY_ESC_CS('+', '0') : setCharset (3, '0'); break; //VT100
509
case TY_ESC_CS('+', 'A') : setCharset (3, 'A'); break; //VT100
510
case TY_ESC_CS('+', 'B') : setCharset (3, 'B'); break; //VT100
512
case TY_ESC_CS('%', 'G') : setCodec (Utf8Codec ); break; //LINUX
513
case TY_ESC_CS('%', '@') : setCodec (LocaleCodec ); break; //LINUX
515
case TY_ESC_DE('3' ) : /* Double height line, top half */
516
_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
517
_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
519
case TY_ESC_DE('4' ) : /* Double height line, bottom half */
520
_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
521
_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
523
case TY_ESC_DE('5' ) : /* Single width, single height line*/
524
_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , false);
525
_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
527
case TY_ESC_DE('6' ) : /* Double width, single height line*/
528
_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true);
529
_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
531
case TY_ESC_DE('8' ) : _currentScreen->helpAlign ( ); break;
533
// resize = \e[8;<row>;<col>t
534
case TY_CSI_PS('t', 8) : setImageSize( q /* columns */, p /* lines */ ); break;
536
// change tab text color : \e[28;<color>t color: 0-16,777,215
537
case TY_CSI_PS('t', 28) : emit changeTabTextColorRequest ( p ); break;
539
case TY_CSI_PS('K', 0) : _currentScreen->clearToEndOfLine ( ); break;
540
case TY_CSI_PS('K', 1) : _currentScreen->clearToBeginOfLine ( ); break;
541
case TY_CSI_PS('K', 2) : _currentScreen->clearEntireLine ( ); break;
542
case TY_CSI_PS('J', 0) : _currentScreen->clearToEndOfScreen ( ); break;
543
case TY_CSI_PS('J', 1) : _currentScreen->clearToBeginOfScreen ( ); break;
544
case TY_CSI_PS('J', 2) : _currentScreen->clearEntireScreen ( ); break;
545
case TY_CSI_PS('J', 3) : clearHistory(); break;
546
case TY_CSI_PS('g', 0) : _currentScreen->changeTabStop (false ); break; //VT100
547
case TY_CSI_PS('g', 3) : _currentScreen->clearTabStops ( ); break; //VT100
548
case TY_CSI_PS('h', 4) : _currentScreen-> setMode (MODE_Insert ); break;
549
case TY_CSI_PS('h', 20) : setMode (MODE_NewLine ); break;
550
case TY_CSI_PS('i', 0) : /* IGNORE: attached printer */ break; //VT100
551
case TY_CSI_PS('l', 4) : _currentScreen-> resetMode (MODE_Insert ); break;
552
case TY_CSI_PS('l', 20) : resetMode (MODE_NewLine ); break;
553
case TY_CSI_PS('s', 0) : saveCursor ( ); break;
554
case TY_CSI_PS('u', 0) : restoreCursor ( ); break;
556
case TY_CSI_PS('m', 0) : _currentScreen->setDefaultRendition ( ); break;
557
case TY_CSI_PS('m', 1) : _currentScreen-> setRendition (RE_BOLD ); break; //VT100
558
case TY_CSI_PS('m', 4) : _currentScreen-> setRendition (RE_UNDERLINE); break; //VT100
559
case TY_CSI_PS('m', 5) : _currentScreen-> setRendition (RE_BLINK ); break; //VT100
560
case TY_CSI_PS('m', 7) : _currentScreen-> setRendition (RE_REVERSE ); break;
561
case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX
562
case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX
563
case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX
564
case TY_CSI_PS('m', 22) : _currentScreen->resetRendition (RE_BOLD ); break;
565
case TY_CSI_PS('m', 24) : _currentScreen->resetRendition (RE_UNDERLINE); break;
566
case TY_CSI_PS('m', 25) : _currentScreen->resetRendition (RE_BLINK ); break;
567
case TY_CSI_PS('m', 27) : _currentScreen->resetRendition (RE_REVERSE ); break;
569
case TY_CSI_PS('m', 30) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 0); break;
570
case TY_CSI_PS('m', 31) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 1); break;
571
case TY_CSI_PS('m', 32) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 2); break;
572
case TY_CSI_PS('m', 33) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 3); break;
573
case TY_CSI_PS('m', 34) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 4); break;
574
case TY_CSI_PS('m', 35) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 5); break;
575
case TY_CSI_PS('m', 36) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 6); break;
576
case TY_CSI_PS('m', 37) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 7); break;
578
case TY_CSI_PS('m', 38) : _currentScreen->setForeColor (p, q); break;
580
case TY_CSI_PS('m', 39) : _currentScreen->setForeColor (COLOR_SPACE_DEFAULT, 0); break;
582
case TY_CSI_PS('m', 40) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 0); break;
583
case TY_CSI_PS('m', 41) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 1); break;
584
case TY_CSI_PS('m', 42) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 2); break;
585
case TY_CSI_PS('m', 43) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 3); break;
586
case TY_CSI_PS('m', 44) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 4); break;
587
case TY_CSI_PS('m', 45) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 5); break;
588
case TY_CSI_PS('m', 46) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 6); break;
589
case TY_CSI_PS('m', 47) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 7); break;
591
case TY_CSI_PS('m', 48) : _currentScreen->setBackColor (p, q); break;
593
case TY_CSI_PS('m', 49) : _currentScreen->setBackColor (COLOR_SPACE_DEFAULT, 1); break;
595
case TY_CSI_PS('m', 90) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 8); break;
596
case TY_CSI_PS('m', 91) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 9); break;
597
case TY_CSI_PS('m', 92) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 10); break;
598
case TY_CSI_PS('m', 93) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 11); break;
599
case TY_CSI_PS('m', 94) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 12); break;
600
case TY_CSI_PS('m', 95) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 13); break;
601
case TY_CSI_PS('m', 96) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 14); break;
602
case TY_CSI_PS('m', 97) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 15); break;
604
case TY_CSI_PS('m', 100) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 8); break;
605
case TY_CSI_PS('m', 101) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 9); break;
606
case TY_CSI_PS('m', 102) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 10); break;
607
case TY_CSI_PS('m', 103) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 11); break;
608
case TY_CSI_PS('m', 104) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 12); break;
609
case TY_CSI_PS('m', 105) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 13); break;
610
case TY_CSI_PS('m', 106) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 14); break;
611
case TY_CSI_PS('m', 107) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 15); break;
613
case TY_CSI_PS('n', 5) : reportStatus ( ); break;
614
case TY_CSI_PS('n', 6) : reportCursorPosition ( ); break;
615
case TY_CSI_PS('q', 0) : /* IGNORED: LEDs off */ break; //VT100
616
case TY_CSI_PS('q', 1) : /* IGNORED: LED1 on */ break; //VT100
617
case TY_CSI_PS('q', 2) : /* IGNORED: LED2 on */ break; //VT100
618
case TY_CSI_PS('q', 3) : /* IGNORED: LED3 on */ break; //VT100
619
case TY_CSI_PS('q', 4) : /* IGNORED: LED4 on */ break; //VT100
620
case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100
621
case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100
623
case TY_CSI_PN('@' ) : _currentScreen->insertChars (p ); break;
624
case TY_CSI_PN('A' ) : _currentScreen->cursorUp (p ); break; //VT100
625
case TY_CSI_PN('B' ) : _currentScreen->cursorDown (p ); break; //VT100
626
case TY_CSI_PN('C' ) : _currentScreen->cursorRight (p ); break; //VT100
627
case TY_CSI_PN('D' ) : _currentScreen->cursorLeft (p ); break; //VT100
628
case TY_CSI_PN('G' ) : _currentScreen->setCursorX (p ); break; //LINUX
629
case TY_CSI_PN('H' ) : _currentScreen->setCursorYX (p, q); break; //VT100
630
case TY_CSI_PN('I' ) : _currentScreen->tab (p ); break;
631
case TY_CSI_PN('L' ) : _currentScreen->insertLines (p ); break;
632
case TY_CSI_PN('M' ) : _currentScreen->deleteLines (p ); break;
633
case TY_CSI_PN('P' ) : _currentScreen->deleteChars (p ); break;
634
case TY_CSI_PN('S' ) : _currentScreen->scrollUp (p ); break;
635
case TY_CSI_PN('T' ) : _currentScreen->scrollDown (p ); break;
636
case TY_CSI_PN('X' ) : _currentScreen->eraseChars (p ); break;
637
case TY_CSI_PN('Z' ) : _currentScreen->backtab (p ); break;
638
case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100
639
case TY_CSI_PN('d' ) : _currentScreen->setCursorY (p ); break; //LINUX
640
case TY_CSI_PN('f' ) : _currentScreen->setCursorYX (p, q); break; //VT100
641
case TY_CSI_PN('r' ) : setMargins (p, q); break; //VT100
642
case TY_CSI_PN('y' ) : /* IGNORED: Confidence test */ break; //VT100
644
case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break; //VT100
645
case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break; //VT100
646
case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break; //FIXME
647
case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break; //FIXME
649
case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break; //VT100
651
case TY_CSI_PR('h', 3) : setMode (MODE_132Columns);break; //VT100
652
case TY_CSI_PR('l', 3) : resetMode (MODE_132Columns);break; //VT100
654
case TY_CSI_PR('h', 4) : /* IGNORED: soft scrolling */ break; //VT100
655
case TY_CSI_PR('l', 4) : /* IGNORED: soft scrolling */ break; //VT100
657
case TY_CSI_PR('h', 5) : _currentScreen-> setMode (MODE_Screen ); break; //VT100
658
case TY_CSI_PR('l', 5) : _currentScreen-> resetMode (MODE_Screen ); break; //VT100
660
case TY_CSI_PR('h', 6) : _currentScreen-> setMode (MODE_Origin ); break; //VT100
661
case TY_CSI_PR('l', 6) : _currentScreen-> resetMode (MODE_Origin ); break; //VT100
662
case TY_CSI_PR('s', 6) : _currentScreen-> saveMode (MODE_Origin ); break; //FIXME
663
case TY_CSI_PR('r', 6) : _currentScreen->restoreMode (MODE_Origin ); break; //FIXME
665
case TY_CSI_PR('h', 7) : _currentScreen-> setMode (MODE_Wrap ); break; //VT100
666
case TY_CSI_PR('l', 7) : _currentScreen-> resetMode (MODE_Wrap ); break; //VT100
667
case TY_CSI_PR('s', 7) : _currentScreen-> saveMode (MODE_Wrap ); break; //FIXME
668
case TY_CSI_PR('r', 7) : _currentScreen->restoreMode (MODE_Wrap ); break; //FIXME
670
case TY_CSI_PR('h', 8) : /* IGNORED: autorepeat on */ break; //VT100
671
case TY_CSI_PR('l', 8) : /* IGNORED: autorepeat off */ break; //VT100
672
case TY_CSI_PR('s', 8) : /* IGNORED: autorepeat on */ break; //VT100
673
case TY_CSI_PR('r', 8) : /* IGNORED: autorepeat off */ break; //VT100
675
case TY_CSI_PR('h', 9) : /* IGNORED: interlace */ break; //VT100
676
case TY_CSI_PR('l', 9) : /* IGNORED: interlace */ break; //VT100
677
case TY_CSI_PR('s', 9) : /* IGNORED: interlace */ break; //VT100
678
case TY_CSI_PR('r', 9) : /* IGNORED: interlace */ break; //VT100
680
case TY_CSI_PR('h', 12) : /* IGNORED: Cursor blink */ break; //att610
681
case TY_CSI_PR('l', 12) : /* IGNORED: Cursor blink */ break; //att610
682
case TY_CSI_PR('s', 12) : /* IGNORED: Cursor blink */ break; //att610
683
case TY_CSI_PR('r', 12) : /* IGNORED: Cursor blink */ break; //att610
685
case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break; //VT100
686
case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break; //VT100
687
case TY_CSI_PR('s', 25) : saveMode (MODE_Cursor ); break; //VT100
688
case TY_CSI_PR('r', 25) : restoreMode (MODE_Cursor ); break; //VT100
690
case TY_CSI_PR('h', 40) : setMode(MODE_Allow132Columns ); break; // XTERM
691
case TY_CSI_PR('l', 40) : resetMode(MODE_Allow132Columns ); break; // XTERM
693
case TY_CSI_PR('h', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
694
case TY_CSI_PR('l', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
695
case TY_CSI_PR('s', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
696
case TY_CSI_PR('r', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
698
case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break; //VT100
699
case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break; //VT100
700
case TY_CSI_PR('s', 47) : saveMode (MODE_AppScreen); break; //XTERM
701
case TY_CSI_PR('r', 47) : restoreMode (MODE_AppScreen); break; //XTERM
703
case TY_CSI_PR('h', 67) : /* IGNORED: DECBKM */ break; //XTERM
704
case TY_CSI_PR('l', 67) : /* IGNORED: DECBKM */ break; //XTERM
705
case TY_CSI_PR('s', 67) : /* IGNORED: DECBKM */ break; //XTERM
706
case TY_CSI_PR('r', 67) : /* IGNORED: DECBKM */ break; //XTERM
708
// XTerm defines the following modes:
709
// SET_VT200_MOUSE 1000
710
// SET_VT200_HIGHLIGHT_MOUSE 1001
711
// SET_BTN_EVENT_MOUSE 1002
712
// SET_ANY_EVENT_MOUSE 1003
715
//Note about mouse modes:
716
//There are four mouse modes which xterm-compatible terminals can support - 1000,1001,1002,1003
717
//Konsole currently supports mode 1000 (basic mouse press and release) and mode 1002 (dragging the mouse).
718
//TODO: Implementation of mouse modes 1001 (something called hilight tracking) and
719
//1003 (a slight variation on dragging the mouse)
722
case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break; //XTERM
723
case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break; //XTERM
724
case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break; //XTERM
725
case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break; //XTERM
727
case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
728
case TY_CSI_PR('l', 1001) : resetMode (MODE_Mouse1001); break; //XTERM
729
case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
730
case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
732
case TY_CSI_PR('h', 1002) : setMode (MODE_Mouse1002); break; //XTERM
733
case TY_CSI_PR('l', 1002) : resetMode (MODE_Mouse1002); break; //XTERM
734
case TY_CSI_PR('s', 1002) : saveMode (MODE_Mouse1002); break; //XTERM
735
case TY_CSI_PR('r', 1002) : restoreMode (MODE_Mouse1002); break; //XTERM
737
case TY_CSI_PR('h', 1003) : setMode (MODE_Mouse1003); break; //XTERM
738
case TY_CSI_PR('l', 1003) : resetMode (MODE_Mouse1003); break; //XTERM
739
case TY_CSI_PR('s', 1003) : saveMode (MODE_Mouse1003); break; //XTERM
740
case TY_CSI_PR('r', 1003) : restoreMode (MODE_Mouse1003); break; //XTERM
742
case TY_CSI_PR('h', 1034) : /* IGNORED: 8bitinput activation */ break; //XTERM
744
case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break; //XTERM
745
case TY_CSI_PR('l', 1047) : _screen[1]->clearEntireScreen(); resetMode(MODE_AppScreen); break; //XTERM
746
case TY_CSI_PR('s', 1047) : saveMode (MODE_AppScreen); break; //XTERM
747
case TY_CSI_PR('r', 1047) : restoreMode (MODE_AppScreen); break; //XTERM
749
//FIXME: Unitoken: save translations
750
case TY_CSI_PR('h', 1048) : saveCursor ( ); break; //XTERM
751
case TY_CSI_PR('l', 1048) : restoreCursor ( ); break; //XTERM
752
case TY_CSI_PR('s', 1048) : saveCursor ( ); break; //XTERM
753
case TY_CSI_PR('r', 1048) : restoreCursor ( ); break; //XTERM
755
//FIXME: every once new sequences like this pop up in xterm.
756
// Here's a guess of what they could mean.
757
case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM
758
case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM
760
//FIXME: weird DEC reset sequence
761
case TY_CSI_PE('p' ) : /* IGNORED: reset ( ) */ break;
763
//FIXME: when changing between vt52 and ansi mode evtl do some resetting.
764
case TY_VT52('A' ) : _currentScreen->cursorUp ( 1); break; //VT52
765
case TY_VT52('B' ) : _currentScreen->cursorDown ( 1); break; //VT52
766
case TY_VT52('C' ) : _currentScreen->cursorRight ( 1); break; //VT52
767
case TY_VT52('D' ) : _currentScreen->cursorLeft ( 1); break; //VT52
769
case TY_VT52('F' ) : setAndUseCharset (0, '0'); break; //VT52
770
case TY_VT52('G' ) : setAndUseCharset (0, 'B'); break; //VT52
772
case TY_VT52('H' ) : _currentScreen->setCursorYX (1,1 ); break; //VT52
773
case TY_VT52('I' ) : _currentScreen->reverseIndex ( ); break; //VT52
774
case TY_VT52('J' ) : _currentScreen->clearToEndOfScreen ( ); break; //VT52
775
case TY_VT52('K' ) : _currentScreen->clearToEndOfLine ( ); break; //VT52
776
case TY_VT52('Y' ) : _currentScreen->setCursorYX (p-31,q-31 ); break; //VT52
777
case TY_VT52('Z' ) : reportTerminalType ( ); break; //VT52
778
case TY_VT52('<' ) : setMode (MODE_Ansi ); break; //VT52
779
case TY_VT52('=' ) : setMode (MODE_AppKeyPad); break; //VT52
780
case TY_VT52('>' ) : resetMode (MODE_AppKeyPad); break; //VT52
782
case TY_CSI_PG('c' ) : reportSecondaryAttributes( ); break; //VT100
785
reportDecodingError();
790
void Vt102Emulation::clearScreenAndSetColumns(int columnCount)
792
setImageSize(_currentScreen->getLines(),columnCount);
795
_currentScreen->setCursorYX(0,0);
798
void Vt102Emulation::sendString(const char* s , int length)
801
emit sendData(s,length);
803
emit sendData(s,strlen(s));
806
void Vt102Emulation::reportCursorPosition()
809
sprintf(tmp,"\033[%d;%dR",_currentScreen->getCursorY()+1,_currentScreen->getCursorX()+1);
813
void Vt102Emulation::reportTerminalType()
815
// Primary device attribute response (Request was: ^[[0c or ^[[c (from TT321 Users Guide))
816
// VT220: ^[[?63;1;2;3;6;7;8c (list deps on emul. capabilities)
820
if (getMode(MODE_Ansi))
821
sendString("\033[?1;2c"); // I'm a VT100
823
sendString("\033/Z"); // I'm a VT52
826
void Vt102Emulation::reportSecondaryAttributes()
828
// Seconday device attribute response (Request was: ^[[>0c or ^[[>c)
829
if (getMode(MODE_Ansi))
830
sendString("\033[>0;115;0c"); // Why 115? ;)
832
sendString("\033/Z"); // FIXME I don't think VT52 knows about it but kept for
833
// konsoles backward compatibility.
836
void Vt102Emulation::reportTerminalParms(int p)
840
sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
844
void Vt102Emulation::reportStatus()
846
sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
849
void Vt102Emulation::reportAnswerBack()
851
// FIXME - Test this with VTTEST
852
// This is really obsolete VT100 stuff.
853
const char* ANSWER_BACK = "";
854
sendString(ANSWER_BACK);
858
`cx',`cy' are 1-based.
859
`eventType' indicates the button pressed (0-2)
860
or a general mouse release (3).
862
eventType represents the kind of mouse action that occurred:
863
0 = Mouse button press or release
867
void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
869
if (cx < 1 || cy < 1)
872
// normal buttons are passed as 0x20 + button,
873
// mouse wheel (buttons 4,5) as 0x5c + button
877
//Mouse motion handling
878
if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1)
879
cb += 0x20; //add 32 to signify motion event
882
sprintf(command,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20);
886
void Vt102Emulation::sendText( const QString& text )
890
QKeyEvent event(QEvent::KeyPress,
894
sendKeyEvent(&event); // expose as a big fat keypress event
897
void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
899
Qt::KeyboardModifiers modifiers = event->modifiers();
900
KeyboardTranslator::States states = KeyboardTranslator::NoState;
902
// get current states
903
if (getMode(MODE_NewLine) ) states |= KeyboardTranslator::NewLineState;
904
if (getMode(MODE_Ansi) ) states |= KeyboardTranslator::AnsiState;
905
if (getMode(MODE_AppCuKeys)) states |= KeyboardTranslator::CursorKeysState;
906
if (getMode(MODE_AppScreen)) states |= KeyboardTranslator::AlternateScreenState;
907
if (getMode(MODE_AppKeyPad) && (modifiers & Qt::KeypadModifier))
908
states |= KeyboardTranslator::ApplicationKeypadState;
910
// check flow control state
911
if (modifiers & Qt::ControlModifier)
913
if (event->key() == Qt::Key_S)
914
emit flowControlKeyPressed(true);
915
else if (event->key() == Qt::Key_Q)
916
emit flowControlKeyPressed(false);
919
// lookup key binding
920
if ( _keyTranslator )
922
KeyboardTranslator::Entry entry = _keyTranslator->findEntry(
927
// send result to terminal
928
QByteArray textToSend;
930
// special handling for the Alt (aka. Meta) modifier. pressing
931
// Alt+[Character] results in Esc+[Character] being sent
932
// (unless there is an entry defined for this particular combination
933
// in the keyboard modifier)
934
bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier;
935
bool wantsAnyModifier = entry.state() &
936
entry.stateMask() & KeyboardTranslator::AnyModifierState;
938
if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier)
939
&& !event->text().isEmpty() )
941
textToSend.prepend("\033");
944
if ( entry.command() != KeyboardTranslator::NoCommand )
946
if (entry.command() & KeyboardTranslator::EraseCommand)
947
textToSend += eraseChar();
949
// TODO command handling
951
else if ( !entry.text().isEmpty() )
953
textToSend += _codec->fromUnicode(entry.text(true,modifiers));
955
else if((modifiers & Qt::ControlModifier) && event->key() >= 0x40 && event->key() < 0x5f) {
956
textToSend += (event->key() & 0x1f);
958
else if(event->key() == Qt::Key_Tab) {
961
else if (event->key() == Qt::Key_PageUp) {
962
textToSend += "\033[5~";
964
else if (event->key() == Qt::Key_PageDown) {
965
textToSend += "\033[6~";
968
textToSend += _codec->fromUnicode(event->text());
971
sendData( textToSend.constData() , textToSend.length() );
975
// print an error message to the terminal if no key translator has been
977
QString translatorError = tr("No keyboard translator available. "
978
"The information needed to convert key presses "
979
"into characters to send to the terminal "
982
receiveData( translatorError.toUtf8().constData() , translatorError.count() );
986
/* ------------------------------------------------------------------------- */
990
/* ------------------------------------------------------------------------- */
992
// Character Set Conversion ------------------------------------------------ --
995
The processing contains a VT100 specific code translation layer.
996
It's still in use and mainly responsible for the line drawing graphics.
998
These and some other glyphs are assigned to codes (0x5f-0xfe)
999
normally occupied by the latin letters. Since this codes also
1000
appear within control sequences, the extra code conversion
1001
does not permute with the tokenizer and is placed behind it
1002
in the pipeline. It only applies to tokens, which represent
1005
This conversion it eventually continued in TerminalDisplay.C, since
1006
it might involve VT100 enhanced fonts, which have these
1007
particular glyphs allocated in (0x00-0x1f) in their code page.
1010
#define CHARSET _charset[_currentScreen==_screen[1]]
1012
// Apply current character map.
1014
unsigned short Vt102Emulation::applyCharset(unsigned short c)
1016
if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
1017
if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete
1022
"Charset" related part of the emulation state.
1023
This configures the VT100 charset filter.
1025
While most operation work on the current _screen,
1026
the following two are different.
1029
void Vt102Emulation::resetCharset(int scrno)
1031
_charset[scrno].cu_cs = 0;
1032
strncpy(_charset[scrno].charset,"BBBB",4);
1033
_charset[scrno].sa_graphic = false;
1034
_charset[scrno].sa_pound = false;
1035
_charset[scrno].graphic = false;
1036
_charset[scrno].pound = false;
1039
void Vt102Emulation::setCharset(int n, int cs) // on both screens.
1041
_charset[0].charset[n&3] = cs; useCharset(_charset[0].cu_cs);
1042
_charset[1].charset[n&3] = cs; useCharset(_charset[1].cu_cs);
1045
void Vt102Emulation::setAndUseCharset(int n, int cs)
1047
CHARSET.charset[n&3] = cs;
1051
void Vt102Emulation::useCharset(int n)
1053
CHARSET.cu_cs = n&3;
1054
CHARSET.graphic = (CHARSET.charset[n&3] == '0');
1055
CHARSET.pound = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
1058
void Vt102Emulation::setDefaultMargins()
1060
_screen[0]->setDefaultMargins();
1061
_screen[1]->setDefaultMargins();
1064
void Vt102Emulation::setMargins(int t, int b)
1066
_screen[0]->setMargins(t, b);
1067
_screen[1]->setMargins(t, b);
1070
void Vt102Emulation::saveCursor()
1072
CHARSET.sa_graphic = CHARSET.graphic;
1073
CHARSET.sa_pound = CHARSET.pound; //This mode is obsolete
1074
// we are not clear about these
1075
//sa_charset = charsets[cScreen->_charset];
1076
//sa_charset_num = cScreen->_charset;
1077
_currentScreen->saveCursor();
1080
void Vt102Emulation::restoreCursor()
1082
CHARSET.graphic = CHARSET.sa_graphic;
1083
CHARSET.pound = CHARSET.sa_pound; //This mode is obsolete
1084
_currentScreen->restoreCursor();
1087
/* ------------------------------------------------------------------------- */
1089
/* Mode Operations */
1091
/* ------------------------------------------------------------------------- */
1094
Some of the emulations state is either added to the state of the screens.
1096
This causes some scoping problems, since different emulations choose to
1097
located the mode either to the current _screen or to both.
1099
For strange reasons, the extend of the rendition attributes ranges over
1100
all screens and not over the actual _screen.
1102
We decided on the precise precise extend, somehow.
1105
// "Mode" related part of the state. These are all booleans.
1107
void Vt102Emulation::resetModes()
1109
// MODE_Allow132Columns is not reset here
1110
// to match Xterm's behaviour (see Xterm's VTReset() function)
1112
resetMode(MODE_132Columns); saveMode(MODE_132Columns);
1113
resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000);
1114
resetMode(MODE_Mouse1001); saveMode(MODE_Mouse1001);
1115
resetMode(MODE_Mouse1002); saveMode(MODE_Mouse1002);
1116
resetMode(MODE_Mouse1003); saveMode(MODE_Mouse1003);
1118
resetMode(MODE_AppScreen); saveMode(MODE_AppScreen);
1119
resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys);
1120
resetMode(MODE_AppKeyPad); saveMode(MODE_AppKeyPad);
1121
resetMode(MODE_NewLine);
1125
void Vt102Emulation::setMode(int m)
1127
_currentModes.mode[m] = true;
1130
case MODE_132Columns:
1131
if (getMode(MODE_Allow132Columns))
1132
clearScreenAndSetColumns(132);
1134
_currentModes.mode[m] = false;
1136
case MODE_Mouse1000:
1137
case MODE_Mouse1001:
1138
case MODE_Mouse1002:
1139
case MODE_Mouse1003:
1140
emit programUsesMouseChanged(false);
1143
case MODE_AppScreen : _screen[1]->clearSelection();
1147
if (m < MODES_SCREEN || m == MODE_NewLine)
1149
_screen[0]->setMode(m);
1150
_screen[1]->setMode(m);
1154
void Vt102Emulation::resetMode(int m)
1156
_currentModes.mode[m] = false;
1159
case MODE_132Columns:
1160
if (getMode(MODE_Allow132Columns))
1161
clearScreenAndSetColumns(80);
1163
case MODE_Mouse1000 :
1164
case MODE_Mouse1001 :
1165
case MODE_Mouse1002 :
1166
case MODE_Mouse1003 :
1167
emit programUsesMouseChanged(true);
1170
case MODE_AppScreen :
1171
_screen[0]->clearSelection();
1175
if (m < MODES_SCREEN || m == MODE_NewLine)
1177
_screen[0]->resetMode(m);
1178
_screen[1]->resetMode(m);
1182
void Vt102Emulation::saveMode(int m)
1184
_savedModes.mode[m] = _currentModes.mode[m];
1187
void Vt102Emulation::restoreMode(int m)
1189
if (_savedModes.mode[m])
1195
bool Vt102Emulation::getMode(int m)
1197
return _currentModes.mode[m];
1200
char Vt102Emulation::eraseChar() const
1202
KeyboardTranslator::Entry entry = _keyTranslator->findEntry(
1206
if ( entry.text().count() > 0 )
1207
return entry.text()[0];
1212
// print contents of the scan buffer
1213
static void hexdump(int* s, int len)
1215
for (i = 0; i < len; i++)
1220
if ((s[i]) > 32 && s[i] < 127)
1223
printf("\\%04x(hex)",s[i]);
1227
void Vt102Emulation::reportDecodingError()
1229
if (tokenBufferPos == 0 || ( tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32) )
1231
printf("Undecodable sequence: ");
1232
hexdump(tokenBuffer,tokenBufferPos);
1236
//#include "Vt102Emulation.moc"