~larryprice/acolyterm/release-0.1

« back to all changes in this revision

Viewing changes to src/plugin/konsole/Vt102Emulation.cpp

  • Committer: Larry Price
  • Date: 2016-06-15 14:47:59 UTC
  • Revision ID: larry.price@canonical.com-20160615144759-6wopn0gxwgta3x1n
Updating QMLTermWidget and removing unnecessary konsole codebase

Show diffs side-by-side

added added

removed removed

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