source: ogBrowser-Git/qtermwidget/src/Vt102Emulation.cpp @ 0c33630

jenkinsmain
Last change on this file since 0c33630 was 8ab4781, checked in by adelcastillo <adelcastillo@…>, 15 years ago

Cambiando a qmake de nuevo.

git-svn-id: https://opengnsys.es/svn/trunk@518 a21b9725-9963-47de-94b9-378ad31fedc9

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