GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Vt102Emulation.cpp
Go to the documentation of this file.
1/*
2 This file is part of Konsole, an X terminal.
3 Copyright (C) 1997-1998, 2013 by Lars Doelle <lars.doelle@on-line.de>
4
5 Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
6
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.
11
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.
16
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
20 02110-1301 USA.
21*/
22
23// Own
24#include "unix/Vt102Emulation.h"
25
26#if defined(__osf__) || defined(__APPLE__)
27#define AVOID_XKB
28#endif
29
30// this allows konsole to be compiled without XKB and XTEST extensions
31// even though it might be available on a particular system.
32#if defined(AVOID_XKB)
33#undef HAVE_XKB
34#endif
35
36// Standard
37#include <stdio.h>
38#include <unistd.h>
39#include <assert.h>
40
41// Qt
42#include <QtCore/QEvent>
43#include <QKeyEvent>
44#include <QtCore/QByteRef>
45
46// Konsole
48#include "unix/Screen.h"
49
50#if defined(HAVE_XKB)
51void scrolllock_set_off();
52void scrolllock_set_on();
53#endif
54
55
56/* VT102 Terminal Emulation
57
58 This class puts together the screens, the pty and the widget to a
59 complete terminal emulation. Beside combining it's componentes, it
60 handles the emulations's protocol.
61
62 This module consists of the following sections:
63
64 - Constructor/Destructor
65 - Incoming Bytes Event pipeline
66 - Outgoing Bytes
67 - Mouse Events
68 - Keyboard Events
69 - Modes and Charset State
70 - Diagnostics
71*/
72
73/* ------------------------------------------------------------------------- */
74/* */
75/* Constructor / Destructor */
76/* */
77/* ------------------------------------------------------------------------- */
78
79
81 : Emulation(),
82 _titleUpdateTimer(new QTimer(this))
83{
84 _titleUpdateTimer->setSingleShot(true);
85
86 QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle()));
87
89 reset();
90}
91
93{
94}
95
97{
99
101}
102
104{
105 //kDebug(1211)<<"Vt102Emulation::reset() resetToken()";
106 resetToken();
107 //kDebug(1211)<<"Vt102Emulation::reset() resetModes()";
108 resetModes();
109 //kDebug(1211)<<"Vt102Emulation::reset() resetCharSet()";
110 resetCharset(0);
111 //kDebug(1211)<<"Vt102Emulation::reset() reset screen0()";
112 _screen[0]->reset();
113 //kDebug(1211)<<"Vt102Emulation::reset() resetCharSet()";
114 resetCharset(1);
115 //kDebug(1211)<<"Vt102Emulation::reset() reset _screen 1";
116 _screen[1]->reset();
117 //kDebug(1211)<<"Vt102Emulation::reset() setCodec()";
119 //kDebug(1211)<<"Vt102Emulation::reset() done";
120
122}
123
124/* ------------------------------------------------------------------------- */
125/* */
126/* Processing the incoming byte stream */
127/* */
128/* ------------------------------------------------------------------------- */
129
130/* Incoming Bytes Event pipeline
131
132 This section deals with decoding the incoming character stream.
133 Decoding means here, that the stream is first separated into `tokens'
134 which are then mapped to a `meaning' provided as operations by the
135 `Screen' class or by the emulation class itself.
136
137 The pipeline proceeds as follows:
138
139 - Tokenizing the ESC codes (onReceiveChar)
140 - VT100 code page translation of plain characters (applyCharset)
141 - Interpretation of ESC codes (tau)
142
143 The escape codes and their meaning are described in the
144 technical reference of this program.
145*/
146
147// Tokens ------------------------------------------------------------------ --
148
149/*
150 Since the tokens are the central notion if this section, we've put them
151 in front. They provide the syntactical elements used to represent the
152 terminals operations as byte sequences.
153
154 They are encodes here into a single machine word, so that we can later
155 switch over them easily. Depending on the token itself, additional
156 argument variables are filled with parameter values.
157
158 The tokens are defined below:
159
160 - CHR - Printable characters (32..255 but DEL (=127))
161 - CTL - Control characters (0..31 but ESC (= 27), DEL)
162 - ESC - Escape codes of the form <ESC><CHR but `[]()+*#'>
163 - ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C
164 - CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C
165 - CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C
166 - CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C
167 - CSI_PE - Escape codes of the form <ESC>'[' '!' {Pn} ';' ... C
168 - VT52 - VT52 escape codes
169 - <ESC><Chr>
170 - <ESC>'Y'{Pc}{Pc}
171 - XTE_HA - Xterm hacks <ESC>`]' {Pn} `;' {Text} <BEL>
172 note that this is handled differently
173
174 The last two forms allow list of arguments. Since the elements of
175 the lists are treated individually the same way, they are passed
176 as individual tokens to the interpretation. Further, because the
177 meaning of the parameters are names (althought represented as numbers),
178 they are includes within the token ('N').
179
180*/
181
182#define TY_CONSTR(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
183
184#define TY_CHR( ) TY_CONSTR(0,0,0)
185#define TY_CTL(A ) TY_CONSTR(1,A,0)
186#define TY_ESC(A ) TY_CONSTR(2,A,0)
187#define TY_ESC_CS(A,B) TY_CONSTR(3,A,B)
188#define TY_ESC_DE(A ) TY_CONSTR(4,A,0)
189#define TY_CSI_PS(A,N) TY_CONSTR(5,A,N)
190#define TY_CSI_PN(A ) TY_CONSTR(6,A,0)
191#define TY_CSI_PR(A,N) TY_CONSTR(7,A,N)
192
193#define TY_VT52(A ) TY_CONSTR(8,A,0)
194
195#define TY_CSI_PG(A ) TY_CONSTR(9,A,0)
196
197#define TY_CSI_PE(A ) TY_CONSTR(10,A,0)
198
199// Tokenizer --------------------------------------------------------------- --
200
201/* The tokenizers state
202
203 The state is represented by the buffer (pbuf, ppos),
204 and accompanied by decoded arguments kept in (argv,argc).
205 Note that they are kept internal in the tokenizer.
206*/
207
209{
210 ppos = 0; argc = 0; argv[0] = 0; argv[1] = 0;
211}
212
214{
215 argv[argc] = 10*argv[argc] + dig;
216}
217
219{
220 argc = qMin(argc+1,MAXARGS-1);
221 argv[argc] = 0;
222}
223
225{
226 pbuf[ppos] = cc;
227 ppos = qMin(ppos+1,MAXPBUF-1);
228}
229
230// Character Classes used while decoding
231
232#define CTL 1
233#define CHR 2
234#define CPN 4
235#define DIG 8
236#define SCS 16
237#define GRP 32
238#define CPS 64
239
241{ int i; quint8* s;
242 for(i = 0; i < 256; i++) tbl[ i] = 0;
243 for(i = 0; i < 32; i++) tbl[ i] |= CTL;
244 for(i = 32; i < 256; i++) tbl[ i] |= CHR;
245 for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; s++) tbl[*s] |= CPN;
246// resize = \e[8;<row>;<col>t
247 for(s = (quint8*)"t"; *s; s++) tbl[*s] |= CPS;
248 for(s = (quint8*)"0123456789" ; *s; s++) tbl[*s] |= DIG;
249 for(s = (quint8*)"()+*%" ; *s; s++) tbl[*s] |= SCS;
250 for(s = (quint8*)"()+*#[]%" ; *s; s++) tbl[*s] |= GRP;
251 resetToken();
252}
253
254/* Ok, here comes the nasty part of the decoder.
255
256 Instead of keeping an explicit state, we deduce it from the
257 token scanned so far. It is then immediately combined with
258 the current character to form a scanning decision.
259
260 This is done by the following defines.
261
262 - P is the length of the token scanned so far.
263 - L (often P-1) is the position on which contents we base a decision.
264 - C is a character or a group of characters (taken from 'tbl').
265
266 Note that they need to applied in proper order.
267*/
268
269#define lec(P,L,C) (p == (P) && s[(L)] == (C))
270#define lun( ) (p == 1 && cc >= 32 )
271#define les(P,L,C) (p == (P) && s[L] < 256 && (tbl[s[(L)]] & (C)) == (C))
272#define eec(C) (p >= 3 && cc == (C))
273#define ees(C) (p >= 3 && cc < 256 && (tbl[ cc ] & (C)) == (C))
274#define eps(C) (p >= 3 && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (tbl[ cc ] & (C)) == (C))
275#define epp( ) (p >= 3 && s[2] == '?' )
276#define epe( ) (p >= 3 && s[2] == '!' )
277#define egt( ) (p >= 3 && s[2] == '>' )
278#define Xpe (ppos>=2 && pbuf[1] == ']' )
279#define Xte (Xpe && cc == 7 )
280#define ces(C) ( cc < 256 && (tbl[ cc ] & (C)) == (C) && !Xte)
281
282#define ESC 27
283#define CNTL(c) ((c)-'@')
284
285// process an incoming unicode character
286
288{
289 int i;
290 if (cc == 127) return; //VT100: ignore.
291
292 if (ces( CTL))
293 { // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
294 // This means, they do neither a resetToken nor a pushToToken. Some of them, do
295 // of course. Guess this originates from a weakly layered handling of the X-on
296 // X-off protocol, which comes really below this level.
297 if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken(); //VT100: CAN or SUB
298 if (cc != ESC) { tau( TY_CTL(cc+'@' ), 0, 0); return; }
299 }
300
301 pushToToken(cc); // advance the state
302
303 int* s = pbuf;
304 int p = ppos;
305
306 if (getMode(MODE_Ansi)) // decide on proper action
307 {
308 if (lec(1,0,ESC)) { return; }
309 if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('['); return; }
310 if (les(2,1,GRP)) { return; }
311 if (Xte ) { XtermHack(); resetToken(); return; }
312 if (Xpe ) { return; }
313 if (lec(3,2,'?')) { return; }
314 if (lec(3,2,'>')) { return; }
315 if (lec(3,2,'!')) { return; }
316 if (lun( )) { tau( TY_CHR(), applyCharset(cc), 0); resetToken(); return; }
317 if (lec(2,0,ESC)) { tau( TY_ESC(s[1]), 0, 0); resetToken(); return; }
318 if (les(3,1,SCS)) { tau( TY_ESC_CS(s[1],s[2]), 0, 0); resetToken(); return; }
319 if (lec(3,1,'#')) { tau( TY_ESC_DE(s[2]), 0, 0); resetToken(); return; }
320 if (eps( CPN)) { tau( TY_CSI_PN(cc), argv[0],argv[1]); resetToken(); return; }
321
322// resize = \e[8;<row>;<col>t
323 if (eps( CPS)) { tau( TY_CSI_PS(cc, argv[0]), argv[1], argv[2]); resetToken(); return; }
324
325 if (epe( )) { tau( TY_CSI_PE(cc), 0, 0); resetToken(); return; }
326 if (ees( DIG)) { addDigit(cc-'0'); return; }
327 if (eec( ';')) { addArgument(); return; }
328 for (i=0;i<=argc;i++)
329 if ( epp( )) { tau( TY_CSI_PR(cc,argv[i]), 0, 0); }
330 else if(egt( )) { tau( TY_CSI_PG(cc ), 0, 0); } // spec. case for ESC]>0c or ESC]>c
331 else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)
332 { // ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m
333 i += 2;
334 tau( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i+1] << 8) | argv[i+2]);
335 i += 2;
336 }
337 else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 5)
338 { // ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m
339 i += 2;
340 tau( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]);
341 }
342 else { tau( TY_CSI_PS(cc,argv[i]), 0, 0); }
343 resetToken();
344 }
345 else // mode VT52
346 {
347 if (lec(1,0,ESC)) return;
348 if (les(1,0,CHR)) { tau( TY_CHR( ), s[0], 0); resetToken(); return; }
349 if (lec(2,1,'Y')) return;
350 if (lec(3,1,'Y')) return;
351 if (p < 4) { tau( TY_VT52(s[1] ), 0, 0); resetToken(); return; }
352 tau( TY_VT52(s[1] ), s[2],s[3]); resetToken(); return;
353 }
354}
355
357{ int i,arg = 0;
358 for (i = 2; i < ppos && '0'<=pbuf[i] && pbuf[i]<'9' ; i++)
359 arg = 10*arg + (pbuf[i]-'0');
360 if (pbuf[i] != ';') { ReportErrorToken(); return; }
361 QChar *str = new QChar[ppos-i-2];
362 for (int j = 0; j < ppos-i-2; j++) str[j] = pbuf[i+1+j];
363 QString unistr(str,ppos-i-2);
364
365 // arg == 1 doesn't change the title. In XTerm it only changes the icon name
366 // (btw: arg=0 changes title and icon, arg=1 only icon, arg=2 only title
367// emit changeTitle(arg,unistr);
368 _pendingTitleUpdates[arg] = unistr;
369 _titleUpdateTimer->start(20);
370
371 delete [] str;
372}
373
375{
376 QListIterator<int> iter( _pendingTitleUpdates.keys() );
377 while (iter.hasNext()) {
378 int arg = iter.next();
379 emit titleChanged( arg , _pendingTitleUpdates[arg] );
380 }
381
382 _pendingTitleUpdates.clear();
383}
384
385// Interpreting Codes ---------------------------------------------------------
386
387/*
388 Now that the incoming character stream is properly tokenized,
389 meaning is assigned to them. These are either operations of
390 the current _screen, or of the emulation class itself.
391
392 The token to be interpreteted comes in as a machine word
393 possibly accompanied by two parameters.
394
395 Likewise, the operations assigned to, come with up to two
396 arguments. One could consider to make up a proper table
397 from the function below.
398
399 The technical reference manual provides more information
400 about this mapping.
401*/
402
403void Vt102Emulation::tau( int token, int p, int q )
404{
405#if 0
406int N = (token>>0)&0xff;
407int A = (token>>8)&0xff;
408switch( N )
409{
410 case 0: printf("%c", (p < 128) ? p : '?');
411 break;
412 case 1: if (A == 'J') printf("\r");
413 else if (A == 'M') printf("\n");
414 else printf("CTL-%c ", (token>>8)&0xff);
415 break;
416 case 2: printf("ESC-%c ", (token>>8)&0xff);
417 break;
418 case 3: printf("ESC_CS-%c-%c ", (token>>8)&0xff, (token>>16)&0xff);
419 break;
420 case 4: printf("ESC_DE-%c ", (token>>8)&0xff);
421 break;
422 case 5: printf("CSI-PS-%c-%d", (token>>8)&0xff, (token>>16)&0xff );
423 break;
424 case 6: printf("CSI-PN-%c [%d]", (token>>8)&0xff, p);
425 break;
426 case 7: printf("CSI-PR-%c-%d", (token>>8)&0xff, (token>>16)&0xff );
427 break;
428 case 8: printf("VT52-%c", (token>>8)&0xff);
429 break;
430 case 9: printf("CSI-PG-%c", (token>>8)&0xff);
431 break;
432 case 10: printf("CSI-PE-%c", (token>>8)&0xff);
433 break;
434}
435#endif
436
437 switch (token)
438 {
439
440 case TY_CHR( ) : _currentScreen->ShowCharacter (p ); break; //UTF16
441
442 // 127 DEL : ignored on input
443
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);
452 break; //VT100
453 case TY_CTL('H' ) : _currentScreen->BackSpace ( ); break; //VT100
454 case TY_CTL('I' ) : _currentScreen->Tabulate ( ); 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->Return ( ); break; //VT100
459
460 case TY_CTL('N' ) : useCharset ( 1); break; //VT100
461 case TY_CTL('O' ) : useCharset ( 0); break; //VT100
462
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->ShowCharacter ( 0x2592); break; //VT100
472 case TY_CTL('Y' ) : /* EM : ignored */ break;
473 case TY_CTL('Z' ) : _currentScreen->ShowCharacter ( 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;
479
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;
486
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;
491
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
495
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
499
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
503
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
507
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
511
512 case TY_ESC_CS('%', 'G') : setCodec (Utf8Codec ); break; //LINUX
513 case TY_ESC_CS('%', '@') : setCodec (LocaleCodec ); break; //LINUX
514
515 case TY_ESC_DE('3' ) : /* Double height line, top half */
518 break;
519 case TY_ESC_DE('4' ) : /* Double height line, bottom half */
522 break;
523 case TY_ESC_DE('5' ) : /* Single width, single height line*/
526 break;
527 case TY_ESC_DE('6' ) : /* Double width, single height line*/
530 break;
531 case TY_ESC_DE('8' ) : _currentScreen->helpAlign ( ); break;
532
533// resize = \e[8;<row>;<col>t
534 case TY_CSI_PS('t', 8) : setImageSize( q /* colums */, p /* lines */ ); break;
535
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;
538
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('g', 0) : _currentScreen->changeTabStop (false ); break; //VT100
546 case TY_CSI_PS('g', 3) : _currentScreen->clearTabStops ( ); break; //VT100
547 case TY_CSI_PS('h', 4) : _currentScreen-> setMode (MODE_Insert ); break;
548 case TY_CSI_PS('h', 20) : setMode (MODE_NewLine ); break;
549 case TY_CSI_PS('i', 0) : /* IGNORE: attached printer */ break; //VT100
550 case TY_CSI_PS('l', 4) : _currentScreen-> resetMode (MODE_Insert ); break;
551 case TY_CSI_PS('l', 20) : resetMode (MODE_NewLine ); break;
552 case TY_CSI_PS('s', 0) : saveCursor ( ); break;
553 case TY_CSI_PS('u', 0) : restoreCursor ( ); break;
554
555 case TY_CSI_PS('m', 0) : _currentScreen->setDefaultRendition ( ); break;
556 case TY_CSI_PS('m', 1) : _currentScreen-> setRendition (RE_BOLD ); break; //VT100
557 case TY_CSI_PS('m', 4) : _currentScreen-> setRendition (RE_UNDERLINE); break; //VT100
558 case TY_CSI_PS('m', 5) : _currentScreen-> setRendition (RE_BLINK ); break; //VT100
559 case TY_CSI_PS('m', 7) : _currentScreen-> setRendition (RE_REVERSE ); break;
560 case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX
561 case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX
562 case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX
563 case TY_CSI_PS('m', 22) : _currentScreen->resetRendition (RE_BOLD ); break;
564 case TY_CSI_PS('m', 24) : _currentScreen->resetRendition (RE_UNDERLINE); break;
565 case TY_CSI_PS('m', 25) : _currentScreen->resetRendition (RE_BLINK ); break;
566 case TY_CSI_PS('m', 27) : _currentScreen->resetRendition (RE_REVERSE ); break;
567
568 case TY_CSI_PS('m', 30) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 0); break;
569 case TY_CSI_PS('m', 31) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 1); break;
570 case TY_CSI_PS('m', 32) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 2); break;
571 case TY_CSI_PS('m', 33) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 3); break;
572 case TY_CSI_PS('m', 34) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 4); break;
573 case TY_CSI_PS('m', 35) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 5); break;
574 case TY_CSI_PS('m', 36) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 6); break;
575 case TY_CSI_PS('m', 37) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 7); break;
576
577 case TY_CSI_PS('m', 38) : _currentScreen->setForeColor (p, q); break;
578
579 case TY_CSI_PS('m', 39) : _currentScreen->setForeColor (COLOR_SPACE_DEFAULT, 0); break;
580
581 case TY_CSI_PS('m', 40) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 0); break;
582 case TY_CSI_PS('m', 41) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 1); break;
583 case TY_CSI_PS('m', 42) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 2); break;
584 case TY_CSI_PS('m', 43) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 3); break;
585 case TY_CSI_PS('m', 44) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 4); break;
586 case TY_CSI_PS('m', 45) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 5); break;
587 case TY_CSI_PS('m', 46) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 6); break;
588 case TY_CSI_PS('m', 47) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 7); break;
589
590 case TY_CSI_PS('m', 48) : _currentScreen->setBackColor (p, q); break;
591
592 case TY_CSI_PS('m', 49) : _currentScreen->setBackColor (COLOR_SPACE_DEFAULT, 1); break;
593
594 case TY_CSI_PS('m', 90) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 8); break;
595 case TY_CSI_PS('m', 91) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 9); break;
596 case TY_CSI_PS('m', 92) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 10); break;
597 case TY_CSI_PS('m', 93) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 11); break;
598 case TY_CSI_PS('m', 94) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 12); break;
599 case TY_CSI_PS('m', 95) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 13); break;
600 case TY_CSI_PS('m', 96) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 14); break;
601 case TY_CSI_PS('m', 97) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 15); break;
602
603 case TY_CSI_PS('m', 100) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 8); break;
604 case TY_CSI_PS('m', 101) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 9); break;
605 case TY_CSI_PS('m', 102) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 10); break;
606 case TY_CSI_PS('m', 103) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 11); break;
607 case TY_CSI_PS('m', 104) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 12); break;
608 case TY_CSI_PS('m', 105) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 13); break;
609 case TY_CSI_PS('m', 106) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 14); break;
610 case TY_CSI_PS('m', 107) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 15); break;
611
612 case TY_CSI_PS('n', 5) : reportStatus ( ); break;
613 case TY_CSI_PS('n', 6) : reportCursorPosition ( ); break;
614 case TY_CSI_PS('q', 0) : /* IGNORED: LEDs off */ break; //VT100
615 case TY_CSI_PS('q', 1) : /* IGNORED: LED1 on */ break; //VT100
616 case TY_CSI_PS('q', 2) : /* IGNORED: LED2 on */ break; //VT100
617 case TY_CSI_PS('q', 3) : /* IGNORED: LED3 on */ break; //VT100
618 case TY_CSI_PS('q', 4) : /* IGNORED: LED4 on */ break; //VT100
619 case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100
620 case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100
621
622 case TY_CSI_PN('@' ) : _currentScreen->insertChars (p ); break;
623 case TY_CSI_PN('A' ) : _currentScreen->cursorUp (p ); break; //VT100
624 case TY_CSI_PN('B' ) : _currentScreen->cursorDown (p ); break; //VT100
625 case TY_CSI_PN('C' ) : _currentScreen->cursorRight (p ); break; //VT100
626 case TY_CSI_PN('D' ) : _currentScreen->cursorLeft (p ); break; //VT100
627 case TY_CSI_PN('G' ) : _currentScreen->setCursorX (p ); break; //LINUX
628 case TY_CSI_PN('H' ) : _currentScreen->setCursorYX (p, q); break; //VT100
629 case TY_CSI_PN('I' ) : _currentScreen->Tabulate (p ); break;
630 case TY_CSI_PN('L' ) : _currentScreen->insertLines (p ); break;
631 case TY_CSI_PN('M' ) : _currentScreen->deleteLines (p ); break;
632 case TY_CSI_PN('P' ) : _currentScreen->deleteChars (p ); break;
633 case TY_CSI_PN('S' ) : _currentScreen->scrollUp (p ); break;
634 case TY_CSI_PN('T' ) : _currentScreen->scrollDown (p ); break;
635 case TY_CSI_PN('X' ) : _currentScreen->eraseChars (p ); break;
636 case TY_CSI_PN('Z' ) : _currentScreen->backTabulate (p ); break;
637 case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100
638 case TY_CSI_PN('d' ) : _currentScreen->setCursorY (p ); break; //LINUX
639 case TY_CSI_PN('f' ) : _currentScreen->setCursorYX (p, q); break; //VT100
640 case TY_CSI_PN('r' ) : setMargins (p, q); break; //VT100
641 case TY_CSI_PN('y' ) : /* IGNORED: Confidence test */ break; //VT100
642
643 case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break; //VT100
644 case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break; //VT100
645 case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break; //FIXME
646 case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break; //FIXME
647
648 case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break; //VT100
649
650 case TY_CSI_PR('h', 3) : clearScreenAndSetColumns(132); break; //VT100
651 case TY_CSI_PR('l', 3) : clearScreenAndSetColumns(80); break; //VT100
652
653 case TY_CSI_PR('h', 4) : /* IGNORED: soft scrolling */ break; //VT100
654 case TY_CSI_PR('l', 4) : /* IGNORED: soft scrolling */ break; //VT100
655
656 case TY_CSI_PR('h', 5) : _currentScreen-> setMode (MODE_Screen ); break; //VT100
657 case TY_CSI_PR('l', 5) : _currentScreen-> resetMode (MODE_Screen ); break; //VT100
658
659 case TY_CSI_PR('h', 6) : _currentScreen-> setMode (MODE_Origin ); break; //VT100
660 case TY_CSI_PR('l', 6) : _currentScreen-> resetMode (MODE_Origin ); break; //VT100
661 case TY_CSI_PR('s', 6) : _currentScreen-> saveMode (MODE_Origin ); break; //FIXME
662 case TY_CSI_PR('r', 6) : _currentScreen->restoreMode (MODE_Origin ); break; //FIXME
663
664 case TY_CSI_PR('h', 7) : _currentScreen-> setMode (MODE_Wrap ); break; //VT100
665 case TY_CSI_PR('l', 7) : _currentScreen-> resetMode (MODE_Wrap ); break; //VT100
666 case TY_CSI_PR('s', 7) : _currentScreen-> saveMode (MODE_Wrap ); break; //FIXME
667 case TY_CSI_PR('r', 7) : _currentScreen->restoreMode (MODE_Wrap ); break; //FIXME
668
669 case TY_CSI_PR('h', 8) : /* IGNORED: autorepeat on */ break; //VT100
670 case TY_CSI_PR('l', 8) : /* IGNORED: autorepeat off */ break; //VT100
671 case TY_CSI_PR('s', 8) : /* IGNORED: autorepeat on */ break; //VT100
672 case TY_CSI_PR('r', 8) : /* IGNORED: autorepeat off */ break; //VT100
673
674 case TY_CSI_PR('h', 9) : /* IGNORED: interlace */ break; //VT100
675 case TY_CSI_PR('l', 9) : /* IGNORED: interlace */ break; //VT100
676 case TY_CSI_PR('s', 9) : /* IGNORED: interlace */ break; //VT100
677 case TY_CSI_PR('r', 9) : /* IGNORED: interlace */ break; //VT100
678
679 case TY_CSI_PR('h', 12) : /* IGNORED: Cursor blink */ break; //att610
680 case TY_CSI_PR('l', 12) : /* IGNORED: Cursor blink */ break; //att610
681 case TY_CSI_PR('s', 12) : /* IGNORED: Cursor blink */ break; //att610
682 case TY_CSI_PR('r', 12) : /* IGNORED: Cursor blink */ break; //att610
683
684 case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break; //VT100
685 case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break; //VT100
686 case TY_CSI_PR('s', 25) : saveMode (MODE_Cursor ); break; //VT100
687 case TY_CSI_PR('r', 25) : restoreMode (MODE_Cursor ); break; //VT100
688
689 case TY_CSI_PR('h', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
690 case TY_CSI_PR('l', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
691 case TY_CSI_PR('s', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
692 case TY_CSI_PR('r', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
693
694 case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break; //VT100
695 case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break; //VT100
696 case TY_CSI_PR('s', 47) : saveMode (MODE_AppScreen); break; //XTERM
697 case TY_CSI_PR('r', 47) : restoreMode (MODE_AppScreen); break; //XTERM
698
699 case TY_CSI_PR('h', 67) : /* IGNORED: DECBKM */ break; //XTERM
700 case TY_CSI_PR('l', 67) : /* IGNORED: DECBKM */ break; //XTERM
701 case TY_CSI_PR('s', 67) : /* IGNORED: DECBKM */ break; //XTERM
702 case TY_CSI_PR('r', 67) : /* IGNORED: DECBKM */ break; //XTERM
703
704 // XTerm defines the following modes:
705 // SET_VT200_MOUSE 1000
706 // SET_VT200_HIGHLIGHT_MOUSE 1001
707 // SET_BTN_EVENT_MOUSE 1002
708 // SET_ANY_EVENT_MOUSE 1003
709 //
710
711 //Note about mouse modes:
712 //There are four mouse modes which xterm-compatible terminals can support - 1000,1001,1002,1003
713 //Konsole currently supports mode 1000 (basic mouse press and release) and mode 1002 (dragging the mouse).
714 //TODO: Implementation of mouse modes 1001 (something called hilight tracking) and
715 //1003 (a slight variation on dragging the mouse)
716 //
717
718 case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break; //XTERM
719 case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break; //XTERM
720 case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break; //XTERM
721 case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break; //XTERM
722
723 case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
724 case TY_CSI_PR('l', 1001) : resetMode (MODE_Mouse1001); break; //XTERM
725 case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
726 case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
727
728 case TY_CSI_PR('h', 1002) : setMode (MODE_Mouse1002); break; //XTERM
729 case TY_CSI_PR('l', 1002) : resetMode (MODE_Mouse1002); break; //XTERM
730 case TY_CSI_PR('s', 1002) : saveMode (MODE_Mouse1002); break; //XTERM
731 case TY_CSI_PR('r', 1002) : restoreMode (MODE_Mouse1002); break; //XTERM
732
733 case TY_CSI_PR('h', 1003) : setMode (MODE_Mouse1003); break; //XTERM
734 case TY_CSI_PR('l', 1003) : resetMode (MODE_Mouse1003); break; //XTERM
735 case TY_CSI_PR('s', 1003) : saveMode (MODE_Mouse1003); break; //XTERM
736 case TY_CSI_PR('r', 1003) : restoreMode (MODE_Mouse1003); break; //XTERM
737 case TY_CSI_PR('h', 1034) : /* IGNORED: 8bitinput activation */ break; //XTERM
738
739 case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break; //XTERM
740 case TY_CSI_PR('l', 1047) : _screen[1]->clearEntireScreen(); resetMode(MODE_AppScreen); break; //XTERM
741 case TY_CSI_PR('s', 1047) : saveMode (MODE_AppScreen); break; //XTERM
742 case TY_CSI_PR('r', 1047) : restoreMode (MODE_AppScreen); break; //XTERM
743
744 //FIXME: Unitoken: save translations
745 case TY_CSI_PR('h', 1048) : saveCursor ( ); break; //XTERM
746 case TY_CSI_PR('l', 1048) : restoreCursor ( ); break; //XTERM
747 case TY_CSI_PR('s', 1048) : saveCursor ( ); break; //XTERM
748 case TY_CSI_PR('r', 1048) : restoreCursor ( ); break; //XTERM
749
750 //FIXME: every once new sequences like this pop up in xterm.
751 // Here's a guess of what they could mean.
752 case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM
753 case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM
754
755 case TY_CSI_PR('h', 2004) : setMode (MODE_BracketedPaste); break; //XTERM
756 case TY_CSI_PR('l', 2004) : resetMode (MODE_BracketedPaste); break; //XTERM
757 case TY_CSI_PR('s', 2004) : saveMode (MODE_BracketedPaste); break; //XTERM
758 case TY_CSI_PR('r', 2004) : restoreMode (MODE_BracketedPaste); break; //XTERM
759
760 //FIXME: weird DEC reset sequence
761 case TY_CSI_PE('p' ) : /* IGNORED: reset ( ) */ break;
762
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
768
769 case TY_VT52('F' ) : setAndUseCharset (0, '0'); break; //VT52
770 case TY_VT52('G' ) : setAndUseCharset (0, 'B'); break; //VT52
771
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
781
782 case TY_CSI_PG('c' ) : reportSecondaryAttributes( ); break; //VT100
783
784 default : ReportErrorToken(); break;
785 };
786}
787
789{
790 setImageSize(_currentScreen->getLines(),columnCount);
794}
795
796/* ------------------------------------------------------------------------- */
797/* */
798/* Terminal to Host protocol */
799/* */
800/* ------------------------------------------------------------------------- */
801
802/*
803 Outgoing bytes originate from several sources:
804
805 - Replies to Enquieries.
806 - Mouse Events
807 - Keyboard Events
808*/
809
810/*!
811*/
812
813void Vt102Emulation::sendString(const char* s , int length)
814{
815 if ( length >= 0 )
816 emit sendData(s,length);
817 else
818 emit sendData(s,strlen(s));
819}
820
821// Replies ----------------------------------------------------------------- --
822
823// This section copes with replies send as response to an enquiery control code.
824
825/*!
826*/
827
829{ char tmp[20];
830 sprintf(tmp,"\033[%d;%dR",_currentScreen->getCursorY()+1,_currentScreen->getCursorX()+1);
831 sendString(tmp);
832}
833
834/*
835 What follows here is rather obsolete and faked stuff.
836 The correspondent enquieries are neverthenless issued.
837*/
838
839/*!
840*/
841
843{
844 // Primary device attribute response (Request was: ^[[0c or ^[[c (from TT321 Users Guide))
845 // VT220: ^[[?63;1;2;3;6;7;8c (list deps on emul. capabilities)
846 // VT100: ^[[?1;2c
847 // VT101: ^[[?1;0c
848 // VT102: ^[[?6v
849 if (getMode(MODE_Ansi))
850 sendString("\033[?1;2c"); // I'm a VT100
851 else
852 sendString("\033/Z"); // I'm a VT52
853}
854
856{
857 // Seconday device attribute response (Request was: ^[[>0c or ^[[>c)
858 if (getMode(MODE_Ansi))
859 sendString("\033[>0;115;0c"); // Why 115? ;)
860 else
861 sendString("\033/Z"); // FIXME I don't think VT52 knows about it but kept for
862 // konsoles backward compatibility.
863}
864
866// DECREPTPARM
867{ char tmp[100];
868 sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
869 sendString(tmp);
870}
871
872/*!
873*/
874
876{
877 sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
878}
879
880/*!
881*/
882
883#define ANSWER_BACK "" // This is really obsolete VT100 stuff.
884
886{
888}
889
890// Mouse Handling ---------------------------------------------------------- --
891
892/*!
893 Mouse clicks are possibly reported to the client
894 application if it has issued interest in them.
895 They are normally consumed by the widget for copy
896 and paste, but may be propagated from the widget
897 when gui->setMouseMarks is set via setMode(MODE_Mouse1000).
898
899 `x',`y' are 1-based.
900 `ev' (event) indicates the button pressed (0-2)
901 or a general mouse release (3).
902
903 eventType represents the kind of mouse action that occurred:
904 0 = Mouse button press or release
905 1 = Mouse drag
906*/
907
908void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
909{ char tmp[20];
910 if ( cx<1 || cy<1 ) return;
911 // normal buttons are passed as 0x20 + button,
912 // mouse wheel (buttons 4,5) as 0x5c + button
913 if (cb >= 4) cb += 0x3c;
914
915 //Mouse motion handling
916 if ( (getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1 )
917 cb += 0x20; //add 32 to signify motion event
918
919 sprintf(tmp,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20);
920 sendString(tmp);
921}
922
923// Keyboard Handling ------------------------------------------------------- --
924
925#define encodeMode(M,B) BITS(B,getMode(M))
926#define encodeStat(M,B) BITS(B,((ev->modifiers() & (M)) == (M)))
927
928void Vt102Emulation::sendText( const QString& text )
929{
930 if (!text.isEmpty()) {
931 QKeyEvent event(QEvent::KeyPress,
932 0,
933 Qt::NoModifier,
934 text);
935 sendKeyEvent(&event); // expose as a big fat keypress event
936 }
937
938}
939
940void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
941{
942 Qt::KeyboardModifiers modifiers = event->modifiers();
943 KeyboardTranslator::States states = KeyboardTranslator::NoState;
944
945 // get current states
950
951 // lookup key binding
952 if ( _keyTranslator )
953 {
955 event->key() ,
956 modifiers,
957 states );
958
959 // send result to terminal
960 QByteArray textToSend;
961
962 // special handling for the Alt (aka. Meta) modifier. pressing
963 // Alt+[Character] results in Esc+[Character] being sent
964 // (unless there is an entry defined for this particular combination
965 // in the keyboard modifier)
966 bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier;
967 bool wantsAnyModifier = entry.state() & entry.stateMask() & KeyboardTranslator::AnyModifierState;
968
969 if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier)
970 && !event->text().isEmpty() )
971 {
972#if !defined(Q_OS_MAC)
973 textToSend.prepend("\033");
974#endif
975 }
976
977 if ( entry.command() != KeyboardTranslator::NoCommand )
978 {
980 textToSend += getErase();
981 // TODO command handling
982 }
983 else if ( !entry.text().isEmpty() )
984 {
985 textToSend += _codec->fromUnicode(entry.text(true,modifiers));
986 }
987 else if (event->key() == Qt::Key_PageUp)
988 {
989 textToSend += "\033[5~";
990 }
991 else if (event->key() == Qt::Key_PageDown)
992 {
993 textToSend += "\033[6~";
994 }
995 else
996 textToSend += _codec->fromUnicode(event->text());
997
998 sendData( textToSend.constData() , textToSend.length() );
999 }
1000 else
1001 {
1002 // print an error message to the terminal if no key translator has been
1003 // set
1004 QString translatorError = ("No keyboard translator available. "
1005 "The information needed to convert key presses "
1006 "into characters to send to the terminal "
1007 "is missing.");
1008
1009 reset();
1010 receiveData( translatorError.toLatin1().constData() , translatorError.count() );
1011 }
1012}
1013
1014/* ------------------------------------------------------------------------- */
1015/* */
1016/* VT100 Charsets */
1017/* */
1018/* ------------------------------------------------------------------------- */
1019
1020// Character Set Conversion ------------------------------------------------ --
1021
1022/*
1023 The processing contains a VT100 specific code translation layer.
1024 It's still in use and mainly responsible for the line drawing graphics.
1025
1026 These and some other glyphs are assigned to codes (0x5f-0xfe)
1027 normally occupied by the latin letters. Since this codes also
1028 appear within control sequences, the extra code conversion
1029 does not permute with the tokenizer and is placed behind it
1030 in the pipeline. It only applies to tokens, which represent
1031 plain characters.
1032
1033 This conversion it eventually continued in TerminalDisplay.C, since
1034 it might involve VT100 enhanced fonts, which have these
1035 particular glyphs allocated in (0x00-0x1f) in their code page.
1036*/
1037
1038#define CHARSET _charset[_currentScreen==_screen[1]]
1039
1040// Apply current character map.
1041
1042unsigned short Vt102Emulation::applyCharset(unsigned short c)
1043{
1044 if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
1045 if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete
1046 return c;
1047}
1048
1049/*
1050 "Charset" related part of the emulation state.
1051 This configures the VT100 _charset filter.
1052
1053 While most operation work on the current _screen,
1054 the following two are different.
1055*/
1056
1058{
1059 _charset[scrno].cu_cs = 0;
1060 strncpy(_charset[scrno].charset,"BBBB",4);
1061 _charset[scrno].sa_graphic = false;
1062 _charset[scrno].sa_pound = false;
1063 _charset[scrno].graphic = false;
1064 _charset[scrno].pound = false;
1065}
1066
1067void Vt102Emulation::setCharset(int n, int cs) // on both screens.
1068{
1069 _charset[0].charset[n&3] = cs; useCharset(_charset[0].cu_cs);
1070 _charset[1].charset[n&3] = cs; useCharset(_charset[1].cu_cs);
1071}
1072
1074{
1075 CHARSET.charset[n&3] = cs;
1076 useCharset(n&3);
1077}
1078
1080{
1081 CHARSET.cu_cs = n&3;
1082 CHARSET.graphic = (CHARSET.charset[n&3] == '0');
1083 CHARSET.pound = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
1084}
1085
1087{
1090}
1091
1093{
1094 _screen[0]->setMargins(t, b);
1095 _screen[1]->setMargins(t, b);
1096}
1097
1098/*! Save the cursor position and the rendition attribute settings. */
1099
1101{
1102 CHARSET.sa_graphic = CHARSET.graphic;
1103 CHARSET.sa_pound = CHARSET.pound; //This mode is obsolete
1104 // we are not clear about these
1105 //sa_charset = charsets[cScreen->_charset];
1106 //sa_charset_num = cScreen->_charset;
1108}
1109
1110/*! Restore the cursor position and the rendition attribute settings. */
1111
1113{
1114 CHARSET.graphic = CHARSET.sa_graphic;
1115 CHARSET.pound = CHARSET.sa_pound; //This mode is obsolete
1117}
1118
1119/* ------------------------------------------------------------------------- */
1120/* */
1121/* Mode Operations */
1122/* */
1123/* ------------------------------------------------------------------------- */
1124
1125/*
1126 Some of the emulations state is either added to the state of the screens.
1127
1128 This causes some scoping problems, since different emulations choose to
1129 located the mode either to the current _screen or to both.
1130
1131 For strange reasons, the extend of the rendition attributes ranges over
1132 all screens and not over the actual _screen.
1133
1134 We decided on the precise precise extend, somehow.
1135*/
1136
1137// "Mode" related part of the state. These are all booleans.
1138
1140{
1146
1148 // here come obsolete modes
1152}
1153
1155{
1156 _currParm.mode[m] = true;
1157 switch (m)
1158 {
1159 case MODE_Mouse1000:
1160 case MODE_Mouse1001:
1161 case MODE_Mouse1002:
1162 case MODE_Mouse1003:
1163 emit programUsesMouseChanged(false);
1164 break;
1165
1168 break;
1169
1171 setScreen(1);
1172 break;
1173 }
1174 if (m < MODES_SCREEN || m == MODE_NewLine)
1175 {
1176 _screen[0]->setMode(m);
1177 _screen[1]->setMode(m);
1178 }
1179}
1180
1182{
1183 _currParm.mode[m] = false;
1184 switch (m)
1185 {
1186 case MODE_Mouse1000 :
1187 case MODE_Mouse1001 :
1188 case MODE_Mouse1002 :
1189 case MODE_Mouse1003 :
1190 emit programUsesMouseChanged(true);
1191 break;
1192
1195 break;
1196
1198 setScreen(0);
1199 break;
1200 }
1201 if (m < MODES_SCREEN || m == MODE_NewLine)
1202 {
1203 _screen[0]->resetMode(m);
1204 _screen[1]->resetMode(m);
1205 }
1206}
1207
1209{
1210 _saveParm.mode[m] = _currParm.mode[m];
1211}
1212
1214{
1215 if (_saveParm.mode[m])
1216 setMode(m);
1217 else
1218 resetMode(m);
1219}
1220
1222{
1223 return _currParm.mode[m];
1224}
1225
1227{
1229 Qt::Key_Backspace,
1230 Qt::NoModifier);
1231
1232 if ( entry.text().count() > 0 )
1233 return entry.text()[0];
1234 else
1235 return '\b';
1236}
1237
1238/* ------------------------------------------------------------------------- */
1239/* */
1240/* Diagnostic */
1241/* */
1242/* ------------------------------------------------------------------------- */
1243
1244/*! shows the contents of the scan buffer.
1245
1246 This functions is used for diagnostics. It is called by @e ReportErrorToken
1247 to inform about strings that cannot be decoded or handled by the emulation.
1248
1249 @sa ReportErrorToken
1250*/
1251
1252static void hexdump(int* s, int len)
1253{ int i;
1254 for (i = 0; i < len; i++)
1255 {
1256 if (s[i] == '\\')
1257 printf("\\\\");
1258 else
1259 if ((s[i]) > 32 && s[i] < 127)
1260 printf("%c",s[i]);
1261 else
1262 printf("\\%04x(hex)",s[i]);
1263 }
1264}
1265
1267 if (ppos == 0 || (ppos == 1 && (pbuf[0] & 0xff) >= 32)) {
1268 return;
1269 }
1270 printf("token: ");
1271 hexdump(pbuf,ppos);
1272 printf("\n");
1273}
1274
1275/*!
1276*/
1277
1279{
1280 // #ifndef NDEBUG
1281 // printf("undecodable "); scan_buffer_report();
1282 // #endif
1283}
#define COLOR_SPACE_SYSTEM
#define COLOR_SPACE_RGB
#define COLOR_SPACE_256
#define COLOR_SPACE_DEFAULT
static const int LINE_DOUBLEHEIGHT
Definition: Character.h:39
#define RE_REVERSE
Definition: Character.h:45
#define RE_UNDERLINE
Definition: Character.h:44
unsigned short vt100_graphics[32]
static const int LINE_DOUBLEWIDTH
Definition: Character.h:38
#define RE_BOLD
Definition: Character.h:42
#define RE_BLINK
Definition: Character.h:43
@ NOTIFYBELL
The terminal program has triggered a bell event to get the user's attention.
Definition: Emulation.h:58
#define MODE_NewLine
Definition: Screen.h:42
#define MODE_Wrap
Definition: Screen.h:38
#define MODE_Insert
Definition: Screen.h:39
#define MODE_Screen
Definition: Screen.h:40
#define MODE_Origin
Definition: Screen.h:37
#define MODES_SCREEN
Definition: Screen.h:43
#define MODE_Cursor
Definition: Screen.h:41
#define TY_CSI_PE(A)
#define eps(C)
#define CHARSET
static void hexdump(int *s, int len)
#define Xte
#define TY_VT52(A)
#define TY_ESC_DE(A)
#define ANSWER_BACK
#define TY_CSI_PS(A, N)
#define TY_ESC(A)
#define ESC
#define ees(C)
#define SCS
#define epp()
#define les(P, L, C)
#define epe()
#define TY_CTL(A)
#define CNTL(c)
#define CPN
#define ces(C)
#define TY_CHR()
#define CPS
#define DIG
#define TY_CSI_PN(A)
#define TY_CSI_PG(A)
#define CTL
#define TY_CSI_PR(A, N)
#define Xpe
#define lun()
#define eec(C)
#define GRP
#define egt()
#define TY_ESC_CS(A, B)
#define lec(P, L, C)
#define CHR
#define MODE_BracketedPaste
#define MODE_Mouse1001
#define MODE_Mouse1002
#define MODE_Mouse1003
#define MODE_AppScreen
#define MAXARGS
#define MAXPBUF
#define MODE_Ansi
#define MODE_AppCuKeys
#define MODE_AppKeyPad
#define MODE_Mouse1000
Base class for terminal emulation back-ends.
Definition: Emulation.h:119
const QTextCodec * _codec
Definition: Emulation.h:431
Screen * _currentScreen
Definition: Emulation.h:420
void receiveData(const char *buffer, int len)
Processes an incoming stream of characters.
Definition: Emulation.cpp:262
void programUsesMouseChanged(bool usesMouse)
This is emitted when the program running in the shell indicates whether or not it is interested in mo...
void bufferedUpdate()
Schedules an update of attached views.
Definition: Emulation.cpp:310
const KeyboardTranslator * _keyTranslator
Definition: Emulation.h:434
void programBracketedPasteModeChanged(bool bracketedPasteMode)
void changeTabTextColorRequest(int color)
Requests that the color of the text used to represent the tabs associated with this emulation be chan...
void titleChanged(int title, const QString &newTitle)
Emitted when the program running in the terminal wishes to update the session's title.
@ LocaleCodec
Definition: Emulation.h:412
void sendData(const char *data, int len)
Emitted when a buffer of data is ready to send to the standard input of the terminal.
virtual void setImageSize(int lines, int columns)
Change the size of the emulation's image.
Definition: Emulation.cpp:326
void setScreen(int index)
Sets the active screen.
Definition: Emulation.cpp:130
Screen * _screen[2]
Definition: Emulation.h:423
void stateSet(int state)
Emitted when the activity state of the emulation is set.
void setCodec(const QTextCodec *)
Sets the codec used to decode incoming characters.
Definition: Emulation.cpp:163
Represents an association between a key sequence pressed by the user and the character sequence and c...
QByteArray text(bool expandWildCards=false, Qt::KeyboardModifiers modifiers=Qt::NoModifier) const
Returns the character sequence associated with this entry, optionally replacing wildcard '*' characte...
States state() const
Returns a bitwise-OR of the enabled state flags associated with this entry.
Command command() const
Returns the commands associated with this entry.
Qt::KeyboardModifiers modifiers() const
Returns a bitwise-OR of the enabled keyboard modifiers associated with this entry.
States stateMask() const
Returns the state flags which are valid in this entry.
Qt::KeyboardModifiers modifierMask() const
Returns the keyboard modifiers which are valid in this entry.
@ NewLineState
TODO More documentation.
@ NoState
Indicates that no special state is active.
@ AnyModifierState
Indicates that any of the modifier keys is active.
@ AnsiState
Indicates that the terminal is in 'Ansi' mode.
@ AlternateScreenState
Indicates that the alternate screen ( typically used by interactive programs such as screen or vim ) ...
@ CursorKeysState
TODO More documentation.
Entry findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state=NoState) const
Looks for an entry in this keyboard translator which matches the given key code, keyboard modifiers a...
@ EraseCommand
Echos the operating system specific erase character.
@ NoCommand
Indicates that no command is associated with this command sequence.
void backTabulate(int n)
Moves the cursor n tab-stops to the left.
Definition: Screen.cpp:690
void setCursorYX(int y, int x)
Position the cursor at line y, column x.
Definition: Screen.cpp:910
int getCursorY() const
Returns the line which the cursor is positioned on.
Definition: Screen.cpp:945
void clearToEndOfScreen()
Clear the area of the screen from the current cursor position to the end of the screen.
Definition: Screen.cpp:1103
void deleteChars(int n)
Delete n characters beginning from the current cursor position.
Definition: Screen.cpp:247
void setMargins(int topLine, int bottomLine)
Sets the margins for scrolling the screen.
Definition: Screen.cpp:180
void reset(bool clearScreen=true)
Resets the state of the screen.
Definition: Screen.cpp:639
void clearEntireScreen()
Clear the whole screen, moving the current screen contents into the history first.
Definition: Screen.cpp:1113
void saveCursor()
Saves the current position and appearence (text color and style) of the cursor.
Definition: Screen.cpp:341
void clearToBeginOfLine()
Clears from the current cursor position to the beginning of the line.
Definition: Screen.cpp:1138
void clearEntireLine()
Clears the whole of the line on which the cursor is currently positioned.
Definition: Screen.cpp:1143
void setCursorY(int y)
Position the cursor on line y.
Definition: Screen.cpp:922
void BackSpace()
Moves the cursor one column to the left and erases the character at the new cursor position.
Definition: Screen.cpp:667
void insertChars(int n)
Insert n blank characters beginning from the current cursor position.
Definition: Screen.cpp:268
void Return()
Moves the cursor to the beginning of the current line.
Definition: Screen.cpp:935
void changeTabStop(bool set)
Sets or removes a tab stop at the cursor's current column.
Definition: Screen.cpp:706
void cursorDown(int n)
Move the cursor down by n lines.
Definition: Screen.cpp:144
void setDefaultMargins()
Resets the scrolling margins back to the top and bottom lines of the screen.
Definition: Screen.cpp:422
void setCursorX(int x)
Position the cursor at column x.
Definition: Screen.cpp:915
void NewLine()
Moves the cursor down one line, if the MODE_NewLine mode flag is enabled then the cursor is returned ...
Definition: Screen.cpp:729
void clearTabStops()
Clears all the tab stops.
Definition: Screen.cpp:701
void clearToBeginOfScreen()
Clear the area of the screen from the current cursor position to the start of the screen.
Definition: Screen.cpp:1108
void eraseChars(int n)
Erase n characters beginning from the current cursor position.
Definition: Screen.cpp:240
void helpAlign()
Fills the entire screen with the letter 'E'.
Definition: Screen.cpp:1128
int getCursorX() const
Returns the column which the cursor is positioned at.
Definition: Screen.cpp:940
void Tabulate(int n=1)
Moves the cursor n tab-stops to the right.
Definition: Screen.cpp:679
void cursorUp(int n)
Move the cursor up by n lines.
Definition: Screen.cpp:129
void clearSelection()
Clears the current selection.
Definition: Screen.cpp:1194
void setLineProperty(LineProperty property, bool enable)
Sets or clears an attribute of the current line.
Definition: Screen.cpp:1551
void setMode(int mode)
Sets (enables) the specified screen mode.
Definition: Screen.cpp:302
void setDefaultRendition()
Resets the cursor's color back to the default and sets the character's rendition flags back to the de...
Definition: Screen.cpp:1160
void scrollDown(int n)
Scroll the scrolling region of the screen down by n lines.
Definition: Screen.cpp:884
void scrollUp(int n)
Scroll the scrolling region of the screen up by n lines.
Definition: Screen.cpp:855
void NextLine()
Moves the cursor down one line and positions it at the beginning of the line.
Definition: Screen.cpp:234
void cursorRight(int n)
Move the cursor to the right by n columns.
Definition: Screen.cpp:173
void restoreMode(int mode)
Restores the state of a screen mode saved by calling saveMode()
Definition: Screen.cpp:331
void resetRendition(int rendition)
Disables the given rendition flag.
Definition: Screen.cpp:1154
void restoreCursor()
Restores the position and appearence of the cursor.
Definition: Screen.cpp:350
void setBackColor(int space, int color)
Sets the cursor's background color.
Definition: Screen.cpp:1178
void ShowCharacter(unsigned short c)
Displays a new character at the current cursor position.
Definition: Screen.cpp:752
void deleteLines(int n)
Removes n lines beginning from the current cursor position.
Definition: Screen.cpp:281
void resetMode(int mode)
Resets (clears) the specified screen mode.
Definition: Screen.cpp:313
void index()
Move the cursor down one line.
Definition: Screen.cpp:207
void reverseIndex()
Move the cursor up one line.
Definition: Screen.cpp:218
void clearToEndOfLine()
Clears from the current cursor position to the end of the line.
Definition: Screen.cpp:1133
int getLines()
Return the number of lines.
Definition: Screen.h:377
void cursorLeft(int n)
Move the cursor to the left by n columns.
Definition: Screen.cpp:159
void setForeColor(int space, int color)
Sets the cursor's foreground color.
Definition: Screen.cpp:1168
void insertLines(int n)
Inserts lines beginning from the current cursor position.
Definition: Screen.cpp:292
QTimer * _titleUpdateTimer
void setAndUseCharset(int n, int cs)
virtual void setMode(int mode)
bool getMode(int mode)
void clearScreenAndSetColumns(int columnCount)
void setMargins(int top, int bottom)
virtual void reset()
Resets the state of the terminal.
void setCharset(int n, int cs)
virtual char getErase() const
TODO Document me.
void addDigit(int dig)
void reportSecondaryAttributes()
void restoreMode(int mode)
void useCharset(int n)
virtual void sendMouseEvent(int buttons, int column, int line, int eventType)
virtual void sendKeyEvent(QKeyEvent *)
virtual void receiveChar(int cc)
Processes an incoming character.
virtual void sendText(const QString &text)
void reportTerminalParms(int p)
unsigned short applyCharset(unsigned short c)
QHash< int, QString > _pendingTitleUpdates
virtual void clearEntireScreen()
Copies the current image into the history and clears the screen.
Vt102Emulation()
Constructs a new emulation.
void reportCursorPosition()
void saveMode(int mode)
void resetCharset(int scrno)
CharCodes _charset[2]
virtual void resetMode(int mode)
virtual void sendString(const char *, int length=-1)
void tau(int code, int p, int q)
void pushToToken(int cc)
F77_RET_T const F77_INT F77_CMPLX * A
F77_RET_T const F77_INT & N
T::size_type strlen(const typename T::value_type *str)
Definition: oct-string.cc:85
char charset[4]
bool sa_graphic
bool mode[(MODES_SCREEN+9)]
F77_RET_T len
Definition: xerbla.cc:61