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();
46
#include <QtCore/QEvent>
47
#include <QtGui/QKeyEvent>
48
#include <QtCore/QByteRef>
52
//#include <klocale.h>
55
#include "KeyboardTranslator.h"
58
Vt102Emulation::Vt102Emulation()
60
_titleUpdateTimer(new QTimer(this))
62
_titleUpdateTimer->setSingleShot(true);
63
QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle()));
69
Vt102Emulation::~Vt102Emulation()
72
void Vt102Emulation::clearEntireScreen()
74
_currentScreen->clearEntireScreen();
78
void Vt102Emulation::reset()
86
setCodec(LocaleCodec);
91
/* ------------------------------------------------------------------------- */
93
/* Processing the incoming byte stream */
95
/* ------------------------------------------------------------------------- */
97
/* Incoming Bytes Event pipeline
99
This section deals with decoding the incoming character stream.
100
Decoding means here, that the stream is first separated into `tokens'
101
which are then mapped to a `meaning' provided as operations by the
102
`Screen' class or by the emulation class itself.
104
The pipeline proceeds as follows:
106
- Tokenizing the ESC codes (onReceiveChar)
107
- VT100 code page translation of plain characters (applyCharset)
108
- Interpretation of ESC codes (processToken)
110
The escape codes and their meaning are described in the
111
technical reference of this program.
114
// Tokens ------------------------------------------------------------------ --
117
Since the tokens are the central notion if this section, we've put them
118
in front. They provide the syntactical elements used to represent the
119
terminals operations as byte sequences.
121
They are encodes here into a single machine word, so that we can later
122
switch over them easily. Depending on the token itself, additional
123
argument variables are filled with parameter values.
125
The tokens are defined below:
127
- CHR - Printable characters (32..255 but DEL (=127))
128
- CTL - Control characters (0..31 but ESC (= 27), DEL)
129
- ESC - Escape codes of the form <ESC><CHR but `[]()+*#'>
130
- ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C
131
- CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C
132
- CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C
133
- CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C
134
- CSI_PE - Escape codes of the form <ESC>'[' '!' {Pn} ';' ... C
135
- VT52 - VT52 escape codes
138
- XTE_HA - Xterm window/terminal attribute commands
139
of the form <ESC>`]' {Pn} `;' {Text} <BEL>
140
(Note that these are handled differently to the other formats)
142
The last two forms allow list of arguments. Since the elements of
143
the lists are treated individually the same way, they are passed
144
as individual tokens to the interpretation. Further, because the
145
meaning of the parameters are names (althought represented as numbers),
146
they are includes within the token ('N').
150
#define TY_CONSTRUCT(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
152
#define TY_CHR( ) TY_CONSTRUCT(0,0,0)
153
#define TY_CTL(A ) TY_CONSTRUCT(1,A,0)
154
#define TY_ESC(A ) TY_CONSTRUCT(2,A,0)
155
#define TY_ESC_CS(A,B) TY_CONSTRUCT(3,A,B)
156
#define TY_ESC_DE(A ) TY_CONSTRUCT(4,A,0)
157
#define TY_CSI_PS(A,N) TY_CONSTRUCT(5,A,N)
158
#define TY_CSI_PN(A ) TY_CONSTRUCT(6,A,0)
159
#define TY_CSI_PR(A,N) TY_CONSTRUCT(7,A,N)
161
#define TY_VT52(A) TY_CONSTRUCT(8,A,0)
162
#define TY_CSI_PG(A) TY_CONSTRUCT(9,A,0)
163
#define TY_CSI_PE(A) TY_CONSTRUCT(10,A,0)
165
#define MAX_ARGUMENT 4096
167
// Tokenizer --------------------------------------------------------------- --
169
/* The tokenizer's state
171
The state is represented by the buffer (tokenBuffer, tokenBufferPos),
172
and accompanied by decoded arguments kept in (argv,argc).
173
Note that they are kept internal in the tokenizer.
176
void Vt102Emulation::resetTokenizer()
184
void Vt102Emulation::addDigit(int digit)
186
if (argv[argc] < MAX_ARGUMENT)
187
argv[argc] = 10*argv[argc] + digit;
190
void Vt102Emulation::addArgument()
192
argc = qMin(argc+1,MAXARGS-1);
196
void Vt102Emulation::addToCurrentToken(int cc)
198
tokenBuffer[tokenBufferPos] = cc;
199
tokenBufferPos = qMin(tokenBufferPos+1,MAX_TOKEN_LENGTH-1);
202
// Character Class flags used while decoding
204
#define CTL 1 // Control character
205
#define CHR 2 // Printable character
206
#define CPN 4 // TODO: Document me
207
#define DIG 8 // Digit
208
#define SCS 16 // TODO: Document me
209
#define GRP 32 // TODO: Document me
210
#define CPS 64 // Character which indicates end of window resize
211
// escape sequence '\e[8;<row>;<col>t'
213
void Vt102Emulation::initTokenizer()
217
for(i = 0;i < 256; ++i)
219
for(i = 0;i < 32; ++i)
221
for(i = 32;i < 256; ++i)
223
for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; ++s)
224
charClass[*s] |= CPN;
225
// resize = \e[8;<row>;<col>t
226
for(s = (quint8*)"t"; *s; ++s)
227
charClass[*s] |= CPS;
228
for(s = (quint8*)"0123456789"; *s; ++s)
229
charClass[*s] |= DIG;
230
for(s = (quint8*)"()+*%"; *s; ++s)
231
charClass[*s] |= SCS;
232
for(s = (quint8*)"()+*#[]%"; *s; ++s)
233
charClass[*s] |= GRP;
238
/* Ok, here comes the nasty part of the decoder.
240
Instead of keeping an explicit state, we deduce it from the
241
token scanned so far. It is then immediately combined with
242
the current character to form a scanning decision.
244
This is done by the following defines.
246
- P is the length of the token scanned so far.
247
- L (often P-1) is the position on which contents we base a decision.
248
- C is a character or a group of characters (taken from 'charClass').
250
- 'cc' is the current character
251
- 's' is a pointer to the start of the token buffer
252
- 'p' is the current position within the token buffer
254
Note that they need to applied in proper order.
257
#define lec(P,L,C) (p == (P) && s[(L)] == (C))
258
#define lun( ) (p == 1 && cc >= 32 )
259
#define les(P,L,C) (p == (P) && s[L] < 256 && (charClass[s[(L)]] & (C)) == (C))
260
#define eec(C) (p >= 3 && cc == (C))
261
#define ees(C) (p >= 3 && cc < 256 && (charClass[cc] & (C)) == (C))
262
#define eps(C) (p >= 3 && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (charClass[cc] & (C)) == (C))
263
#define epp( ) (p >= 3 && s[2] == '?')
264
#define epe( ) (p >= 3 && s[2] == '!')
265
#define egt( ) (p >= 3 && s[2] == '>')
266
#define Xpe (tokenBufferPos >= 2 && tokenBuffer[1] == ']')
267
#define Xte (Xpe && cc == 7 )
268
#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte)
271
#define CNTL(c) ((c)-'@')
273
// process an incoming unicode character
274
void Vt102Emulation::receiveChar(int cc)
277
return; //VT100: ignore.
281
// DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
282
// This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do
283
// of course. Guess this originates from a weakly layered handling of the X-on
284
// X-off protocol, which comes really below this level.
285
if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC)
286
resetTokenizer(); //VT100: CAN or SUB
289
processToken(TY_CTL(cc+'@' ),0,0);
294
addToCurrentToken(cc);
296
int* s = tokenBuffer;
297
int p = tokenBufferPos;
299
if (getMode(MODE_Ansi))
301
if (lec(1,0,ESC)) { return; }
302
if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('['); return; }
303
if (les(2,1,GRP)) { return; }
304
if (Xte ) { processWindowAttributeChange(); resetTokenizer(); return; }
305
if (Xpe ) { return; }
306
if (lec(3,2,'?')) { return; }
307
if (lec(3,2,'>')) { return; }
308
if (lec(3,2,'!')) { return; }
309
if (lun( )) { processToken( TY_CHR(), applyCharset(cc), 0); resetTokenizer(); return; }
310
if (lec(2,0,ESC)) { processToken( TY_ESC(s[1]), 0, 0); resetTokenizer(); return; }
311
if (les(3,1,SCS)) { processToken( TY_ESC_CS(s[1],s[2]), 0, 0); resetTokenizer(); return; }
312
if (lec(3,1,'#')) { processToken( TY_ESC_DE(s[2]), 0, 0); resetTokenizer(); return; }
313
if (eps( CPN)) { processToken( TY_CSI_PN(cc), argv[0],argv[1]); resetTokenizer(); return; }
315
// resize = \e[8;<row>;<col>t
318
processToken( TY_CSI_PS(cc, argv[0]), argv[1], argv[2]);
323
if (epe( )) { processToken( TY_CSI_PE(cc), 0, 0); resetTokenizer(); return; }
324
if (ees(DIG)) { addDigit(cc-'0'); return; }
325
if (eec(';')) { addArgument(); return; }
326
for (int i=0;i<=argc;i++)
329
processToken( TY_CSI_PR(cc,argv[i]), 0, 0);
331
processToken( TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c
332
else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)
334
// ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m
336
processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i+1] << 8) | argv[i+2]);
339
else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 5)
341
// ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m
343
processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]);
346
processToken( TY_CSI_PS(cc,argv[i]), 0, 0);
357
processToken( TY_CHR(), s[0], 0);
367
processToken( TY_VT52(s[1] ), 0, 0);
371
processToken( TY_VT52(s[1]), s[2], s[3]);
376
void Vt102Emulation::processWindowAttributeChange()
378
// Describes the window or terminal session attribute to change
379
// See Session::UserTitleChange for possible values
380
int attributeToChange = 0;
382
for (i = 2; i < tokenBufferPos &&
383
tokenBuffer[i] >= '0' &&
384
tokenBuffer[i] <= '9'; i++)
386
attributeToChange = 10 * attributeToChange + (tokenBuffer[i]-'0');
389
if (tokenBuffer[i] != ';')
391
reportDecodingError();
396
newValue.reserve(tokenBufferPos-i-2);
397
for (int j = 0; j < tokenBufferPos-i-2; j++)
398
newValue[j] = tokenBuffer[i+1+j];
400
_pendingTitleUpdates[attributeToChange] = newValue;
401
_titleUpdateTimer->start(20);
404
void Vt102Emulation::updateTitle()
406
QListIterator<int> iter( _pendingTitleUpdates.keys() );
407
while (iter.hasNext()) {
408
int arg = iter.next();
409
emit titleChanged( arg , _pendingTitleUpdates[arg] );
411
_pendingTitleUpdates.clear();
414
// Interpreting Codes ---------------------------------------------------------
417
Now that the incoming character stream is properly tokenized,
418
meaning is assigned to them. These are either operations of
419
the current _screen, or of the emulation class itself.
421
The token to be interpreteted comes in as a machine word
422
possibly accompanied by two parameters.
424
Likewise, the operations assigned to, come with up to two
425
arguments. One could consider to make up a proper table
426
from the function below.
428
The technical reference manual provides more information
432
void Vt102Emulation::processToken(int token, int p, int q)
437
case TY_CHR( ) : _currentScreen->displayCharacter (p ); break; //UTF16
439
// 127 DEL : ignored on input
441
case TY_CTL('@' ) : /* NUL: ignored */ break;
442
case TY_CTL('A' ) : /* SOH: ignored */ break;
443
case TY_CTL('B' ) : /* STX: ignored */ break;
444
case TY_CTL('C' ) : /* ETX: ignored */ break;
445
case TY_CTL('D' ) : /* EOT: ignored */ break;
446
case TY_CTL('E' ) : reportAnswerBack ( ); break; //VT100
447
case TY_CTL('F' ) : /* ACK: ignored */ break;
448
case TY_CTL('G' ) : emit stateSet(NOTIFYBELL);
450
case TY_CTL('H' ) : _currentScreen->backspace ( ); break; //VT100
451
case TY_CTL('I' ) : _currentScreen->tab ( ); break; //VT100
452
case TY_CTL('J' ) : _currentScreen->newLine ( ); break; //VT100
453
case TY_CTL('K' ) : _currentScreen->newLine ( ); break; //VT100
454
case TY_CTL('L' ) : _currentScreen->newLine ( ); break; //VT100
455
case TY_CTL('M' ) : _currentScreen->toStartOfLine ( ); break; //VT100
457
case TY_CTL('N' ) : useCharset ( 1); break; //VT100
458
case TY_CTL('O' ) : useCharset ( 0); break; //VT100
460
case TY_CTL('P' ) : /* DLE: ignored */ break;
461
case TY_CTL('Q' ) : /* DC1: XON continue */ break; //VT100
462
case TY_CTL('R' ) : /* DC2: ignored */ break;
463
case TY_CTL('S' ) : /* DC3: XOFF halt */ break; //VT100
464
case TY_CTL('T' ) : /* DC4: ignored */ break;
465
case TY_CTL('U' ) : /* NAK: ignored */ break;
466
case TY_CTL('V' ) : /* SYN: ignored */ break;
467
case TY_CTL('W' ) : /* ETB: ignored */ break;
468
case TY_CTL('X' ) : _currentScreen->displayCharacter ( 0x2592); break; //VT100
469
case TY_CTL('Y' ) : /* EM : ignored */ break;
470
case TY_CTL('Z' ) : _currentScreen->displayCharacter ( 0x2592); break; //VT100
471
case TY_CTL('[' ) : /* ESC: cannot be seen here. */ break;
472
case TY_CTL('\\' ) : /* FS : ignored */ break;
473
case TY_CTL(']' ) : /* GS : ignored */ break;
474
case TY_CTL('^' ) : /* RS : ignored */ break;
475
case TY_CTL('_' ) : /* US : ignored */ break;
477
case TY_ESC('D' ) : _currentScreen->index ( ); break; //VT100
478
case TY_ESC('E' ) : _currentScreen->nextLine ( ); break; //VT100
479
case TY_ESC('H' ) : _currentScreen->changeTabStop (true ); break; //VT100
480
case TY_ESC('M' ) : _currentScreen->reverseIndex ( ); break; //VT100
481
case TY_ESC('Z' ) : reportTerminalType ( ); break;
482
case TY_ESC('c' ) : reset ( ); break;
484
case TY_ESC('n' ) : useCharset ( 2); break;
485
case TY_ESC('o' ) : useCharset ( 3); break;
486
case TY_ESC('7' ) : saveCursor ( ); break;
487
case TY_ESC('8' ) : restoreCursor ( ); break;
489
case TY_ESC('=' ) : setMode (MODE_AppKeyPad); break;
490
case TY_ESC('>' ) : resetMode (MODE_AppKeyPad); break;
491
case TY_ESC('<' ) : setMode (MODE_Ansi ); break; //VT100
493
case TY_ESC_CS('(', '0') : setCharset (0, '0'); break; //VT100
494
case TY_ESC_CS('(', 'A') : setCharset (0, 'A'); break; //VT100
495
case TY_ESC_CS('(', 'B') : setCharset (0, 'B'); break; //VT100
497
case TY_ESC_CS(')', '0') : setCharset (1, '0'); break; //VT100
498
case TY_ESC_CS(')', 'A') : setCharset (1, 'A'); break; //VT100
499
case TY_ESC_CS(')', 'B') : setCharset (1, 'B'); break; //VT100
501
case TY_ESC_CS('*', '0') : setCharset (2, '0'); break; //VT100
502
case TY_ESC_CS('*', 'A') : setCharset (2, 'A'); break; //VT100
503
case TY_ESC_CS('*', 'B') : setCharset (2, 'B'); break; //VT100
505
case TY_ESC_CS('+', '0') : setCharset (3, '0'); break; //VT100
506
case TY_ESC_CS('+', 'A') : setCharset (3, 'A'); break; //VT100
507
case TY_ESC_CS('+', 'B') : setCharset (3, 'B'); break; //VT100
509
case TY_ESC_CS('%', 'G') : setCodec (Utf8Codec ); break; //LINUX
510
case TY_ESC_CS('%', '@') : setCodec (LocaleCodec ); break; //LINUX
512
case TY_ESC_DE('3' ) : /* Double height line, top half */
513
_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
514
_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
516
case TY_ESC_DE('4' ) : /* Double height line, bottom half */
517
_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
518
_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
520
case TY_ESC_DE('5' ) : /* Single width, single height line*/
521
_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , false);
522
_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
524
case TY_ESC_DE('6' ) : /* Double width, single height line*/
525
_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true);
526
_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
528
case TY_ESC_DE('8' ) : _currentScreen->helpAlign ( ); break;
530
// resize = \e[8;<row>;<col>t
531
case TY_CSI_PS('t', 8) : setImageSize( q /* columns */, p /* lines */ ); break;
533
// change tab text color : \e[28;<color>t color: 0-16,777,215
534
case TY_CSI_PS('t', 28) : emit changeTabTextColorRequest ( p ); break;
536
case TY_CSI_PS('K', 0) : _currentScreen->clearToEndOfLine ( ); break;
537
case TY_CSI_PS('K', 1) : _currentScreen->clearToBeginOfLine ( ); break;
538
case TY_CSI_PS('K', 2) : _currentScreen->clearEntireLine ( ); break;
539
case TY_CSI_PS('J', 0) : _currentScreen->clearToEndOfScreen ( ); break;
540
case TY_CSI_PS('J', 1) : _currentScreen->clearToBeginOfScreen ( ); break;
541
case TY_CSI_PS('J', 2) : _currentScreen->clearEntireScreen ( ); break;
542
case TY_CSI_PS('J', 3) : clearHistory(); break;
543
case TY_CSI_PS('g', 0) : _currentScreen->changeTabStop (false ); break; //VT100
544
case TY_CSI_PS('g', 3) : _currentScreen->clearTabStops ( ); break; //VT100
545
case TY_CSI_PS('h', 4) : _currentScreen-> setMode (MODE_Insert ); break;
546
case TY_CSI_PS('h', 20) : setMode (MODE_NewLine ); break;
547
case TY_CSI_PS('i', 0) : /* IGNORE: attached printer */ break; //VT100
548
case TY_CSI_PS('l', 4) : _currentScreen-> resetMode (MODE_Insert ); break;
549
case TY_CSI_PS('l', 20) : resetMode (MODE_NewLine ); break;
550
case TY_CSI_PS('s', 0) : saveCursor ( ); break;
551
case TY_CSI_PS('u', 0) : restoreCursor ( ); break;
553
case TY_CSI_PS('m', 0) : _currentScreen->setDefaultRendition ( ); break;
554
case TY_CSI_PS('m', 1) : _currentScreen-> setRendition (RE_BOLD ); break; //VT100
555
case TY_CSI_PS('m', 4) : _currentScreen-> setRendition (RE_UNDERLINE); break; //VT100
556
case TY_CSI_PS('m', 5) : _currentScreen-> setRendition (RE_BLINK ); break; //VT100
557
case TY_CSI_PS('m', 7) : _currentScreen-> setRendition (RE_REVERSE ); break;
558
case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX
559
case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX
560
case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX
561
case TY_CSI_PS('m', 22) : _currentScreen->resetRendition (RE_BOLD ); break;
562
case TY_CSI_PS('m', 24) : _currentScreen->resetRendition (RE_UNDERLINE); break;
563
case TY_CSI_PS('m', 25) : _currentScreen->resetRendition (RE_BLINK ); break;
564
case TY_CSI_PS('m', 27) : _currentScreen->resetRendition (RE_REVERSE ); break;
566
case TY_CSI_PS('m', 30) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 0); break;
567
case TY_CSI_PS('m', 31) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 1); break;
568
case TY_CSI_PS('m', 32) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 2); break;
569
case TY_CSI_PS('m', 33) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 3); break;
570
case TY_CSI_PS('m', 34) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 4); break;
571
case TY_CSI_PS('m', 35) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 5); break;
572
case TY_CSI_PS('m', 36) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 6); break;
573
case TY_CSI_PS('m', 37) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 7); break;
575
case TY_CSI_PS('m', 38) : _currentScreen->setForeColor (p, q); break;
577
case TY_CSI_PS('m', 39) : _currentScreen->setForeColor (COLOR_SPACE_DEFAULT, 0); break;
579
case TY_CSI_PS('m', 40) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 0); break;
580
case TY_CSI_PS('m', 41) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 1); break;
581
case TY_CSI_PS('m', 42) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 2); break;
582
case TY_CSI_PS('m', 43) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 3); break;
583
case TY_CSI_PS('m', 44) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 4); break;
584
case TY_CSI_PS('m', 45) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 5); break;
585
case TY_CSI_PS('m', 46) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 6); break;
586
case TY_CSI_PS('m', 47) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 7); break;
588
case TY_CSI_PS('m', 48) : _currentScreen->setBackColor (p, q); break;
590
case TY_CSI_PS('m', 49) : _currentScreen->setBackColor (COLOR_SPACE_DEFAULT, 1); break;
592
case TY_CSI_PS('m', 90) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 8); break;
593
case TY_CSI_PS('m', 91) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 9); break;
594
case TY_CSI_PS('m', 92) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 10); break;
595
case TY_CSI_PS('m', 93) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 11); break;
596
case TY_CSI_PS('m', 94) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 12); break;
597
case TY_CSI_PS('m', 95) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 13); break;
598
case TY_CSI_PS('m', 96) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 14); break;
599
case TY_CSI_PS('m', 97) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 15); break;
601
case TY_CSI_PS('m', 100) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 8); break;
602
case TY_CSI_PS('m', 101) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 9); break;
603
case TY_CSI_PS('m', 102) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 10); break;
604
case TY_CSI_PS('m', 103) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 11); break;
605
case TY_CSI_PS('m', 104) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 12); break;
606
case TY_CSI_PS('m', 105) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 13); break;
607
case TY_CSI_PS('m', 106) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 14); break;
608
case TY_CSI_PS('m', 107) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 15); break;
610
case TY_CSI_PS('n', 5) : reportStatus ( ); break;
611
case TY_CSI_PS('n', 6) : reportCursorPosition ( ); break;
612
case TY_CSI_PS('q', 0) : /* IGNORED: LEDs off */ break; //VT100
613
case TY_CSI_PS('q', 1) : /* IGNORED: LED1 on */ break; //VT100
614
case TY_CSI_PS('q', 2) : /* IGNORED: LED2 on */ break; //VT100
615
case TY_CSI_PS('q', 3) : /* IGNORED: LED3 on */ break; //VT100
616
case TY_CSI_PS('q', 4) : /* IGNORED: LED4 on */ break; //VT100
617
case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100
618
case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100
620
case TY_CSI_PN('@' ) : _currentScreen->insertChars (p ); break;
621
case TY_CSI_PN('A' ) : _currentScreen->cursorUp (p ); break; //VT100
622
case TY_CSI_PN('B' ) : _currentScreen->cursorDown (p ); break; //VT100
623
case TY_CSI_PN('C' ) : _currentScreen->cursorRight (p ); break; //VT100
624
case TY_CSI_PN('D' ) : _currentScreen->cursorLeft (p ); break; //VT100
625
case TY_CSI_PN('G' ) : _currentScreen->setCursorX (p ); break; //LINUX
626
case TY_CSI_PN('H' ) : _currentScreen->setCursorYX (p, q); break; //VT100
627
case TY_CSI_PN('I' ) : _currentScreen->tab (p ); break;
628
case TY_CSI_PN('L' ) : _currentScreen->insertLines (p ); break;
629
case TY_CSI_PN('M' ) : _currentScreen->deleteLines (p ); break;
630
case TY_CSI_PN('P' ) : _currentScreen->deleteChars (p ); break;
631
case TY_CSI_PN('S' ) : _currentScreen->scrollUp (p ); break;
632
case TY_CSI_PN('T' ) : _currentScreen->scrollDown (p ); break;
633
case TY_CSI_PN('X' ) : _currentScreen->eraseChars (p ); break;
634
case TY_CSI_PN('Z' ) : _currentScreen->backtab (p ); break;
635
case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100
636
case TY_CSI_PN('d' ) : _currentScreen->setCursorY (p ); break; //LINUX
637
case TY_CSI_PN('f' ) : _currentScreen->setCursorYX (p, q); break; //VT100
638
case TY_CSI_PN('r' ) : setMargins (p, q); break; //VT100
639
case TY_CSI_PN('y' ) : /* IGNORED: Confidence test */ break; //VT100
641
case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break; //VT100
642
case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break; //VT100
643
case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break; //FIXME
644
case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break; //FIXME
646
case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break; //VT100
648
case TY_CSI_PR('h', 3) : setMode (MODE_132Columns);break; //VT100
649
case TY_CSI_PR('l', 3) : resetMode (MODE_132Columns);break; //VT100
651
case TY_CSI_PR('h', 4) : /* IGNORED: soft scrolling */ break; //VT100
652
case TY_CSI_PR('l', 4) : /* IGNORED: soft scrolling */ break; //VT100
654
case TY_CSI_PR('h', 5) : _currentScreen-> setMode (MODE_Screen ); break; //VT100
655
case TY_CSI_PR('l', 5) : _currentScreen-> resetMode (MODE_Screen ); break; //VT100
657
case TY_CSI_PR('h', 6) : _currentScreen-> setMode (MODE_Origin ); break; //VT100
658
case TY_CSI_PR('l', 6) : _currentScreen-> resetMode (MODE_Origin ); break; //VT100
659
case TY_CSI_PR('s', 6) : _currentScreen-> saveMode (MODE_Origin ); break; //FIXME
660
case TY_CSI_PR('r', 6) : _currentScreen->restoreMode (MODE_Origin ); break; //FIXME
662
case TY_CSI_PR('h', 7) : _currentScreen-> setMode (MODE_Wrap ); break; //VT100
663
case TY_CSI_PR('l', 7) : _currentScreen-> resetMode (MODE_Wrap ); break; //VT100
664
case TY_CSI_PR('s', 7) : _currentScreen-> saveMode (MODE_Wrap ); break; //FIXME
665
case TY_CSI_PR('r', 7) : _currentScreen->restoreMode (MODE_Wrap ); break; //FIXME
667
case TY_CSI_PR('h', 8) : /* IGNORED: autorepeat on */ break; //VT100
668
case TY_CSI_PR('l', 8) : /* IGNORED: autorepeat off */ break; //VT100
669
case TY_CSI_PR('s', 8) : /* IGNORED: autorepeat on */ break; //VT100
670
case TY_CSI_PR('r', 8) : /* IGNORED: autorepeat off */ break; //VT100
672
case TY_CSI_PR('h', 9) : /* IGNORED: interlace */ break; //VT100
673
case TY_CSI_PR('l', 9) : /* IGNORED: interlace */ break; //VT100
674
case TY_CSI_PR('s', 9) : /* IGNORED: interlace */ break; //VT100
675
case TY_CSI_PR('r', 9) : /* IGNORED: interlace */ break; //VT100
677
case TY_CSI_PR('h', 12) : /* IGNORED: Cursor blink */ break; //att610
678
case TY_CSI_PR('l', 12) : /* IGNORED: Cursor blink */ break; //att610
679
case TY_CSI_PR('s', 12) : /* IGNORED: Cursor blink */ break; //att610
680
case TY_CSI_PR('r', 12) : /* IGNORED: Cursor blink */ break; //att610
682
case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break; //VT100
683
case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break; //VT100
684
case TY_CSI_PR('s', 25) : saveMode (MODE_Cursor ); break; //VT100
685
case TY_CSI_PR('r', 25) : restoreMode (MODE_Cursor ); break; //VT100
687
case TY_CSI_PR('h', 40) : setMode(MODE_Allow132Columns ); break; // XTERM
688
case TY_CSI_PR('l', 40) : resetMode(MODE_Allow132Columns ); break; // XTERM
690
case TY_CSI_PR('h', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
691
case TY_CSI_PR('l', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
692
case TY_CSI_PR('s', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
693
case TY_CSI_PR('r', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
695
case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break; //VT100
696
case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break; //VT100
697
case TY_CSI_PR('s', 47) : saveMode (MODE_AppScreen); break; //XTERM
698
case TY_CSI_PR('r', 47) : restoreMode (MODE_AppScreen); break; //XTERM
700
case TY_CSI_PR('h', 67) : /* IGNORED: DECBKM */ break; //XTERM
701
case TY_CSI_PR('l', 67) : /* IGNORED: DECBKM */ break; //XTERM
702
case TY_CSI_PR('s', 67) : /* IGNORED: DECBKM */ break; //XTERM
703
case TY_CSI_PR('r', 67) : /* IGNORED: DECBKM */ break; //XTERM
705
// XTerm defines the following modes:
706
// SET_VT200_MOUSE 1000
707
// SET_VT200_HIGHLIGHT_MOUSE 1001
708
// SET_BTN_EVENT_MOUSE 1002
709
// SET_ANY_EVENT_MOUSE 1003
712
//Note about mouse modes:
713
//There are four mouse modes which xterm-compatible terminals can support - 1000,1001,1002,1003
714
//Konsole currently supports mode 1000 (basic mouse press and release) and mode 1002 (dragging the mouse).
715
//TODO: Implementation of mouse modes 1001 (something called hilight tracking) and
716
//1003 (a slight variation on dragging the mouse)
719
case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break; //XTERM
720
case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break; //XTERM
721
case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break; //XTERM
722
case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break; //XTERM
724
case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
725
case TY_CSI_PR('l', 1001) : resetMode (MODE_Mouse1001); break; //XTERM
726
case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
727
case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
729
case TY_CSI_PR('h', 1002) : setMode (MODE_Mouse1002); break; //XTERM
730
case TY_CSI_PR('l', 1002) : resetMode (MODE_Mouse1002); break; //XTERM
731
case TY_CSI_PR('s', 1002) : saveMode (MODE_Mouse1002); break; //XTERM
732
case TY_CSI_PR('r', 1002) : restoreMode (MODE_Mouse1002); break; //XTERM
734
case TY_CSI_PR('h', 1003) : setMode (MODE_Mouse1003); break; //XTERM
735
case TY_CSI_PR('l', 1003) : resetMode (MODE_Mouse1003); break; //XTERM
736
case TY_CSI_PR('s', 1003) : saveMode (MODE_Mouse1003); break; //XTERM
737
case TY_CSI_PR('r', 1003) : restoreMode (MODE_Mouse1003); break; //XTERM
739
case TY_CSI_PR('h', 1034) : /* IGNORED: 8bitinput activation */ break; //XTERM
741
case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break; //XTERM
742
case TY_CSI_PR('l', 1047) : _screen[1]->clearEntireScreen(); resetMode(MODE_AppScreen); break; //XTERM
743
case TY_CSI_PR('s', 1047) : saveMode (MODE_AppScreen); break; //XTERM
744
case TY_CSI_PR('r', 1047) : restoreMode (MODE_AppScreen); break; //XTERM
746
//FIXME: Unitoken: save translations
747
case TY_CSI_PR('h', 1048) : saveCursor ( ); break; //XTERM
748
case TY_CSI_PR('l', 1048) : restoreCursor ( ); break; //XTERM
749
case TY_CSI_PR('s', 1048) : saveCursor ( ); break; //XTERM
750
case TY_CSI_PR('r', 1048) : restoreCursor ( ); break; //XTERM
752
//FIXME: every once new sequences like this pop up in xterm.
753
// Here's a guess of what they could mean.
754
case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM
755
case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM
757
//FIXME: weird DEC reset sequence
758
case TY_CSI_PE('p' ) : /* IGNORED: reset ( ) */ break;
760
//FIXME: when changing between vt52 and ansi mode evtl do some resetting.
761
case TY_VT52('A' ) : _currentScreen->cursorUp ( 1); break; //VT52
762
case TY_VT52('B' ) : _currentScreen->cursorDown ( 1); break; //VT52
763
case TY_VT52('C' ) : _currentScreen->cursorRight ( 1); break; //VT52
764
case TY_VT52('D' ) : _currentScreen->cursorLeft ( 1); break; //VT52
766
case TY_VT52('F' ) : setAndUseCharset (0, '0'); break; //VT52
767
case TY_VT52('G' ) : setAndUseCharset (0, 'B'); break; //VT52
769
case TY_VT52('H' ) : _currentScreen->setCursorYX (1,1 ); break; //VT52
770
case TY_VT52('I' ) : _currentScreen->reverseIndex ( ); break; //VT52
771
case TY_VT52('J' ) : _currentScreen->clearToEndOfScreen ( ); break; //VT52
772
case TY_VT52('K' ) : _currentScreen->clearToEndOfLine ( ); break; //VT52
773
case TY_VT52('Y' ) : _currentScreen->setCursorYX (p-31,q-31 ); break; //VT52
774
case TY_VT52('Z' ) : reportTerminalType ( ); break; //VT52
775
case TY_VT52('<' ) : setMode (MODE_Ansi ); break; //VT52
776
case TY_VT52('=' ) : setMode (MODE_AppKeyPad); break; //VT52
777
case TY_VT52('>' ) : resetMode (MODE_AppKeyPad); break; //VT52
779
case TY_CSI_PG('c' ) : reportSecondaryAttributes( ); break; //VT100
782
reportDecodingError();
787
void Vt102Emulation::clearScreenAndSetColumns(int columnCount)
789
setImageSize(_currentScreen->getLines(),columnCount);
792
_currentScreen->setCursorYX(0,0);
795
void Vt102Emulation::sendString(const char* s , int length)
798
emit sendData(s,length);
800
emit sendData(s,strlen(s));
803
void Vt102Emulation::reportCursorPosition()
806
sprintf(tmp,"\033[%d;%dR",_currentScreen->getCursorY()+1,_currentScreen->getCursorX()+1);
810
void Vt102Emulation::reportTerminalType()
812
// Primary device attribute response (Request was: ^[[0c or ^[[c (from TT321 Users Guide))
813
// VT220: ^[[?63;1;2;3;6;7;8c (list deps on emul. capabilities)
817
if (getMode(MODE_Ansi))
818
sendString("\033[?1;2c"); // I'm a VT100
820
sendString("\033/Z"); // I'm a VT52
823
void Vt102Emulation::reportSecondaryAttributes()
825
// Seconday device attribute response (Request was: ^[[>0c or ^[[>c)
826
if (getMode(MODE_Ansi))
827
sendString("\033[>0;115;0c"); // Why 115? ;)
829
sendString("\033/Z"); // FIXME I don't think VT52 knows about it but kept for
830
// konsoles backward compatibility.
833
void Vt102Emulation::reportTerminalParms(int p)
837
sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
841
void Vt102Emulation::reportStatus()
843
sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
846
void Vt102Emulation::reportAnswerBack()
848
// FIXME - Test this with VTTEST
849
// This is really obsolete VT100 stuff.
850
const char* ANSWER_BACK = "";
851
sendString(ANSWER_BACK);
855
`cx',`cy' are 1-based.
856
`eventType' indicates the button pressed (0-2)
857
or a general mouse release (3).
859
eventType represents the kind of mouse action that occurred:
860
0 = Mouse button press or release
864
void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
866
if (cx < 1 || cy < 1)
869
// normal buttons are passed as 0x20 + button,
870
// mouse wheel (buttons 4,5) as 0x5c + button
874
//Mouse motion handling
875
if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1)
876
cb += 0x20; //add 32 to signify motion event
879
sprintf(command,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20);
883
void Vt102Emulation::sendText( const QString& text )
887
QKeyEvent event(QEvent::KeyPress,
891
sendKeyEvent(&event); // expose as a big fat keypress event
894
void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
896
Qt::KeyboardModifiers modifiers = event->modifiers();
897
KeyboardTranslator::States states = KeyboardTranslator::NoState;
899
// get current states
900
if (getMode(MODE_NewLine) ) states |= KeyboardTranslator::NewLineState;
901
if (getMode(MODE_Ansi) ) states |= KeyboardTranslator::AnsiState;
902
if (getMode(MODE_AppCuKeys)) states |= KeyboardTranslator::CursorKeysState;
903
if (getMode(MODE_AppScreen)) states |= KeyboardTranslator::AlternateScreenState;
904
if (getMode(MODE_AppKeyPad) && (modifiers & Qt::KeypadModifier))
905
states |= KeyboardTranslator::ApplicationKeypadState;
907
// check flow control state
908
if (modifiers & Qt::ControlModifier)
910
if (event->key() == Qt::Key_S)
911
emit flowControlKeyPressed(true);
912
else if (event->key() == Qt::Key_Q)
913
emit flowControlKeyPressed(false);
916
// lookup key binding
917
if ( _keyTranslator )
919
KeyboardTranslator::Entry entry = _keyTranslator->findEntry(
924
// send result to terminal
925
QByteArray textToSend;
927
// special handling for the Alt (aka. Meta) modifier. pressing
928
// Alt+[Character] results in Esc+[Character] being sent
929
// (unless there is an entry defined for this particular combination
930
// in the keyboard modifier)
931
bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier;
932
bool wantsAnyModifier = entry.state() &
933
entry.stateMask() & KeyboardTranslator::AnyModifierState;
935
if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier)
936
&& !event->text().isEmpty() )
938
textToSend.prepend("\033");
941
if ( entry.command() != KeyboardTranslator::NoCommand )
943
if (entry.command() & KeyboardTranslator::EraseCommand)
944
textToSend += eraseChar();
946
// TODO command handling
948
else if ( !entry.text().isEmpty() )
950
textToSend += _codec->fromUnicode(entry.text(true,modifiers));
953
textToSend += _codec->fromUnicode(event->text());
955
sendData( textToSend.constData() , textToSend.length() );
959
// print an error message to the terminal if no key translator has been
961
QString translatorError = tr("No keyboard translator available. "
962
"The information needed to convert key presses "
963
"into characters to send to the terminal "
966
receiveData( translatorError.toLatin1().constData() , translatorError.count() );
970
/* ------------------------------------------------------------------------- */
974
/* ------------------------------------------------------------------------- */
976
// Character Set Conversion ------------------------------------------------ --
979
The processing contains a VT100 specific code translation layer.
980
It's still in use and mainly responsible for the line drawing graphics.
982
These and some other glyphs are assigned to codes (0x5f-0xfe)
983
normally occupied by the latin letters. Since this codes also
984
appear within control sequences, the extra code conversion
985
does not permute with the tokenizer and is placed behind it
986
in the pipeline. It only applies to tokens, which represent
989
This conversion it eventually continued in TerminalDisplay.C, since
990
it might involve VT100 enhanced fonts, which have these
991
particular glyphs allocated in (0x00-0x1f) in their code page.
994
#define CHARSET _charset[_currentScreen==_screen[1]]
996
// Apply current character map.
998
unsigned short Vt102Emulation::applyCharset(unsigned short c)
1000
if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
1001
if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete
1006
"Charset" related part of the emulation state.
1007
This configures the VT100 charset filter.
1009
While most operation work on the current _screen,
1010
the following two are different.
1013
void Vt102Emulation::resetCharset(int scrno)
1015
_charset[scrno].cu_cs = 0;
1016
strncpy(_charset[scrno].charset,"BBBB",4);
1017
_charset[scrno].sa_graphic = false;
1018
_charset[scrno].sa_pound = false;
1019
_charset[scrno].graphic = false;
1020
_charset[scrno].pound = false;
1023
void Vt102Emulation::setCharset(int n, int cs) // on both screens.
1025
_charset[0].charset[n&3] = cs; useCharset(_charset[0].cu_cs);
1026
_charset[1].charset[n&3] = cs; useCharset(_charset[1].cu_cs);
1029
void Vt102Emulation::setAndUseCharset(int n, int cs)
1031
CHARSET.charset[n&3] = cs;
1035
void Vt102Emulation::useCharset(int n)
1037
CHARSET.cu_cs = n&3;
1038
CHARSET.graphic = (CHARSET.charset[n&3] == '0');
1039
CHARSET.pound = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
1042
void Vt102Emulation::setDefaultMargins()
1044
_screen[0]->setDefaultMargins();
1045
_screen[1]->setDefaultMargins();
1048
void Vt102Emulation::setMargins(int t, int b)
1050
_screen[0]->setMargins(t, b);
1051
_screen[1]->setMargins(t, b);
1054
void Vt102Emulation::saveCursor()
1056
CHARSET.sa_graphic = CHARSET.graphic;
1057
CHARSET.sa_pound = CHARSET.pound; //This mode is obsolete
1058
// we are not clear about these
1059
//sa_charset = charsets[cScreen->_charset];
1060
//sa_charset_num = cScreen->_charset;
1061
_currentScreen->saveCursor();
1064
void Vt102Emulation::restoreCursor()
1066
CHARSET.graphic = CHARSET.sa_graphic;
1067
CHARSET.pound = CHARSET.sa_pound; //This mode is obsolete
1068
_currentScreen->restoreCursor();
1071
/* ------------------------------------------------------------------------- */
1073
/* Mode Operations */
1075
/* ------------------------------------------------------------------------- */
1078
Some of the emulations state is either added to the state of the screens.
1080
This causes some scoping problems, since different emulations choose to
1081
located the mode either to the current _screen or to both.
1083
For strange reasons, the extend of the rendition attributes ranges over
1084
all screens and not over the actual _screen.
1086
We decided on the precise precise extend, somehow.
1089
// "Mode" related part of the state. These are all booleans.
1091
void Vt102Emulation::resetModes()
1093
// MODE_Allow132Columns is not reset here
1094
// to match Xterm's behaviour (see Xterm's VTReset() function)
1096
resetMode(MODE_132Columns); saveMode(MODE_132Columns);
1097
resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000);
1098
resetMode(MODE_Mouse1001); saveMode(MODE_Mouse1001);
1099
resetMode(MODE_Mouse1002); saveMode(MODE_Mouse1002);
1100
resetMode(MODE_Mouse1003); saveMode(MODE_Mouse1003);
1102
resetMode(MODE_AppScreen); saveMode(MODE_AppScreen);
1103
resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys);
1104
resetMode(MODE_AppKeyPad); saveMode(MODE_AppKeyPad);
1105
resetMode(MODE_NewLine);
1109
void Vt102Emulation::setMode(int m)
1111
_currentModes.mode[m] = true;
1114
case MODE_132Columns:
1115
if (getMode(MODE_Allow132Columns))
1116
clearScreenAndSetColumns(132);
1118
_currentModes.mode[m] = false;
1120
case MODE_Mouse1000:
1121
case MODE_Mouse1001:
1122
case MODE_Mouse1002:
1123
case MODE_Mouse1003:
1124
emit programUsesMouseChanged(false);
1127
case MODE_AppScreen : _screen[1]->clearSelection();
1131
if (m < MODES_SCREEN || m == MODE_NewLine)
1133
_screen[0]->setMode(m);
1134
_screen[1]->setMode(m);
1138
void Vt102Emulation::resetMode(int m)
1140
_currentModes.mode[m] = false;
1143
case MODE_132Columns:
1144
if (getMode(MODE_Allow132Columns))
1145
clearScreenAndSetColumns(80);
1147
case MODE_Mouse1000 :
1148
case MODE_Mouse1001 :
1149
case MODE_Mouse1002 :
1150
case MODE_Mouse1003 :
1151
emit programUsesMouseChanged(true);
1154
case MODE_AppScreen :
1155
_screen[0]->clearSelection();
1159
if (m < MODES_SCREEN || m == MODE_NewLine)
1161
_screen[0]->resetMode(m);
1162
_screen[1]->resetMode(m);
1166
void Vt102Emulation::saveMode(int m)
1168
_savedModes.mode[m] = _currentModes.mode[m];
1171
void Vt102Emulation::restoreMode(int m)
1173
if (_savedModes.mode[m])
1179
bool Vt102Emulation::getMode(int m)
1181
return _currentModes.mode[m];
1184
char Vt102Emulation::eraseChar() const
1186
KeyboardTranslator::Entry entry = _keyTranslator->findEntry(
1190
if ( entry.text().count() > 0 )
1191
return entry.text()[0];
1196
// print contents of the scan buffer
1197
static void hexdump(int* s, int len)
1199
for (i = 0; i < len; i++)
1204
if ((s[i]) > 32 && s[i] < 127)
1207
printf("\\%04x(hex)",s[i]);
1211
void Vt102Emulation::reportDecodingError()
1213
if (tokenBufferPos == 0 || ( tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32) )
1215
printf("Undecodable sequence: ");
1216
hexdump(tokenBuffer,tokenBufferPos);
1220
//#include "Vt102Emulation.moc"