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